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 // Note: the created closure is cached after it's created |
| 11418 // once. If eager compilation is desired, the compiler can |
| 11419 // be invoked here. The same applies for getters below. |
| 11420 return new(Z) LiteralNode(property_pos, setter_closure); |
| 11421 } |
| 11422 } else { |
| 11423 const Instance& getter_closure = |
| 11424 Instance::ZoneHandle(Z, field.GetterClosure()); |
| 11425 ASSERT(getter_closure.IsClosure()); |
| 11426 return new(Z) LiteralNode(property_pos, getter_closure); |
| 11427 } |
| 11428 } else { |
| 11429 Function& func = Function::Handle(Z); |
| 11430 if (is_setter_name) { |
| 11431 extractor_name = Field::SetterName(extractor_name); |
| 11432 func = cls.LookupStaticFunction(extractor_name); |
| 11433 } else { |
| 11434 func = cls.LookupStaticFunction(extractor_name); |
| 11435 if (func.IsNull()) { |
| 11436 const String& getter_name = |
| 11437 String::Handle(Z, Field::GetterName(extractor_name)); |
| 11438 func = cls.LookupStaticFunction(getter_name); |
| 11439 } |
| 11440 } |
| 11441 if (!func.IsNull()) { |
| 11442 return CreateImplicitClosureNode(func, property_pos, NULL); |
| 11443 } |
| 11444 } |
| 11445 return ThrowNoSuchMethodError(property_pos, |
| 11446 cls, |
| 11447 extractor_name, |
| 11448 NULL, // No arguments. |
| 11449 InvocationMirror::kStatic, |
| 11450 is_setter_name |
| 11451 ? InvocationMirror::kSetter |
| 11452 : InvocationMirror::kMethod, |
| 11453 NULL); // No existing function. |
| 11454 } |
| 11455 |
| 11456 // Closurization of instance getter, setter, method or operator. |
| 11457 if (is_setter_name) { |
| 11458 extractor_name = String::Concat(Symbols::SetterPrefix(), extractor_name); |
| 11459 } |
| 11460 extractor_name = String::Concat(Symbols::HashMark(), extractor_name); |
| 11461 extractor_name = Symbols::New(extractor_name); |
| 11462 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); |
| 11463 } |
| 11464 |
| 11465 |
11321 AstNode* Parser::ParsePostfixExpr() { | 11466 AstNode* Parser::ParsePostfixExpr() { |
11322 TRACE_PARSER("ParsePostfixExpr"); | 11467 TRACE_PARSER("ParsePostfixExpr"); |
11323 String* expr_ident = | 11468 String* expr_ident = |
11324 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11469 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
11325 const intptr_t expr_pos = TokenPos(); | 11470 const intptr_t expr_pos = TokenPos(); |
11326 AstNode* expr = ParsePrimary(); | 11471 AstNode* expr = ParsePrimary(); |
11327 expr = ParseSelectors(expr, false); | 11472 if (CurrentToken() == Token::kHASH) { |
| 11473 expr = LoadFieldIfUnresolved(expr); |
| 11474 expr = ParseClosurization(expr); |
| 11475 } else { |
| 11476 expr = ParseSelectors(expr, false); |
| 11477 } |
11328 if (IsIncrementOperator(CurrentToken())) { | 11478 if (IsIncrementOperator(CurrentToken())) { |
11329 TRACE_PARSER("IncrementOperator"); | 11479 TRACE_PARSER("IncrementOperator"); |
11330 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 11480 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
11331 ReportError(expr_pos, "expression is not assignable"); | 11481 ReportError(expr_pos, "expression is not assignable"); |
11332 } | 11482 } |
11333 Token::Kind incr_op = CurrentToken(); | 11483 Token::Kind incr_op = CurrentToken(); |
11334 ConsumeToken(); | 11484 ConsumeToken(); |
11335 // Not prefix. | 11485 // Not prefix. |
11336 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11486 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
11337 LocalVariable* temp = let_expr->AddInitializer(expr); | 11487 LocalVariable* temp = let_expr->AddInitializer(expr); |
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11999 | 12149 |
12000 if (finalization == ClassFinalizer::kIgnore) { | 12150 if (finalization == ClassFinalizer::kIgnore) { |
12001 if (!is_top_level_ && (current_block_ != NULL)) { | 12151 if (!is_top_level_ && (current_block_ != NULL)) { |
12002 // Add the library prefix or type class name to the list of referenced | 12152 // Add the library prefix or type class name to the list of referenced |
12003 // names of this scope, even if the type is ignored. | 12153 // names of this scope, even if the type is ignored. |
12004 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); | 12154 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); |
12005 } | 12155 } |
12006 SkipQualIdent(); | 12156 SkipQualIdent(); |
12007 } else { | 12157 } else { |
12008 *prefix = ParsePrefix(); | 12158 *prefix = ParsePrefix(); |
| 12159 if (!prefix->IsNull()) { |
| 12160 ExpectToken(Token::kPERIOD); |
| 12161 } |
12009 type_name = CurrentLiteral()->raw(); | 12162 type_name = CurrentLiteral()->raw(); |
12010 ConsumeToken(); | 12163 ConsumeToken(); |
12011 | 12164 |
12012 // Check whether we have a malformed qualified type name if the caller | 12165 // Check whether we have a malformed qualified type name if the caller |
12013 // requests to consume unresolved prefix names: | 12166 // requests to consume unresolved prefix names: |
12014 // If we didn't see a valid prefix but the identifier is followed by | 12167 // If we didn't see a valid prefix but the identifier is followed by |
12015 // a period and another identifier, consume the qualified identifier | 12168 // a period and another identifier, consume the qualified identifier |
12016 // and create a malformed type. | 12169 // and create a malformed type. |
12017 if (consume_unresolved_prefix && | 12170 if (consume_unresolved_prefix && |
12018 prefix->IsNull() && | 12171 prefix->IsNull() && |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12624 TRACE_PARSER("ParseNewOperator"); | 12777 TRACE_PARSER("ParseNewOperator"); |
12625 const intptr_t new_pos = TokenPos(); | 12778 const intptr_t new_pos = TokenPos(); |
12626 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 12779 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
12627 bool is_const = (op_kind == Token::kCONST); | 12780 bool is_const = (op_kind == Token::kCONST); |
12628 if (!IsIdentifier()) { | 12781 if (!IsIdentifier()) { |
12629 ReportError("type name expected"); | 12782 ReportError("type name expected"); |
12630 } | 12783 } |
12631 intptr_t type_pos = TokenPos(); | 12784 intptr_t type_pos = TokenPos(); |
12632 // Can't allocate const objects of a deferred type. | 12785 // Can't allocate const objects of a deferred type. |
12633 const bool allow_deferred_type = !is_const; | 12786 const bool allow_deferred_type = !is_const; |
12634 const bool consume_unresolved_prefix = (LookaheadToken(3) == Token::kLT) || | 12787 const Token::Kind la3 = LookaheadToken(3); |
12635 (LookaheadToken(3) == Token::kPERIOD); | 12788 const bool consume_unresolved_prefix = |
| 12789 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); |
| 12790 |
12636 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); | 12791 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); |
12637 AbstractType& type = AbstractType::Handle(Z, | 12792 AbstractType& type = AbstractType::Handle(Z, |
12638 ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 12793 ParseType(ClassFinalizer::kCanonicalizeWellFormed, |
12639 allow_deferred_type, | 12794 allow_deferred_type, |
12640 consume_unresolved_prefix, | 12795 consume_unresolved_prefix, |
12641 &prefix)); | 12796 &prefix)); |
| 12797 if (CurrentToken() == Token::kHASH) { |
| 12798 ReportError("constructor closurization not yet supported"); |
| 12799 } |
12642 if (FLAG_load_deferred_eagerly && | 12800 if (FLAG_load_deferred_eagerly && |
12643 !prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) { | 12801 !prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) { |
12644 // Add runtime check. | 12802 // Add runtime check. |
12645 Type& malformed_type = Type::Handle(Z); | 12803 Type& malformed_type = Type::Handle(Z); |
12646 malformed_type = ClassFinalizer::NewFinalizedMalformedType( | 12804 malformed_type = ClassFinalizer::NewFinalizedMalformedType( |
12647 Error::Handle(Z), // No previous error. | 12805 Error::Handle(Z), // No previous error. |
12648 script_, | 12806 script_, |
12649 type_pos, | 12807 type_pos, |
12650 "deferred type '%s.%s' is not yet loaded", | 12808 "deferred type '%s.%s' is not yet loaded", |
12651 String::Handle(Z, prefix.name()).ToCString(), | 12809 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(); | 13224 const Token::Kind token = CurrentToken(); |
13067 if (IsFunctionLiteral()) { | 13225 if (IsFunctionLiteral()) { |
13068 // The name of a literal function is visible from inside the function, but | 13226 // 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. | 13227 // must not collide with names in the scope declaring the literal. |
13070 OpenBlock(); | 13228 OpenBlock(); |
13071 primary = ParseFunctionStatement(true); | 13229 primary = ParseFunctionStatement(true); |
13072 CloseBlock(); | 13230 CloseBlock(); |
13073 } else if (IsIdentifier()) { | 13231 } else if (IsIdentifier()) { |
13074 intptr_t qual_ident_pos = TokenPos(); | 13232 intptr_t qual_ident_pos = TokenPos(); |
13075 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 13233 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
| 13234 if (!prefix.IsNull()) { |
| 13235 if (CurrentToken() == Token::kHASH) { |
| 13236 // Closurization of top-level entity in prefix scope. |
| 13237 return new(Z) LiteralNode(qual_ident_pos, prefix); |
| 13238 } else { |
| 13239 ExpectToken(Token::kPERIOD); |
| 13240 } |
| 13241 } |
13076 String& ident = *CurrentLiteral(); | 13242 String& ident = *CurrentLiteral(); |
13077 ConsumeToken(); | 13243 ConsumeToken(); |
13078 if (prefix.IsNull()) { | 13244 if (prefix.IsNull()) { |
13079 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { | 13245 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { |
13080 // Check whether the identifier is a type parameter. | 13246 // Check whether the identifier is a type parameter. |
13081 if (!current_class().IsNull()) { | 13247 if (!current_class().IsNull()) { |
13082 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, | 13248 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, |
13083 current_class().LookupTypeParameter(ident)); | 13249 current_class().LookupTypeParameter(ident)); |
13084 if (!type_param.IsNull()) { | 13250 if (!type_param.IsNull()) { |
13085 return new(Z) PrimaryNode(qual_ident_pos, type_param); | 13251 return new(Z) PrimaryNode(qual_ident_pos, type_param); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13427 } else { | 13593 } else { |
13428 UnexpectedToken(); | 13594 UnexpectedToken(); |
13429 } | 13595 } |
13430 } | 13596 } |
13431 | 13597 |
13432 | 13598 |
13433 void Parser::SkipNewOperator() { | 13599 void Parser::SkipNewOperator() { |
13434 ConsumeToken(); // Skip new or const keyword. | 13600 ConsumeToken(); // Skip new or const keyword. |
13435 if (IsIdentifier()) { | 13601 if (IsIdentifier()) { |
13436 SkipType(false); | 13602 SkipType(false); |
| 13603 SkipIf(Token::kHASH); |
| 13604 if (CurrentToken() == Token::kPERIOD) { |
| 13605 ConsumeToken(); |
| 13606 ExpectIdentifier("identifier expected"); |
| 13607 } |
13437 if (CurrentToken() == Token::kLPAREN) { | 13608 if (CurrentToken() == Token::kLPAREN) { |
13438 SkipActualParameters(); | 13609 SkipActualParameters(); |
13439 return; | 13610 return; |
13440 } | 13611 } |
13441 } | 13612 } |
13442 } | 13613 } |
13443 | 13614 |
13444 | 13615 |
13445 void Parser::SkipStringLiteral() { | 13616 void Parser::SkipStringLiteral() { |
13446 ASSERT(CurrentToken() == Token::kSTRING); | 13617 ASSERT(CurrentToken() == Token::kSTRING); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13545 } else if (current_token == Token::kLPAREN) { | 13716 } else if (current_token == Token::kLPAREN) { |
13546 SkipActualParameters(); | 13717 SkipActualParameters(); |
13547 } else { | 13718 } else { |
13548 break; | 13719 break; |
13549 } | 13720 } |
13550 } | 13721 } |
13551 } | 13722 } |
13552 | 13723 |
13553 void Parser::SkipPostfixExpr() { | 13724 void Parser::SkipPostfixExpr() { |
13554 SkipPrimary(); | 13725 SkipPrimary(); |
| 13726 if (CurrentToken() == Token::kHASH) { |
| 13727 if (IsIdentifier()) { |
| 13728 ConsumeToken(); |
| 13729 SkipIf(Token::kASSIGN); |
| 13730 } else if (Token::CanBeOverloaded(CurrentToken())) { |
| 13731 ConsumeToken(); |
| 13732 } else { |
| 13733 ReportError("identifier or operator expected"); |
| 13734 } |
| 13735 } |
13555 SkipSelectors(); | 13736 SkipSelectors(); |
13556 if (IsIncrementOperator(CurrentToken())) { | 13737 if (IsIncrementOperator(CurrentToken())) { |
13557 ConsumeToken(); | 13738 ConsumeToken(); |
13558 } | 13739 } |
13559 } | 13740 } |
13560 | 13741 |
13561 | 13742 |
13562 void Parser::SkipUnaryExpr() { | 13743 void Parser::SkipUnaryExpr() { |
13563 if (IsPrefixOperator(CurrentToken()) || | 13744 if (IsPrefixOperator(CurrentToken()) || |
13564 IsIncrementOperator(CurrentToken()) || | 13745 IsIncrementOperator(CurrentToken()) || |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13630 void Parser::SkipQualIdent() { | 13811 void Parser::SkipQualIdent() { |
13631 ASSERT(IsIdentifier()); | 13812 ASSERT(IsIdentifier()); |
13632 ConsumeToken(); | 13813 ConsumeToken(); |
13633 if (CurrentToken() == Token::kPERIOD) { | 13814 if (CurrentToken() == Token::kPERIOD) { |
13634 ConsumeToken(); // Consume the kPERIOD token. | 13815 ConsumeToken(); // Consume the kPERIOD token. |
13635 ExpectIdentifier("identifier expected after '.'"); | 13816 ExpectIdentifier("identifier expected after '.'"); |
13636 } | 13817 } |
13637 } | 13818 } |
13638 | 13819 |
13639 } // namespace dart | 13820 } // namespace dart |
OLD | NEW |