| Index: runtime/vm/parser.cc
|
| ===================================================================
|
| --- runtime/vm/parser.cc (revision 1593)
|
| +++ runtime/vm/parser.cc (working copy)
|
| @@ -25,7 +25,7 @@
|
| DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks.");
|
| DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
|
| DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors.");
|
| -DEFINE_FLAG(bool, silent_warnings, true, "Silence warnings.");
|
| +DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
|
|
|
| // All references to Dart names are listed here.
|
| static const char* kAssertionErrorName = "AssertionError";
|
| @@ -280,13 +280,13 @@
|
| Clear();
|
| }
|
| void Clear() {
|
| - local_scope_ident = false;
|
| + is_local_scope_ident = false;
|
| lib_prefix = NULL;
|
| qualifier = NULL;
|
| ident_pos = 0;
|
| ident = NULL;
|
| }
|
| - bool local_scope_ident;
|
| + bool is_local_scope_ident;
|
| LibraryPrefix* lib_prefix;
|
| String* qualifier;
|
| intptr_t ident_pos;
|
| @@ -572,6 +572,7 @@
|
| case RawFunction::kGetterFunction:
|
| case RawFunction::kSetterFunction:
|
| case RawFunction::kConstructor:
|
| + ASSERT(!func.IsFactory() || (func.signature_class() != Class::null()));
|
| node_sequence = parser.ParseFunc(func, default_parameter_values);
|
| break;
|
| case RawFunction::kImplicitGetter:
|
| @@ -641,7 +642,7 @@
|
| // fragment to evaluate the expression. Instead, we just make sure
|
| // the static const field initializer is a constant expression and
|
| // leave the evaluation to the getter function.
|
| - intptr_t expr_pos = token_index_;
|
| + const intptr_t expr_pos = token_index_;
|
| AstNode* expr = ParseExpr(kAllowConst);
|
| if (expr->EvalConstExpr() == NULL) {
|
| ErrorMsg(expr_pos, "initializer must be a compile time constant");
|
| @@ -731,7 +732,7 @@
|
| void Parser::SkipBlock() {
|
| ASSERT(CurrentToken() == Token::kLBRACE);
|
| GrowableArray<Token::Kind> token_stack(8);
|
| - intptr_t block_start_pos = token_index_;
|
| + const intptr_t block_start_pos = token_index_;
|
| bool is_match = true;
|
| bool unexpected_token_found = false;
|
| Token::Kind token;
|
| @@ -1372,7 +1373,7 @@
|
| GrowableArray<FieldInitExpression>* initializers) {
|
| const Array& fields = Array::Handle(cls.fields());
|
| Field& f = Field::Handle();
|
| - intptr_t saved_pos = token_index_;
|
| + const intptr_t saved_pos = token_index_;
|
| for (int i = 0; i < fields.Length(); i++) {
|
| f ^= fields.At(i);
|
| if (!f.is_static() && f.has_initializer()) {
|
| @@ -1416,7 +1417,7 @@
|
| AstNode* init_statement;
|
| if (CurrentToken() == Token::kSUPER) {
|
| if (super_init_seen) {
|
| - ErrorMsg("Duplicate call to super constructor");
|
| + ErrorMsg("duplicate call to super constructor");
|
| }
|
| init_statement = ParseSuperInitializer(cls, receiver);
|
| super_init_seen = true;
|
| @@ -1438,7 +1439,7 @@
|
| void Parser::ParseConstructorRedirection(const Class& cls,
|
| LocalVariable* receiver) {
|
| ASSERT(CurrentToken() == Token::kTHIS);
|
| - intptr_t call_pos = token_index_;
|
| + const intptr_t call_pos = token_index_;
|
| ConsumeToken();
|
| String& ctor_name = String::Handle(cls.Name());
|
| String& ctor_suffix = String::Handle(String::NewSymbol("."));
|
| @@ -1481,7 +1482,7 @@
|
|
|
| SequenceNode* Parser::MakeImplicitConstructor(const Function& func) {
|
| ASSERT(func.IsConstructor());
|
| - intptr_t ctor_pos = token_index_;
|
| + const intptr_t ctor_pos = token_index_;
|
|
|
| // Implicit 'this' is the only parameter/local variable.
|
| OpenFunctionBlock(func);
|
| @@ -1843,7 +1844,7 @@
|
| ExpectToken(Token::kRBRACE);
|
| } else if (CurrentToken() == Token::kARROW) {
|
| ConsumeToken();
|
| - intptr_t expr_pos = token_index_;
|
| + const intptr_t expr_pos = token_index_;
|
| AstNode* expr = ParseExpr(kAllowConst);
|
| ASSERT(expr != NULL);
|
| current_block_->statements->Add(new ReturnNode(expr_pos, expr));
|
| @@ -1910,16 +1911,16 @@
|
| void Parser::ParseQualIdent(QualIdent* qual_ident) {
|
| ASSERT(CurrentToken() == Token::kIDENT);
|
| if (!is_top_level_) {
|
| - bool local_ident = ResolveIdentInLocalScope(token_index_,
|
| - *CurrentLiteral(),
|
| - NULL);
|
| + bool is_local_ident = ResolveIdentInLocalScope(token_index_,
|
| + *CurrentLiteral(),
|
| + NULL);
|
| qual_ident->ident_pos = token_index_;
|
| qual_ident->ident = CurrentLiteral();
|
| qual_ident->lib_prefix = NULL;
|
| qual_ident->qualifier = NULL;
|
| - qual_ident->local_scope_ident = local_ident;
|
| + qual_ident->is_local_scope_ident = is_local_ident;
|
| ConsumeToken();
|
| - if (!local_ident && (CurrentToken() == Token::kPERIOD)) {
|
| + if (!is_local_ident && (CurrentToken() == Token::kPERIOD)) {
|
| LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle();
|
| lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident));
|
| if (!lib_prefix.IsNull()) {
|
| @@ -1936,7 +1937,7 @@
|
| qual_ident->ident = CurrentLiteral();
|
| qual_ident->lib_prefix = NULL;
|
| qual_ident->qualifier = NULL;
|
| - qual_ident->local_scope_ident = false;
|
| + qual_ident->is_local_scope_ident = false;
|
| ConsumeToken();
|
| if (CurrentToken() == Token::kPERIOD) {
|
| ConsumeToken(); // Consume the kPERIOD token.
|
| @@ -2291,10 +2292,7 @@
|
| ConsumeToken();
|
| member.has_factory = true;
|
| member.has_static = true;
|
| - // The member result type is the type of this class.
|
| - // TODO(regis): What are the type arguments?
|
| - member.type =
|
| - &Type::ZoneHandle(Type::NewRawType(Class::Handle(members->clazz())));
|
| + // The result type depends on the name of the factory method.
|
| }
|
| // Optionally parse a type.
|
| if (CurrentToken() == Token::kVOID) {
|
| @@ -2306,7 +2304,7 @@
|
| member.type = &Type::ZoneHandle(Type::VoidType());
|
| } else if (CurrentToken() == Token::kIDENT) {
|
| // This is either a type name or the name of a method/constructor/field.
|
| - if (member.type == NULL) {
|
| + 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);
|
| @@ -2329,18 +2327,26 @@
|
| (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) {
|
| member.name = CurrentLiteral();
|
| member.name_pos = this->token_index_;
|
| - // Factory result type is the same as the type name of the factory.
|
| - // TODO(srdjan): Implement checks in class finalization when all types have
|
| - // been resolved.
|
| - if (member.has_factory && !member.name->Equals(members->class_name())) {
|
| - const UnresolvedClass& type =
|
| + ConsumeToken();
|
| + // Resolution of the factory result type is always postponed until class
|
| + // finalization, so that the list of type parameters in the factory
|
| + // signature can be checked at the same time.
|
| + if (member.has_factory) {
|
| + const UnresolvedClass& unresolved_factory_class =
|
| UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos,
|
| String::Handle(),
|
| *(member.name)));
|
| + const Class& signature_class = Class::Handle(
|
| + Class::New(String::Handle(String::NewSymbol(":factory_signature")),
|
| + Script::Handle()));
|
| + signature_class.set_is_finalized();
|
| + unresolved_factory_class.set_factory_signature_class(signature_class);
|
| + // The type arguments of the result type are set during finalization.
|
| const TypeArguments& args = TypeArguments::Handle();
|
| - member.type = &Type::ZoneHandle(Type::NewParameterizedType(type, args));
|
| + member.type = &Type::ZoneHandle(
|
| + Type::NewParameterizedType(unresolved_factory_class, args));
|
| + ParseTypeParameters(signature_class);
|
| }
|
| - ConsumeToken();
|
| // We must be dealing with a constructor or named constructor.
|
| member.kind = RawFunction::kConstructor;
|
| String& ctor_suffix = String::ZoneHandle(String::NewSymbol("."));
|
| @@ -2354,9 +2360,11 @@
|
| // Ensure that names are symbols.
|
| *member.name = String::NewSymbol(*member.name);
|
| if (member.type == NULL) {
|
| - // TODO(regis): What are the type arguments?
|
| - member.type =
|
| - &Type::ZoneHandle(Type::NewRawType(Class::Handle(members->clazz())));
|
| + ASSERT(!member.has_factory);
|
| + // The body of the constructor cannot modify the type arguments of the
|
| + // constructed instance, which is passed in as a hidden parameter.
|
| + // Therefore, there is no need to set the result type to be checked.
|
| + member.type = &Type::ZoneHandle(Type::DynamicType());
|
| } else {
|
| // The type can only be already set in the factory case.
|
| if (!member.has_factory) {
|
| @@ -2442,9 +2450,9 @@
|
|
|
| void Parser::ParseClassDefinition(GrowableArray<const Class*>* classes) {
|
| TRACE_PARSER("ParseClassDefinition");
|
| - intptr_t class_pos = token_index_;
|
| + const intptr_t class_pos = token_index_;
|
| ExpectToken(Token::kCLASS);
|
| - intptr_t classname_pos = token_index_;
|
| + const intptr_t classname_pos = token_index_;
|
| String& class_name = *ExpectIdentifier("class name expected");
|
| if (FLAG_trace_parser) {
|
| OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString());
|
| @@ -2537,9 +2545,10 @@
|
| &Type::ZoneHandle(Type::DynamicType()));
|
|
|
| AddFormalParamsToFunction(¶ms, ctor);
|
| - // TODO(regis): What are the type arguments?
|
| - Type& result_type = Type::ZoneHandle(
|
| - Type::NewRawType(Class::Handle(class_desc->clazz())));
|
| + // The body of the constructor cannot modify the type arguments of the
|
| + // constructed instance, which is passed in as a hidden parameter.
|
| + // Therefore, there is no need to set the result type to be checked.
|
| + const Type& result_type = Type::ZoneHandle(Type::DynamicType());
|
| ctor.set_result_type(result_type);
|
| class_desc->AddFunction(&ctor);
|
| }
|
| @@ -2598,7 +2607,7 @@
|
| ExpectToken(Token::kTYPEDEF);
|
|
|
| Type& result_type = Type::Handle(Type::DynamicType());
|
| - intptr_t result_type_pos = token_index_;
|
| + const intptr_t result_type_pos = token_index_;
|
| if (CurrentToken() == Token::kVOID) {
|
| ConsumeToken();
|
| result_type = Type::VoidType();
|
| @@ -2627,8 +2636,8 @@
|
|
|
| // At this point, the type parameters have been parsed, so we can resolve the
|
| // result type.
|
| - if (!result_type.IsNull() && !result_type.IsResolved()) {
|
| - ResolveTypeFromClass(result_type_pos, alias_owner, &result_type);
|
| + if (!result_type.IsNull()) {
|
| + TryResolveTypeFromClass(result_type_pos, alias_owner, &result_type);
|
| }
|
| ParamList func_params;
|
| const bool no_explicit_default_values = false;
|
| @@ -2685,9 +2694,9 @@
|
|
|
| void Parser::ParseInterfaceDefinition(GrowableArray<const Class*>* classes) {
|
| TRACE_PARSER("ParseInterfaceDefinition");
|
| - intptr_t interface_pos = token_index_;
|
| + const intptr_t interface_pos = token_index_;
|
| ExpectToken(Token::kINTERFACE);
|
| - intptr_t interfacename_pos = token_index_;
|
| + const intptr_t interfacename_pos = token_index_;
|
| String& interface_name = *ExpectIdentifier("interface name expected");
|
| if (FLAG_trace_parser) {
|
| OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString());
|
| @@ -2727,17 +2736,27 @@
|
|
|
| if (CurrentToken() == Token::kFACTORY) {
|
| ConsumeToken();
|
| - Type& factory_type = Type::Handle();
|
| - const intptr_t factory_type_pos = token_index_;
|
| - factory_type = ParseType(kCanResolve);
|
| - if (factory_type.IsInterfaceType()) {
|
| - ErrorMsg(factory_type_pos,
|
| - "interface '%s' must have a factory class "
|
| - "but '%s' is an interface",
|
| - interface_name.ToCString(),
|
| - String::Handle(factory_type.Name()).ToCString());
|
| + const intptr_t factory_pos = token_index_;
|
| + QualIdent factory_name;
|
| + ParseQualIdent(&factory_name);
|
| + if (factory_name.is_local_scope_ident) {
|
| + ErrorMsg(factory_pos,
|
| + "using '%s' in this context is invalid",
|
| + factory_name.ident->ToCString());
|
| }
|
| - interface.set_factory_type(factory_type);
|
| + String& qualifier = String::Handle();
|
| + if (factory_name.qualifier != NULL) {
|
| + qualifier ^= factory_name.qualifier->raw();
|
| + }
|
| + const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle(
|
| + UnresolvedClass::New(factory_pos, qualifier, *(factory_name.ident)));
|
| + const Class& signature_class = Class::Handle(
|
| + Class::New(String::Handle(String::NewSymbol(":factory_signature")),
|
| + Script::Handle()));
|
| + signature_class.set_is_finalized();
|
| + ParseTypeParameters(signature_class);
|
| + unresolved_factory_class.set_factory_signature_class(signature_class);
|
| + interface.set_factory_class(unresolved_factory_class);
|
| }
|
|
|
| ExpectToken(Token::kLBRACE);
|
| @@ -2810,6 +2829,7 @@
|
|
|
| void Parser::ParseTypeParameters(const Class& cls) {
|
| if (CurrentToken() == Token::kLT) {
|
| + const intptr_t type_pos = token_index_;
|
| GrowableArray<String*> type_parameters;
|
| GrowableArray<Type*> type_parameter_extends;
|
| do {
|
| @@ -2836,8 +2856,18 @@
|
| ErrorMsg("right angle bracket expected");
|
| }
|
| cls.set_type_parameters(Array::Handle(NewArray<String>(type_parameters)));
|
| - cls.set_type_parameter_extends(
|
| - TypeArray::Handle(NewTypeArray(type_parameter_extends)));
|
| + const TypeArray& extends_array =
|
| + TypeArray::Handle(NewTypeArray(type_parameter_extends));
|
| + cls.set_type_parameter_extends(extends_array);
|
| + // Try to resolve the upper bounds, which will at least resolve the
|
| + // referenced type parameters.
|
| + Type& type_extends = Type::Handle();
|
| + const intptr_t num_types = extends_array.Length();
|
| + for (intptr_t i = 0; i < num_types; i++) {
|
| + type_extends = extends_array.TypeAt(i);
|
| + TryResolveTypeFromClass(type_pos, cls, &type_extends);
|
| + extends_array.SetTypeAt(i, type_extends);
|
| + }
|
| }
|
| }
|
|
|
| @@ -3026,13 +3056,13 @@
|
| UnexpectedToken();
|
| }
|
| }
|
| - intptr_t name_pos = token_index_;
|
| + const intptr_t name_pos = token_index_;
|
| const String* field_name = ExpectIdentifier("accessor name expected");
|
|
|
| if (CurrentToken() != Token::kLPAREN) {
|
| ErrorMsg("'(' expected");
|
| }
|
| - intptr_t accessor_pos = token_index_;
|
| + const intptr_t accessor_pos = token_index_;
|
| ParamList params;
|
| const bool allow_explicit_default_values = true;
|
| ParseFormalParameterList(allow_explicit_default_values, ¶ms);
|
| @@ -3114,7 +3144,7 @@
|
|
|
| void Parser::ParseLibraryImport() {
|
| while (CurrentToken() == Token::kIMPORT) {
|
| - intptr_t import_pos = token_index_;
|
| + const intptr_t import_pos = token_index_;
|
| ConsumeToken();
|
| ExpectToken(Token::kLPAREN);
|
| if (CurrentToken() != Token::kSTRING) {
|
| @@ -3171,7 +3201,7 @@
|
|
|
| void Parser::ParseLibraryInclude() {
|
| while (CurrentToken() == Token::kSOURCE) {
|
| - intptr_t source_pos = token_index_;
|
| + const intptr_t source_pos = token_index_;
|
| ConsumeToken();
|
| ExpectToken(Token::kLPAREN);
|
| if (CurrentToken() != Token::kSTRING) {
|
| @@ -3385,7 +3415,7 @@
|
| const int num_parameters = params->parameters->length();
|
|
|
| // Parse the function name out.
|
| - intptr_t native_pos = token_index_;
|
| + const intptr_t native_pos = token_index_;
|
| const String& native_name = ParseNativeDeclaration();
|
|
|
| // Now resolve the native function to the corresponding native entrypoint.
|
| @@ -3579,7 +3609,7 @@
|
| (LookaheadToken(1) != Token::kLPAREN)) {
|
| result_type = ParseType(kMustResolve);
|
| }
|
| - intptr_t ident_pos = token_index_;
|
| + const intptr_t ident_pos = token_index_;
|
| if (CurrentToken() == Token::kIDENT) {
|
| variable_name = CurrentLiteral();
|
| function_name = variable_name;
|
| @@ -3779,7 +3809,7 @@
|
| ParseQualIdent(&type_name);
|
| // Check if the type_name has been defined as a variable in a local scope,
|
| // hiding the type.
|
| - if (type_name.local_scope_ident) {
|
| + if (type_name.is_local_scope_ident) {
|
| return false;
|
| }
|
| if (CurrentToken() == Token::kLT && !IsTypeParameter()) {
|
| @@ -3816,7 +3846,7 @@
|
| if (CurrentToken() != Token::kIDENT) {
|
| return false;
|
| }
|
| - intptr_t saved_pos = token_index_;
|
| + const intptr_t saved_pos = token_index_;
|
| bool is_var_decl = false;
|
| if (IsOptionalType()) {
|
| if (CurrentToken() == Token::kIDENT) {
|
| @@ -3853,7 +3883,7 @@
|
| if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
|
| return true;
|
| }
|
| - intptr_t saved_pos = token_index_;
|
| + const intptr_t saved_pos = token_index_;
|
| if (IsReturnType()) {
|
| if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
|
| if (LookaheadToken(1) == Token::kIDENT) { // Accessor name.
|
| @@ -3871,7 +3901,7 @@
|
| if (!allow_function_literals_) {
|
| return false;
|
| }
|
| - intptr_t saved_pos = token_index_;
|
| + const intptr_t saved_pos = token_index_;
|
| bool is_function_literal = false;
|
| if ((CurrentToken() == Token::kIDENT) &&
|
| (LookaheadToken(1) == Token::kLPAREN)) {
|
| @@ -3899,7 +3929,7 @@
|
| // statement. Returns true if we recognize a for ( .. in expr)
|
| // statement.
|
| bool Parser::IsForInStatement() {
|
| - intptr_t saved_pos = token_index_;
|
| + const intptr_t saved_pos = token_index_;
|
| bool result = false;
|
| if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) {
|
| ConsumeToken();
|
| @@ -3945,7 +3975,7 @@
|
| const bool dead_code_allowed = true;
|
| bool abrupt_completing_seen = false;
|
| while (CurrentToken() != Token::kRBRACE) {
|
| - intptr_t statement_pos = token_index_;
|
| + const intptr_t statement_pos = token_index_;
|
| AstNode* statement = ParseStatement();
|
| if (statement != NULL) {
|
| if (!dead_code_allowed && abrupt_completing_seen) {
|
| @@ -3990,7 +4020,7 @@
|
| AstNode* Parser::ParseIfStatement(String* label_name) {
|
| TRACE_PARSER("ParseIfStatement");
|
| ASSERT(CurrentToken() == Token::kIF);
|
| - intptr_t if_pos = token_index_;
|
| + const intptr_t if_pos = token_index_;
|
| SourceLabel* label = NULL;
|
| if (label_name != NULL) {
|
| label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement);
|
| @@ -4023,7 +4053,7 @@
|
| SourceLabel* case_label) {
|
| TRACE_PARSER("ParseCaseStatement");
|
| bool default_seen = false;
|
| - intptr_t case_pos = token_index_;
|
| + const intptr_t case_pos = token_index_;
|
| SequenceNode* case_expressions =
|
| new SequenceNode(case_pos, current_block_->scope);
|
| while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) {
|
| @@ -4032,7 +4062,7 @@
|
| ErrorMsg("default clause must be last case");
|
| }
|
| ConsumeToken(); // Keyword case.
|
| - intptr_t expr_pos = token_index_;
|
| + const intptr_t expr_pos = token_index_;
|
| AstNode* expr = ParseExpr(kAllowConst);
|
| AstNode* switch_expr_load = new LoadLocalNode(case_pos,
|
| *switch_expr_value);
|
| @@ -4097,7 +4127,7 @@
|
| AstNode* Parser::ParseSwitchStatement(String* label_name) {
|
| TRACE_PARSER("ParseSwitchStatement");
|
| ASSERT(CurrentToken() == Token::kSWITCH);
|
| - intptr_t switch_pos = token_index_;
|
| + const intptr_t switch_pos = token_index_;
|
| SourceLabel* label =
|
| SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch);
|
| ConsumeToken();
|
| @@ -4109,7 +4139,7 @@
|
| } else if (parens_are_mandatory) {
|
| ErrorMsg("'(' expected");
|
| }
|
| - intptr_t expr_pos = token_index_;
|
| + const intptr_t expr_pos = token_index_;
|
| AstNode* switch_expr = ParseExpr(kAllowConst);
|
| if (paren_found) {
|
| ExpectToken(Token::kRPAREN);
|
| @@ -4137,7 +4167,7 @@
|
| LookaheadToken(1) == Token::kCOLON) {
|
| // Case statements start with a label.
|
| String* label_name = CurrentLiteral();
|
| - intptr_t label_pos = token_index_;
|
| + const intptr_t label_pos = token_index_;
|
| ConsumeToken(); // Consume label identifier.
|
| ConsumeToken(); // Consume colon.
|
| case_label = current_block_->scope->LocalLookupLabel(*label_name);
|
| @@ -4189,7 +4219,7 @@
|
|
|
| AstNode* Parser::ParseWhileStatement(String* label_name) {
|
| TRACE_PARSER("ParseWhileStatement");
|
| - intptr_t while_pos = token_index_;
|
| + const intptr_t while_pos = token_index_;
|
| SourceLabel* label =
|
| SourceLabel::New(while_pos, label_name, SourceLabel::kWhile);
|
| ConsumeToken();
|
| @@ -4204,7 +4234,7 @@
|
|
|
| AstNode* Parser::ParseDoWhileStatement(String* label_name) {
|
| TRACE_PARSER("ParseDoWhileStatement");
|
| - intptr_t do_pos = token_index_;
|
| + const intptr_t do_pos = token_index_;
|
| SourceLabel* label =
|
| SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile);
|
| ConsumeToken();
|
| @@ -4240,7 +4270,7 @@
|
| }
|
| }
|
| ExpectToken(Token::kIN);
|
| - intptr_t collection_pos = token_index_;
|
| + const intptr_t collection_pos = token_index_;
|
| AstNode* collection_expr = ParseExpr(kAllowConst);
|
| ExpectToken(Token::kRPAREN);
|
|
|
| @@ -4332,7 +4362,7 @@
|
|
|
| AstNode* Parser::ParseForStatement(String* label_name) {
|
| TRACE_PARSER("ParseForStatement");
|
| - intptr_t for_pos = token_index_;
|
| + const intptr_t for_pos = token_index_;
|
| ConsumeToken();
|
| ExpectToken(Token::kLPAREN);
|
| SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor);
|
| @@ -4344,7 +4374,7 @@
|
| // the loop variable declarations.
|
| current_block_->scope->AddLabel(label);
|
| AstNode* initializer = NULL;
|
| - intptr_t init_pos = token_index_;
|
| + const intptr_t init_pos = token_index_;
|
| LocalScope* init_scope = current_block_->scope;
|
| if (CurrentToken() != Token::kSEMICOLON) {
|
| if (IsVariableDeclaration()) {
|
| @@ -4360,7 +4390,7 @@
|
| }
|
| ExpectSemicolon();
|
| AstNode* increment = NULL;
|
| - intptr_t incr_pos = token_index_;
|
| + const intptr_t incr_pos = token_index_;
|
| LocalScope* incr_scope = current_block_->scope;
|
| if (CurrentToken() != Token::kRPAREN) {
|
| increment = ParseExprList();
|
| @@ -4628,7 +4658,7 @@
|
| current_block_->scope->AddVariable(catch_trace_var);
|
| }
|
|
|
| - intptr_t try_pos = token_index_;
|
| + const intptr_t try_pos = token_index_;
|
| ConsumeToken(); // Consume the 'try'.
|
|
|
| SourceLabel* try_label = NULL;
|
| @@ -4658,12 +4688,12 @@
|
| bool catch_seen = false;
|
| bool generic_catch_seen = false;
|
| SequenceNode* catch_handler_list = NULL;
|
| - intptr_t handler_pos = token_index_;
|
| + const intptr_t handler_pos = token_index_;
|
| OpenBlock(); // Start the catch block sequence.
|
| current_block_->scope->AddLabel(end_catch_label);
|
| while (CurrentToken() == Token::kCATCH) {
|
| catch_seen = true;
|
| - intptr_t catch_pos = token_index_;
|
| + const intptr_t catch_pos = token_index_;
|
| ConsumeToken(); // Consume the 'catch'.
|
| ExpectToken(Token::kLPAREN);
|
| CatchParamDesc exception_param;
|
| @@ -4679,7 +4709,7 @@
|
| // subsequent catch statements are dead. We issue an error for now,
|
| // it might make sense to turn this into a warning.
|
| if (generic_catch_seen) {
|
| - ErrorMsg("A generic 'catch all' statement already exists for this "
|
| + ErrorMsg("a generic 'catch all' statement already exists for this "
|
| "try block. All subsequent catch statements are dead code");
|
| }
|
| OpenBlock();
|
| @@ -4755,7 +4785,7 @@
|
| if (CurrentToken() == Token::kFINALLY) {
|
| current_function_.set_is_optimizable(false);
|
| ConsumeToken(); // Consume the 'finally'.
|
| - intptr_t finally_pos = token_index_;
|
| + const intptr_t finally_pos = token_index_;
|
| // Add the finally block to the exit points recorded so far.
|
| intptr_t node_index = 0;
|
| AstNode* node_to_inline =
|
| @@ -4818,7 +4848,7 @@
|
| AstNode* Parser::ParseJump(String* label_name) {
|
| ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE);
|
| Token::Kind jump_kind = CurrentToken();
|
| - intptr_t jump_pos = token_index_;
|
| + const intptr_t jump_pos = token_index_;
|
| SourceLabel* target = NULL;
|
| ConsumeToken();
|
| if (CurrentToken() == Token::kIDENT) {
|
| @@ -5041,6 +5071,8 @@
|
| if (FLAG_warning_as_error) {
|
| Isolate::Current()->long_jump_base()->Jump(1, error_msg_);
|
| UNREACHABLE();
|
| + } else {
|
| + OS::Print(error_msg_);
|
| }
|
| }
|
|
|
| @@ -5338,7 +5370,7 @@
|
| case Token::kASSIGN_XOR:
|
| return new BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs);
|
| default:
|
| - ErrorMsg(op_pos, "Internal error: ExpandAssignableOp '%s' unimplemented",
|
| + ErrorMsg(op_pos, "internal error: ExpandAssignableOp '%s' unimplemented",
|
| Token::Name(assignment_op));
|
| UNIMPLEMENTED();
|
| return NULL;
|
| @@ -5386,7 +5418,7 @@
|
| AstNode* assign_expr = expr->MakeAssignmentNode(right_expr);
|
| if (assign_expr == NULL) {
|
| ErrorMsg(assignment_pos,
|
| - "Left hand side of '%s' is not assignable",
|
| + "left hand side of '%s' is not assignable",
|
| Token::Str(assignment_op));
|
| }
|
| return assign_expr;
|
| @@ -5430,7 +5462,7 @@
|
| ConsumeToken();
|
| expr = ParseUnaryExpr();
|
| if (!IsAssignableExpr(expr)) {
|
| - ErrorMsg("Expression is not assignable");
|
| + ErrorMsg("expression is not assignable");
|
| }
|
| // is_prefix.
|
| AstNode* incr_op_node = expr->MakeIncrOpNode(op_pos, incr_op, true);
|
| @@ -5781,7 +5813,7 @@
|
| // Dynamic function call on implicit "this" parameter.
|
| if (current_function().is_static()) {
|
| ErrorMsg(primary_pos,
|
| - "Cannot access instance method '%s' "
|
| + "cannot access instance method '%s' "
|
| "from static function",
|
| func_name.ToCString());
|
| }
|
| @@ -5801,7 +5833,7 @@
|
| }
|
| } else if (primary->primary().IsClass()) {
|
| ErrorMsg(left->token_index(),
|
| - "must use 'new' or 'const' to construct new instance");
|
| + "must use 'new' or 'const' to construct new instance");
|
| } else {
|
| // Internal parser error.
|
| UNREACHABLE();
|
| @@ -5882,9 +5914,13 @@
|
| }
|
|
|
|
|
| -bool Parser::ResolveTypeFromClass(intptr_t type_pos,
|
| - const Class& cls,
|
| - Type* type) {
|
| +// Try to resolve the given type and its type arguments from the given class.
|
| +// Not all involved type classes may get resolved yet, but at least the type
|
| +// parameters of the given class will get resolved, thereby relieving the class
|
| +// finalizer from resolving type parameters out of context.
|
| +void Parser::TryResolveTypeFromClass(intptr_t type_pos,
|
| + const Class& cls,
|
| + Type* type) {
|
| ASSERT(type != NULL);
|
| // Resolve class.
|
| if (!type->HasResolvedTypeClass()) {
|
| @@ -5896,42 +5932,36 @@
|
| const TypeParameter& type_parameter = TypeParameter::Handle(
|
| cls.LookupTypeParameter(unresolved_class_name));
|
| if (!type_parameter.IsNull()) {
|
| - CheckTypeParameterReference(type_pos, unresolved_class_name);
|
| // A type parameter cannot be parameterized, so report an error if type
|
| // arguments have previously been parsed.
|
| if (type->arguments() != TypeArguments::null()) {
|
| ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized",
|
| type_parameter.ToCString());
|
| - return false;
|
| }
|
| *type = type_parameter.raw();
|
| - return true;
|
| + return;
|
| }
|
| const Class& resolved_type_class =
|
| Class::Handle(LookupClass(unresolved_class_name));
|
| - if (resolved_type_class.IsNull()) {
|
| - return false;
|
| + if (!resolved_type_class.IsNull()) {
|
| + Object& type_class = Object::Handle(resolved_type_class.raw());
|
| + ASSERT(type->IsParameterizedType());
|
| + // Replace unresolved class with resolved type class.
|
| + ParameterizedType& parameterized_type = ParameterizedType::Handle();
|
| + parameterized_type ^= type->raw();
|
| + parameterized_type.set_type_class(type_class);
|
| }
|
| - Object& type_class = Object::Handle(resolved_type_class.raw());
|
| - ASSERT(type->IsParameterizedType());
|
| - // Replace unresolved class with resolved type class.
|
| - ParameterizedType& parameterized_type = ParameterizedType::Handle();
|
| - parameterized_type ^= type->raw();
|
| - parameterized_type.set_type_class(type_class);
|
| }
|
| // Resolve type arguments, if any.
|
| const TypeArguments& arguments = TypeArguments::Handle(type->arguments());
|
| if (!arguments.IsNull()) {
|
| - intptr_t num_arguments = arguments.Length();
|
| + const intptr_t num_arguments = arguments.Length();
|
| for (intptr_t i = 0; i < num_arguments; i++) {
|
| Type& type_argument = Type::Handle(arguments.TypeAt(i));
|
| - if (!ResolveTypeFromClass(type_pos, cls, &type_argument)) {
|
| - return false;
|
| - }
|
| + TryResolveTypeFromClass(type_pos, cls, &type_argument);
|
| arguments.SetTypeAt(i, type_argument);
|
| }
|
| }
|
| - return true;
|
| }
|
|
|
|
|
| @@ -5990,22 +6020,51 @@
|
| }
|
|
|
|
|
| -void Parser::CheckTypeParameterReference(intptr_t type_parameter_pos,
|
| - const String& type_parameter_name) {
|
| +// If type parameters are currently in scope, return their declaring class,
|
| +// otherwise return null.
|
| +RawClass* Parser::TypeParametersScopeClass() {
|
| // Type parameters cannot be referred to from a static function, except from
|
| // a constructor or from a factory.
|
| // A constructor is considered as non-static by the compiler.
|
| - if ((is_top_level_ &&
|
| - (current_member_ != NULL) &&
|
| - current_member_->has_static &&
|
| - !current_member_->has_factory) ||
|
| - (!current_function().IsNull() &&
|
| - current_function().is_static() &&
|
| - !current_function().IsInFactoryScope())) {
|
| - ErrorMsg(type_parameter_pos,
|
| - "cannot refer to type parameter '%s' from a static function",
|
| - type_parameter_name.ToCString());
|
| + if (is_top_level_) {
|
| + if ((current_member_ != NULL) && current_member_->has_factory) {
|
| + const Type& factory_result_type = *current_member_->type;
|
| + ASSERT(!factory_result_type.IsNull());
|
| + const UnresolvedClass& unresolved_factory_class =
|
| + UnresolvedClass::Handle(factory_result_type.unresolved_class());
|
| + // TODO(regis): For now, and until the core lib is fixed, we accept a
|
| + // factory method with missing list of type parameters and use the
|
| + // list of the enclosing class.
|
| + // See bug 5408808.
|
| + // Therefore, we temporarily return the current class instead of the
|
| + // factory signature class if the latter one does not declare any type
|
| + // parameters.
|
| + const Class& factory_signature_class =
|
| + Class::Handle(unresolved_factory_class.factory_signature_class());
|
| + if (factory_signature_class.NumTypeParameters() == 0) {
|
| + return current_class().raw();
|
| + } else {
|
| + return factory_signature_class.raw();
|
| + }
|
| + }
|
| + if ((current_member_ == NULL) || !current_member_->has_static) {
|
| + return current_class().raw();
|
| + }
|
| + } else {
|
| + if (!current_function().IsNull()) {
|
| + Function& outer_function = Function::Handle(current_function().raw());
|
| + while (outer_function.IsLocalFunction()) {
|
| + outer_function = outer_function.parent_function();
|
| + }
|
| + if (outer_function.IsFactory()) {
|
| + return outer_function.signature_class();
|
| + }
|
| + if (!outer_function.is_static()) {
|
| + return current_class().raw();
|
| + }
|
| + }
|
| }
|
| + return Class::null();
|
| }
|
|
|
|
|
| @@ -6013,7 +6072,7 @@
|
| ASSERT(field.is_static());
|
| const Instance& value = Instance::Handle(field.value());
|
| if (value.raw() == Object::transition_sentinel()) {
|
| - ErrorMsg("Circular dependency while initializing static field '%s'",
|
| + ErrorMsg("circular dependency while initializing static field '%s'",
|
| String::Handle(field.name()).ToCString());
|
|
|
| } else if (value.raw() == Object::sentinel()) {
|
| @@ -6040,7 +6099,7 @@
|
| Instance& const_value = Instance::Handle(
|
| DartEntry::InvokeStatic(func, arguments, kNoArgumentNames));
|
| if (const_value.IsUnhandledException()) {
|
| - ErrorMsg("Exception thrown in Parser::RunStaticFieldInitializer");
|
| + ErrorMsg("exception thrown in Parser::RunStaticFieldInitializer");
|
| }
|
| if (!const_value.IsNull()) {
|
| const_value ^= const_value.Canonicalize();
|
| @@ -6339,10 +6398,10 @@
|
| ErrorMsg("type name expected");
|
| }
|
| QualIdent type_name;
|
| - intptr_t type_pos = token_index_;
|
| + const intptr_t type_pos = token_index_;
|
| ParseQualIdent(&type_name);
|
| - if (type_name.local_scope_ident) {
|
| - ErrorMsg(type_pos, "Using '%s' in this context is invalid",
|
| + if (type_name.is_local_scope_ident) {
|
| + ErrorMsg(type_pos, "using '%s' in this context is invalid",
|
| type_name.ident->ToCString());
|
| }
|
| Object& type_class = Object::Handle();
|
| @@ -6353,26 +6412,27 @@
|
| }
|
| type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident));
|
| } else {
|
| - TypeParameter& type_parameter = TypeParameter::Handle();
|
| - // Check if qualifier is a type parameter of the class we are parsing.
|
| - if (type_name.qualifier != NULL) {
|
| - type_parameter =
|
| - current_class().LookupTypeParameter(*type_name.qualifier);
|
| - if (!type_parameter.IsNull()) {
|
| - ErrorMsg(type_pos, "Use of '%s' in this context is invalid",
|
| - type_name.qualifier->ToCString());
|
| - }
|
| - } else {
|
| - // Check if ident is a type parameter of the class we are parsing.
|
| - type_parameter = current_class().LookupTypeParameter(*type_name.ident);
|
| - if (!type_parameter.IsNull()) {
|
| - CheckTypeParameterReference(type_name.ident_pos, *type_name.ident);
|
| - if (CurrentToken() == Token::kLT) {
|
| - // A type parameter cannot be parameterized.
|
| - ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized",
|
| - String::Handle(type_parameter.Name()).ToCString());
|
| + const Class& scope_class = Class::Handle(TypeParametersScopeClass());
|
| + if (!scope_class.IsNull()) {
|
| + TypeParameter& type_parameter = TypeParameter::Handle();
|
| + // Check if qualifier is a type parameter in scope.
|
| + if (type_name.qualifier != NULL) {
|
| + type_parameter = scope_class.LookupTypeParameter(*type_name.qualifier);
|
| + if (!type_parameter.IsNull()) {
|
| + ErrorMsg(type_pos, "type Parameter '%s' cannot be used as qualifier",
|
| + type_name.qualifier->ToCString());
|
| }
|
| - return type_parameter.raw();
|
| + } else {
|
| + // Check if ident is a type parameter in scope.
|
| + type_parameter = scope_class.LookupTypeParameter(*type_name.ident);
|
| + if (!type_parameter.IsNull()) {
|
| + if (CurrentToken() == Token::kLT) {
|
| + // A type parameter cannot be parameterized.
|
| + ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized",
|
| + String::Handle(type_parameter.Name()).ToCString());
|
| + }
|
| + return type_parameter.raw();
|
| + }
|
| }
|
| }
|
| // Try to resolve the type class.
|
| @@ -6396,12 +6456,20 @@
|
|
|
| void Parser::CheckConstructorCallTypeArguments(
|
| intptr_t pos, Function& constructor, const TypeArguments& type_arguments) {
|
| - if (!type_arguments.IsNull() &&
|
| - (type_arguments.Length() !=
|
| - Class::Handle(constructor.owner()).NumTypeArguments())) {
|
| - ErrorMsg(pos, "Incorrect number of type arguments, expected %d got %d",
|
| - Class::Handle(constructor.owner()).NumTypeArguments(),
|
| - type_arguments.Length());
|
| + if (!type_arguments.IsNull()) {
|
| + Class& signature_class = Class::Handle();
|
| + if (constructor.IsFactory()) {
|
| + signature_class = constructor.signature_class();
|
| + } else {
|
| + signature_class = constructor.owner();
|
| + }
|
| + ASSERT(!signature_class.IsNull());
|
| + ASSERT(signature_class.is_finalized());
|
| + if (type_arguments.Length() != signature_class.NumTypeArguments()) {
|
| + ErrorMsg(pos, "incorrect number of type arguments, expected %d got %d",
|
| + signature_class.NumTypeArguments(),
|
| + type_arguments.Length());
|
| + }
|
| }
|
| }
|
|
|
| @@ -6414,7 +6482,7 @@
|
| bool is_const,
|
| const TypeArguments& type_arguments) {
|
| ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX);
|
| - intptr_t literal_pos = token_index_;
|
| + const intptr_t literal_pos = token_index_;
|
| bool is_empty_literal = CurrentToken() == Token::kINDEX;
|
| ConsumeToken();
|
|
|
| @@ -6523,7 +6591,7 @@
|
| const TypeArguments& type_arguments) {
|
| TRACE_PARSER("ParseMapLiteral");
|
| ASSERT(CurrentToken() == Token::kLBRACE);
|
| - intptr_t literal_pos = token_index_;
|
| + const intptr_t literal_pos = token_index_;
|
| ConsumeToken();
|
|
|
| String& map_class_name = String::Handle(
|
| @@ -6635,7 +6703,7 @@
|
| is_const = true;
|
| ConsumeToken();
|
| }
|
| - intptr_t type_pos = token_index_;
|
| + const intptr_t type_pos = token_index_;
|
| TypeArguments& type_arguments =
|
| TypeArguments::ZoneHandle(ParseTypeArguments(kMustResolve));
|
| AstNode* primary = NULL;
|
| @@ -6645,7 +6713,7 @@
|
| } else if (CurrentToken() == Token::kLBRACE) {
|
| primary = ParseMapLiteral(type_pos, is_const, type_arguments);
|
| } else {
|
| - ErrorMsg("Unexpected token %s", Token::Str(CurrentToken()));
|
| + ErrorMsg("unexpected token %s", Token::Str(CurrentToken()));
|
| }
|
| return primary;
|
| }
|
| @@ -6688,36 +6756,35 @@
|
| String& type_class_name = String::Handle();
|
| TypeArguments& type_arguments = TypeArguments::ZoneHandle();
|
| String* named_constructor = NULL;
|
| - intptr_t type_pos = token_index_;
|
| + const intptr_t type_pos = token_index_;
|
| QualIdent type_name;
|
| ParseQualIdent(&type_name);
|
| - if (type_name.local_scope_ident) {
|
| - ErrorMsg(type_pos, "Using '%s' in this context is invalid",
|
| + if (type_name.is_local_scope_ident) {
|
| + ErrorMsg(type_pos, "using '%s' in this context is invalid",
|
| type_name.ident->ToCString());
|
| }
|
| if (CurrentToken() == Token::kPERIOD) {
|
| ConsumeToken();
|
| named_constructor = ExpectIdentifier("identifier expected after '.'");
|
| }
|
| - TypeParameter& type_parameter = TypeParameter::Handle();
|
| - if (type_name.lib_prefix != NULL) {
|
| - // TODO(regis): Ascertain that this check for shadowing is valid
|
| - // See bug (490270).
|
| - // Check if qualifier is a type parameter of the class we are parsing.
|
| - type_parameter ^= current_class().LookupTypeParameter(*type_name.qualifier);
|
| + const Class& scope_class = Class::Handle(TypeParametersScopeClass());
|
| + if (!scope_class.IsNull()) {
|
| + TypeParameter& type_parameter = TypeParameter::Handle();
|
| + if (type_name.lib_prefix != NULL) {
|
| + // Check if qualifier is a type parameter in scope.
|
| + type_parameter ^= scope_class.LookupTypeParameter(*type_name.qualifier);
|
| + if (!type_parameter.IsNull()) {
|
| + ErrorMsg(type_pos, "type parameter '%s' cannot be used as qualifier",
|
| + String::Handle(type_parameter.Name()).ToCString());
|
| + }
|
| + }
|
| + // Check if ident is a type parameter in scope.
|
| + type_parameter = scope_class.LookupTypeParameter(*type_name.ident);
|
| if (!type_parameter.IsNull()) {
|
| - CheckTypeParameterReference(type_pos, *type_name.qualifier);
|
| ErrorMsg(type_pos, "type parameter '%s' cannot be instantiated",
|
| String::Handle(type_parameter.Name()).ToCString());
|
| }
|
| }
|
| - // Check if ident is a type parameter of the class we are parsing.
|
| - type_parameter = current_class().LookupTypeParameter(*type_name.ident);
|
| - if (!type_parameter.IsNull()) {
|
| - CheckTypeParameterReference(type_name.ident_pos, *type_name.ident);
|
| - ErrorMsg(type_pos, "type parameter '%s' cannot be instantiated",
|
| - String::Handle(type_parameter.Name()).ToCString());
|
| - }
|
| type_class ^= LookupTypeClass(type_name, kMustResolve);
|
| type_class_name = type_class.Name();
|
| // Type arguments are not allowed after the optional constructor name.
|
| @@ -6769,37 +6836,29 @@
|
| external_constructor_name.ToCString(),
|
| type_class_name.ToCString());
|
| }
|
| -
|
| - // TODO(srdjan): Evaluate if the mapping should occur during code
|
| - // generation or here in the parser.
|
| - const Type& factory_type = Type::Handle(type_class.factory_type());
|
| - if (factory_type.IsNull()) {
|
| + if (!type_class.HasFactoryClass()) {
|
| ErrorMsg("cannot allocate interface '%s' without factory class",
|
| type_class_name.ToCString());
|
| }
|
| - if (!factory_type.HasResolvedTypeClass()) {
|
| + if (!type_class.HasResolvedFactoryClass()) {
|
| // This error can occur only with bootstrap classes.
|
| const UnresolvedClass& unresolved =
|
| - UnresolvedClass::Handle(factory_type.unresolved_class());
|
| + UnresolvedClass::Handle(type_class.UnresolvedFactoryClass());
|
| const String& missing_class_name = String::Handle(unresolved.ident());
|
| - ErrorMsg("Unresolved factory class '%s'", missing_class_name.ToCString());
|
| + ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString());
|
| }
|
| -
|
| // Only change the class of the constructor to the factory class if the
|
| // factory class implements the interface 'type'.
|
| - Class& factory_type_class = Class::Handle(factory_type.type_class());
|
| - // TODO(regis): Verify in the guide/spec that a factory class must have
|
| - // identical type parameters as the interface.
|
| - // TODO(regis): Do we check that in the parser?
|
| - // Assuming that it has been checked, it is sufficient to test if the
|
| - // raw factory type implements the raw interface type.
|
| - if (factory_type_class.IsSubtypeOf(TypeArguments::Handle(),
|
| - type_class,
|
| - TypeArguments::Handle())) {
|
| - type_class_name = factory_type_class.Name();
|
| + const Class& factory_class = Class::Handle(type_class.FactoryClass());
|
| + if (factory_class.IsSubtypeOf(TypeArguments::Handle(),
|
| + type_class,
|
| + TypeArguments::Handle())) {
|
| + // Class finalization verifies that the factory class has identical type
|
| + // parameters as the interface.
|
| + type_class_name = factory_class.Name();
|
| }
|
| // Always change the result type of the constructor to the factory type.
|
| - type_class = factory_type_class.raw();
|
| + type_class = factory_class.raw();
|
| ASSERT(!type_class.is_interface());
|
| }
|
|
|
| @@ -6868,7 +6927,7 @@
|
| // there are never two kSTRING tokens next to each other.
|
| AstNode* Parser::ParseStringLiteral() {
|
| AstNode* primary = NULL;
|
| - intptr_t literal_start = token_index_;
|
| + const intptr_t literal_start = token_index_;
|
| if ((CurrentToken() == Token::kSTRING) &&
|
| (LookaheadToken(1) != Token::kINTERPOL_VAR) &&
|
| (LookaheadToken(1) != Token::kINTERPOL_START)) {
|
| @@ -6927,7 +6986,7 @@
|
| } else if (CurrentToken() == Token::kIDENT) {
|
| QualIdent qual_ident;
|
| ParseQualIdent(&qual_ident);
|
| - if (qual_ident.local_scope_ident) {
|
| + if (qual_ident.is_local_scope_ident) {
|
| ResolveIdentInLocalScope(qual_ident.ident_pos,
|
| *qual_ident.ident,
|
| &primary);
|
| @@ -7028,7 +7087,7 @@
|
| Token::CanBeOverloaded(CurrentToken())) {
|
| primary = ParseSuperOperator();
|
| } else {
|
| - ErrorMsg("Illegal super call");
|
| + ErrorMsg("illegal super call");
|
| }
|
| } else {
|
| UnexpectedToken();
|
|
|