Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Unified Diff: runtime/vm/parser.cc

Issue 2267473002: Revert "Implement parsing support for generic functions" (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/generic_functions_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 3e6ab91c6912ac7cea76da3fc3e3410ac08a9267..e9e6e93b215b35c03ca941902529e795dc244fa2 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -48,7 +48,6 @@ DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef.");
// committed to the current version.
DEFINE_FLAG(bool, conditional_directives, true,
"Enable conditional directives");
-DEFINE_FLAG(bool, generic_method_syntax, false, "Enable generic functions.");
DEFINE_FLAG(bool, initializing_formal_access, false,
"Make initializing formal parameters visible in initializer list.");
DEFINE_FLAG(bool, warn_super, false,
@@ -126,25 +125,6 @@ class BoolScope : public ValueObject {
};
-// Helper class to save and restore token position.
-class Parser::TokenPosScope : public ValueObject {
- public:
- explicit TokenPosScope(Parser *p) : p_(p) {
- saved_pos_ = p_->TokenPos();
- }
- TokenPosScope(Parser *p, TokenPosition pos) : p_(p), saved_pos_(pos) {
- }
- ~TokenPosScope() {
- p_->SetPosition(saved_pos_);
- }
-
- private:
- Parser* p_;
- TokenPosition saved_pos_;
- DISALLOW_COPY_AND_ASSIGN(TokenPosScope);
-};
-
-
class RecursionChecker : public ValueObject {
public:
explicit RecursionChecker(Parser* p) : parser_(p) {
@@ -2085,7 +2065,7 @@ void Parser::ParseFormalParameter(bool allow_explicit_default_value,
}
}
- if (IsParameterPart()) {
+ if (CurrentToken() == Token::kLPAREN) {
// This parameter is probably a closure. If we saw the keyword 'var'
// or 'final', a closure is not legal here and we ignore the
// opening parens.
@@ -2099,18 +2079,6 @@ void Parser::ParseFormalParameter(bool allow_explicit_default_value,
AbstractType::Handle(Z, parameter.type->raw());
// Finish parsing the function type parameter.
- if (CurrentToken() == Token::kLT) {
- // TODO(hausner): handle generic function types.
- if (!FLAG_generic_method_syntax) {
- ReportError("generic function types not supported");
- }
- TokenPosition type_param_pos = TokenPos();
- if (!TryParseTypeParameters()) {
- ReportError(type_param_pos, "error in type parameters");
- }
- }
-
- ASSERT(CurrentToken() == Token::kLPAREN);
ParamList func_params;
// Add implicit closure object parameter.
@@ -3748,10 +3716,7 @@ RawLibraryPrefix* Parser::ParsePrefix() {
void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
TRACE_PARSER("ParseMethodOrConstructor");
- // We are at the beginning of the formal parameters list.
- ASSERT(CurrentToken() == Token::kLPAREN ||
- CurrentToken() == Token::kLT ||
- method->IsGetter());
+ ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter());
ASSERT(method->type != NULL);
ASSERT(current_member_ == method);
@@ -3776,25 +3741,6 @@ void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
current_class().set_is_const();
}
- if (CurrentToken() == Token::kLT) {
- // Parse type parameters, but ignore them.
- // TODO(hausner): handle type parameters.
- if (!FLAG_generic_method_syntax) {
- ReportError("generic type arguments not supported.");
- }
- TokenPosition type_param_pos = TokenPos();
- if (method->IsFactoryOrConstructor()) {
- ReportError(method->name_pos, "constructor cannot be generic");
- }
- if (method->IsGetter() || method->IsSetter()) {
- ReportError(type_param_pos, "%s cannot be generic",
- method->IsGetter() ? "getter" : "setter");
- }
- if (!TryParseTypeParameters()) {
- ReportError(type_param_pos, "error in type parameters");
- }
- }
-
// Parse the formal parameters.
const bool are_implicitly_final = method->has_const;
const bool allow_explicit_default_values = true;
@@ -4395,7 +4341,6 @@ void Parser::ParseClassMemberDefinition(ClassDesc* members,
member.has_static = true;
// The result type depends on the name of the factory method.
}
-
// Optionally parse a type.
if (CurrentToken() == Token::kVOID) {
if (member.has_var || member.has_factory) {
@@ -4404,24 +4349,29 @@ void Parser::ParseClassMemberDefinition(ClassDesc* members,
ConsumeToken();
ASSERT(member.type == NULL);
member.type = &Object::void_type();
- } else {
- bool found_type = false;
- {
- // Lookahead to determine whether the next tokens are a return type.
- TokenPosScope saved_pos(this);
- if (TryParseReturnType()) {
- if (IsIdentifier() ||
- (CurrentToken() == Token::kGET) ||
- (CurrentToken() == Token::kSET) ||
- (CurrentToken() == Token::kOPERATOR)) {
- found_type = true;
- }
+ } else if (CurrentToken() == Token::kIDENT) {
+ // This is either a type name or the name of a method/constructor/field.
+ if ((member.type == NULL) && !member.has_factory) {
+ // We have not seen a member type yet, so we check if the next
+ // identifier could represent a type before parsing it.
+ Token::Kind follower = LookaheadToken(1);
+ // We have an identifier followed by a 'follower' token.
+ // We either parse a type or assume that no type is specified.
+ if ((follower == Token::kLT) || // Parameterized type.
+ (follower == Token::kGET) || // Getter following a type.
+ (follower == Token::kSET) || // Setter following a type.
+ (follower == Token::kOPERATOR) || // Operator following a type.
+ (Token::IsIdentifier(follower)) || // Member name following a type.
+ ((follower == Token::kPERIOD) && // Qualified class name of type,
+ (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr.
+ ASSERT(is_top_level_);
+ // The declared type of fields is never ignored, even in unchecked mode,
+ // because getters and setters could be closurized at some time (not
+ // supported yet).
+ member.type = &AbstractType::ZoneHandle(Z,
+ ParseType(ClassFinalizer::kResolveTypeParameters));
}
}
- if (found_type) {
- member.type = &AbstractType::ZoneHandle(Z,
- ParseType(ClassFinalizer::kResolveTypeParameters));
- }
}
// Optionally parse a (possibly named) constructor name or factory.
@@ -4472,7 +4422,6 @@ void Parser::ParseClassMemberDefinition(ClassDesc* members,
CheckToken(Token::kLPAREN);
} else if ((CurrentToken() == Token::kGET) && !member.has_var &&
(LookaheadToken(1) != Token::kLPAREN) &&
- (LookaheadToken(1) != Token::kLT) &&
(LookaheadToken(1) != Token::kASSIGN) &&
(LookaheadToken(1) != Token::kCOMMA) &&
(LookaheadToken(1) != Token::kSEMICOLON)) {
@@ -4483,7 +4432,6 @@ void Parser::ParseClassMemberDefinition(ClassDesc* members,
// If the result type was not specified, it will be set to DynamicType.
} else if ((CurrentToken() == Token::kSET) && !member.has_var &&
(LookaheadToken(1) != Token::kLPAREN) &&
- (LookaheadToken(1) != Token::kLT) &&
(LookaheadToken(1) != Token::kASSIGN) &&
(LookaheadToken(1) != Token::kCOMMA) &&
(LookaheadToken(1) != Token::kSEMICOLON)) {
@@ -4502,8 +4450,6 @@ void Parser::ParseClassMemberDefinition(ClassDesc* members,
(LookaheadToken(1) != Token::kASSIGN) &&
(LookaheadToken(1) != Token::kCOMMA) &&
(LookaheadToken(1) != Token::kSEMICOLON)) {
- // TODO(hausner): handle the case of a generic function named 'operator':
- // eg: T operator<T>(a, b) => ...
ConsumeToken();
if (!Token::CanBeOverloaded(CurrentToken())) {
ReportError("invalid operator overloading");
@@ -4527,7 +4473,7 @@ void Parser::ParseClassMemberDefinition(ClassDesc* members,
}
ASSERT(member.name != NULL);
- if (IsParameterPart() || member.IsGetter()) {
+ if (CurrentToken() == Token::kLPAREN || member.IsGetter()) {
// Constructor or method.
if (member.type == NULL) {
member.type = &Object::dynamic_type();
@@ -5182,14 +5128,16 @@ bool Parser::IsFunctionTypeAliasName() {
if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
return true;
}
- const TokenPosScope saved_pos(this);
+ const TokenPosition saved_pos = TokenPos();
+ bool is_alias_name = false;
if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
ConsumeToken();
if (TryParseTypeParameters() && (CurrentToken() == Token::kLPAREN)) {
- return true;
+ is_alias_name = true;
}
}
- return false;
+ SetPosition(saved_pos);
+ return is_alias_name;
}
@@ -5199,14 +5147,16 @@ bool Parser::IsMixinAppAlias() {
if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) {
return true;
}
- const TokenPosScope saved_pos(this);
+ const TokenPosition saved_pos = TokenPos();
+ bool is_mixin_def = false;
if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
ConsumeToken();
if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) {
- return true;
+ is_mixin_def = true;
}
}
- return false;
+ SetPosition(saved_pos);
+ return is_mixin_def;
}
@@ -5313,9 +5263,9 @@ void Parser::ParseTypedef(const GrowableObjectArray& pending_classes,
}
-// Consumes exactly one right angle bracket. If the current token is
-// a single bracket token, it is consumed normally. However, if it is
-// a double bracket, it is replaced by a single bracket token without
+// Consumes exactly one right angle bracket. If the current token is a single
+// bracket token, it is consumed normally. However, if it is a double or triple
+// bracket, it is replaced by a single or double bracket token without
// incrementing the token index.
void Parser::ConsumeRightAngleBracket() {
if (token_kind_ == Token::kGT) {
@@ -5332,10 +5282,12 @@ bool Parser::IsPatchAnnotation(TokenPosition pos) {
if (pos == TokenPosition::kNoSource) {
return false;
}
- TokenPosScope saved_pos(this);
+ TokenPosition saved_pos = TokenPos();
SetPosition(pos);
ExpectToken(Token::kAT);
- return IsSymbol(Symbols::Patch());
+ bool is_patch = IsSymbol(Symbols::Patch());
+ SetPosition(saved_pos);
+ return is_patch;
}
@@ -5693,7 +5645,8 @@ void Parser::ParseTopLevelFunction(TopLevel* top_level,
result_type = Type::VoidType();
} else {
// Parse optional type.
- if (IsFunctionReturnType()) {
+ if ((CurrentToken() == Token::kIDENT) &&
+ (LookaheadToken(1) != Token::kLPAREN)) {
result_type = ParseType(ClassFinalizer::kResolveTypeParameters);
}
}
@@ -5715,18 +5668,6 @@ void Parser::ParseTopLevelFunction(TopLevel* top_level,
// A setter named x= may co-exist with a function named x, thus we do
// not need to check setters.
- if (CurrentToken() == Token::kLT) {
- // Type parameters of generic function.
- // TODO(hausner): handle type parameters.
- if (!FLAG_generic_method_syntax) {
- ReportError("generic functions not supported");
- }
- TokenPosition type_arg_pos = TokenPos();
- if (!TryParseTypeParameters()) {
- ReportError(type_arg_pos, "error in type parameters");
- }
- }
-
CheckToken(Token::kLPAREN);
const TokenPosition function_pos = TokenPos();
ParamList params;
@@ -7819,14 +7760,15 @@ AstNode* Parser::ParseFunctionStatement(bool is_literal) {
const TokenPosition function_pos = TokenPos();
TokenPosition metadata_pos = TokenPosition::kNoSource;
if (is_literal) {
- ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT);
+ ASSERT(CurrentToken() == Token::kLPAREN);
function_name = &Symbols::AnonymousClosure();
} else {
metadata_pos = SkipMetadata();
if (CurrentToken() == Token::kVOID) {
ConsumeToken();
result_type = Type::VoidType();
- } else if (IsFunctionReturnType()) {
+ } else if ((CurrentToken() == Token::kIDENT) &&
+ (LookaheadToken(1) != Token::kLPAREN)) {
result_type = ParseType(ClassFinalizer::kCanonicalize);
}
const TokenPosition name_pos = TokenPos();
@@ -7848,18 +7790,6 @@ AstNode* Parser::ParseFunctionStatement(bool is_literal) {
line_number);
}
}
-
- if (CurrentToken() == Token::kLT) {
- if (!FLAG_generic_method_syntax) {
- ReportError("generic functions not supported");
- }
- TokenPosition type_arg_pos = TokenPos();
- // TODO(hausner): handle type parameters of generic function.
- if (!TryParseTypeParameters()) {
- ReportError(type_arg_pos, "error in type parameters");
- }
- }
-
CheckToken(Token::kLPAREN);
// Check whether we have parsed this closure function before, in a previous
@@ -8033,113 +7963,37 @@ AstNode* Parser::ParseFunctionStatement(bool is_literal) {
// Returns true if the current and next tokens can be parsed as type
// parameters. Current token position is not saved and restored.
bool Parser::TryParseTypeParameters() {
- ASSERT(CurrentToken() == Token::kLT);
- int nesting_level = 0;
- do {
- Token::Kind ct = CurrentToken();
- if (ct == Token::kLT) {
- nesting_level++;
- } else if (ct == Token::kGT) {
- nesting_level--;
- } else if (ct == Token::kSHR) {
- nesting_level -= 2;
- } else if (ct == Token::kIDENT) {
- // Check to see if it is a qualified identifier.
- if (LookaheadToken(1) == Token::kPERIOD) {
- // Consume the identifier, the period will be consumed below.
- ConsumeToken();
- }
- } else if ((ct != Token::kCOMMA) &&
- (ct != Token::kEXTENDS) &&
- (!FLAG_generic_method_syntax || (ct != Token::kSUPER))) {
- // We are looking at something other than type parameters.
- return false;
- }
- ConsumeToken();
- } while (nesting_level > 0);
- if (nesting_level < 0) {
- return false;
- }
- return true;
-}
-
-
-// Returns true if the next tokens can be parsed as type parameters.
-bool Parser::IsTypeParameters() {
if (CurrentToken() == Token::kLT) {
- TokenPosScope param_pos(this);
- if (!TryParseTypeParameters()) {
- return false;
- }
- return true;
- }
- return false;
-}
-
-
-// Returns true if the next tokens are [ typeParameters ] '('.
-bool Parser::IsParameterPart() {
- if (CurrentToken() == Token::kLPAREN) {
- return true;
- }
- if (CurrentToken() == Token::kLT) {
- TokenPosScope type_arg_pos(this);
- if (!TryParseTypeParameters()) {
- return false;
- }
- return CurrentToken() == Token::kLPAREN;
- }
- return false;
-}
-
-
-// Returns true if the current and next tokens can be parsed as type
-// arguments. Current token position is not saved and restored.
-bool Parser::TryParseTypeArguments() {
- ASSERT(CurrentToken() == Token::kLT);
- int nesting_level = 0;
- do {
- Token::Kind ct = CurrentToken();
- if (ct == Token::kLT) {
- nesting_level++;
- } else if (ct == Token::kGT) {
- nesting_level--;
- } else if (ct == Token::kSHR) {
- nesting_level -= 2;
- } else if (ct == Token::kIDENT) {
- // Check to see if it is a qualified identifier.
- if (LookaheadToken(1) == Token::kPERIOD) {
- // Consume the identifier, the period will be consumed below.
- ConsumeToken();
+ // We are possibly looking at type parameters. Find closing ">".
+ int nesting_level = 0;
+ do {
+ if (CurrentToken() == Token::kLT) {
+ nesting_level++;
+ } else if (CurrentToken() == Token::kGT) {
+ nesting_level--;
+ } else if (CurrentToken() == Token::kSHR) {
+ nesting_level -= 2;
+ } else if (CurrentToken() == Token::kIDENT) {
+ // Check to see if it is a qualified identifier.
+ if (LookaheadToken(1) == Token::kPERIOD) {
+ // Consume the identifier, the period will be consumed below.
+ ConsumeToken();
+ }
+ } else if (CurrentToken() != Token::kCOMMA &&
+ CurrentToken() != Token::kEXTENDS) {
+ // We are looking at something other than type parameters.
+ return false;
}
- } else if (ct != Token::kCOMMA) {
+ ConsumeToken();
+ } while (nesting_level > 0);
+ if (nesting_level < 0) {
return false;
}
- ConsumeToken();
- } while (nesting_level > 0);
- if (nesting_level < 0) {
- return false;
}
return true;
}
-// Returns true if the next tokens are [ typeArguments ] '('.
-bool Parser::IsArgumentPart() {
- if (CurrentToken() == Token::kLPAREN) {
- return true;
- }
- if (CurrentToken() == Token::kLT) {
- TokenPosScope type_arg_pos(this);
- if (!TryParseTypeArguments()) {
- return false;
- }
- return CurrentToken() == Token::kLPAREN;
- }
- return false;
-}
-
-
bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) {
// Assigning null never causes a type error.
if (CurrentToken() == Token::kNULL) {
@@ -8303,106 +8157,84 @@ bool Parser::IsVariableDeclaration() {
}
-// Look ahead to see if the following tokens are a return type followed
-// by an identifier.
-bool Parser::IsFunctionReturnType() {
- TokenPosScope decl_pos(this);
- if (TryParseReturnType()) {
- if (IsIdentifier()) {
- // Return type followed by function name.
- return true;
- }
- }
- return false;
-}
-
-
// Look ahead to detect whether the next tokens should be parsed as
// a function declaration. Token position remains unchanged.
bool Parser::IsFunctionDeclaration() {
+ const TokenPosition saved_pos = TokenPos();
bool is_external = false;
- TokenPosScope decl_pos(this);
SkipMetadata();
- if ((is_top_level_) && (CurrentToken() == Token::kEXTERNAL)) {
+ if (is_top_level_ && (CurrentToken() == Token::kEXTERNAL)) {
// Skip over 'external' for top-level function declarations.
is_external = true;
ConsumeToken();
}
- const TokenPosition type_or_name_pos = TokenPos();
- if (TryParseReturnType()) {
+ if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
+ // Possibly a function without explicit return type.
+ ConsumeToken(); // Consume function identifier.
+ } else if (TryParseReturnType()) {
if (!IsIdentifier()) {
- SetPosition(type_or_name_pos);
+ SetPosition(saved_pos);
+ return false;
}
+ ConsumeToken(); // Consume function identifier.
} else {
- SetPosition(type_or_name_pos);
- }
- // Check for function name followed by optional type parameters.
- if (!IsIdentifier()) {
- return false;
- }
- ConsumeToken();
- if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) {
- return false;
- }
-
- // Optional type, function name and optinal type parameters are parsed.
- if (CurrentToken() != Token::kLPAREN) {
+ SetPosition(saved_pos);
return false;
}
-
// Check parameter list and the following token.
- SkipToMatchingParenthesis();
- if ((CurrentToken() == Token::kLBRACE) ||
- (CurrentToken() == Token::kARROW) ||
- (is_top_level_ && IsSymbol(Symbols::Native())) ||
- is_external ||
- IsSymbol(Symbols::Async()) ||
- IsSymbol(Symbols::Sync())) {
- return true;
+ if (CurrentToken() == Token::kLPAREN) {
+ SkipToMatchingParenthesis();
+ if ((CurrentToken() == Token::kLBRACE) ||
+ (CurrentToken() == Token::kARROW) ||
+ (is_top_level_ && IsSymbol(Symbols::Native())) ||
+ is_external ||
+ IsSymbol(Symbols::Async()) ||
+ IsSymbol(Symbols::Sync())) {
+ SetPosition(saved_pos);
+ return true;
+ }
}
+ SetPosition(saved_pos);
return false;
}
bool Parser::IsTopLevelAccessor() {
- const TokenPosScope saved_pos(this);
+ const TokenPosition saved_pos = TokenPos();
if (CurrentToken() == Token::kEXTERNAL) {
ConsumeToken();
}
if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
+ SetPosition(saved_pos);
return true;
}
if (TryParseReturnType()) {
if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name.
+ SetPosition(saved_pos);
return true;
}
}
}
+ SetPosition(saved_pos);
return false;
}
bool Parser::IsFunctionLiteral() {
- if (!allow_function_literals_) {
+ if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) {
return false;
}
- if ((CurrentToken() == Token::kLPAREN) || (CurrentToken() == Token::kLT)) {
- TokenPosScope saved_pos(this);
- if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) {
- return false;
- }
- if (CurrentToken() != Token::kLPAREN) {
- return false;
- }
- SkipToMatchingParenthesis();
- ParseFunctionModifier();
- if ((CurrentToken() == Token::kLBRACE) ||
- (CurrentToken() == Token::kARROW)) {
- return true;
- }
+ const TokenPosition saved_pos = TokenPos();
+ bool is_function_literal = false;
+ SkipToMatchingParenthesis();
+ ParseFunctionModifier();
+ if ((CurrentToken() == Token::kLBRACE) ||
+ (CurrentToken() == Token::kARROW)) {
+ is_function_literal = true;
}
- return false;
+ SetPosition(saved_pos);
+ return is_function_literal;
}
@@ -8410,7 +8242,8 @@ bool Parser::IsFunctionLiteral() {
// statement. Returns true if we recognize a for ( .. in expr)
// statement.
bool Parser::IsForInStatement() {
- const TokenPosScope saved_pos(this);
+ const TokenPosition saved_pos = TokenPos();
+ bool result = false;
// Allow const modifier as well when recognizing a for-in statement
// pattern. We will get an error later if the loop variable is
// declared with const.
@@ -8421,15 +8254,16 @@ bool Parser::IsForInStatement() {
}
if (IsIdentifier()) {
if (LookaheadToken(1) == Token::kIN) {
- return true;
+ result = true;
} else if (TryParseOptionalType()) {
if (IsIdentifier()) {
ConsumeToken();
}
- return CurrentToken() == Token::kIN;
+ result = (CurrentToken() == Token::kIN);
}
}
- return false;
+ SetPosition(saved_pos);
+ return result;
}
@@ -11829,17 +11663,8 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) {
}
const TokenPosition ident_pos = TokenPos();
String* ident = ExpectIdentifier("identifier expected");
- if (IsArgumentPart()) {
- // Identifier followed by optional type arguments and opening paren:
- // method call.
- if (CurrentToken() == Token::kLT) {
- // Type arguments.
- if (!FLAG_generic_method_syntax) {
- ReportError("generic type arguments not supported.");
- }
- // TODO(hausner): handle type arguments.
- ParseTypeArguments(ClassFinalizer::kIgnore);
- }
+ if (CurrentToken() == Token::kLPAREN) {
+ // Identifier followed by a opening paren: method call.
if (left->IsPrimaryNode() &&
left->AsPrimaryNode()->primary().IsClass()) {
// Static method call prefixed with class name.
@@ -11931,15 +11756,7 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) {
}
selector = new(Z) LoadIndexedNode(
bracket_pos, array, index, Class::ZoneHandle(Z));
- } else if (IsArgumentPart()) {
- if (CurrentToken() == Token::kLT) {
- // Type arguments.
- if (!FLAG_generic_method_syntax) {
- ReportError("generic type arguments not supported.");
- }
- // TODO(hausner): handle type arguments.
- ParseTypeArguments(ClassFinalizer::kIgnore);
- }
+ } else if (CurrentToken() == Token::kLPAREN) {
if (left->IsPrimaryNode()) {
PrimaryNode* primary_node = left->AsPrimaryNode();
const TokenPosition primary_pos = primary_node->token_pos();
@@ -14560,9 +14377,6 @@ void Parser::SkipMapLiteral() {
void Parser::SkipActualParameters() {
- if (CurrentToken() == Token::kLT) {
- SkipTypeArguments();
- }
ExpectToken(Token::kLPAREN);
while (CurrentToken() != Token::kRPAREN) {
if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) {
@@ -14730,7 +14544,7 @@ void Parser::SkipSelectors() {
ConsumeToken();
SkipNestedExpr();
ExpectToken(Token::kRBRACK);
- } else if (IsArgumentPart()) {
+ } else if (current_token == Token::kLPAREN) {
SkipActualParameters();
} else {
break;
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/generic_functions_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698