Browse Source

Allow using AstType.ToTypeReference().Resolve(compilation.TypeResolveContext) - this will now resolve in the global namespace.

Fixed increment operator on System.Char.
newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
bb822e94d4
  1. 8
      ICSharpCode.NRefactory.CSharp/Ast/AstType.cs
  2. 74
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  3. 6
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeOrNamespaceReference.cs
  4. 7
      ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs
  5. 5
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  6. 9
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnaryOperatorTests.cs
  7. 3
      NRefactory.sln

8
ICSharpCode.NRefactory.CSharp/Ast/AstType.cs

@ -110,9 +110,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -110,9 +110,11 @@ namespace ICSharpCode.NRefactory.CSharp
/// Create an ITypeReference for this AstType.
/// </summary>
/// <remarks>
/// The resulting type reference requires a
/// <see cref="ICSharpCode.NRefactory.CSharp.TypeSystem.CSharpTypeResolveContext"/>
/// to be resolved.
/// The resulting type reference will read the context information from the
/// <see cref="ITypeResolveContext"/>:
/// For resolving type parameters, the CurrentTypeDefinition/CurrentMember is used.
/// For resolving simple names, the current namespace and usings from the CurrentUsingScope
/// (on CSharpTypeResolveContext only) is used.
/// </remarks>
public abstract ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type);

74
ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs

