[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:
Jens Johansen 2019-12-12 06:59:53 +00:00 committed by commit-bot@chromium.org
parent 2a886d257f
commit e2d5aa352c
11 changed files with 284 additions and 1 deletions

View file

@ -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.

View file

@ -0,0 +1 @@
Logger get log => Zone.current[logKey] as Logger? ?? _default;

View 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, )

View file

@ -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, )

View file

@ -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]

View file

@ -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]

View file

@ -0,0 +1 @@
Logger get log => (Zone.current[logKey] as Logger?) ?? _default;

View file

@ -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, )

View file

@ -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, )

View file

@ -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]

View file

@ -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]