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 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 |