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 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
831 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 831 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
832 ASSERT(parsed_function != NULL); | 832 ASSERT(parsed_function != NULL); |
833 const Function& func = parsed_function->function(); | 833 const Function& func = parsed_function->function(); |
834 const Script& script = Script::Handle(zone, func.script()); | 834 const Script& script = Script::Handle(zone, func.script()); |
835 Parser parser(script, parsed_function, func.token_pos()); | 835 Parser parser(script, parsed_function, func.token_pos()); |
836 SequenceNode* node_sequence = NULL; | 836 SequenceNode* node_sequence = NULL; |
837 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); | 837 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); |
838 switch (func.kind()) { | 838 switch (func.kind()) { |
839 case RawFunction::kClosureFunction: | 839 case RawFunction::kClosureFunction: |
840 if (func.IsImplicitClosureFunction()) { | 840 if (func.IsImplicitClosureFunction()) { |
841 parser.SkipFunctionPreamble(); | |
842 node_sequence = | 841 node_sequence = |
843 parser.ParseImplicitClosure(func, &default_parameter_values); | 842 parser.ParseImplicitClosure(func, &default_parameter_values); |
844 break; | 843 break; |
845 } | 844 } |
846 // Fall-through: Handle non-implicit closures. | 845 // Fall-through: Handle non-implicit closures. |
847 case RawFunction::kRegularFunction: | 846 case RawFunction::kRegularFunction: |
848 case RawFunction::kGetterFunction: | 847 case RawFunction::kGetterFunction: |
849 case RawFunction::kSetterFunction: | 848 case RawFunction::kSetterFunction: |
850 case RawFunction::kConstructor: | 849 case RawFunction::kConstructor: |
851 // The call to a redirecting factory is redirected. | 850 // The call to a redirecting factory is redirected. |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1272 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 1271 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
1273 current_block_->statements->Add(store_field); | 1272 current_block_->statements->Add(store_field); |
1274 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 1273 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); |
1275 return CloseBlock(); | 1274 return CloseBlock(); |
1276 } | 1275 } |
1277 | 1276 |
1278 | 1277 |
1279 SequenceNode* Parser::ParseImplicitClosure(const Function& func, | 1278 SequenceNode* Parser::ParseImplicitClosure(const Function& func, |
1280 Array* default_values) { | 1279 Array* default_values) { |
1281 TRACE_PARSER("ParseImplicitClosure"); | 1280 TRACE_PARSER("ParseImplicitClosure"); |
1282 | |
1283 intptr_t token_pos = func.token_pos(); | 1281 intptr_t token_pos = func.token_pos(); |
1284 | 1282 |
1285 OpenFunctionBlock(func); | 1283 OpenFunctionBlock(func); |
1286 | 1284 |
1287 ParamList params; | 1285 ParamList params; |
1288 | |
1289 params.AddFinalParameter( | 1286 params.AddFinalParameter( |
1290 token_pos, | 1287 token_pos, |
1291 &Symbols::ClosureParameter(), | 1288 &Symbols::ClosureParameter(), |
1292 &Type::ZoneHandle(Type::DynamicType())); | 1289 &Type::ZoneHandle(Type::DynamicType())); |
1293 | 1290 |
1294 const bool allow_explicit_default_values = true; | |
1295 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | |
1296 SetupDefaultsForOptionalParams(¶ms, default_values); | |
1297 | |
1298 // Getters can't be closurized. If supported, they need special | |
1299 // handling of the parameters as in ParseFunc. | |
1300 const Function& parent = Function::ZoneHandle(func.parent_function()); | 1291 const Function& parent = Function::ZoneHandle(func.parent_function()); |
1301 ASSERT(!parent.IsGetterFunction()); | 1292 if (parent.IsImplicitSetterFunction()) { |
1293 const intptr_t ident_pos = func.token_pos(); | |
1294 ASSERT(IsIdentifier()); | |
1295 const String& field_name = *CurrentLiteral(); | |
1296 const Class& field_class = Class::ZoneHandle(Z, parent.Owner()); | |
1297 const Field& field = | |
1298 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | |
1299 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | |
1300 params.AddFinalParameter(ident_pos, | |
1301 &Symbols::Value(), | |
1302 &field_type); | |
1303 ASSERT(func.num_fixed_parameters() == 2); // closure, value. | |
1304 } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) { | |
1305 const bool allow_explicit_default_values = true; | |
1306 SkipFunctionPreamble(); | |
1307 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | |
1308 SetupDefaultsForOptionalParams(¶ms, default_values); | |
1309 } | |
1302 | 1310 |
1303 // Populate function scope with the formal parameters. | 1311 // Populate function scope with the formal parameters. |
1304 LocalScope* scope = current_block_->scope; | 1312 LocalScope* scope = current_block_->scope; |
1305 AddFormalParamsToScope(¶ms, scope); | 1313 AddFormalParamsToScope(¶ms, scope); |
1306 | 1314 |
1307 ArgumentListNode* func_args = new ArgumentListNode(token_pos); | 1315 ArgumentListNode* func_args = new ArgumentListNode(token_pos); |
1308 if (!func.is_static()) { | 1316 if (!func.is_static()) { |
1309 func_args->Add(LoadReceiver(token_pos)); | 1317 func_args->Add(LoadReceiver(token_pos)); |
1310 } | 1318 } |
1311 // Skip implicit parameter at 0. | 1319 // Skip implicit parameter at 0. |
(...skipping 2104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3416 } while (CurrentToken() == Token::kCOMMA); | 3424 } while (CurrentToken() == Token::kCOMMA); |
3417 } | 3425 } |
3418 | 3426 |
3419 | 3427 |
3420 // If the current identifier is a library prefix followed by a period, | 3428 // If the current identifier is a library prefix followed by a period, |
3421 // consume the identifier and period, and return the resolved library | 3429 // consume the identifier and period, and return the resolved library |
3422 // prefix. | 3430 // prefix. |
3423 RawLibraryPrefix* Parser::ParsePrefix() { | 3431 RawLibraryPrefix* Parser::ParsePrefix() { |
3424 ASSERT(IsIdentifier()); | 3432 ASSERT(IsIdentifier()); |
3425 // A library prefix can never stand by itself. It must be followed by | 3433 // A library prefix can never stand by itself. It must be followed by |
3426 // a period. | 3434 // a period or a hash mark (for closurization). |
3427 if (LookaheadToken(1) != Token::kPERIOD) { | 3435 Token::Kind next_token = LookaheadToken(1); |
3436 if ((next_token != Token::kPERIOD) && (next_token != Token::kHASH)) { | |
3428 return LibraryPrefix::null(); | 3437 return LibraryPrefix::null(); |
3429 } | 3438 } |
3430 const String& ident = *CurrentLiteral(); | 3439 const String& ident = *CurrentLiteral(); |
3431 | 3440 |
3432 // It is relatively fast to look up a name in the library dictionary, | 3441 // It is relatively fast to look up a name in the library dictionary, |
3433 // compared to searching the nested local scopes. Look up the name | 3442 // compared to searching the nested local scopes. Look up the name |
3434 // in the library scope and return in the common case where ident is | 3443 // in the library scope and return in the common case where ident is |
3435 // not a library prefix. | 3444 // not a library prefix. |
3436 LibraryPrefix& prefix = | 3445 LibraryPrefix& prefix = |
3437 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident)); | 3446 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident)); |
3438 if (prefix.IsNull()) { | 3447 if (prefix.IsNull()) { |
3439 return LibraryPrefix::null(); | 3448 return LibraryPrefix::null(); |
3440 } | 3449 } |
3441 | 3450 |
3442 // A library prefix with the name exists. Now check whether it is | 3451 // A library prefix with the name exists. Now check whether it is |
3443 // shadowed by a local definition. | 3452 // shadowed by a local definition. |
3444 if (!is_top_level_ && | 3453 if (!is_top_level_ && |
3445 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { | 3454 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { |
3446 return LibraryPrefix::null(); | 3455 return LibraryPrefix::null(); |
3447 } | 3456 } |
3448 // Check whether the identifier is shadowed by a type parameter. | 3457 // Check whether the identifier is shadowed by a type parameter. |
3449 ASSERT(!current_class().IsNull()); | 3458 ASSERT(!current_class().IsNull()); |
3450 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { | 3459 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { |
3451 return LibraryPrefix::null(); | 3460 return LibraryPrefix::null(); |
3452 } | 3461 } |
3453 | 3462 |
3454 // We have a name that is not shadowed, followed by a period. | 3463 // We have a name that is not shadowed, followed by a period or #. |
3455 // Consume the identifier and the period. | 3464 // Consume the identifier, let the caller consume the . or #. |
3456 ConsumeToken(); | |
3457 ASSERT(CurrentToken() == Token::kPERIOD); // We checked above. | |
3458 ConsumeToken(); | 3465 ConsumeToken(); |
3459 return prefix.raw(); | 3466 return prefix.raw(); |
3460 } | 3467 } |
3461 | 3468 |
3462 | 3469 |
3463 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 3470 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
3464 TRACE_PARSER("ParseMethodOrConstructor"); | 3471 TRACE_PARSER("ParseMethodOrConstructor"); |
3465 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); | 3472 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); |
3466 ASSERT(method->type != NULL); | 3473 ASSERT(method->type != NULL); |
3467 ASSERT(current_member_ == method); | 3474 ASSERT(current_member_ == method); |
(...skipping 7819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11287 } | 11294 } |
11288 // Done parsing selectors. | 11295 // Done parsing selectors. |
11289 return left; | 11296 return left; |
11290 } | 11297 } |
11291 ASSERT(selector != NULL); | 11298 ASSERT(selector != NULL); |
11292 left = selector; | 11299 left = selector; |
11293 } | 11300 } |
11294 } | 11301 } |
11295 | 11302 |
11296 | 11303 |
11304 // Closurization e#m of getter, setter, method or operator. | |
11305 AstNode* Parser::ParseClosurization(AstNode* primary) { | |
11306 ExpectToken(Token::kHASH); | |
11307 intptr_t property_pos = TokenPos(); | |
11308 bool is_setter_name = false; | |
11309 | |
11310 String& extractor_name = String::ZoneHandle(Z); | |
11311 if (IsIdentifier()) { | |
11312 extractor_name = CurrentLiteral()->raw(); | |
11313 ConsumeToken(); | |
11314 if (CurrentToken() == Token::kASSIGN) { | |
11315 ConsumeToken(); | |
11316 is_setter_name = true; | |
11317 } | |
11318 } else if (Token::CanBeOverloaded(CurrentToken())) { | |
11319 extractor_name = String::New(Token::Str(CurrentToken())); | |
11320 ConsumeToken(); | |
11321 } else { | |
11322 ReportError("identifier or operator expected"); | |
11323 } | |
11324 | |
11325 if (primary->IsPrimaryNode() && primary->AsPrimaryNode()->IsSuper()) { | |
11326 // TODO(hausner): implement super#m | |
11327 ReportError("closurization of super method not yet supported"); | |
11328 } | |
11329 | |
11330 // Handle closurization of top-level names from library prefixes, P#m | |
11331 if (primary->IsLiteralNode() && | |
11332 primary->AsLiteralNode()->literal().IsLibraryPrefix()) { | |
11333 const LibraryPrefix& prefix = | |
11334 LibraryPrefix::Cast(primary->AsLiteralNode()->literal()); | |
11335 Object& obj = Object::Handle(Z); | |
11336 const bool is_private_name = | |
11337 (extractor_name.CharAt(0) == Library::kPrivateIdentifierStart); | |
11338 if (!is_private_name) { | |
11339 // Private names are not exported by libraries. The name mangling | |
11340 // of private names with a library-specific suffix usually ensures | |
11341 // that _x in library A is not found when looked up from library B. | |
11342 // In the pathological case where a library imports itself with | |
11343 // a prefix, the name mangling does not help in hiding the private | |
11344 // name, so we explicitly prevent lookup of private names here. | |
11345 obj = prefix.LookupObject(extractor_name); | |
11346 } | |
11347 if (!prefix.is_loaded() && (parsed_function() != NULL)) { | |
11348 // Remember that this function depends on an import prefix of an | |
11349 // unloaded deferred library. | |
11350 parsed_function()->AddDeferredPrefix(prefix); | |
11351 } | |
11352 | |
11353 if (obj.IsFunction()) { | |
11354 const Function& func = Function::Cast(obj); | |
11355 if (!func.IsSetterFunction() || is_setter_name) { | |
11356 return CreateImplicitClosureNode(func, property_pos, NULL); | |
11357 } | |
11358 } else if (obj.IsField()) { | |
11359 const Field& field = Field::Cast(obj); | |
11360 if (is_setter_name && !field.is_final()) { | |
11361 Instance& setter_closure = Instance::ZoneHandle(field.SetterClosure()); | |
Ivan Posva
2015/07/17 08:35:42
These closures are not cached anywhere, which mean
hausner
2015/07/17 17:53:51
They get collected if they are not stored anywhere
| |
11362 return new(Z) LiteralNode(property_pos, setter_closure); | |
11363 } | |
11364 if (!is_setter_name) { | |
11365 Instance& getter_closure = Instance::ZoneHandle(field.GetterClosure()); | |
11366 return new(Z) LiteralNode(property_pos, getter_closure); | |
11367 } | |
11368 } | |
11369 return ThrowNoSuchMethodError(property_pos, | |
11370 current_class(), | |
11371 extractor_name, | |
11372 NULL, // No arguments. | |
11373 InvocationMirror::kTopLevel, | |
11374 is_setter_name | |
11375 ? InvocationMirror::kSetter | |
11376 : InvocationMirror::kMethod, | |
11377 NULL); // No existing function. | |
11378 } | |
11379 | |
11380 // Handle closurization of static properties of classes, C#n. | |
11381 if (primary->IsPrimaryNode() && | |
11382 primary->AsPrimaryNode()->primary().IsClass()) { | |
11383 const Class& cls = Class::Cast(primary->AsPrimaryNode()->primary()); | |
11384 const Field& field = | |
11385 Field::Handle(Z, cls.LookupStaticField(extractor_name)); | |
11386 if (!field.IsNull()) { | |
11387 if (is_setter_name) { | |
11388 extractor_name = Field::SetterName(extractor_name); | |
11389 if (!field.is_final()) { | |
11390 const Instance& setter_closure = | |
11391 Instance::ZoneHandle(Z, field.SetterClosure()); | |
11392 return new(Z) LiteralNode(property_pos, setter_closure); | |
Florian Schneider
2015/07/17 09:42:02
My suggestion would be to do sth. like
return Cre
hausner
2015/07/17 17:53:51
Yes, I was considering this. I am hoping that we c
| |
11393 } | |
11394 } | |
11395 if (!is_setter_name) { | |
11396 const Instance& getter_closure = | |
11397 Instance::ZoneHandle(Z, field.GetterClosure()); | |
11398 return new(Z) LiteralNode(property_pos, getter_closure); | |
11399 } | |
11400 } else { | |
11401 Function& func = Function::Handle(Z); | |
11402 if (is_setter_name) { | |
11403 extractor_name = Field::SetterName(extractor_name); | |
11404 func = cls.LookupStaticFunction(extractor_name); | |
11405 } else { | |
11406 func = cls.LookupStaticFunction(extractor_name); | |
11407 if (func.IsNull()) { | |
11408 const String& getter_name = | |
11409 String::Handle(Z, Field::GetterName(extractor_name)); | |
11410 func = cls.LookupStaticFunction(getter_name); | |
11411 } | |
11412 } | |
11413 if (!func.IsNull()) { | |
11414 return CreateImplicitClosureNode(func, property_pos, NULL); | |
11415 } | |
11416 } | |
11417 return ThrowNoSuchMethodError(property_pos, | |
11418 cls, | |
11419 extractor_name, | |
11420 NULL, // No arguments. | |
11421 InvocationMirror::kStatic, | |
11422 is_setter_name | |
11423 ? InvocationMirror::kSetter | |
11424 : InvocationMirror::kMethod, | |
11425 NULL); // No existing function. | |
11426 } | |
11427 | |
11428 // Closurization of instance getter, setter, method or operator. | |
11429 if (is_setter_name) { | |
11430 extractor_name = String::Concat(Symbols::SetterPrefix(), extractor_name); | |
11431 } | |
11432 extractor_name = String::Concat(Symbols::HashMark(), extractor_name); | |
11433 extractor_name = Symbols::New(extractor_name); | |
11434 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); | |
11435 } | |
11436 | |
11437 | |
11297 AstNode* Parser::ParsePostfixExpr() { | 11438 AstNode* Parser::ParsePostfixExpr() { |
11298 TRACE_PARSER("ParsePostfixExpr"); | 11439 TRACE_PARSER("ParsePostfixExpr"); |
11299 String* expr_ident = | 11440 String* expr_ident = |
11300 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11441 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
11301 const intptr_t expr_pos = TokenPos(); | 11442 const intptr_t expr_pos = TokenPos(); |
11302 AstNode* expr = ParsePrimary(); | 11443 AstNode* expr = ParsePrimary(); |
11303 expr = ParseSelectors(expr, false); | 11444 if (CurrentToken() == Token::kHASH) { |
11445 expr = ParseClosurization(expr); | |
11446 } else { | |
11447 expr = ParseSelectors(expr, false); | |
11448 } | |
11304 if (IsIncrementOperator(CurrentToken())) { | 11449 if (IsIncrementOperator(CurrentToken())) { |
11305 TRACE_PARSER("IncrementOperator"); | 11450 TRACE_PARSER("IncrementOperator"); |
11306 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 11451 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
11307 ReportError(expr_pos, "expression is not assignable"); | 11452 ReportError(expr_pos, "expression is not assignable"); |
11308 } | 11453 } |
11309 Token::Kind incr_op = CurrentToken(); | 11454 Token::Kind incr_op = CurrentToken(); |
11310 ConsumeToken(); | 11455 ConsumeToken(); |
11311 // Not prefix. | 11456 // Not prefix. |
11312 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11457 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
11313 LocalVariable* temp = let_expr->AddInitializer(expr); | 11458 LocalVariable* temp = let_expr->AddInitializer(expr); |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11966 | 12111 |
11967 if (finalization == ClassFinalizer::kIgnore) { | 12112 if (finalization == ClassFinalizer::kIgnore) { |
11968 if (!is_top_level_ && (current_block_ != NULL)) { | 12113 if (!is_top_level_ && (current_block_ != NULL)) { |
11969 // Add the library prefix or type class name to the list of referenced | 12114 // Add the library prefix or type class name to the list of referenced |
11970 // names of this scope, even if the type is ignored. | 12115 // names of this scope, even if the type is ignored. |
11971 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); | 12116 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); |
11972 } | 12117 } |
11973 SkipQualIdent(); | 12118 SkipQualIdent(); |
11974 } else { | 12119 } else { |
11975 prefix = ParsePrefix(); | 12120 prefix = ParsePrefix(); |
12121 if (!prefix.IsNull()) { | |
12122 ExpectToken(Token::kPERIOD); | |
12123 } | |
11976 type_name = CurrentLiteral()->raw(); | 12124 type_name = CurrentLiteral()->raw(); |
11977 ConsumeToken(); | 12125 ConsumeToken(); |
11978 | 12126 |
11979 // Check whether we have a malformed qualified type name if the caller | 12127 // Check whether we have a malformed qualified type name if the caller |
11980 // requests to consume unresolved prefix names: | 12128 // requests to consume unresolved prefix names: |
11981 // If we didn't see a valid prefix but the identifier is followed by | 12129 // If we didn't see a valid prefix but the identifier is followed by |
11982 // a period and another identifier, consume the qualified identifier | 12130 // a period and another identifier, consume the qualified identifier |
11983 // and create a malformed type. | 12131 // and create a malformed type. |
11984 if (consume_unresolved_prefix && | 12132 if (consume_unresolved_prefix && |
11985 prefix.IsNull() && | 12133 prefix.IsNull() && |
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12590 TRACE_PARSER("ParseNewOperator"); | 12738 TRACE_PARSER("ParseNewOperator"); |
12591 const intptr_t new_pos = TokenPos(); | 12739 const intptr_t new_pos = TokenPos(); |
12592 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 12740 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
12593 bool is_const = (op_kind == Token::kCONST); | 12741 bool is_const = (op_kind == Token::kCONST); |
12594 if (!IsIdentifier()) { | 12742 if (!IsIdentifier()) { |
12595 ReportError("type name expected"); | 12743 ReportError("type name expected"); |
12596 } | 12744 } |
12597 intptr_t type_pos = TokenPos(); | 12745 intptr_t type_pos = TokenPos(); |
12598 // Can't allocate const objects of a deferred type. | 12746 // Can't allocate const objects of a deferred type. |
12599 const bool allow_deferred_type = !is_const; | 12747 const bool allow_deferred_type = !is_const; |
12600 const bool consume_unresolved_prefix = (LookaheadToken(3) == Token::kLT) || | 12748 const Token::Kind la3 = LookaheadToken(3); |
12601 (LookaheadToken(3) == Token::kPERIOD); | 12749 const bool consume_unresolved_prefix = |
12750 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); | |
12602 AbstractType& type = AbstractType::Handle(Z, | 12751 AbstractType& type = AbstractType::Handle(Z, |
12603 ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 12752 ParseType(ClassFinalizer::kCanonicalizeWellFormed, |
12604 allow_deferred_type, | 12753 allow_deferred_type, |
12605 consume_unresolved_prefix)); | 12754 consume_unresolved_prefix)); |
12755 if (CurrentToken() == Token::kHASH) { | |
12756 ReportError("constructor closurization not yet supported"); | |
12757 } | |
12606 // In case the type is malformed, throw a dynamic type error after finishing | 12758 // In case the type is malformed, throw a dynamic type error after finishing |
12607 // parsing the instance creation expression. | 12759 // parsing the instance creation expression. |
12608 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { | 12760 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { |
12609 // Replace the type with a malformed type. | 12761 // Replace the type with a malformed type. |
12610 type = ClassFinalizer::NewFinalizedMalformedType( | 12762 type = ClassFinalizer::NewFinalizedMalformedType( |
12611 Error::Handle(Z), // No previous error. | 12763 Error::Handle(Z), // No previous error. |
12612 script_, | 12764 script_, |
12613 type_pos, | 12765 type_pos, |
12614 "%s'%s' cannot be instantiated", | 12766 "%s'%s' cannot be instantiated", |
12615 type.IsTypeParameter() ? "type parameter " : "", | 12767 type.IsTypeParameter() ? "type parameter " : "", |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13014 const Token::Kind token = CurrentToken(); | 13166 const Token::Kind token = CurrentToken(); |
13015 if (IsFunctionLiteral()) { | 13167 if (IsFunctionLiteral()) { |
13016 // The name of a literal function is visible from inside the function, but | 13168 // The name of a literal function is visible from inside the function, but |
13017 // must not collide with names in the scope declaring the literal. | 13169 // must not collide with names in the scope declaring the literal. |
13018 OpenBlock(); | 13170 OpenBlock(); |
13019 primary = ParseFunctionStatement(true); | 13171 primary = ParseFunctionStatement(true); |
13020 CloseBlock(); | 13172 CloseBlock(); |
13021 } else if (IsIdentifier()) { | 13173 } else if (IsIdentifier()) { |
13022 intptr_t qual_ident_pos = TokenPos(); | 13174 intptr_t qual_ident_pos = TokenPos(); |
13023 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 13175 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
13176 if (!prefix.IsNull()) { | |
13177 if (CurrentToken() == Token::kHASH) { | |
13178 // Closurization of top-level entity in prefix scope. | |
13179 return new(Z) LiteralNode(qual_ident_pos, prefix); | |
13180 } else { | |
13181 ExpectToken(Token::kPERIOD); | |
13182 } | |
13183 } | |
13024 String& ident = *CurrentLiteral(); | 13184 String& ident = *CurrentLiteral(); |
13025 ConsumeToken(); | 13185 ConsumeToken(); |
13026 if (prefix.IsNull()) { | 13186 if (prefix.IsNull()) { |
13027 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { | 13187 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { |
13028 // Check whether the identifier is a type parameter. | 13188 // Check whether the identifier is a type parameter. |
13029 if (!current_class().IsNull()) { | 13189 if (!current_class().IsNull()) { |
13030 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, | 13190 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, |
13031 current_class().LookupTypeParameter(ident)); | 13191 current_class().LookupTypeParameter(ident)); |
13032 if (!type_param.IsNull()) { | 13192 if (!type_param.IsNull()) { |
13033 return new(Z) PrimaryNode(qual_ident_pos, type_param); | 13193 return new(Z) PrimaryNode(qual_ident_pos, type_param); |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13556 void Parser::SkipQualIdent() { | 13716 void Parser::SkipQualIdent() { |
13557 ASSERT(IsIdentifier()); | 13717 ASSERT(IsIdentifier()); |
13558 ConsumeToken(); | 13718 ConsumeToken(); |
13559 if (CurrentToken() == Token::kPERIOD) { | 13719 if (CurrentToken() == Token::kPERIOD) { |
13560 ConsumeToken(); // Consume the kPERIOD token. | 13720 ConsumeToken(); // Consume the kPERIOD token. |
13561 ExpectIdentifier("identifier expected after '.'"); | 13721 ExpectIdentifier("identifier expected after '.'"); |
13562 } | 13722 } |
13563 } | 13723 } |
13564 | 13724 |
13565 } // namespace dart | 13725 } // namespace dart |
OLD | NEW |