Chromium Code Reviews| 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 |