diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs index 12333eb2a8..d5df7fe95e 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs @@ -94,13 +94,19 @@ namespace ICSharpCode.NRefactory.Visitors return base.VisitWithStatement(withStatement, data); } - Stack blockStack = new Stack(); + Stack endLocationStack = new Stack(); + + Location CurrentEndLocation { + get { + return (endLocationStack.Count == 0) ? Location.Empty : endLocationStack.Peek(); + } + } public override object VisitBlockStatement(BlockStatement blockStatement, object data) { - blockStack.Push(blockStatement); + endLocationStack.Push(blockStatement.EndLocation); base.VisitBlockStatement(blockStatement, data); - blockStack.Pop(); + endLocationStack.Pop(); return null; } @@ -112,7 +118,7 @@ namespace ICSharpCode.NRefactory.Visitors AddVariable(localVariableDeclaration.GetTypeForVariable(i), varDecl.Name, localVariableDeclaration.StartLocation, - (blockStack.Count == 0) ? new Location(-1, -1) : blockStack.Peek().EndLocation, + CurrentEndLocation, (localVariableDeclaration.Modifier & Modifiers.Const) == Modifiers.Const); } return base.VisitLocalVariableDeclaration(localVariableDeclaration, data); @@ -126,8 +132,32 @@ namespace ICSharpCode.NRefactory.Visitors return base.VisitAnonymousMethodExpression(anonymousMethodExpression, data); } - // ForStatement and UsingStatement use a LocalVariableDeclaration, - // so they don't need to be visited separately + public override object VisitForNextStatement(ForNextStatement forNextStatement, object data) + { + // uses LocalVariableDeclaration, we just have to put the end location on the stack + endLocationStack.Push(forNextStatement.EmbeddedStatement.EndLocation); + base.VisitForNextStatement(forNextStatement, data); + endLocationStack.Pop(); + return null; + } + + public override object VisitForStatement(ForStatement forStatement, object data) + { + // uses LocalVariableDeclaration, we just have to put the end location on the stack + endLocationStack.Push(forStatement.EmbeddedStatement.EndLocation); + base.VisitForStatement(forStatement, data); + endLocationStack.Pop(); + return null; + } + + public override object VisitUsingStatement(UsingStatement usingStatement, object data) + { + // uses LocalVariableDeclaration, we just have to put the end location on the stack + endLocationStack.Push(usingStatement.EmbeddedStatement.EndLocation); + base.VisitUsingStatement(usingStatement, data); + endLocationStack.Pop(); + return null; + } public override object VisitForeachStatement(ForeachStatement foreachStatement, object data) { @@ -146,8 +176,6 @@ namespace ICSharpCode.NRefactory.Visitors return foreachStatement.EmbeddedStatement.AcceptVisitor(this, data); } - - public override object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) { if (tryCatchStatement == null) { diff --git a/src/Main/Base/Test/NRefactoryResolverTests.cs b/src/Main/Base/Test/NRefactoryResolverTests.cs index 072332d71f..be53276e0a 100644 --- a/src/Main/Base/Test/NRefactoryResolverTests.cs +++ b/src/Main/Base/Test/NRefactoryResolverTests.cs @@ -772,6 +772,27 @@ namespace A.B { TypeResolveResult trr = Resolve(program, "C.D", 7); Assert.AreEqual("A.B.C.D", trr.ResolvedClass.FullyQualifiedName, "trr.ResolvedClass.FullyQualifiedName"); } + + [Test] + public void LoopVariableScopeTest() + { + string program = @"using System; +class TestClass { + void Test() { + for (int i = 0; i < 10; i++) { + + } + for (long i = 0; i < 10; i++) { + + } + } +} +"; + LocalResolveResult lr = Resolve(program, "i", 5); + Assert.AreEqual("System.Int32", lr.ResolvedType.FullyQualifiedName); + lr = Resolve(program, "i", 8); + Assert.AreEqual("System.Int64", lr.ResolvedType.FullyQualifiedName); + } #endregion #region Import class tests