@ -388,7 +388,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -388,7 +388,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// C# 4.0 spec: §7.6.9 Postfix increment and decrement operators
// C# 4.0 spec: §7.7.5 Prefix increment and decrement operators
TypeCode code = ReflectionHelper.GetTypeCode(type);
if ((code >= TypeCode.SByte && code <= TypeCode.Decimal) || type.Kind == TypeKind.Enum || type.Kind == TypeKind.Pointer)
if ((code >= TypeCode.Char && code <= TypeCode.Decimal) || type.Kind == TypeKind.Enum || type.Kind == TypeKind.Pointer)
return UnaryOperatorResolveResult(expression.Type, op, expression);
else
return new ErrorResolveResult(expression.Type);
@ -1352,7 +1352,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1352,7 +1352,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return r;
}
if (context.CurrentUsingScope != null) {
if (context.CurrentUsingScope == null) {
// If no using scope was specified, we still need to look in the global namespace:
r = LookInUsingScopeNamespace(null, compilation.RootNamespace, identifier, typeArguments, parameterizeResultType);
} else {
if (k == 0 && lookupMode != SimpleNameLookupMode.TypeInUsingDeclaration) {
if (!context.CurrentUsingScope.ResolveCache.TryGetValue(identifier, out r)) {
r = LookInCurrentUsingScope(identifier, typeArguments, false, false);
@ -1361,9 +1364,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1361,9 +1364,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} else {
r = LookInCurrentUsingScope(identifier, typeArguments, lookupMode == SimpleNameLookupMode.TypeInUsingDeclaration, parameterizeResultType);
}
if (r != null)
return r;
}
if (r != null)
return r;
if (typeArguments.Count == 0 && identifier == "dynamic") {
return new TypeResolveResult(SpecialType.Dynamic);
@ -1418,36 +1421,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1418,36 +1421,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult LookInCurrentUsingScope(string identifier, IList<IType> typeArguments, bool isInUsingDeclaration, bool parameterizeResultType)
{
int k = typeArguments.Count;
// look in current namespace definitions
ResolvedUsingScope currentUsingScope = this.CurrentUsingScope;
for (ResolvedUsingScope u = currentUsingScope; u != null; u = u.Parent) {
INamespace n = u.Namespace;
// first look for a namespace
if (k == 0 && n != null) {
INamespace childNamespace = n.GetChildNamespace(identifier);
if (childNamespace != null) {
if (u.HasAlias(identifier))
return new AmbiguousTypeResolveResult(new UnknownType(null, identifier));
return new NamespaceResolveResult(childNamespace);
}
}
// then look for a type
if (n != null) {
ITypeDefinition def = n.GetTypeDefinition(identifier, k);
if (def != null) {
IType result = def;
if (parameterizeResultType && k > 0) {
result = new ParameterizedType(def, typeArguments);
}
if (u.HasAlias(identifier))
return new AmbiguousTypeResolveResult(result);
else
return new TypeResolveResult(result);
}
}
var resultInNamespace = LookInUsingScopeNamespace(u, u.Namespace, identifier, typeArguments, parameterizeResultType);
if (resultInNamespace != null)
return resultInNamespace;
// then look for aliases:
if (k == 0) {
if (typeArguments.Count == 0) {
if (u.ExternAliases.Contains(identifier)) {
return ResolveExternAlias(identifier);
}
@ -1463,10 +1444,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1463,10 +1444,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (!(isInUsingDeclaration && u == currentUsingScope)) {
IType firstResult = null;
foreach (var importedNamespace in u.Usings) {
ITypeDefinition def = importedNamespace.GetTypeDefinition(identifier, k);
ITypeDefinition def = importedNamespace.GetTypeDefinition(identifier, typeArguments.Count);
if (def != null) {
IType resultType;
if (parameterizeResultType && k > 0)
if (parameterizeResultType && typeArguments.Count > 0)
resultType = new ParameterizedType(def, typeArguments);
else
resultType = def;
@ -1485,6 +1466,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1485,6 +1466,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
return null;
}
ResolveResult LookInUsingScopeNamespace(ResolvedUsingScope usingScope, INamespace n, string identifier, IList<IType> typeArguments, bool parameterizeResultType)
{
if (n == null)
return null;
// first look for a namespace
int k = typeArguments.Count;
if (k == 0) {
INamespace childNamespace = n.GetChildNamespace(identifier);
if (childNamespace != null) {
if (usingScope != null && usingScope.HasAlias(identifier))
return new AmbiguousTypeResolveResult(new UnknownType(null, identifier));
return new NamespaceResolveResult(childNamespace);
}
}
// then look for a type
ITypeDefinition def = n.GetTypeDefinition(identifier, k);
if (def != null) {
IType result = def;
if (parameterizeResultType && k > 0) {
result = new ParameterizedType(def, typeArguments);
}
if (usingScope != null && usingScope.HasAlias(identifier))
return new AmbiguousTypeResolveResult(result);
else
return new TypeResolveResult(result);
}
return null;
}
bool TopLevelTypeDefinitionIsAccessible(ITypeDefinition typeDef)
{

6
ICSharpCode.NRefactory.CSharp/TypeSystem/TypeOrNamespaceReference.cs

@ -58,7 +58,11 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -58,7 +58,11 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
// to what we're doing with ConstantExpression.
// However, in almost all cases this will work correctly - if the resulting type is only available in the
// nested compilation and not in this, we wouldn't be able to map it anyways.
return ResolveType(new CSharpResolver((CSharpTypeResolveContext)context));
var ctx = context as CSharpTypeResolveContext;
if (ctx == null) {
ctx = new CSharpTypeResolveContext(context.CurrentAssembly ?? context.Compilation.MainAssembly, null, context.CurrentTypeDefinition, context.CurrentMember);
}
return ResolveType(new CSharpResolver(ctx));
// A potential issue might be this scenario:

7
ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs

@ -80,6 +80,13 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -80,6 +80,13 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
Assert.AreEqual(genericInterfaceOfString, interfaceMethod2.DeclaringType);
Assert.IsTrue(interfaceMethod2.Parameters[1].IsRef);
}
[Test]
public void ConvertStandaloneTypeReference()
{
var typeRef = new MemberType(new SimpleType("System"), "Array").ToTypeReference();
Assert.AreEqual(compilation.FindType(KnownTypeCode.Array), typeRef.Resolve(compilation.TypeResolveContext));
}
}
[TestFixture]

5
ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs

@ -61,8 +61,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -61,8 +61,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void SimpleNameLookupWithoutContext()
{
// nothing should be found without specifying any UsingScope - however, the resolver also must not crash
Assert.IsTrue(resolver.WithCurrentUsingScope(null).ResolveSimpleName("System", new IType[0]).IsError);
// without any using scope, we still want to find elements of the global namespace:
var nrr = (NamespaceResolveResult)resolver.WithCurrentUsingScope(null).ResolveSimpleName("System", new IType[0]);
Assert.AreEqual("System", nrr.NamespaceName);
}
[Test]

9
ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnaryOperatorTests.cs

@ -71,6 +71,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -71,6 +71,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
TestOperator(UnaryOperatorType.Increment, MakeResult(typeof(byte)),
Conversion.IdentityConversion, typeof(byte));
TestOperator(UnaryOperatorType.PostIncrement, MakeResult(typeof(char)),
Conversion.IdentityConversion, typeof(char));
TestOperator(UnaryOperatorType.PostIncrement, MakeResult(typeof(float)),
Conversion.IdentityConversion, typeof(float));
TestOperator(UnaryOperatorType.PostIncrement, MakeResult(typeof(decimal)),
Conversion.IdentityConversion, typeof(decimal));
TestOperator(UnaryOperatorType.Decrement, MakeResult(typeof(ulong)),
Conversion.IdentityConversion, typeof(ulong));

3
NRefactory.sln

@ -1,12 +1,13 @@ @@ -1,12 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.2.0.8299-alpha
# SharpDevelop 4.2.0.8528-beta
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}"
ProjectSection(SolutionItems) = preProject
README = README
doc\TODO = doc\TODO
Packages\ICSharpCode.NRefactory.nuspec = Packages\ICSharpCode.NRefactory.nuspec
ICSharpCode.NRefactory.snk = ICSharpCode.NRefactory.snk
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory", "ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj", "{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}"

Loading…
Cancel
Save