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