mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:55:08 +00:00
[parser] Allow ?? after Type?
Fixes #39697. Change-Id: I65c762304881038b205f1221d6cfdd1125ba71e1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/127890 Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
2a886d257f
commit
e2d5aa352c
|
@ -5308,7 +5308,7 @@ class Parser {
|
|||
TypeInfo typeInfo = computeType(token, true);
|
||||
if (typeInfo.isNullable) {
|
||||
Token next = typeInfo.skipType(token).next;
|
||||
if (!isOneOfOrEof(next, const [')', '?', ';', 'is', 'as'])) {
|
||||
if (!isOneOfOrEof(next, const [')', '?', '??', ';', 'is', 'as'])) {
|
||||
// TODO(danrubel): investigate other situations
|
||||
// where `?` should be considered part of the type info
|
||||
// rather than the start of a conditional expression.
|
||||
|
|
1
pkg/front_end/parser_testcases/nnbd/issue_39697.dart
Normal file
1
pkg/front_end/parser_testcases/nnbd/issue_39697.dart
Normal file
|
@ -0,0 +1 @@
|
|||
Logger get log => Zone.current[logKey] as Logger? ?? _default;
|
40
pkg/front_end/parser_testcases/nnbd/issue_39697.dart.expect
Normal file
40
pkg/front_end/parser_testcases/nnbd/issue_39697.dart.expect
Normal file
|
@ -0,0 +1,40 @@
|
|||
beginCompilationUnit(Logger)
|
||||
beginMetadataStar(Logger)
|
||||
endMetadataStar(0)
|
||||
beginTopLevelMember(Logger)
|
||||
beginTopLevelMethod(, null)
|
||||
handleIdentifier(Logger, typeReference)
|
||||
handleNoTypeArguments(get)
|
||||
handleType(Logger, null)
|
||||
handleIdentifier(log, topLevelFunctionDeclaration)
|
||||
handleNoTypeVariables(=>)
|
||||
handleNoFormalParameters(=>, MemberKind.TopLevelMethod)
|
||||
handleAsyncModifier(null, null)
|
||||
handleIdentifier(Zone, expression)
|
||||
handleNoTypeArguments(.)
|
||||
handleNoArguments(.)
|
||||
handleSend(Zone, .)
|
||||
handleIdentifier(current, expressionContinuation)
|
||||
handleNoTypeArguments([)
|
||||
handleNoArguments([)
|
||||
handleSend(current, [)
|
||||
endBinaryExpression(.)
|
||||
handleIdentifier(logKey, expression)
|
||||
handleNoTypeArguments(])
|
||||
handleNoArguments(])
|
||||
handleSend(logKey, ])
|
||||
handleIndexedExpression([, ])
|
||||
handleIdentifier(Logger, typeReference)
|
||||
handleNoTypeArguments(?)
|
||||
handleType(Logger, ?)
|
||||
handleAsOperator(as)
|
||||
beginBinaryExpression(??)
|
||||
handleIdentifier(_default, expression)
|
||||
handleNoTypeArguments(;)
|
||||
handleNoArguments(;)
|
||||
handleSend(_default, ;)
|
||||
endBinaryExpression(??)
|
||||
handleExpressionFunctionBody(=>, ;)
|
||||
endTopLevelMethod(Logger, get, ;)
|
||||
endTopLevelDeclaration()
|
||||
endCompilationUnit(1, )
|
|
@ -0,0 +1,89 @@
|
|||
parseUnit(Logger)
|
||||
skipErrorTokens(Logger)
|
||||
listener: beginCompilationUnit(Logger)
|
||||
syntheticPreviousToken(Logger)
|
||||
parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
|
||||
parseMetadataStar()
|
||||
listener: beginMetadataStar(Logger)
|
||||
listener: endMetadataStar(0)
|
||||
parseTopLevelMemberImpl()
|
||||
listener: beginTopLevelMember(Logger)
|
||||
parseTopLevelMethod(, null, , Instance of 'SimpleType', get, log)
|
||||
listener: beginTopLevelMethod(, null)
|
||||
listener: handleIdentifier(Logger, typeReference)
|
||||
listener: handleNoTypeArguments(get)
|
||||
listener: handleType(Logger, null)
|
||||
ensureIdentifier(get, topLevelFunctionDeclaration)
|
||||
listener: handleIdentifier(log, topLevelFunctionDeclaration)
|
||||
listener: handleNoTypeVariables(=>)
|
||||
parseGetterOrFormalParameters(log, log, true, MemberKind.TopLevelMethod)
|
||||
listener: handleNoFormalParameters(=>, MemberKind.TopLevelMethod)
|
||||
parseAsyncModifierOpt(log)
|
||||
listener: handleAsyncModifier(null, null)
|
||||
inPlainSync()
|
||||
inPlainSync()
|
||||
parseFunctionBody(log, false, false)
|
||||
parseExpressionFunctionBody(=>, false)
|
||||
parseExpression(=>)
|
||||
parsePrecedenceExpression(=>, 1, true)
|
||||
parseUnaryExpression(=>, true)
|
||||
parsePrimary(=>, expression)
|
||||
parseSendOrFunctionLiteral(=>, expression)
|
||||
parseSend(=>, expression)
|
||||
ensureIdentifier(=>, expression)
|
||||
listener: handleIdentifier(Zone, expression)
|
||||
listener: handleNoTypeArguments(.)
|
||||
parseArgumentsOpt(Zone)
|
||||
listener: handleNoArguments(.)
|
||||
listener: handleSend(Zone, .)
|
||||
parsePrimary(., expressionContinuation)
|
||||
parseSendOrFunctionLiteral(., expressionContinuation)
|
||||
parseSend(., expressionContinuation)
|
||||
ensureIdentifier(., expressionContinuation)
|
||||
listener: handleIdentifier(current, expressionContinuation)
|
||||
listener: handleNoTypeArguments([)
|
||||
parseArgumentsOpt(current)
|
||||
listener: handleNoArguments([)
|
||||
listener: handleSend(current, [)
|
||||
listener: endBinaryExpression(.)
|
||||
parseArgumentOrIndexStar(current, Instance of 'NoTypeParamOrArg')
|
||||
parseExpression([)
|
||||
parsePrecedenceExpression([, 1, true)
|
||||
parseUnaryExpression([, true)
|
||||
parsePrimary([, expression)
|
||||
parseSendOrFunctionLiteral([, expression)
|
||||
parseSend([, expression)
|
||||
ensureIdentifier([, expression)
|
||||
listener: handleIdentifier(logKey, expression)
|
||||
listener: handleNoTypeArguments(])
|
||||
parseArgumentsOpt(logKey)
|
||||
listener: handleNoArguments(])
|
||||
listener: handleSend(logKey, ])
|
||||
listener: handleIndexedExpression([, ])
|
||||
parseAsOperatorRest(])
|
||||
computeTypeAfterIsOrAs(as)
|
||||
listener: handleIdentifier(Logger, typeReference)
|
||||
listener: handleNoTypeArguments(?)
|
||||
listener: handleType(Logger, ?)
|
||||
listener: handleAsOperator(as)
|
||||
skipChainedAsIsOperators(?)
|
||||
listener: beginBinaryExpression(??)
|
||||
parsePrecedenceExpression(??, 5, true)
|
||||
parseUnaryExpression(??, true)
|
||||
parsePrimary(??, expression)
|
||||
parseSendOrFunctionLiteral(??, expression)
|
||||
parseSend(??, expression)
|
||||
ensureIdentifier(??, expression)
|
||||
listener: handleIdentifier(_default, expression)
|
||||
listener: handleNoTypeArguments(;)
|
||||
parseArgumentsOpt(_default)
|
||||
listener: handleNoArguments(;)
|
||||
listener: handleSend(_default, ;)
|
||||
listener: endBinaryExpression(??)
|
||||
ensureSemicolon(_default)
|
||||
listener: handleExpressionFunctionBody(=>, ;)
|
||||
inGenerator()
|
||||
listener: endTopLevelMethod(Logger, get, ;)
|
||||
listener: endTopLevelDeclaration()
|
||||
reportAllErrorTokens(Logger)
|
||||
listener: endCompilationUnit(1, )
|
|
@ -0,0 +1,3 @@
|
|||
Logger get log => Zone.current[logKey] as Logger? ?? _default;
|
||||
|
||||
Logger[StringToken] get[KeywordToken] log[StringToken] =>[SimpleToken] Zone[StringToken].[SimpleToken]current[StringToken][[BeginToken]logKey[StringToken]][SimpleToken] as[KeywordToken] Logger[StringToken]?[SimpleToken] ??[SimpleToken] _default[StringToken];[SimpleToken][SimpleToken]
|
|
@ -0,0 +1,3 @@
|
|||
Logger get log => Zone.current[logKey] as Logger? ?? _default;
|
||||
|
||||
Logger[StringToken] get[KeywordToken] log[StringToken] =>[SimpleToken] Zone[StringToken].[SimpleToken]current[StringToken][[BeginToken]logKey[StringToken]][SimpleToken] as[KeywordToken] Logger[StringToken]?[SimpleToken] ??[SimpleToken] _default[StringToken];[SimpleToken][SimpleToken]
|
|
@ -0,0 +1 @@
|
|||
Logger get log => (Zone.current[logKey] as Logger?) ?? _default;
|
|
@ -0,0 +1,41 @@
|
|||
beginCompilationUnit(Logger)
|
||||
beginMetadataStar(Logger)
|
||||
endMetadataStar(0)
|
||||
beginTopLevelMember(Logger)
|
||||
beginTopLevelMethod(, null)
|
||||
handleIdentifier(Logger, typeReference)
|
||||
handleNoTypeArguments(get)
|
||||
handleType(Logger, null)
|
||||
handleIdentifier(log, topLevelFunctionDeclaration)
|
||||
handleNoTypeVariables(=>)
|
||||
handleNoFormalParameters(=>, MemberKind.TopLevelMethod)
|
||||
handleAsyncModifier(null, null)
|
||||
handleIdentifier(Zone, expression)
|
||||
handleNoTypeArguments(.)
|
||||
handleNoArguments(.)
|
||||
handleSend(Zone, .)
|
||||
handleIdentifier(current, expressionContinuation)
|
||||
handleNoTypeArguments([)
|
||||
handleNoArguments([)
|
||||
handleSend(current, [)
|
||||
endBinaryExpression(.)
|
||||
handleIdentifier(logKey, expression)
|
||||
handleNoTypeArguments(])
|
||||
handleNoArguments(])
|
||||
handleSend(logKey, ])
|
||||
handleIndexedExpression([, ])
|
||||
handleIdentifier(Logger, typeReference)
|
||||
handleNoTypeArguments(?)
|
||||
handleType(Logger, ?)
|
||||
handleAsOperator(as)
|
||||
handleParenthesizedExpression(()
|
||||
beginBinaryExpression(??)
|
||||
handleIdentifier(_default, expression)
|
||||
handleNoTypeArguments(;)
|
||||
handleNoArguments(;)
|
||||
handleSend(_default, ;)
|
||||
endBinaryExpression(??)
|
||||
handleExpressionFunctionBody(=>, ;)
|
||||
endTopLevelMethod(Logger, get, ;)
|
||||
endTopLevelDeclaration()
|
||||
endCompilationUnit(1, )
|
|
@ -0,0 +1,99 @@
|
|||
parseUnit(Logger)
|
||||
skipErrorTokens(Logger)
|
||||
listener: beginCompilationUnit(Logger)
|
||||
syntheticPreviousToken(Logger)
|
||||
parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
|
||||
parseMetadataStar()
|
||||
listener: beginMetadataStar(Logger)
|
||||
listener: endMetadataStar(0)
|
||||
parseTopLevelMemberImpl()
|
||||
listener: beginTopLevelMember(Logger)
|
||||
parseTopLevelMethod(, null, , Instance of 'SimpleType', get, log)
|
||||
listener: beginTopLevelMethod(, null)
|
||||
listener: handleIdentifier(Logger, typeReference)
|
||||
listener: handleNoTypeArguments(get)
|
||||
listener: handleType(Logger, null)
|
||||
ensureIdentifier(get, topLevelFunctionDeclaration)
|
||||
listener: handleIdentifier(log, topLevelFunctionDeclaration)
|
||||
listener: handleNoTypeVariables(=>)
|
||||
parseGetterOrFormalParameters(log, log, true, MemberKind.TopLevelMethod)
|
||||
listener: handleNoFormalParameters(=>, MemberKind.TopLevelMethod)
|
||||
parseAsyncModifierOpt(log)
|
||||
listener: handleAsyncModifier(null, null)
|
||||
inPlainSync()
|
||||
inPlainSync()
|
||||
parseFunctionBody(log, false, false)
|
||||
parseExpressionFunctionBody(=>, false)
|
||||
parseExpression(=>)
|
||||
parsePrecedenceExpression(=>, 1, true)
|
||||
parseUnaryExpression(=>, true)
|
||||
parsePrimary(=>, expression)
|
||||
parseParenthesizedExpressionOrFunctionLiteral(=>)
|
||||
parseParenthesizedExpression(=>)
|
||||
parseExpressionInParenthesis(=>)
|
||||
parseExpressionInParenthesisRest(()
|
||||
parseExpression(()
|
||||
parsePrecedenceExpression((, 1, true)
|
||||
parseUnaryExpression((, true)
|
||||
parsePrimary((, expression)
|
||||
parseSendOrFunctionLiteral((, expression)
|
||||
parseSend((, expression)
|
||||
ensureIdentifier((, expression)
|
||||
listener: handleIdentifier(Zone, expression)
|
||||
listener: handleNoTypeArguments(.)
|
||||
parseArgumentsOpt(Zone)
|
||||
listener: handleNoArguments(.)
|
||||
listener: handleSend(Zone, .)
|
||||
parsePrimary(., expressionContinuation)
|
||||
parseSendOrFunctionLiteral(., expressionContinuation)
|
||||
parseSend(., expressionContinuation)
|
||||
ensureIdentifier(., expressionContinuation)
|
||||
listener: handleIdentifier(current, expressionContinuation)
|
||||
listener: handleNoTypeArguments([)
|
||||
parseArgumentsOpt(current)
|
||||
listener: handleNoArguments([)
|
||||
listener: handleSend(current, [)
|
||||
listener: endBinaryExpression(.)
|
||||
parseArgumentOrIndexStar(current, Instance of 'NoTypeParamOrArg')
|
||||
parseExpression([)
|
||||
parsePrecedenceExpression([, 1, true)
|
||||
parseUnaryExpression([, true)
|
||||
parsePrimary([, expression)
|
||||
parseSendOrFunctionLiteral([, expression)
|
||||
parseSend([, expression)
|
||||
ensureIdentifier([, expression)
|
||||
listener: handleIdentifier(logKey, expression)
|
||||
listener: handleNoTypeArguments(])
|
||||
parseArgumentsOpt(logKey)
|
||||
listener: handleNoArguments(])
|
||||
listener: handleSend(logKey, ])
|
||||
listener: handleIndexedExpression([, ])
|
||||
parseAsOperatorRest(])
|
||||
computeTypeAfterIsOrAs(as)
|
||||
listener: handleIdentifier(Logger, typeReference)
|
||||
listener: handleNoTypeArguments(?)
|
||||
listener: handleType(Logger, ?)
|
||||
listener: handleAsOperator(as)
|
||||
skipChainedAsIsOperators(?)
|
||||
ensureCloseParen(?, ()
|
||||
listener: handleParenthesizedExpression(()
|
||||
listener: beginBinaryExpression(??)
|
||||
parsePrecedenceExpression(??, 5, true)
|
||||
parseUnaryExpression(??, true)
|
||||
parsePrimary(??, expression)
|
||||
parseSendOrFunctionLiteral(??, expression)
|
||||
parseSend(??, expression)
|
||||
ensureIdentifier(??, expression)
|
||||
listener: handleIdentifier(_default, expression)
|
||||
listener: handleNoTypeArguments(;)
|
||||
parseArgumentsOpt(_default)
|
||||
listener: handleNoArguments(;)
|
||||
listener: handleSend(_default, ;)
|
||||
listener: endBinaryExpression(??)
|
||||
ensureSemicolon(_default)
|
||||
listener: handleExpressionFunctionBody(=>, ;)
|
||||
inGenerator()
|
||||
listener: endTopLevelMethod(Logger, get, ;)
|
||||
listener: endTopLevelDeclaration()
|
||||
reportAllErrorTokens(Logger)
|
||||
listener: endCompilationUnit(1, )
|
|
@ -0,0 +1,3 @@
|
|||
Logger get log => (Zone.current[logKey] as Logger?) ?? _default;
|
||||
|
||||
Logger[StringToken] get[KeywordToken] log[StringToken] =>[SimpleToken] ([BeginToken]Zone[StringToken].[SimpleToken]current[StringToken][[BeginToken]logKey[StringToken]][SimpleToken] as[KeywordToken] Logger[StringToken]?[SimpleToken])[SimpleToken] ??[SimpleToken] _default[StringToken];[SimpleToken][SimpleToken]
|
|
@ -0,0 +1,3 @@
|
|||
Logger get log => (Zone.current[logKey] as Logger?) ?? _default;
|
||||
|
||||
Logger[StringToken] get[KeywordToken] log[StringToken] =>[SimpleToken] ([BeginToken]Zone[StringToken].[SimpleToken]current[StringToken][[BeginToken]logKey[StringToken]][SimpleToken] as[KeywordToken] Logger[StringToken]?[SimpleToken])[SimpleToken] ??[SimpleToken] _default[StringToken];[SimpleToken][SimpleToken]
|
Loading…
Reference in a new issue