From 624aa62836a1de3818dec44590a4ca6e6f998abb Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 4 Nov 2016 18:49:58 -0700 Subject: [PATCH] IsMakingProgress should compute current token position properly (#14852) --- .../CSharp/Portable/Parser/SyntaxParser.cs | 15 ++++++++----- .../Test/Emit/CodeGen/CodeGenTupleTest.cs | 22 +++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs b/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs index b3dc2c611b5..b6430e8b2f2 100644 --- a/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs @@ -25,8 +25,8 @@ internal abstract partial class SyntaxParser : IDisposable private SyntaxToken _currentToken; private ArrayElement[] _lexedTokens; private GreenNode _prevTokenTrailingTrivia; - private int _firstToken; - private int _tokenOffset; + private int _firstToken; // The position of _lexedTokens[0] (or _blendedTokens[0]). + private int _tokenOffset; // The index of the current token within _lexedTokens or _blendedTokens. private int _tokenCount; private int _resetCount; private int _resetStart; @@ -135,7 +135,7 @@ private void PreLex() protected ResetPoint GetResetPoint() { - var pos = _firstToken + _tokenOffset; + var pos = CurrentTokenPosition; if (_resetCount == 0) { _resetStart = pos; // low water mark @@ -1079,16 +1079,19 @@ protected bool IsFeatureEnabled(MessageID feature) /// while (IsMakingProgress(ref tokenProgress)) /// It should be used as a guardrail, not as a crutch, so it asserts if no progress was made. /// - protected bool IsMakingProgress(ref int lastTokenOffset) + protected bool IsMakingProgress(ref int lastTokenPosition) { - if (_tokenOffset > lastTokenOffset) + var pos = CurrentTokenPosition; + if (pos > lastTokenPosition) { - lastTokenOffset = _tokenOffset; + lastTokenPosition = pos; return true; } Debug.Assert(false); return false; } + + private int CurrentTokenPosition => _firstToken + _tokenOffset; } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs index c44bcdaa3c1..4d94559d38d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs @@ -19902,5 +19902,27 @@ class C2: ClassLibrary1.C1 Assert.Equal("ref (System.Int32, dynamic) ClassLibrary1.C1.Foo.get", b.GetMethod.ToTestDisplayString()); } + [Fact] + [WorkItem(14649, "https://github.com/dotnet/roslyn/issues/14649")] + public void ParseLongLambda() + { + string filler = string.Join("\r\n", Enumerable.Range(1, 1000).Select(i => $"int y{i};")); + string parameters = string.Join(", ", Enumerable.Range(1, 2000).Select(i => $"int x{i}")); + string text = @" +class C +{ + " + filler + @" + public void M() + { + N((" + parameters + @") => 1); + } +} +"; + // This is designed to trigger a shift of the array of lexed tokens (see AddLexedTokenSlot) while + // parsing lambda parameters + var tree = SyntaxFactory.ParseSyntaxTree(text, CSharpParseOptions.Default); + // no assertion + } + } } \ No newline at end of file -- GitLab