OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
839 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 839 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
840 ASSERT(parsed_function != NULL); | 840 ASSERT(parsed_function != NULL); |
841 const Function& func = parsed_function->function(); | 841 const Function& func = parsed_function->function(); |
842 const Script& script = Script::Handle(zone, func.script()); | 842 const Script& script = Script::Handle(zone, func.script()); |
843 Parser parser(script, parsed_function, func.token_pos()); | 843 Parser parser(script, parsed_function, func.token_pos()); |
844 SequenceNode* node_sequence = NULL; | 844 SequenceNode* node_sequence = NULL; |
845 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); | 845 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); |
846 switch (func.kind()) { | 846 switch (func.kind()) { |
847 case RawFunction::kClosureFunction: | 847 case RawFunction::kClosureFunction: |
848 if (func.IsImplicitClosureFunction()) { | 848 if (func.IsImplicitClosureFunction()) { |
849 parser.SkipFunctionPreamble(); | |
850 node_sequence = | 849 node_sequence = |
851 parser.ParseImplicitClosure(func, &default_parameter_values); | 850 parser.ParseImplicitClosure(func, &default_parameter_values); |
852 break; | 851 break; |
853 } | 852 } |
854 // Fall-through: Handle non-implicit closures. | 853 // Fall-through: Handle non-implicit closures. |
855 case RawFunction::kRegularFunction: | 854 case RawFunction::kRegularFunction: |
856 case RawFunction::kGetterFunction: | 855 case RawFunction::kGetterFunction: |
857 case RawFunction::kSetterFunction: | 856 case RawFunction::kSetterFunction: |
858 case RawFunction::kConstructor: | 857 case RawFunction::kConstructor: |
859 // The call to a redirecting factory is redirected. | 858 // The call to a redirecting factory is redirected. |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1280 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 1279 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
1281 current_block_->statements->Add(store_field); | 1280 current_block_->statements->Add(store_field); |
1282 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 1281 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); |
1283 return CloseBlock(); | 1282 return CloseBlock(); |
1284 } | 1283 } |
1285 | 1284 |
1286 | 1285 |
1287 SequenceNode* Parser::ParseImplicitClosure(const Function& func, | 1286 SequenceNode* Parser::ParseImplicitClosure(const Function& func, |
1288 Array* default_values) { | 1287 Array* default_values) { |
1289 TRACE_PARSER("ParseImplicitClosure"); | 1288 TRACE_PARSER("ParseImplicitClosure"); |
1290 | |
1291 intptr_t token_pos = func.token_pos(); | 1289 intptr_t token_pos = func.token_pos(); |
1292 | 1290 |
1293 OpenFunctionBlock(func); | 1291 OpenFunctionBlock(func); |
1294 | 1292 |
1295 ParamList params; | 1293 ParamList params; |
1296 | |
1297 params.AddFinalParameter( | 1294 params.AddFinalParameter( |
1298 token_pos, | 1295 token_pos, |
1299 &Symbols::ClosureParameter(), | 1296 &Symbols::ClosureParameter(), |
1300 &Type::ZoneHandle(Type::DynamicType())); | 1297 &Type::ZoneHandle(Type::DynamicType())); |
1301 | 1298 |
1302 const bool allow_explicit_default_values = true; | |
1303 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | |
1304 SetupDefaultsForOptionalParams(¶ms, default_values); | |
1305 | |
1306 // Getters can't be closurized. If supported, they need special | |
1307 // handling of the parameters as in ParseFunc. | |
1308 const Function& parent = Function::ZoneHandle(func.parent_function()); | 1299 const Function& parent = Function::ZoneHandle(func.parent_function()); |
1309 ASSERT(!parent.IsGetterFunction()); | 1300 if (parent.IsImplicitSetterFunction()) { |
1301 const intptr_t ident_pos = func.token_pos(); | |
1302 ASSERT(IsIdentifier()); | |
1303 const String& field_name = *CurrentLiteral(); | |
1304 const Class& field_class = Class::ZoneHandle(Z, parent.Owner()); | |
1305 const Field& field = | |
1306 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | |
1307 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | |
1308 params.AddFinalParameter(ident_pos, | |
1309 &Symbols::Value(), | |
1310 &field_type); | |
1311 ASSERT(func.num_fixed_parameters() == 2); // closure, value. | |
1312 } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) { | |
1313 const bool allow_explicit_default_values = true; | |
1314 SkipFunctionPreamble(); | |
1315 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | |
1316 SetupDefaultsForOptionalParams(¶ms, default_values); | |
1317 } | |
1310 | 1318 |
1311 // Populate function scope with the formal parameters. | 1319 // Populate function scope with the formal parameters. |
1312 LocalScope* scope = current_block_->scope; | 1320 LocalScope* scope = current_block_->scope; |
1313 AddFormalParamsToScope(¶ms, scope); | 1321 AddFormalParamsToScope(¶ms, scope); |
1314 | 1322 |
1315 ArgumentListNode* func_args = new ArgumentListNode(token_pos); | 1323 ArgumentListNode* func_args = new ArgumentListNode(token_pos); |
1316 if (!func.is_static()) { | 1324 if (!func.is_static()) { |
1317 func_args->Add(LoadReceiver(token_pos)); | 1325 func_args->Add(LoadReceiver(token_pos)); |
1318 } | 1326 } |
1319 // Skip implicit parameter at 0. | 1327 // Skip implicit parameter at 0. |
(...skipping 2104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3424 } while (CurrentToken() == Token::kCOMMA); | 3432 } while (CurrentToken() == Token::kCOMMA); |
3425 } | 3433 } |
3426 | 3434 |
3427 | 3435 |
3428 // If the current identifier is a library prefix followed by a period, | 3436 // If the current identifier is a library prefix followed by a period, |
3429 // consume the identifier and period, and return the resolved library | 3437 // consume the identifier and period, and return the resolved library |
3430 // prefix. | 3438 // prefix. |
3431 RawLibraryPrefix* Parser::ParsePrefix() { | 3439 RawLibraryPrefix* Parser::ParsePrefix() { |
3432 ASSERT(IsIdentifier()); | 3440 ASSERT(IsIdentifier()); |
3433 // A library prefix can never stand by itself. It must be followed by | 3441 // A library prefix can never stand by itself. It must be followed by |
3434 // a period. | 3442 // a period or a hash mark (for closurization). |
3435 if (LookaheadToken(1) != Token::kPERIOD) { | 3443 Token::Kind next_token = LookaheadToken(1); |
3444 if ((next_token != Token::kPERIOD) && (next_token != Token::kHASH)) { | |
3436 return LibraryPrefix::null(); | 3445 return LibraryPrefix::null(); |
3437 } | 3446 } |
3438 const String& ident = *CurrentLiteral(); | 3447 const String& ident = *CurrentLiteral(); |
3439 | 3448 |
3440 // It is relatively fast to look up a name in the library dictionary, | 3449 // It is relatively fast to look up a name in the library dictionary, |
3441 // compared to searching the nested local scopes. Look up the name | 3450 // compared to searching the nested local scopes. Look up the name |
3442 // in the library scope and return in the common case where ident is | 3451 // in the library scope and return in the common case where ident is |
3443 // not a library prefix. | 3452 // not a library prefix. |
3444 LibraryPrefix& prefix = | 3453 LibraryPrefix& prefix = |
3445 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident)); | 3454 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident)); |
3446 if (prefix.IsNull()) { | 3455 if (prefix.IsNull()) { |
3447 return LibraryPrefix::null(); | 3456 return LibraryPrefix::null(); |
3448 } | 3457 } |
3449 | 3458 |
3450 // A library prefix with the name exists. Now check whether it is | 3459 // A library prefix with the name exists. Now check whether it is |
3451 // shadowed by a local definition. | 3460 // shadowed by a local definition. |
3452 if (!is_top_level_ && | 3461 if (!is_top_level_ && |
3453 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { | 3462 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { |
3454 return LibraryPrefix::null(); | 3463 return LibraryPrefix::null(); |
3455 } | 3464 } |
3456 // Check whether the identifier is shadowed by a type parameter. | 3465 // Check whether the identifier is shadowed by a type parameter. |
3457 ASSERT(!current_class().IsNull()); | 3466 ASSERT(!current_class().IsNull()); |
3458 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { | 3467 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { |
3459 return LibraryPrefix::null(); | 3468 return LibraryPrefix::null(); |
3460 } | 3469 } |
3461 | 3470 |
3462 // We have a name that is not shadowed, followed by a period. | 3471 // We have a name that is not shadowed, followed by a period or #. |
3463 // Consume the identifier and the period. | 3472 // Consume the identifier, let the caller consume the . or #. |
3464 ConsumeToken(); | |
3465 ASSERT(CurrentToken() == Token::kPERIOD); // We checked above. | |
3466 ConsumeToken(); | 3473 ConsumeToken(); |
3467 return prefix.raw(); | 3474 return prefix.raw(); |
3468 } | 3475 } |
3469 | 3476 |
3470 | 3477 |
3471 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 3478 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
3472 TRACE_PARSER("ParseMethodOrConstructor"); | 3479 TRACE_PARSER("ParseMethodOrConstructor"); |
3473 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); | 3480 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); |
3474 ASSERT(method->type != NULL); | 3481 ASSERT(method->type != NULL); |
3475 ASSERT(current_member_ == method); | 3482 ASSERT(current_member_ == method); |
(...skipping 7835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11311 } | 11318 } |
11312 // Done parsing selectors. | 11319 // Done parsing selectors. |
11313 return left; | 11320 return left; |
11314 } | 11321 } |
11315 ASSERT(selector != NULL); | 11322 ASSERT(selector != NULL); |
11316 left = selector; | 11323 left = selector; |
11317 } | 11324 } |
11318 } | 11325 } |
11319 | 11326 |
11320 | 11327 |
11328 // Closurization e#m of getter, setter, method or operator. | |
11329 AstNode* Parser::ParseClosurization(AstNode* primary) { | |
11330 ExpectToken(Token::kHASH); | |
11331 intptr_t property_pos = TokenPos(); | |
11332 bool is_setter_name = false; | |
11333 | |
11334 String& extractor_name = String::ZoneHandle(Z); | |
11335 if (IsIdentifier()) { | |
11336 extractor_name = CurrentLiteral()->raw(); | |
11337 ConsumeToken(); | |
11338 if (CurrentToken() == Token::kASSIGN) { | |
11339 ConsumeToken(); | |
11340 is_setter_name = true; | |
11341 } | |
11342 } else if (Token::CanBeOverloaded(CurrentToken())) { | |
11343 extractor_name = String::New(Token::Str(CurrentToken())); | |
11344 ConsumeToken(); | |
11345 } else { | |
11346 ReportError("identifier or operator expected"); | |
11347 } | |
11348 | |
11349 if (primary->IsPrimaryNode() && primary->AsPrimaryNode()->IsSuper()) { | |
11350 // TODO(hausner): implement super#m | |
11351 ReportError("closurization of super method not yet supported"); | |
11352 } | |
11353 | |
11354 // Handle closurization of top-level names from library prefixes, P#m | |
11355 if (primary->IsLiteralNode() && | |
11356 primary->AsLiteralNode()->literal().IsLibraryPrefix()) { | |
11357 const LibraryPrefix& prefix = | |
11358 LibraryPrefix::Cast(primary->AsLiteralNode()->literal()); | |
11359 Object& obj = Object::Handle(Z); | |
11360 const bool is_private_name = | |
11361 (extractor_name.CharAt(0) == Library::kPrivateIdentifierStart); | |
11362 if (!is_private_name) { | |
11363 // Private names are not exported by libraries. The name mangling | |
11364 // of private names with a library-specific suffix usually ensures | |
11365 // that _x in library A is not found when looked up from library B. | |
11366 // In the pathological case where a library imports itself with | |
11367 // a prefix, the name mangling does not help in hiding the private | |
11368 // name, so we explicitly prevent lookup of private names here. | |
11369 obj = prefix.LookupObject(extractor_name); | |
11370 } | |
11371 if (!prefix.is_loaded() && (parsed_function() != NULL)) { | |
11372 // Remember that this function depends on an import prefix of an | |
11373 // unloaded deferred library. | |
11374 parsed_function()->AddDeferredPrefix(prefix); | |
11375 } | |
11376 | |
11377 if (obj.IsFunction()) { | |
11378 const Function& func = Function::Cast(obj); | |
11379 if (!func.IsSetterFunction() || is_setter_name) { | |
11380 return CreateImplicitClosureNode(func, property_pos, NULL); | |
11381 } | |
11382 } else if (obj.IsField()) { | |
11383 const Field& field = Field::Cast(obj); | |
11384 if (is_setter_name && !field.is_final()) { | |
11385 Instance& setter_closure = Instance::ZoneHandle(field.SetterClosure()); | |
11386 return new(Z) LiteralNode(property_pos, setter_closure); | |
11387 } | |
11388 if (!is_setter_name) { | |
11389 Instance& getter_closure = Instance::ZoneHandle(field.GetterClosure()); | |
11390 return new(Z) LiteralNode(property_pos, getter_closure); | |
11391 } | |
11392 } | |
11393 return ThrowNoSuchMethodError(property_pos, | |
11394 current_class(), | |
11395 extractor_name, | |
11396 NULL, // No arguments. | |
11397 InvocationMirror::kTopLevel, | |
11398 is_setter_name | |
11399 ? InvocationMirror::kSetter | |
11400 : InvocationMirror::kMethod, | |
11401 NULL); // No existing function. | |
11402 } | |
11403 | |
11404 // Handle closurization of static properties of classes, C#n. | |
11405 if (primary->IsPrimaryNode() && | |
11406 primary->AsPrimaryNode()->primary().IsClass()) { | |
11407 const Class& cls = Class::Cast(primary->AsPrimaryNode()->primary()); | |
11408 const Field& field = | |
11409 Field::Handle(Z, cls.LookupStaticField(extractor_name)); | |
11410 if (!field.IsNull()) { | |
11411 if (is_setter_name) { | |
11412 extractor_name = Field::SetterName(extractor_name); | |
11413 if (!field.is_final()) { | |
11414 const Instance& setter_closure = | |
11415 Instance::ZoneHandle(Z, field.SetterClosure()); | |
11416 ASSERT(setter_closure.IsClosure()); | |
11417 const Function& cf = | |
11418 Function::Handle(Closure::function(setter_closure)); | |
11419 Error& error = Error::Handle(Z); | |
11420 error = Compiler::CompileFunction(Thread::Current(), cf); | |
11421 ASSERT(error.IsNull()); | |
11422 return new(Z) LiteralNode(property_pos, setter_closure); | |
11423 } | |
11424 } | |
11425 if (!is_setter_name) { | |
Florian Schneider
2015/07/22 08:25:54
if (is_setter_name) { }
if (!is_setter_name) { }
hausner
2015/07/22 18:41:10
Done.
I also removed the pre-compilation code, si
| |
11426 const Instance& getter_closure = | |
11427 Instance::ZoneHandle(Z, field.GetterClosure()); | |
11428 ASSERT(getter_closure.IsClosure()); | |
11429 const Function& cf = | |
11430 Function::Handle(Closure::function(getter_closure)); | |
11431 Error& error = Error::Handle(Z); | |
11432 error = Compiler::CompileFunction(Thread::Current(), cf); | |
11433 ASSERT(error.IsNull()); | |
11434 return new(Z) LiteralNode(property_pos, getter_closure); | |
11435 } | |
11436 } else { | |
11437 Function& func = Function::Handle(Z); | |
11438 if (is_setter_name) { | |
11439 extractor_name = Field::SetterName(extractor_name); | |
11440 func = cls.LookupStaticFunction(extractor_name); | |
11441 } else { | |
11442 func = cls.LookupStaticFunction(extractor_name); | |
11443 if (func.IsNull()) { | |
11444 const String& getter_name = | |
11445 String::Handle(Z, Field::GetterName(extractor_name)); | |
11446 func = cls.LookupStaticFunction(getter_name); | |
11447 } | |
11448 } | |
11449 if (!func.IsNull()) { | |
11450 return CreateImplicitClosureNode(func, property_pos, NULL); | |
11451 } | |
11452 } | |
11453 return ThrowNoSuchMethodError(property_pos, | |
11454 cls, | |
11455 extractor_name, | |
11456 NULL, // No arguments. | |
11457 InvocationMirror::kStatic, | |
11458 is_setter_name | |
11459 ? InvocationMirror::kSetter | |
11460 : InvocationMirror::kMethod, | |
11461 NULL); // No existing function. | |
11462 } | |
11463 | |
11464 // Closurization of instance getter, setter, method or operator. | |
11465 if (is_setter_name) { | |
11466 extractor_name = String::Concat(Symbols::SetterPrefix(), extractor_name); | |
11467 } | |
11468 extractor_name = String::Concat(Symbols::HashMark(), extractor_name); | |
11469 extractor_name = Symbols::New(extractor_name); | |
11470 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); | |
11471 } | |
11472 | |
11473 | |
11321 AstNode* Parser::ParsePostfixExpr() { | 11474 AstNode* Parser::ParsePostfixExpr() { |
11322 TRACE_PARSER("ParsePostfixExpr"); | 11475 TRACE_PARSER("ParsePostfixExpr"); |
11323 String* expr_ident = | 11476 String* expr_ident = |
11324 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11477 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
11325 const intptr_t expr_pos = TokenPos(); | 11478 const intptr_t expr_pos = TokenPos(); |
11326 AstNode* expr = ParsePrimary(); | 11479 AstNode* expr = ParsePrimary(); |
11327 expr = ParseSelectors(expr, false); | 11480 if (CurrentToken() == Token::kHASH) { |
11481 expr = LoadFieldIfUnresolved(expr); | |
11482 expr = ParseClosurization(expr); | |
11483 } else { | |
11484 expr = ParseSelectors(expr, false); | |
11485 } | |
11328 if (IsIncrementOperator(CurrentToken())) { | 11486 if (IsIncrementOperator(CurrentToken())) { |
11329 TRACE_PARSER("IncrementOperator"); | 11487 TRACE_PARSER("IncrementOperator"); |
11330 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 11488 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
11331 ReportError(expr_pos, "expression is not assignable"); | 11489 ReportError(expr_pos, "expression is not assignable"); |
11332 } | 11490 } |
11333 Token::Kind incr_op = CurrentToken(); | 11491 Token::Kind incr_op = CurrentToken(); |
11334 ConsumeToken(); | 11492 ConsumeToken(); |
11335 // Not prefix. | 11493 // Not prefix. |
11336 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11494 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
11337 LocalVariable* temp = let_expr->AddInitializer(expr); | 11495 LocalVariable* temp = let_expr->AddInitializer(expr); |
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11999 | 12157 |
12000 if (finalization == ClassFinalizer::kIgnore) { | 12158 if (finalization == ClassFinalizer::kIgnore) { |
12001 if (!is_top_level_ && (current_block_ != NULL)) { | 12159 if (!is_top_level_ && (current_block_ != NULL)) { |
12002 // Add the library prefix or type class name to the list of referenced | 12160 // Add the library prefix or type class name to the list of referenced |
12003 // names of this scope, even if the type is ignored. | 12161 // names of this scope, even if the type is ignored. |
12004 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); | 12162 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); |
12005 } | 12163 } |
12006 SkipQualIdent(); | 12164 SkipQualIdent(); |
12007 } else { | 12165 } else { |
12008 *prefix = ParsePrefix(); | 12166 *prefix = ParsePrefix(); |
12167 if (!prefix->IsNull()) { | |
12168 ExpectToken(Token::kPERIOD); | |
12169 } | |
12009 type_name = CurrentLiteral()->raw(); | 12170 type_name = CurrentLiteral()->raw(); |
12010 ConsumeToken(); | 12171 ConsumeToken(); |
12011 | 12172 |
12012 // Check whether we have a malformed qualified type name if the caller | 12173 // Check whether we have a malformed qualified type name if the caller |
12013 // requests to consume unresolved prefix names: | 12174 // requests to consume unresolved prefix names: |
12014 // If we didn't see a valid prefix but the identifier is followed by | 12175 // If we didn't see a valid prefix but the identifier is followed by |
12015 // a period and another identifier, consume the qualified identifier | 12176 // a period and another identifier, consume the qualified identifier |
12016 // and create a malformed type. | 12177 // and create a malformed type. |
12017 if (consume_unresolved_prefix && | 12178 if (consume_unresolved_prefix && |
12018 prefix->IsNull() && | 12179 prefix->IsNull() && |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12624 TRACE_PARSER("ParseNewOperator"); | 12785 TRACE_PARSER("ParseNewOperator"); |
12625 const intptr_t new_pos = TokenPos(); | 12786 const intptr_t new_pos = TokenPos(); |
12626 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 12787 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
12627 bool is_const = (op_kind == Token::kCONST); | 12788 bool is_const = (op_kind == Token::kCONST); |
12628 if (!IsIdentifier()) { | 12789 if (!IsIdentifier()) { |
12629 ReportError("type name expected"); | 12790 ReportError("type name expected"); |
12630 } | 12791 } |
12631 intptr_t type_pos = TokenPos(); | 12792 intptr_t type_pos = TokenPos(); |
12632 // Can't allocate const objects of a deferred type. | 12793 // Can't allocate const objects of a deferred type. |
12633 const bool allow_deferred_type = !is_const; | 12794 const bool allow_deferred_type = !is_const; |
12634 const bool consume_unresolved_prefix = (LookaheadToken(3) == Token::kLT) || | 12795 const Token::Kind la3 = LookaheadToken(3); |
12635 (LookaheadToken(3) == Token::kPERIOD); | 12796 const bool consume_unresolved_prefix = |
12797 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); | |
12798 | |
12636 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); | 12799 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); |
12637 AbstractType& type = AbstractType::Handle(Z, | 12800 AbstractType& type = AbstractType::Handle(Z, |
12638 ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 12801 ParseType(ClassFinalizer::kCanonicalizeWellFormed, |
12639 allow_deferred_type, | 12802 allow_deferred_type, |
12640 consume_unresolved_prefix, | 12803 consume_unresolved_prefix, |
12641 &prefix)); | 12804 &prefix)); |
12805 if (CurrentToken() == Token::kHASH) { | |
12806 ReportError("constructor closurization not yet supported"); | |
12807 } | |
12642 if (FLAG_load_deferred_eagerly && | 12808 if (FLAG_load_deferred_eagerly && |
12643 !prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) { | 12809 !prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) { |
12644 // Add runtime check. | 12810 // Add runtime check. |
12645 Type& malformed_type = Type::Handle(Z); | 12811 Type& malformed_type = Type::Handle(Z); |
12646 malformed_type = ClassFinalizer::NewFinalizedMalformedType( | 12812 malformed_type = ClassFinalizer::NewFinalizedMalformedType( |
12647 Error::Handle(Z), // No previous error. | 12813 Error::Handle(Z), // No previous error. |
12648 script_, | 12814 script_, |
12649 type_pos, | 12815 type_pos, |
12650 "deferred type '%s.%s' is not yet loaded", | 12816 "deferred type '%s.%s' is not yet loaded", |
12651 String::Handle(Z, prefix.name()).ToCString(), | 12817 String::Handle(Z, prefix.name()).ToCString(), |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13066 const Token::Kind token = CurrentToken(); | 13232 const Token::Kind token = CurrentToken(); |
13067 if (IsFunctionLiteral()) { | 13233 if (IsFunctionLiteral()) { |
13068 // The name of a literal function is visible from inside the function, but | 13234 // The name of a literal function is visible from inside the function, but |
13069 // must not collide with names in the scope declaring the literal. | 13235 // must not collide with names in the scope declaring the literal. |
13070 OpenBlock(); | 13236 OpenBlock(); |
13071 primary = ParseFunctionStatement(true); | 13237 primary = ParseFunctionStatement(true); |
13072 CloseBlock(); | 13238 CloseBlock(); |
13073 } else if (IsIdentifier()) { | 13239 } else if (IsIdentifier()) { |
13074 intptr_t qual_ident_pos = TokenPos(); | 13240 intptr_t qual_ident_pos = TokenPos(); |
13075 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 13241 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
13242 if (!prefix.IsNull()) { | |
13243 if (CurrentToken() == Token::kHASH) { | |
13244 // Closurization of top-level entity in prefix scope. | |
13245 return new(Z) LiteralNode(qual_ident_pos, prefix); | |
13246 } else { | |
13247 ExpectToken(Token::kPERIOD); | |
13248 } | |
13249 } | |
13076 String& ident = *CurrentLiteral(); | 13250 String& ident = *CurrentLiteral(); |
13077 ConsumeToken(); | 13251 ConsumeToken(); |
13078 if (prefix.IsNull()) { | 13252 if (prefix.IsNull()) { |
13079 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { | 13253 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { |
13080 // Check whether the identifier is a type parameter. | 13254 // Check whether the identifier is a type parameter. |
13081 if (!current_class().IsNull()) { | 13255 if (!current_class().IsNull()) { |
13082 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, | 13256 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, |
13083 current_class().LookupTypeParameter(ident)); | 13257 current_class().LookupTypeParameter(ident)); |
13084 if (!type_param.IsNull()) { | 13258 if (!type_param.IsNull()) { |
13085 return new(Z) PrimaryNode(qual_ident_pos, type_param); | 13259 return new(Z) PrimaryNode(qual_ident_pos, type_param); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13427 } else { | 13601 } else { |
13428 UnexpectedToken(); | 13602 UnexpectedToken(); |
13429 } | 13603 } |
13430 } | 13604 } |
13431 | 13605 |
13432 | 13606 |
13433 void Parser::SkipNewOperator() { | 13607 void Parser::SkipNewOperator() { |
13434 ConsumeToken(); // Skip new or const keyword. | 13608 ConsumeToken(); // Skip new or const keyword. |
13435 if (IsIdentifier()) { | 13609 if (IsIdentifier()) { |
13436 SkipType(false); | 13610 SkipType(false); |
13611 SkipIf(Token::kHASH); | |
13612 if (CurrentToken() == Token::kPERIOD) { | |
13613 ConsumeToken(); | |
13614 ExpectIdentifier("identifier expected"); | |
13615 } | |
13437 if (CurrentToken() == Token::kLPAREN) { | 13616 if (CurrentToken() == Token::kLPAREN) { |
13438 SkipActualParameters(); | 13617 SkipActualParameters(); |
13439 return; | 13618 return; |
13440 } | 13619 } |
13441 } | 13620 } |
13442 } | 13621 } |
13443 | 13622 |
13444 | 13623 |
13445 void Parser::SkipStringLiteral() { | 13624 void Parser::SkipStringLiteral() { |
13446 ASSERT(CurrentToken() == Token::kSTRING); | 13625 ASSERT(CurrentToken() == Token::kSTRING); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13545 } else if (current_token == Token::kLPAREN) { | 13724 } else if (current_token == Token::kLPAREN) { |
13546 SkipActualParameters(); | 13725 SkipActualParameters(); |
13547 } else { | 13726 } else { |
13548 break; | 13727 break; |
13549 } | 13728 } |
13550 } | 13729 } |
13551 } | 13730 } |
13552 | 13731 |
13553 void Parser::SkipPostfixExpr() { | 13732 void Parser::SkipPostfixExpr() { |
13554 SkipPrimary(); | 13733 SkipPrimary(); |
13734 if (CurrentToken() == Token::kHASH) { | |
13735 if (IsIdentifier()) { | |
13736 ConsumeToken(); | |
13737 SkipIf(Token::kASSIGN); | |
13738 } else if (Token::CanBeOverloaded(CurrentToken())) { | |
13739 ConsumeToken(); | |
13740 } else { | |
13741 ReportError("identifier or operator expected"); | |
13742 } | |
13743 } | |
13555 SkipSelectors(); | 13744 SkipSelectors(); |
13556 if (IsIncrementOperator(CurrentToken())) { | 13745 if (IsIncrementOperator(CurrentToken())) { |
13557 ConsumeToken(); | 13746 ConsumeToken(); |
13558 } | 13747 } |
13559 } | 13748 } |
13560 | 13749 |
13561 | 13750 |
13562 void Parser::SkipUnaryExpr() { | 13751 void Parser::SkipUnaryExpr() { |
13563 if (IsPrefixOperator(CurrentToken()) || | 13752 if (IsPrefixOperator(CurrentToken()) || |
13564 IsIncrementOperator(CurrentToken()) || | 13753 IsIncrementOperator(CurrentToken()) || |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13630 void Parser::SkipQualIdent() { | 13819 void Parser::SkipQualIdent() { |
13631 ASSERT(IsIdentifier()); | 13820 ASSERT(IsIdentifier()); |
13632 ConsumeToken(); | 13821 ConsumeToken(); |
13633 if (CurrentToken() == Token::kPERIOD) { | 13822 if (CurrentToken() == Token::kPERIOD) { |
13634 ConsumeToken(); // Consume the kPERIOD token. | 13823 ConsumeToken(); // Consume the kPERIOD token. |
13635 ExpectIdentifier("identifier expected after '.'"); | 13824 ExpectIdentifier("identifier expected after '.'"); |
13636 } | 13825 } |
13637 } | 13826 } |
13638 | 13827 |
13639 } // namespace dart | 13828 } // namespace dart |
OLD | NEW |