diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart index 2cefe496b92..151ee550f10 100644 --- a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart +++ b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart @@ -356,6 +356,22 @@ abstract class AbstractScanner implements Scanner { appendToken(new KeywordToken(keyword, tokenStart, comments)); } + int _getLineOf(Token token) { + if (lineStarts.isEmpty) return -1; + final int offset = token.offset; + int low = 0, high = lineStarts.length - 1; + while (low < high) { + int mid = high - ((high - low) >> 1); // Get middle, rounding up. + int pivot = lineStarts[mid]; + if (pivot <= offset) { + low = mid; + } else { + high = mid - 1; + } + } + return low; + } + /// Find the indentation of the logical line of [token]. /// /// By logical take this as an example: @@ -415,18 +431,7 @@ abstract class AbstractScanner implements Scanner { } // Now find the line of [token]. - final int offset = token.offset; - int low = 0, high = lineStarts.length - 1; - while (low < high) { - int mid = high - ((high - low) >> 1); // Get middle, rounding up. - int pivot = lineStarts[mid]; - if (pivot <= offset) { - low = mid; - } else { - high = mid - 1; - } - } - final int lineIndex = low; + final int lineIndex = _getLineOf(token); if (lineIndex == 0) { // On first line. return tokens.next?.charOffset ?? -1; @@ -463,10 +468,12 @@ abstract class AbstractScanner implements Scanner { Token? lastMismatch; while (next != null && !next.isEof) { if (next.isA(TokenType.OPEN_CURLY_BRACKET)) { - int indentOfNext = _spacesAtStartOfLogicalLineOf(next); - if (indentOfNext >= 0 && - indentOfNext != _spacesAtStartOfLogicalLineOf(next.endGroup!)) { - lastMismatch = next; + if (_getLineOf(next) != _getLineOf(next.endGroup!)) { + int indentOfNext = _spacesAtStartOfLogicalLineOf(next); + if (indentOfNext >= 0 && + indentOfNext != _spacesAtStartOfLogicalLineOf(next.endGroup!)) { + lastMismatch = next; + } } } next = next.next; diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart new file mode 100644 index 00000000000..7d5c7684340 --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart @@ -0,0 +1,25 @@ +// Without specific missing-brace recovery, we'll end up with: +// * Class Foo, member Foo.foo_method1, Foo.toplevel_method1, Foo.toplevel_method2 +// With specific missing-brace recovery, we'll end up with the correct: +// * Class Foo, members Foo.foo_method1, Foo.foo_method2 +// * Top-level members toplevel_method1, toplevel_method2 + +class Foo { + void foo_method1(dynamic input) { + if (1 + 1 == 2) { + foo_method2({1, 2, 3 /* missing: }*/) + // missing: } + } + + void foo_method2(dynamic whatever) { + // bla + } +} + +void toplevel_method1() { + // bla +} + +void toplevel_method2() { + // bla +} diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.expect new file mode 100644 index 00000000000..ac177301b24 --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.expect @@ -0,0 +1,137 @@ +Problems reported: + +parser/error_recovery/with_outline/typing_14:10:43: Expected ';' after this. + foo_method2({1, 2, 3 /* missing: }*/) + ^ + +parser/error_recovery/with_outline/typing_14:10:19: Can't find '}' to match '{'. + foo_method2({1, 2, 3 /* missing: }*/) + ^ + +parser/error_recovery/with_outline/typing_14:9:21: Can't find '}' to match '{'. + if (1 + 1 == 2) { + ^ + +beginCompilationUnit(class) + beginMetadataStar(class) + endMetadataStar(0) + beginClassOrMixinOrNamedMixinApplicationPrelude(class) + handleIdentifier(Foo, classOrMixinDeclaration) + handleNoTypeVariables({) + beginClassDeclaration(class, null, null, null, null, null, null, null, null, Foo) + handleNoType(Foo) + handleClassExtends(null, 1) + handleClassNoWithClause() + handleImplements(null, 0) + handleClassHeader(class, class, null) + beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {) + beginMetadataStar(void) + endMetadataStar(0) + beginMember() + beginMethod(DeclarationKind.Class, null, null, null, null, null, null, foo_method1, Foo) + handleVoidKeyword(void) + handleIdentifier(foo_method1, methodDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.NonStaticMethod) + beginMetadataStar(dynamic) + endMetadataStar(0) + beginFormalParameter(dynamic, MemberKind.NonStaticMethod, null, null, null) + handleIdentifier(dynamic, typeReference) + handleNoTypeArguments(input) + handleType(dynamic, null) + handleIdentifier(input, formalParameterDeclaration) + handleFormalParameterWithoutValue()) + endFormalParameter(null, null, null, input, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod) + endFormalParameters(1, (, ), MemberKind.NonStaticMethod) + handleNoInitializers() + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + beginIfStatement(if) + handleLiteralInt(1) + beginBinaryExpression(+) + handleLiteralInt(1) + endBinaryExpression(+, 1) + beginBinaryExpression(==) + handleLiteralInt(2) + endBinaryExpression(==, 2) + handleParenthesizedCondition((, null, null) + beginThenStatement({) + beginBlock({, BlockKind(statement)) + handleIdentifier(foo_method2, expression) + handleNoTypeArguments(() + beginArguments(() + handleNoTypeArguments({) + handleLiteralInt(1) + handleLiteralInt(2) + handleLiteralInt(3) + handleLiteralSetOrMap(3, {, null, }, true) + endArguments(1, (, )) + handleSend(foo_method2, )) + handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), )) + handleExpressionStatement(foo_method2, ;) + endBlock(1, {, }, BlockKind(statement)) + endThenStatement({, }) + endIfStatement(if, null, }) + endBlockFunctionBody(1, {, }) + endClassMethod(null, void, (, null, }) + endMember() + beginMetadataStar(void) + endMetadataStar(0) + beginMember() + beginMethod(DeclarationKind.Class, null, null, null, null, null, null, foo_method2, Foo) + handleVoidKeyword(void) + handleIdentifier(foo_method2, methodDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.NonStaticMethod) + beginMetadataStar(dynamic) + endMetadataStar(0) + beginFormalParameter(dynamic, MemberKind.NonStaticMethod, null, null, null) + handleIdentifier(dynamic, typeReference) + handleNoTypeArguments(whatever) + handleType(dynamic, null) + handleIdentifier(whatever, formalParameterDeclaration) + handleFormalParameterWithoutValue()) + endFormalParameter(null, null, null, whatever, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod) + endFormalParameters(1, (, ), MemberKind.NonStaticMethod) + handleNoInitializers() + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + endBlockFunctionBody(0, {, }) + endClassMethod(null, void, (, null, }) + endMember() + endClassOrMixinOrExtensionBody(DeclarationKind.Class, 2, {, }) + endClassDeclaration(class, }) + endTopLevelDeclaration(}) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(}, null, null) + handleVoidKeyword(void) + handleIdentifier(toplevel_method1, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + endBlockFunctionBody(0, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration(}) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(}, null, null) + handleVoidKeyword(void) + handleIdentifier(toplevel_method2, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + endBlockFunctionBody(0, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration(}) + handleErrorToken(UnmatchedToken({)) + handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({)) + handleErrorToken(UnmatchedToken({)) + handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({)) +endCompilationUnit(3, ) diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.intertwined.expect new file mode 100644 index 00000000000..ab558dd395c --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.intertwined.expect @@ -0,0 +1,269 @@ +parseUnit(UnmatchedToken({)) + skipErrorTokens(UnmatchedToken({)) + listener: beginCompilationUnit(class) + syntheticPreviousToken(class) + parseTopLevelDeclarationImpl(UnmatchedToken({), DirectiveContext(DirectiveState.Unknown)) + parseMetadataStar(UnmatchedToken({)) + listener: beginMetadataStar(class) + listener: endMetadataStar(0) + parseTopLevelKeywordDeclaration(class, UnmatchedToken({), class, null, null, null, null, DirectiveContext(DirectiveState.Unknown)) + parseClassOrNamedMixinApplication(class, null, null, null, null, null, null, null, null, class) + listener: beginClassOrMixinOrNamedMixinApplicationPrelude(class) + ensureIdentifier(class, classOrMixinDeclaration) + listener: handleIdentifier(Foo, classOrMixinDeclaration) + listener: handleNoTypeVariables({) + listener: beginClassDeclaration(class, null, null, null, null, null, null, null, null, Foo) + parseClass(Foo, class, class, Foo) + parseClassHeaderOpt(Foo, class, class) + parseClassExtendsOpt(Foo, DeclarationHeaderKind.Class) + listener: handleNoType(Foo) + listener: handleClassExtends(null, 1) + parseClassWithClauseOpt(Foo) + listener: handleClassNoWithClause() + parseClassOrMixinOrEnumImplementsOpt(Foo) + listener: handleImplements(null, 0) + listener: handleClassHeader(class, class, null) + parseClassOrMixinOrExtensionBody(Foo, DeclarationKind.Class, Foo) + listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {) + notEofOrValue(}, void) + parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, Foo) + parseMetadataStar({) + listener: beginMetadataStar(void) + listener: endMetadataStar(0) + listener: beginMember() + parseMethod({, null, null, null, null, null, null, null, {, VoidType(), null, foo_method1, DeclarationKind.Class, Foo, false) + listener: beginMethod(DeclarationKind.Class, null, null, null, null, null, null, foo_method1, Foo) + listener: handleVoidKeyword(void) + ensureIdentifierPotentiallyRecovered(void, methodDeclaration, false) + listener: handleIdentifier(foo_method1, methodDeclaration) + parseQualifiedRestOpt(foo_method1, methodDeclarationContinuation) + parseMethodTypeVar(foo_method1) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(foo_method1, foo_method1, false, MemberKind.NonStaticMethod) + parseFormalParameters(foo_method1, MemberKind.NonStaticMethod) + parseFormalParametersRest((, MemberKind.NonStaticMethod) + listener: beginFormalParameters((, MemberKind.NonStaticMethod) + parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod) + parseMetadataStar(() + listener: beginMetadataStar(dynamic) + listener: endMetadataStar(0) + listener: beginFormalParameter(dynamic, MemberKind.NonStaticMethod, null, null, null) + listener: handleIdentifier(dynamic, typeReference) + listener: handleNoTypeArguments(input) + listener: handleType(dynamic, null) + ensureIdentifier(dynamic, formalParameterDeclaration) + listener: handleIdentifier(input, formalParameterDeclaration) + listener: handleFormalParameterWithoutValue()) + listener: endFormalParameter(null, null, null, input, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod) + listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod) + parseInitializersOpt()) + listener: handleNoInitializers() + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + inPlainSync() + parseFunctionBody(), false, true) + listener: beginBlockFunctionBody({) + notEofOrValue(}, if) + parseStatement({) + parseStatementX({) + parseIfStatement({) + listener: beginIfStatement(if) + ensureParenthesizedCondition(if, allowCase: false) + parseExpressionInParenthesisRest((, allowCase: false) + parseExpression(() + parsePrecedenceExpression((, 1, true, ConstantPatternContext.none) + parseUnaryExpression((, true, ConstantPatternContext.none) + parsePrimary((, expression, ConstantPatternContext.none) + parseLiteralInt(() + listener: handleLiteralInt(1) + listener: beginBinaryExpression(+) + parsePrecedenceExpression(+, 14, true, ConstantPatternContext.none) + parseUnaryExpression(+, true, ConstantPatternContext.none) + parsePrimary(+, expression, ConstantPatternContext.none) + parseLiteralInt(+) + listener: handleLiteralInt(1) + listener: endBinaryExpression(+, 1) + listener: beginBinaryExpression(==) + parsePrecedenceExpression(==, 8, true, ConstantPatternContext.none) + parseUnaryExpression(==, true, ConstantPatternContext.none) + parsePrimary(==, expression, ConstantPatternContext.none) + parseLiteralInt(==) + listener: handleLiteralInt(2) + listener: endBinaryExpression(==, 2) + ensureCloseParen(2, () + listener: handleParenthesizedCondition((, null, null) + listener: beginThenStatement({) + parseStatement()) + parseStatementX()) + parseBlock(), BlockKind(statement)) + ensureBlock(), BlockKind(statement)) + listener: beginBlock({, BlockKind(statement)) + notEofOrValue(}, foo_method2) + parseStatement({) + parseStatementX({) + parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, null) + looksLikeLocalFunction(foo_method2) + parseExpressionStatement({) + parseExpression({) + parsePrecedenceExpression({, 1, true, ConstantPatternContext.none) + parseUnaryExpression({, true, ConstantPatternContext.none) + parsePrimary({, expression, ConstantPatternContext.none) + parseSendOrFunctionLiteral({, expression, ConstantPatternContext.none) + looksLikeFunctionBody(}) + parseSend({, expression, ConstantPatternContext.none) + isNextIdentifier({) + ensureIdentifier({, expression) + listener: handleIdentifier(foo_method2, expression) + listener: handleNoTypeArguments(() + parseArgumentsOpt(foo_method2) + parseArguments(foo_method2) + parseArgumentsRest(() + listener: beginArguments(() + parseExpression(() + parsePrecedenceExpression((, 1, true, ConstantPatternContext.none) + parseUnaryExpression((, true, ConstantPatternContext.none) + parsePrimary((, expression, ConstantPatternContext.none) + listener: handleNoTypeArguments({) + parseLiteralSetOrMapSuffix((, null) + parseExpression({) + parsePrecedenceExpression({, 1, true, ConstantPatternContext.none) + parseUnaryExpression({, true, ConstantPatternContext.none) + parsePrimary({, expression, ConstantPatternContext.none) + parseLiteralInt({) + listener: handleLiteralInt(1) + parseExpression(,) + parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none) + parseUnaryExpression(,, true, ConstantPatternContext.none) + parsePrimary(,, expression, ConstantPatternContext.none) + parseLiteralInt(,) + listener: handleLiteralInt(2) + parseExpression(,) + parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none) + parseUnaryExpression(,, true, ConstantPatternContext.none) + parsePrimary(,, expression, ConstantPatternContext.none) + parseLiteralInt(,) + listener: handleLiteralInt(3) + listener: handleLiteralSetOrMap(3, {, null, }, true) + listener: endArguments(1, (, )) + listener: handleSend(foo_method2, )) + ensureSemicolon()) + reportRecoverableError(), Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}]) + listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ), )) + rewriter() + listener: handleExpressionStatement(foo_method2, ;) + notEofOrValue(}, }) + listener: endBlock(1, {, }, BlockKind(statement)) + listener: endThenStatement({, }) + listener: endIfStatement(if, null, }) + notEofOrValue(}, }) + listener: endBlockFunctionBody(1, {, }) + listener: endClassMethod(null, void, (, null, }) + listener: endMember() + notEofOrValue(}, void) + parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo) + parseMetadataStar(}) + listener: beginMetadataStar(void) + listener: endMetadataStar(0) + listener: beginMember() + parseMethod(}, null, null, null, null, null, null, null, }, VoidType(), null, foo_method2, DeclarationKind.Class, Foo, false) + listener: beginMethod(DeclarationKind.Class, null, null, null, null, null, null, foo_method2, Foo) + listener: handleVoidKeyword(void) + ensureIdentifierPotentiallyRecovered(void, methodDeclaration, false) + listener: handleIdentifier(foo_method2, methodDeclaration) + parseQualifiedRestOpt(foo_method2, methodDeclarationContinuation) + parseMethodTypeVar(foo_method2) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(foo_method2, foo_method2, false, MemberKind.NonStaticMethod) + parseFormalParameters(foo_method2, MemberKind.NonStaticMethod) + parseFormalParametersRest((, MemberKind.NonStaticMethod) + listener: beginFormalParameters((, MemberKind.NonStaticMethod) + parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod) + parseMetadataStar(() + listener: beginMetadataStar(dynamic) + listener: endMetadataStar(0) + listener: beginFormalParameter(dynamic, MemberKind.NonStaticMethod, null, null, null) + listener: handleIdentifier(dynamic, typeReference) + listener: handleNoTypeArguments(whatever) + listener: handleType(dynamic, null) + ensureIdentifier(dynamic, formalParameterDeclaration) + listener: handleIdentifier(whatever, formalParameterDeclaration) + listener: handleFormalParameterWithoutValue()) + listener: endFormalParameter(null, null, null, whatever, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod) + listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod) + parseInitializersOpt()) + listener: handleNoInitializers() + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + inPlainSync() + parseFunctionBody(), false, true) + listener: beginBlockFunctionBody({) + notEofOrValue(}, }) + listener: endBlockFunctionBody(0, {, }) + listener: endClassMethod(null, void, (, null, }) + listener: endMember() + notEofOrValue(}, }) + listener: endClassOrMixinOrExtensionBody(DeclarationKind.Class, 2, {, }) + listener: endClassDeclaration(class, }) + listener: endTopLevelDeclaration(}) + parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations)) + parseMetadataStar(}) + listener: beginMetadataStar(void) + listener: endMetadataStar(0) + parseTopLevelMemberImpl(}) + listener: beginTopLevelMember(void) + parseTopLevelMethod(}, null, null, }, VoidType(), null, toplevel_method1, false) + listener: beginTopLevelMethod(}, null, null) + listener: handleVoidKeyword(void) + ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false) + listener: handleIdentifier(toplevel_method1, topLevelFunctionDeclaration) + parseMethodTypeVar(toplevel_method1) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(toplevel_method1, toplevel_method1, false, MemberKind.TopLevelMethod) + parseFormalParameters(toplevel_method1, MemberKind.TopLevelMethod) + parseFormalParametersRest((, MemberKind.TopLevelMethod) + listener: beginFormalParameters((, MemberKind.TopLevelMethod) + listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + parseFunctionBody(), false, false) + listener: beginBlockFunctionBody({) + notEofOrValue(}, }) + listener: endBlockFunctionBody(0, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration(}) + parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations)) + parseMetadataStar(}) + listener: beginMetadataStar(void) + listener: endMetadataStar(0) + parseTopLevelMemberImpl(}) + listener: beginTopLevelMember(void) + parseTopLevelMethod(}, null, null, }, VoidType(), null, toplevel_method2, false) + listener: beginTopLevelMethod(}, null, null) + listener: handleVoidKeyword(void) + ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false) + listener: handleIdentifier(toplevel_method2, topLevelFunctionDeclaration) + parseMethodTypeVar(toplevel_method2) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(toplevel_method2, toplevel_method2, false, MemberKind.TopLevelMethod) + parseFormalParameters(toplevel_method2, MemberKind.TopLevelMethod) + parseFormalParametersRest((, MemberKind.TopLevelMethod) + listener: beginFormalParameters((, MemberKind.TopLevelMethod) + listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + parseFunctionBody(), false, false) + listener: beginBlockFunctionBody({) + notEofOrValue(}, }) + listener: endBlockFunctionBody(0, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration(}) + reportAllErrorTokens(UnmatchedToken({)) + listener: handleErrorToken(UnmatchedToken({)) + listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({)) + listener: handleErrorToken(UnmatchedToken({)) + listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({)) + listener: endCompilationUnit(3, ) diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.outline.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.outline.expect new file mode 100644 index 00000000000..96af17b0795 --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.outline.expect @@ -0,0 +1,5 @@ +Class: Foo +Class method: Foo.foo_method1 +Class method: Foo.foo_method2 +Top-level method: toplevel_method1 +Top-level method: toplevel_method2 diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.parser.expect new file mode 100644 index 00000000000..8bd759f82f4 --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.parser.expect @@ -0,0 +1,43 @@ +NOTICE: Stream was rewritten by parser! + +class Foo { +void foo_method1(dynamic input) { +if (1 + 1 == 2) { +foo_method2({1, 2, 3 }) + +;}} + +void foo_method2(dynamic whatever) { + +} +} + +void toplevel_method1() { + +} + +void toplevel_method2() { + +} + + +[UnmatchedToken][UnmatchedToken]class[KeywordToken] Foo[StringToken] {[BeginToken] +void[KeywordToken] foo_method1[StringToken]([BeginToken]dynamic[KeywordToken] input[StringToken])[SimpleToken] {[BeginToken] +if[KeywordToken] ([BeginToken]1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken])[SimpleToken] {[BeginToken] +foo_method2[StringToken]([BeginToken]{[BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] 3[StringToken] }[SyntheticToken])[SimpleToken] + +;[SyntheticToken]}[SyntheticToken]}[SimpleToken] + +void[KeywordToken] foo_method2[StringToken]([BeginToken]dynamic[KeywordToken] whatever[StringToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] +}[SimpleToken] + +void[KeywordToken] toplevel_method1[StringToken]([BeginToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] + +void[KeywordToken] toplevel_method2[StringToken]([BeginToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.scanner.expect new file mode 100644 index 00000000000..3d0432b93a9 --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_14.dart.scanner.expect @@ -0,0 +1,41 @@ +class Foo { +void foo_method1(dynamic input) { +if (1 + 1 == 2) { +foo_method2({1, 2, 3 }) + +}} + +void foo_method2(dynamic whatever) { + +} +} + +void toplevel_method1() { + +} + +void toplevel_method2() { + +} + + +[UnmatchedToken][UnmatchedToken]class[KeywordToken] Foo[StringToken] {[BeginToken] +void[KeywordToken] foo_method1[StringToken]([BeginToken]dynamic[KeywordToken] input[StringToken])[SimpleToken] {[BeginToken] +if[KeywordToken] ([BeginToken]1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken])[SimpleToken] {[BeginToken] +foo_method2[StringToken]([BeginToken]{[BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] 3[StringToken] }[SyntheticToken])[SimpleToken] + +}[SyntheticToken]}[SimpleToken] + +void[KeywordToken] foo_method2[StringToken]([BeginToken]dynamic[KeywordToken] whatever[StringToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] +}[SimpleToken] + +void[KeywordToken] toplevel_method1[StringToken]([BeginToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] + +void[KeywordToken] toplevel_method2[StringToken]([BeginToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart new file mode 100644 index 00000000000..e2ab30de3c0 --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart @@ -0,0 +1,29 @@ +// Without specific missing-brace recovery, we'll end up with: +// * Class Foo, member Foo.foo_method1, Foo.toplevel_method1, Foo.toplevel_method2 +// With specific missing-brace recovery, we'll end up with the correct: +// * Class Foo, members Foo.foo_method1, Foo.foo_method2 +// * Top-level members toplevel_method1, toplevel_method2 + +class Foo { + void foo_method1(dynamic input) { + if (1 + 1 == 2) { + // missing: } + } + + void foo_method2() { + if (1 + 1 == 2 && + 1 + 1 == 2 && + 1 + 1 == 2 && + 1 + 1 == 2 && + 1 + 1 == 2 && + 1 + 1 == 2) {} /* braces on the same line but "if" on another */ + } +} + +void toplevel_method1() { + // bla +} + +void toplevel_method2() { + // bla +} diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.expect new file mode 100644 index 00000000000..779223219ca --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.expect @@ -0,0 +1,165 @@ +Problems reported: + +parser/error_recovery/with_outline/typing_15:9:21: Can't find '}' to match '{'. + if (1 + 1 == 2) { + ^ + +beginCompilationUnit(class) + beginMetadataStar(class) + endMetadataStar(0) + beginClassOrMixinOrNamedMixinApplicationPrelude(class) + handleIdentifier(Foo, classOrMixinDeclaration) + handleNoTypeVariables({) + beginClassDeclaration(class, null, null, null, null, null, null, null, null, Foo) + handleNoType(Foo) + handleClassExtends(null, 1) + handleClassNoWithClause() + handleImplements(null, 0) + handleClassHeader(class, class, null) + beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {) + beginMetadataStar(void) + endMetadataStar(0) + beginMember() + beginMethod(DeclarationKind.Class, null, null, null, null, null, null, foo_method1, Foo) + handleVoidKeyword(void) + handleIdentifier(foo_method1, methodDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.NonStaticMethod) + beginMetadataStar(dynamic) + endMetadataStar(0) + beginFormalParameter(dynamic, MemberKind.NonStaticMethod, null, null, null) + handleIdentifier(dynamic, typeReference) + handleNoTypeArguments(input) + handleType(dynamic, null) + handleIdentifier(input, formalParameterDeclaration) + handleFormalParameterWithoutValue()) + endFormalParameter(null, null, null, input, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod) + endFormalParameters(1, (, ), MemberKind.NonStaticMethod) + handleNoInitializers() + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + beginIfStatement(if) + handleLiteralInt(1) + beginBinaryExpression(+) + handleLiteralInt(1) + endBinaryExpression(+, 1) + beginBinaryExpression(==) + handleLiteralInt(2) + endBinaryExpression(==, 2) + handleParenthesizedCondition((, null, null) + beginThenStatement({) + beginBlock({, BlockKind(statement)) + endBlock(0, {, }, BlockKind(statement)) + endThenStatement({, }) + endIfStatement(if, null, }) + endBlockFunctionBody(1, {, }) + endClassMethod(null, void, (, null, }) + endMember() + beginMetadataStar(void) + endMetadataStar(0) + beginMember() + beginMethod(DeclarationKind.Class, null, null, null, null, null, null, foo_method2, Foo) + handleVoidKeyword(void) + handleIdentifier(foo_method2, methodDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.NonStaticMethod) + endFormalParameters(0, (, ), MemberKind.NonStaticMethod) + handleNoInitializers() + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + beginIfStatement(if) + handleLiteralInt(1) + beginBinaryExpression(+) + handleLiteralInt(1) + endBinaryExpression(+, 1) + beginBinaryExpression(==) + handleLiteralInt(2) + endBinaryExpression(==, 2) + beginBinaryExpression(&&) + handleLiteralInt(1) + beginBinaryExpression(+) + handleLiteralInt(1) + endBinaryExpression(+, 1) + beginBinaryExpression(==) + handleLiteralInt(2) + endBinaryExpression(==, 2) + endBinaryExpression(&&, 2) + beginBinaryExpression(&&) + handleLiteralInt(1) + beginBinaryExpression(+) + handleLiteralInt(1) + endBinaryExpression(+, 1) + beginBinaryExpression(==) + handleLiteralInt(2) + endBinaryExpression(==, 2) + endBinaryExpression(&&, 2) + beginBinaryExpression(&&) + handleLiteralInt(1) + beginBinaryExpression(+) + handleLiteralInt(1) + endBinaryExpression(+, 1) + beginBinaryExpression(==) + handleLiteralInt(2) + endBinaryExpression(==, 2) + endBinaryExpression(&&, 2) + beginBinaryExpression(&&) + handleLiteralInt(1) + beginBinaryExpression(+) + handleLiteralInt(1) + endBinaryExpression(+, 1) + beginBinaryExpression(==) + handleLiteralInt(2) + endBinaryExpression(==, 2) + endBinaryExpression(&&, 2) + beginBinaryExpression(&&) + handleLiteralInt(1) + beginBinaryExpression(+) + handleLiteralInt(1) + endBinaryExpression(+, 1) + beginBinaryExpression(==) + handleLiteralInt(2) + endBinaryExpression(==, 2) + endBinaryExpression(&&, 2) + handleParenthesizedCondition((, null, null) + beginThenStatement({) + beginBlock({, BlockKind(statement)) + endBlock(0, {, }, BlockKind(statement)) + endThenStatement({, }) + endIfStatement(if, null, }) + endBlockFunctionBody(1, {, }) + endClassMethod(null, void, (, null, }) + endMember() + endClassOrMixinOrExtensionBody(DeclarationKind.Class, 2, {, }) + endClassDeclaration(class, }) + endTopLevelDeclaration(}) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(}, null, null) + handleVoidKeyword(void) + handleIdentifier(toplevel_method1, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + endBlockFunctionBody(0, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration(}) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(}, null, null) + handleVoidKeyword(void) + handleIdentifier(toplevel_method2, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + endBlockFunctionBody(0, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration(}) + handleErrorToken(UnmatchedToken({)) + handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({)) +endCompilationUnit(3, ) diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.intertwined.expect new file mode 100644 index 00000000000..6643676ba9b --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.intertwined.expect @@ -0,0 +1,346 @@ +parseUnit(UnmatchedToken({)) + skipErrorTokens(UnmatchedToken({)) + listener: beginCompilationUnit(class) + syntheticPreviousToken(class) + parseTopLevelDeclarationImpl(UnmatchedToken({), DirectiveContext(DirectiveState.Unknown)) + parseMetadataStar(UnmatchedToken({)) + listener: beginMetadataStar(class) + listener: endMetadataStar(0) + parseTopLevelKeywordDeclaration(class, UnmatchedToken({), class, null, null, null, null, DirectiveContext(DirectiveState.Unknown)) + parseClassOrNamedMixinApplication(class, null, null, null, null, null, null, null, null, class) + listener: beginClassOrMixinOrNamedMixinApplicationPrelude(class) + ensureIdentifier(class, classOrMixinDeclaration) + listener: handleIdentifier(Foo, classOrMixinDeclaration) + listener: handleNoTypeVariables({) + listener: beginClassDeclaration(class, null, null, null, null, null, null, null, null, Foo) + parseClass(Foo, class, class, Foo) + parseClassHeaderOpt(Foo, class, class) + parseClassExtendsOpt(Foo, DeclarationHeaderKind.Class) + listener: handleNoType(Foo) + listener: handleClassExtends(null, 1) + parseClassWithClauseOpt(Foo) + listener: handleClassNoWithClause() + parseClassOrMixinOrEnumImplementsOpt(Foo) + listener: handleImplements(null, 0) + listener: handleClassHeader(class, class, null) + parseClassOrMixinOrExtensionBody(Foo, DeclarationKind.Class, Foo) + listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {) + notEofOrValue(}, void) + parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, Foo) + parseMetadataStar({) + listener: beginMetadataStar(void) + listener: endMetadataStar(0) + listener: beginMember() + parseMethod({, null, null, null, null, null, null, null, {, VoidType(), null, foo_method1, DeclarationKind.Class, Foo, false) + listener: beginMethod(DeclarationKind.Class, null, null, null, null, null, null, foo_method1, Foo) + listener: handleVoidKeyword(void) + ensureIdentifierPotentiallyRecovered(void, methodDeclaration, false) + listener: handleIdentifier(foo_method1, methodDeclaration) + parseQualifiedRestOpt(foo_method1, methodDeclarationContinuation) + parseMethodTypeVar(foo_method1) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(foo_method1, foo_method1, false, MemberKind.NonStaticMethod) + parseFormalParameters(foo_method1, MemberKind.NonStaticMethod) + parseFormalParametersRest((, MemberKind.NonStaticMethod) + listener: beginFormalParameters((, MemberKind.NonStaticMethod) + parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod) + parseMetadataStar(() + listener: beginMetadataStar(dynamic) + listener: endMetadataStar(0) + listener: beginFormalParameter(dynamic, MemberKind.NonStaticMethod, null, null, null) + listener: handleIdentifier(dynamic, typeReference) + listener: handleNoTypeArguments(input) + listener: handleType(dynamic, null) + ensureIdentifier(dynamic, formalParameterDeclaration) + listener: handleIdentifier(input, formalParameterDeclaration) + listener: handleFormalParameterWithoutValue()) + listener: endFormalParameter(null, null, null, input, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod) + listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod) + parseInitializersOpt()) + listener: handleNoInitializers() + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + inPlainSync() + parseFunctionBody(), false, true) + listener: beginBlockFunctionBody({) + notEofOrValue(}, if) + parseStatement({) + parseStatementX({) + parseIfStatement({) + listener: beginIfStatement(if) + ensureParenthesizedCondition(if, allowCase: false) + parseExpressionInParenthesisRest((, allowCase: false) + parseExpression(() + parsePrecedenceExpression((, 1, true, ConstantPatternContext.none) + parseUnaryExpression((, true, ConstantPatternContext.none) + parsePrimary((, expression, ConstantPatternContext.none) + parseLiteralInt(() + listener: handleLiteralInt(1) + listener: beginBinaryExpression(+) + parsePrecedenceExpression(+, 14, true, ConstantPatternContext.none) + parseUnaryExpression(+, true, ConstantPatternContext.none) + parsePrimary(+, expression, ConstantPatternContext.none) + parseLiteralInt(+) + listener: handleLiteralInt(1) + listener: endBinaryExpression(+, 1) + listener: beginBinaryExpression(==) + parsePrecedenceExpression(==, 8, true, ConstantPatternContext.none) + parseUnaryExpression(==, true, ConstantPatternContext.none) + parsePrimary(==, expression, ConstantPatternContext.none) + parseLiteralInt(==) + listener: handleLiteralInt(2) + listener: endBinaryExpression(==, 2) + ensureCloseParen(2, () + listener: handleParenthesizedCondition((, null, null) + listener: beginThenStatement({) + parseStatement()) + parseStatementX()) + parseBlock(), BlockKind(statement)) + ensureBlock(), BlockKind(statement)) + listener: beginBlock({, BlockKind(statement)) + notEofOrValue(}, }) + listener: endBlock(0, {, }, BlockKind(statement)) + listener: endThenStatement({, }) + listener: endIfStatement(if, null, }) + notEofOrValue(}, }) + listener: endBlockFunctionBody(1, {, }) + listener: endClassMethod(null, void, (, null, }) + listener: endMember() + notEofOrValue(}, void) + parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo) + parseMetadataStar(}) + listener: beginMetadataStar(void) + listener: endMetadataStar(0) + listener: beginMember() + parseMethod(}, null, null, null, null, null, null, null, }, VoidType(), null, foo_method2, DeclarationKind.Class, Foo, false) + listener: beginMethod(DeclarationKind.Class, null, null, null, null, null, null, foo_method2, Foo) + listener: handleVoidKeyword(void) + ensureIdentifierPotentiallyRecovered(void, methodDeclaration, false) + listener: handleIdentifier(foo_method2, methodDeclaration) + parseQualifiedRestOpt(foo_method2, methodDeclarationContinuation) + parseMethodTypeVar(foo_method2) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(foo_method2, foo_method2, false, MemberKind.NonStaticMethod) + parseFormalParameters(foo_method2, MemberKind.NonStaticMethod) + parseFormalParametersRest((, MemberKind.NonStaticMethod) + listener: beginFormalParameters((, MemberKind.NonStaticMethod) + listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod) + parseInitializersOpt()) + listener: handleNoInitializers() + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + inPlainSync() + parseFunctionBody(), false, true) + listener: beginBlockFunctionBody({) + notEofOrValue(}, if) + parseStatement({) + parseStatementX({) + parseIfStatement({) + listener: beginIfStatement(if) + ensureParenthesizedCondition(if, allowCase: false) + parseExpressionInParenthesisRest((, allowCase: false) + parseExpression(() + parsePrecedenceExpression((, 1, true, ConstantPatternContext.none) + parseUnaryExpression((, true, ConstantPatternContext.none) + parsePrimary((, expression, ConstantPatternContext.none) + parseLiteralInt(() + listener: handleLiteralInt(1) + listener: beginBinaryExpression(+) + parsePrecedenceExpression(+, 14, true, ConstantPatternContext.none) + parseUnaryExpression(+, true, ConstantPatternContext.none) + parsePrimary(+, expression, ConstantPatternContext.none) + parseLiteralInt(+) + listener: handleLiteralInt(1) + listener: endBinaryExpression(+, 1) + listener: beginBinaryExpression(==) + parsePrecedenceExpression(==, 8, true, ConstantPatternContext.none) + parseUnaryExpression(==, true, ConstantPatternContext.none) + parsePrimary(==, expression, ConstantPatternContext.none) + parseLiteralInt(==) + listener: handleLiteralInt(2) + listener: endBinaryExpression(==, 2) + listener: beginBinaryExpression(&&) + parsePrecedenceExpression(&&, 7, true, ConstantPatternContext.none) + parseUnaryExpression(&&, true, ConstantPatternContext.none) + parsePrimary(&&, expression, ConstantPatternContext.none) + parseLiteralInt(&&) + listener: handleLiteralInt(1) + listener: beginBinaryExpression(+) + parsePrecedenceExpression(+, 14, true, ConstantPatternContext.none) + parseUnaryExpression(+, true, ConstantPatternContext.none) + parsePrimary(+, expression, ConstantPatternContext.none) + parseLiteralInt(+) + listener: handleLiteralInt(1) + listener: endBinaryExpression(+, 1) + listener: beginBinaryExpression(==) + parsePrecedenceExpression(==, 8, true, ConstantPatternContext.none) + parseUnaryExpression(==, true, ConstantPatternContext.none) + parsePrimary(==, expression, ConstantPatternContext.none) + parseLiteralInt(==) + listener: handleLiteralInt(2) + listener: endBinaryExpression(==, 2) + listener: endBinaryExpression(&&, 2) + listener: beginBinaryExpression(&&) + parsePrecedenceExpression(&&, 7, true, ConstantPatternContext.none) + parseUnaryExpression(&&, true, ConstantPatternContext.none) + parsePrimary(&&, expression, ConstantPatternContext.none) + parseLiteralInt(&&) + listener: handleLiteralInt(1) + listener: beginBinaryExpression(+) + parsePrecedenceExpression(+, 14, true, ConstantPatternContext.none) + parseUnaryExpression(+, true, ConstantPatternContext.none) + parsePrimary(+, expression, ConstantPatternContext.none) + parseLiteralInt(+) + listener: handleLiteralInt(1) + listener: endBinaryExpression(+, 1) + listener: beginBinaryExpression(==) + parsePrecedenceExpression(==, 8, true, ConstantPatternContext.none) + parseUnaryExpression(==, true, ConstantPatternContext.none) + parsePrimary(==, expression, ConstantPatternContext.none) + parseLiteralInt(==) + listener: handleLiteralInt(2) + listener: endBinaryExpression(==, 2) + listener: endBinaryExpression(&&, 2) + listener: beginBinaryExpression(&&) + parsePrecedenceExpression(&&, 7, true, ConstantPatternContext.none) + parseUnaryExpression(&&, true, ConstantPatternContext.none) + parsePrimary(&&, expression, ConstantPatternContext.none) + parseLiteralInt(&&) + listener: handleLiteralInt(1) + listener: beginBinaryExpression(+) + parsePrecedenceExpression(+, 14, true, ConstantPatternContext.none) + parseUnaryExpression(+, true, ConstantPatternContext.none) + parsePrimary(+, expression, ConstantPatternContext.none) + parseLiteralInt(+) + listener: handleLiteralInt(1) + listener: endBinaryExpression(+, 1) + listener: beginBinaryExpression(==) + parsePrecedenceExpression(==, 8, true, ConstantPatternContext.none) + parseUnaryExpression(==, true, ConstantPatternContext.none) + parsePrimary(==, expression, ConstantPatternContext.none) + parseLiteralInt(==) + listener: handleLiteralInt(2) + listener: endBinaryExpression(==, 2) + listener: endBinaryExpression(&&, 2) + listener: beginBinaryExpression(&&) + parsePrecedenceExpression(&&, 7, true, ConstantPatternContext.none) + parseUnaryExpression(&&, true, ConstantPatternContext.none) + parsePrimary(&&, expression, ConstantPatternContext.none) + parseLiteralInt(&&) + listener: handleLiteralInt(1) + listener: beginBinaryExpression(+) + parsePrecedenceExpression(+, 14, true, ConstantPatternContext.none) + parseUnaryExpression(+, true, ConstantPatternContext.none) + parsePrimary(+, expression, ConstantPatternContext.none) + parseLiteralInt(+) + listener: handleLiteralInt(1) + listener: endBinaryExpression(+, 1) + listener: beginBinaryExpression(==) + parsePrecedenceExpression(==, 8, true, ConstantPatternContext.none) + parseUnaryExpression(==, true, ConstantPatternContext.none) + parsePrimary(==, expression, ConstantPatternContext.none) + parseLiteralInt(==) + listener: handleLiteralInt(2) + listener: endBinaryExpression(==, 2) + listener: endBinaryExpression(&&, 2) + listener: beginBinaryExpression(&&) + parsePrecedenceExpression(&&, 7, true, ConstantPatternContext.none) + parseUnaryExpression(&&, true, ConstantPatternContext.none) + parsePrimary(&&, expression, ConstantPatternContext.none) + parseLiteralInt(&&) + listener: handleLiteralInt(1) + listener: beginBinaryExpression(+) + parsePrecedenceExpression(+, 14, true, ConstantPatternContext.none) + parseUnaryExpression(+, true, ConstantPatternContext.none) + parsePrimary(+, expression, ConstantPatternContext.none) + parseLiteralInt(+) + listener: handleLiteralInt(1) + listener: endBinaryExpression(+, 1) + listener: beginBinaryExpression(==) + parsePrecedenceExpression(==, 8, true, ConstantPatternContext.none) + parseUnaryExpression(==, true, ConstantPatternContext.none) + parsePrimary(==, expression, ConstantPatternContext.none) + parseLiteralInt(==) + listener: handleLiteralInt(2) + listener: endBinaryExpression(==, 2) + listener: endBinaryExpression(&&, 2) + ensureCloseParen(2, () + listener: handleParenthesizedCondition((, null, null) + listener: beginThenStatement({) + parseStatement()) + parseStatementX()) + parseBlock(), BlockKind(statement)) + ensureBlock(), BlockKind(statement)) + listener: beginBlock({, BlockKind(statement)) + notEofOrValue(}, }) + listener: endBlock(0, {, }, BlockKind(statement)) + listener: endThenStatement({, }) + listener: endIfStatement(if, null, }) + notEofOrValue(}, }) + listener: endBlockFunctionBody(1, {, }) + listener: endClassMethod(null, void, (, null, }) + listener: endMember() + notEofOrValue(}, }) + listener: endClassOrMixinOrExtensionBody(DeclarationKind.Class, 2, {, }) + listener: endClassDeclaration(class, }) + listener: endTopLevelDeclaration(}) + parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations)) + parseMetadataStar(}) + listener: beginMetadataStar(void) + listener: endMetadataStar(0) + parseTopLevelMemberImpl(}) + listener: beginTopLevelMember(void) + parseTopLevelMethod(}, null, null, }, VoidType(), null, toplevel_method1, false) + listener: beginTopLevelMethod(}, null, null) + listener: handleVoidKeyword(void) + ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false) + listener: handleIdentifier(toplevel_method1, topLevelFunctionDeclaration) + parseMethodTypeVar(toplevel_method1) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(toplevel_method1, toplevel_method1, false, MemberKind.TopLevelMethod) + parseFormalParameters(toplevel_method1, MemberKind.TopLevelMethod) + parseFormalParametersRest((, MemberKind.TopLevelMethod) + listener: beginFormalParameters((, MemberKind.TopLevelMethod) + listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + parseFunctionBody(), false, false) + listener: beginBlockFunctionBody({) + notEofOrValue(}, }) + listener: endBlockFunctionBody(0, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration(}) + parseTopLevelDeclarationImpl(}, DirectiveContext(DirectiveState.Declarations)) + parseMetadataStar(}) + listener: beginMetadataStar(void) + listener: endMetadataStar(0) + parseTopLevelMemberImpl(}) + listener: beginTopLevelMember(void) + parseTopLevelMethod(}, null, null, }, VoidType(), null, toplevel_method2, false) + listener: beginTopLevelMethod(}, null, null) + listener: handleVoidKeyword(void) + ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false) + listener: handleIdentifier(toplevel_method2, topLevelFunctionDeclaration) + parseMethodTypeVar(toplevel_method2) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(toplevel_method2, toplevel_method2, false, MemberKind.TopLevelMethod) + parseFormalParameters(toplevel_method2, MemberKind.TopLevelMethod) + parseFormalParametersRest((, MemberKind.TopLevelMethod) + listener: beginFormalParameters((, MemberKind.TopLevelMethod) + listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + parseFunctionBody(), false, false) + listener: beginBlockFunctionBody({) + notEofOrValue(}, }) + listener: endBlockFunctionBody(0, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration(}) + reportAllErrorTokens(UnmatchedToken({)) + listener: handleErrorToken(UnmatchedToken({)) + listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({)) + listener: endCompilationUnit(3, ) diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.outline.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.outline.expect new file mode 100644 index 00000000000..96af17b0795 --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.outline.expect @@ -0,0 +1,5 @@ +Class: Foo +Class method: Foo.foo_method1 +Class method: Foo.foo_method2 +Top-level method: toplevel_method1 +Top-level method: toplevel_method2 diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.parser.expect new file mode 100644 index 00000000000..303ff3b8b81 --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.parser.expect @@ -0,0 +1,49 @@ +class Foo { +void foo_method1(dynamic input) { +if (1 + 1 == 2) { + +}} + +void foo_method2() { +if (1 + 1 == 2 && +1 + 1 == 2 && +1 + 1 == 2 && +1 + 1 == 2 && +1 + 1 == 2 && +1 + 1 == 2) {} +} +} + +void toplevel_method1() { + +} + +void toplevel_method2() { + +} + + +[UnmatchedToken]class[KeywordToken] Foo[StringToken] {[BeginToken] +void[KeywordToken] foo_method1[StringToken]([BeginToken]dynamic[KeywordToken] input[StringToken])[SimpleToken] {[BeginToken] +if[KeywordToken] ([BeginToken]1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken])[SimpleToken] {[BeginToken] + +}[SyntheticToken]}[SimpleToken] + +void[KeywordToken] foo_method2[StringToken]([BeginToken])[SimpleToken] {[BeginToken] +if[KeywordToken] ([BeginToken]1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken] +}[SimpleToken] +}[SimpleToken] + +void[KeywordToken] toplevel_method1[StringToken]([BeginToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] + +void[KeywordToken] toplevel_method2[StringToken]([BeginToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.scanner.expect new file mode 100644 index 00000000000..303ff3b8b81 --- /dev/null +++ b/pkg/front_end/parser_testcases/error_recovery/with_outline/typing_15.dart.scanner.expect @@ -0,0 +1,49 @@ +class Foo { +void foo_method1(dynamic input) { +if (1 + 1 == 2) { + +}} + +void foo_method2() { +if (1 + 1 == 2 && +1 + 1 == 2 && +1 + 1 == 2 && +1 + 1 == 2 && +1 + 1 == 2 && +1 + 1 == 2) {} +} +} + +void toplevel_method1() { + +} + +void toplevel_method2() { + +} + + +[UnmatchedToken]class[KeywordToken] Foo[StringToken] {[BeginToken] +void[KeywordToken] foo_method1[StringToken]([BeginToken]dynamic[KeywordToken] input[StringToken])[SimpleToken] {[BeginToken] +if[KeywordToken] ([BeginToken]1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken])[SimpleToken] {[BeginToken] + +}[SyntheticToken]}[SimpleToken] + +void[KeywordToken] foo_method2[StringToken]([BeginToken])[SimpleToken] {[BeginToken] +if[KeywordToken] ([BeginToken]1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken] &&[SimpleToken] +1[StringToken] +[SimpleToken] 1[StringToken] ==[SimpleToken] 2[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken] +}[SimpleToken] +}[SimpleToken] + +void[KeywordToken] toplevel_method1[StringToken]([BeginToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] + +void[KeywordToken] toplevel_method2[StringToken]([BeginToken])[SimpleToken] {[BeginToken] + +}[SimpleToken] +[SimpleToken]