mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:44:27 +00:00
Fix isValidMethodTypeArguments
Change-Id: I3c4bb8dc981c285b8ecfad7dcd7dc849ed1bda7b Reviewed-on: https://dart-review.googlesource.com/52920 Commit-Queue: Dan Rubel <danrubel@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
32f10d6f7a
commit
79a15f52bf
6 changed files with 32 additions and 77 deletions
|
@ -13923,6 +13923,23 @@ class C {}
|
|||
expect(creation.argumentList, isNotNull);
|
||||
}
|
||||
|
||||
void test_parseInstanceCreation_noKeyword_varInit() {
|
||||
enableOptionalNewAndConst = true;
|
||||
createParser('''
|
||||
class C<T, S> {}
|
||||
void main() {final c = C<int, int Function(String)>();}
|
||||
''');
|
||||
CompilationUnit unit = parser.parseCompilationUnit2();
|
||||
expect(unit, isNotNull);
|
||||
FunctionDeclaration f = unit.declarations[1];
|
||||
BlockFunctionBody body = f.functionExpression.body;
|
||||
VariableDeclarationStatement statement = body.block.statements[0];
|
||||
VariableDeclaration variable = statement.variables.variables[0];
|
||||
MethodInvocation creation = variable.initializer;
|
||||
expect(creation.methodName.name, 'C');
|
||||
expect(creation.typeArguments.toSource(), '<int, int Function(String)>');
|
||||
}
|
||||
|
||||
void test_parseLibraryIdentifier_invalid() {
|
||||
parseCompilationUnit('library <myLibId>;',
|
||||
errors: usingFastaParser
|
||||
|
|
|
@ -34,8 +34,6 @@ import '../scanner/token_constants.dart'
|
|||
EOF_TOKEN,
|
||||
EQ_TOKEN,
|
||||
FUNCTION_TOKEN,
|
||||
GT_GT_TOKEN,
|
||||
GT_TOKEN,
|
||||
HASH_TOKEN,
|
||||
HEXADECIMAL_TOKEN,
|
||||
IDENTIFIER_TOKEN,
|
||||
|
@ -45,7 +43,6 @@ import '../scanner/token_constants.dart'
|
|||
OPEN_CURLY_BRACKET_TOKEN,
|
||||
OPEN_PAREN_TOKEN,
|
||||
OPEN_SQUARE_BRACKET_TOKEN,
|
||||
PERIOD_TOKEN,
|
||||
SEMICOLON_TOKEN,
|
||||
STRING_INTERPOLATION_IDENTIFIER_TOKEN,
|
||||
STRING_INTERPOLATION_TOKEN,
|
||||
|
@ -94,6 +91,8 @@ import 'type_info.dart'
|
|||
isValidTypeReference,
|
||||
noType;
|
||||
|
||||
import 'type_info_impl.dart' show skipTypeVariables;
|
||||
|
||||
import 'util.dart' show optional;
|
||||
|
||||
/// An event generating parser of Dart programs. This parser expects all tokens
|
||||
|
@ -1506,76 +1505,14 @@ class Parser {
|
|||
/// arguments in generic method invocations can be recognized, and as few as
|
||||
/// possible other constructs will pass (e.g., 'a < C, D > 3').
|
||||
bool isValidMethodTypeArguments(Token token) {
|
||||
Token Function(Token token) tryParseType;
|
||||
|
||||
/// Returns token after match if [token] matches '<' type (',' type)* '>'
|
||||
/// '(', and otherwise returns null. Does not produce listener events. With
|
||||
/// respect to the final '(', please see the description of
|
||||
/// [isValidMethodTypeArguments].
|
||||
Token tryParseMethodTypeArguments(Token token) {
|
||||
if (!identical(token.kind, LT_TOKEN)) return null;
|
||||
Token endToken = token.endGroup;
|
||||
if (endToken == null ||
|
||||
!identical(endToken.next.kind, OPEN_PAREN_TOKEN)) {
|
||||
return null;
|
||||
// TODO(danrubel): Replace call with a call to computeTypeVar.
|
||||
if (optional('<', token)) {
|
||||
Token endGroup = skipTypeVariables(token);
|
||||
if (endGroup != null && optional('(', endGroup.next)) {
|
||||
return true;
|
||||
}
|
||||
token = tryParseType(token.next);
|
||||
while (token != null && identical(token.kind, COMMA_TOKEN)) {
|
||||
token = tryParseType(token.next);
|
||||
}
|
||||
if (token == null || !identical(token.kind, GT_TOKEN)) return null;
|
||||
return token.next;
|
||||
}
|
||||
|
||||
/// Returns token after match if [token] matches identifier ('.'
|
||||
/// identifier)?, and otherwise returns null. Does not produce listener
|
||||
/// events.
|
||||
Token tryParseQualified(Token token) {
|
||||
if (!isValidTypeReference(token)) return null;
|
||||
token = token.next;
|
||||
if (!identical(token.kind, PERIOD_TOKEN)) return token;
|
||||
token = token.next;
|
||||
if (!identical(token.kind, IDENTIFIER_TOKEN)) return null;
|
||||
return token.next;
|
||||
}
|
||||
|
||||
/// Returns token after match if [token] matches '<' type (',' type)* '>',
|
||||
/// and otherwise returns null. Does not produce listener events. The final
|
||||
/// '>' may be the first character in a '>>' token, in which case a
|
||||
/// synthetic '>' token is created and returned, representing the second
|
||||
/// '>' in the '>>' token.
|
||||
Token tryParseNestedTypeArguments(Token token) {
|
||||
if (!identical(token.kind, LT_TOKEN)) return null;
|
||||
// If the initial '<' matches the first '>' in a '>>' token, we will have
|
||||
// `token.endGroup == null`, so we cannot rely on `token.endGroup == null`
|
||||
// to imply that the match must fail. Hence no `token.endGroup == null`
|
||||
// test here.
|
||||
token = tryParseType(token.next);
|
||||
while (token != null && identical(token.kind, COMMA_TOKEN)) {
|
||||
token = tryParseType(token.next);
|
||||
}
|
||||
if (token == null) return null;
|
||||
if (identical(token.kind, GT_TOKEN)) return token.next;
|
||||
if (!identical(token.kind, GT_GT_TOKEN)) return null;
|
||||
// [token] is '>>' of which the final '>' that we are parsing is the first
|
||||
// character. In order to keep the parsing process on track we must return
|
||||
// a synthetic '>' corresponding to the second character of that '>>'.
|
||||
Token syntheticToken = new Token(TokenType.GT, token.charOffset + 1);
|
||||
syntheticToken.next = token.next;
|
||||
return syntheticToken;
|
||||
}
|
||||
|
||||
/// Returns token after match if [token] matches typeName typeArguments?,
|
||||
/// and otherwise returns null. Does not produce listener events.
|
||||
tryParseType = (Token token) {
|
||||
token = tryParseQualified(token);
|
||||
if (token == null) return null;
|
||||
Token tokenAfterQualified = token;
|
||||
token = tryParseNestedTypeArguments(token);
|
||||
return token == null ? tokenAfterQualified : token;
|
||||
};
|
||||
|
||||
return tryParseMethodTypeArguments(token) != null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ```
|
||||
|
|
|
@ -282,7 +282,7 @@ covariance_type_parameter_test/01: Crash # NoSuchMethodError: The method 'hasSub
|
|||
covariance_type_parameter_test/02: Crash # NoSuchMethodError: The method 'hasSubclass' was called on null.
|
||||
covariance_type_parameter_test/03: Crash # NoSuchMethodError: The method 'hasSubclass' was called on null.
|
||||
covariant_override/runtime_check_test: RuntimeError
|
||||
covariant_subtyping_test: CompileTimeError
|
||||
covariant_subtyping_test: RuntimeError
|
||||
cyclic_constructor_test/01: Crash # Stack Overflow
|
||||
deferred_constraints_constants_test/default_argument2: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
|
||||
deferred_constraints_constants_test/none: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
|
||||
|
@ -1092,7 +1092,7 @@ covariance_type_parameter_test/01: RuntimeError
|
|||
covariance_type_parameter_test/02: RuntimeError
|
||||
covariance_type_parameter_test/03: RuntimeError
|
||||
covariant_override/tear_off_type_test: RuntimeError
|
||||
covariant_subtyping_test: CompileTimeError
|
||||
covariant_subtyping_test: RuntimeError
|
||||
cyclic_constructor_test/01: Crash # Issue 30856
|
||||
cyclic_type_test/00: RuntimeError
|
||||
cyclic_type_test/02: RuntimeError
|
||||
|
@ -1713,7 +1713,7 @@ covariance_type_parameter_test/01: RuntimeError
|
|||
covariance_type_parameter_test/02: RuntimeError
|
||||
covariance_type_parameter_test/03: RuntimeError
|
||||
covariant_override/tear_off_type_test: RuntimeError
|
||||
covariant_subtyping_test: CompileTimeError
|
||||
covariant_subtyping_test: RuntimeError
|
||||
cyclic_constructor_test/01: Crash # Issue 30856
|
||||
cyclic_type_variable_test/01: MissingCompileTimeError
|
||||
cyclic_type_variable_test/02: MissingCompileTimeError
|
||||
|
@ -2189,6 +2189,7 @@ wrong_number_type_arguments_test/none: Pass
|
|||
|
||||
[ $compiler == dart2js && $fasta && $strong ]
|
||||
const_constructor3_test/04: MissingCompileTimeError # OK - Subtype check uses JS number semantics.
|
||||
covariant_subtyping_test: Crash
|
||||
ct_const_test: RuntimeError
|
||||
|
||||
[ $compiler == dart2js && $fasta && !$strong ]
|
||||
|
|
|
@ -348,7 +348,7 @@ constants_test/05: MissingCompileTimeError
|
|||
constructor_redirect1_negative_test/01: MissingCompileTimeError
|
||||
constructor_redirect2_negative_test: MissingCompileTimeError
|
||||
constructor_redirect_test/01: MissingCompileTimeError
|
||||
covariant_subtyping_test: CompileTimeError
|
||||
covariant_subtyping_test: RuntimeError
|
||||
cyclic_constructor_test/01: MissingCompileTimeError
|
||||
cyclic_type_variable_test/01: MissingCompileTimeError
|
||||
cyclic_type_variable_test/02: MissingCompileTimeError
|
||||
|
|
|
@ -82,7 +82,6 @@ const_types_test/39: MissingCompileTimeError
|
|||
constructor_redirect1_negative_test/01: MissingCompileTimeError
|
||||
constructor_redirect2_negative_test: MissingCompileTimeError
|
||||
constructor_redirect_test/01: MissingCompileTimeError # Fasta bug: Initializer refers to this.
|
||||
covariant_subtyping_test: CompileTimeError
|
||||
cyclic_constructor_test/01: MissingCompileTimeError # Fasta bug: Cyclic constructor redirection.
|
||||
cyclic_type_variable_test/01: MissingCompileTimeError
|
||||
cyclic_type_variable_test/02: MissingCompileTimeError
|
||||
|
@ -572,6 +571,7 @@ const_nested_test: RuntimeError # KernelVM bug: Constant evaluation.
|
|||
const_string_test: RuntimeError
|
||||
constructor12_test: RuntimeError
|
||||
constructor3_test: Fail, OK, Pass
|
||||
covariant_subtyping_test: RuntimeError
|
||||
ct_const2_test: Pass, Crash # Flaky
|
||||
ct_const_test: RuntimeError
|
||||
cyclic_type2_test: RuntimeError, CompileTimeError
|
||||
|
|
|
@ -247,7 +247,7 @@ covariant_override/runtime_check_test: RuntimeError
|
|||
covariant_subtyping_tearoff1_test: RuntimeError
|
||||
covariant_subtyping_tearoff2_test: RuntimeError
|
||||
covariant_subtyping_tearoff3_test: RuntimeError
|
||||
covariant_subtyping_test: CompileTimeError
|
||||
covariant_subtyping_test: RuntimeError
|
||||
covariant_subtyping_unsafe_call1_test: RuntimeError
|
||||
covariant_subtyping_unsafe_call2_test: RuntimeError
|
||||
covariant_subtyping_unsafe_call3_test: RuntimeError
|
||||
|
|
Loading…
Reference in a new issue