Chromium Code Reviews| Index: runtime/vm/parser.cc |
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
| index a1c8aa7a85afcc9275340c40dad08501d630dc3b..2cae442353f91cb74d320a0ec224d564f11dfbd8 100644 |
| --- a/runtime/vm/parser.cc |
| +++ b/runtime/vm/parser.cc |
| @@ -443,6 +443,15 @@ void Parser::ParseCompilationUnit(const Library& library, |
| } |
| +intptr_t Parser::FindLibraryDeclarationPosition(const Library& library, |
| + const Script& script) { |
| + Isolate* isolate = Isolate::Current(); |
| + ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| + Parser parser(script, library, 0); |
| + return parser.GetLibraryDeclarationPosition(); |
| +} |
| + |
| + |
| void Parser::ComputeCurrentToken() { |
| ASSERT(token_kind_ == Token::kILLEGAL); |
| token_kind_ = tokens_iterator_.CurrentTokenKind(); |
| @@ -4158,8 +4167,10 @@ void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, |
| const Class& toplevel_class, |
| intptr_t metadata_pos) { |
| TRACE_PARSER("ParseEnumDeclaration"); |
| + const intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos |
| + : TokenPos(); |
| ConsumeToken(); |
| - const intptr_t enum_pos = TokenPos(); |
| + const intptr_t name_pos = TokenPos(); |
| String* enum_name = |
| ExpectUserDefinedTypeIdentifier("enum type name expected"); |
| if (FLAG_trace_parser) { |
| @@ -4186,10 +4197,10 @@ void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, |
| Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); |
| if (!obj.IsNull()) { |
| - ReportError(enum_pos, "'%s' is already defined", enum_name->ToCString()); |
| + ReportError(name_pos, "'%s' is already defined", enum_name->ToCString()); |
| } |
| Class& cls = Class::Handle(Z); |
| - cls = Class::New(*enum_name, script_, enum_pos); |
| + cls = Class::New(*enum_name, script_, declaration_pos); |
| cls.set_library(library_); |
| library_.AddClass(cls); |
| cls.set_is_synthesized_class(); |
| @@ -4208,6 +4219,7 @@ void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| TRACE_PARSER("ParseClassDeclaration"); |
| bool is_patch = false; |
| bool is_abstract = false; |
| + intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos : TokenPos(); |
| if (is_patch_source() && |
| (CurrentToken() == Token::kIDENT) && |
| CurrentLiteral()->Equals("patch")) { |
| @@ -4231,7 +4243,7 @@ void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| ReportError(classname_pos, "missing class '%s' cannot be patched", |
| class_name.ToCString()); |
| } |
| - cls = Class::New(class_name, script_, classname_pos); |
| + cls = Class::New(class_name, script_, declaration_pos); |
| library_.AddClass(cls); |
| } else { |
| if (!obj.IsClass()) { |
| @@ -4247,7 +4259,7 @@ void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| // otherwise the generic signature classes it defines will not match the |
| // patched generic signature classes. Therefore, new signature classes |
| // will be introduced and the original ones will not get finalized. |
| - cls = Class::New(class_name, script_, classname_pos); |
| + cls = Class::New(class_name, script_, declaration_pos); |
| cls.set_library(library_); |
| } else { |
| // Not patching a class, but it has been found. This must be one of the |
| @@ -4259,7 +4271,7 @@ void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| } |
| // Pre-registered classes need their scripts connected at this time. |
| cls.set_script(script_); |
| - cls.set_token_pos(classname_pos); |
| + cls.set_token_pos(declaration_pos); |
| } |
| } |
| ASSERT(!cls.IsNull()); |
| @@ -4399,6 +4411,15 @@ void Parser::ParseClassDefinition(const Class& cls) { |
| set_current_class(cls); |
| is_top_level_ = true; |
| String& class_name = String::Handle(Z, cls.Name()); |
| + SkipMetadata(); |
| + if (is_patch_source() && |
| + (CurrentToken() == Token::kIDENT) && |
| + CurrentLiteral()->Equals("patch")) { |
| + ConsumeToken(); |
| + } else if (CurrentToken() == Token::kABSTRACT) { |
| + ConsumeToken(); |
| + } |
| + ExpectToken(Token::kCLASS); |
| const intptr_t class_pos = TokenPos(); |
| ClassDesc members(cls, class_name, false, class_pos); |
| while (CurrentToken() != Token::kLBRACE) { |
| @@ -4448,6 +4469,9 @@ void Parser::ParseEnumDefinition(const Class& cls) { |
| TRACE_PARSER("ParseEnumDefinition"); |
| CompilerStats::num_classes_compiled++; |
| + SkipMetadata(); |
| + ExpectToken(Token::kENUM); |
| + |
| const String& enum_name = String::Handle(Z, cls.Name()); |
| ClassDesc enum_members(cls, enum_name, false, cls.token_pos()); |
| @@ -4784,6 +4808,7 @@ void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
| const Class& toplevel_class, |
| intptr_t metadata_pos) { |
| TRACE_PARSER("ParseTypedef"); |
| + intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos : TokenPos(); |
| ExpectToken(Token::kTYPEDEF); |
| if (IsMixinAppAlias()) { |
| @@ -4826,7 +4851,7 @@ void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
| Class::NewSignatureClass(*alias_name, |
| Function::Handle(Z), |
| script_, |
| - alias_name_pos)); |
| + declaration_pos)); |
| library_.AddClass(function_type_alias); |
| set_current_class(function_type_alias); |
| // Parse the type parameters of the function type. |
| @@ -4993,6 +5018,8 @@ void Parser::ParseTypeParameters(const Class& cls) { |
| ConsumeToken(); |
| const intptr_t metadata_pos = SkipMetadata(); |
| const intptr_t type_parameter_pos = TokenPos(); |
| + const intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos |
| + : type_parameter_pos; |
| String& type_parameter_name = |
| *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
| // Check for duplicate type parameters. |
| @@ -5018,7 +5045,7 @@ void Parser::ParseTypeParameters(const Class& cls) { |
| index, |
| type_parameter_name, |
| type_parameter_bound, |
| - type_parameter_pos); |
| + declaration_pos); |
| type_parameters_array.Add(type_parameter); |
| if (metadata_pos >= 0) { |
| library_.AddTypeParameterMetadata(type_parameter, metadata_pos); |
| @@ -5773,6 +5800,22 @@ void Parser::ParseLibraryDefinition() { |
| } |
| +intptr_t Parser::GetLibraryDeclarationPosition() { |
|
hausner
2015/02/13 21:02:01
When you look at SkipMetadata, you'll see that thi
rmacnak
2015/02/13 22:57:22
True, I'll do this in mirrors.cc instead.
|
| + if (CurrentToken() == Token::kSCRIPTTAG) { |
| + // Nothing to do for script tags except to skip them. |
| + ConsumeToken(); |
| + } |
| + intptr_t metadata_pos = SkipMetadata(); |
| + if (metadata_pos >= 0) { |
| + return metadata_pos; |
| + } |
| + if (CurrentToken() == Token::kLIBRARY) { |
| + return TokenPos(); |
| + } |
| + return Scanner::kNoSourcePos; |
|
hausner
2015/02/13 21:02:01
Scanner::kNoSourcePos is unfortunately 0, and a fe
|
| +} |
| + |
| + |
| void Parser::ParsePartHeader() { |
| SkipMetadata(); |
| CheckToken(Token::kPART, "'part of' expected"); |