diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs index 8c3c963278..eaf63795ba 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs @@ -165,19 +165,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver OverloadResolution o; o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(int).ToTypeReference().Resolve(context) }); Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m1)); - Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyContraint, o.AddCandidate(m2)); + Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m2)); Assert.AreSame(m1, o.BestCandidate); // Call: Foo(); o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(string).ToTypeReference().Resolve(context) }); - Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyContraint, o.AddCandidate(m1)); + Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m1)); Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m2)); Assert.AreSame(m2, o.BestCandidate); // Call: Foo(); o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(int?).ToTypeReference().Resolve(context) }); - Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyContraint, o.AddCandidate(m1)); - Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyContraint, o.AddCandidate(m2)); + Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m1)); + Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m2)); Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m3)); Assert.AreSame(m3, o.BestCandidate); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs index b449055dd4..418dcd574f 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs @@ -2,6 +2,7 @@ // This code is distributed under MIT X11 license (for details please see \doc\license.txt) using System; +using System.Collections.Generic; using ICSharpCode.NRefactory.TypeSystem; using NUnit.Framework; @@ -35,16 +36,29 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } /// - /// Adds a using to the current top-level using scope. + /// Adds a using to the current using scope. /// protected void AddUsing(string namespaceName) + { + resolver.UsingScope.Usings.Add(MakeReference(namespaceName)); + } + + /// + /// Adds a using alias to the current using scope. + /// + protected void AddUsingAlias(string alias, string target) + { + resolver.UsingScope.UsingAliases.Add(new KeyValuePair(alias, MakeReference(target))); + } + + protected ITypeOrNamespaceReference MakeReference(string namespaceName) { string[] nameParts = namespaceName.Split('.'); ITypeOrNamespaceReference r = new SimpleTypeOrNamespaceReference(nameParts[0], new ITypeReference[0], resolver.CurrentTypeDefinition, resolver.UsingScope, true); for (int i = 1; i < nameParts.Length; i++) { r = new MemberTypeOrNamespaceReference(r, nameParts[i], new ITypeReference[0], resolver.CurrentTypeDefinition, resolver.UsingScope); } - resolver.UsingScope.Usings.Add(r); + return r; } protected IType ResolveType(Type type) diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/SimpleNameLookupTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/SimpleNameLookupTests.cs index de7cd2e65d..4bbdd31961 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/SimpleNameLookupTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/SimpleNameLookupTests.cs @@ -48,5 +48,59 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("String", new IType[0]); Assert.AreEqual("System.String", trr.Type.FullName); } + + [Test] + public void GlobalIsUnknownIdentifier() + { + Assert.IsTrue(resolver.ResolveSimpleName("global", new IType[0]).IsError); + } + + [Test] + public void GlobalIsAlias() + { + NamespaceResolveResult nrr = (NamespaceResolveResult)resolver.ResolveAlias("global"); + Assert.AreEqual("", nrr.NamespaceName); + } + + [Test] + public void AliasToImportedType() + { + AddUsing("System"); + AddUsingAlias("x", "String"); + TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("x", new IType[0]); + // Unknown type (as String isn't looked up in System) + Assert.AreSame(SharedTypes.UnknownType, trr.Type); + } + + [Test] + public void AliasToImportedType2() + { + AddUsing("System"); + resolver.UsingScope = new UsingScope(resolver.UsingScope, "SomeNamespace"); + AddUsingAlias("x", "String"); + TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("x", new IType[0]); + Assert.AreEqual("System.String", trr.Type.FullName); + } + + [Test] + public void AliasOperatorOnTypeAlias() + { + AddUsingAlias("x", "System.String"); + Assert.IsTrue(resolver.ResolveAlias("x").IsError); + } + + [Test] + public void AliasOperatorOnNamespaceAlias() + { + AddUsingAlias("x", "System.Collections.Generic"); + NamespaceResolveResult nrr = (NamespaceResolveResult)resolver.ResolveAlias("x"); + Assert.AreEqual("System.Collections.Generic", nrr.NamespaceName); + } + + [Test] + public void AliasOperatorOnNamespace() + { + Assert.IsTrue(resolver.ResolveAlias("System").IsError); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Dom/AbstractDomVisitor.cs b/ICSharpCode.NRefactory/CSharp/Dom/AbstractDomVisitor.cs index 55d63601a3..383b1200fc 100644 --- a/ICSharpCode.NRefactory/CSharp/Dom/AbstractDomVisitor.cs +++ b/ICSharpCode.NRefactory/CSharp/Dom/AbstractDomVisitor.cs @@ -32,10 +32,10 @@ namespace ICSharpCode.NRefactory.CSharp { protected S VisitChildren (INode node, T data) { - INode child = node.FirstChild as INode; + INode child = node.FirstChild; while (child != null) { child.AcceptVisitor (this, data); - child = child.NextSibling as INode; + child = child.NextSibling; } return default (S); } diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs b/ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs index 94fdb11a28..5ad8d54984 100644 --- a/ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs +++ b/ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs @@ -1452,8 +1452,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver // then look for aliases: if (k == 0) { if (n.ExternAliases.Contains(identifier)) { - // TODO: implement extern alias support - return new NamespaceResolveResult(string.Empty); + return ResolveExternAlias(identifier); } if (lookupMode != SimpleNameLookupMode.TypeInUsingDeclaration || n != this.UsingScope) { foreach (var pair in n.UsingAliases) { @@ -1502,8 +1501,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver return new NamespaceResolveResult(string.Empty); for (UsingScope n = this.UsingScope; n != null; n = n.Parent) { if (n.ExternAliases.Contains(identifier)) { - // TODO: implement extern alias support - return new NamespaceResolveResult(string.Empty); + return ResolveExternAlias(identifier); } foreach (var pair in n.UsingAliases) { if (pair.Key == identifier) { @@ -1513,6 +1511,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } return ErrorResult; } + + ResolveResult ResolveExternAlias(string alias) + { + // TODO: implement extern alias support + return new NamespaceResolveResult(string.Empty); + } #endregion #region ResolveMemberAccess @@ -1667,7 +1671,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } #endregion - #region This/Base + #region Resolve This/Base Reference /// /// Resolves 'this'. /// diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolution.cs b/ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolution.cs index ca5873cb7d..ba251ef279 100644 --- a/ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolution.cs +++ b/ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolution.cs @@ -232,7 +232,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver candidate.ParameterTypes[i] = candidate.ParameterTypes[i].AcceptVisitor(substitution); } if (!substitution.ConstraintsValid) - candidate.AddError(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyContraint); + candidate.AddError(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint); } sealed class ConstraintValidatingSubstitution : TypeVisitor diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolutionErrors.cs b/ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolutionErrors.cs index 672744eb4e..a9de1e4cdc 100644 --- a/ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolutionErrors.cs +++ b/ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolutionErrors.cs @@ -27,9 +27,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver WrongNumberOfTypeArguments = 0x0008, /// /// After substituting type parameters with the inferred types; a constructed type within the formal parameters - /// does not satisfy its contraint. + /// does not satisfy its constraint. /// - ConstructedTypeDoesNotSatisfyContraint = 0x0010, + ConstructedTypeDoesNotSatisfyConstraint = 0x0010, /// /// No argument was mapped to a non-optional parameter /// diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs index 8777b0728a..7b1248c52f 100644 --- a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs @@ -161,7 +161,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver public override ResolveResult VisitDirectionExpression(DirectionExpression directionExpression, object data) { ResolveResult rr = Resolve(directionExpression.Expression); - return new ResolveResult(new ByReferenceType(rr.Type)); + return new ByReferenceResolveResult(rr.Type, directionExpression.FieldDirection == FieldDirection.Out); } public override ResolveResult VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)