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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 2301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2312 // An identifier cannot be resolved in a local scope when top level parsing. | 2312 // An identifier cannot be resolved in a local scope when top level parsing. |
| 2313 if (is_top_level_ || | 2313 if (is_top_level_ || |
| 2314 !ResolveIdentInLocalScope(qual_ident->ident_pos, | 2314 !ResolveIdentInLocalScope(qual_ident->ident_pos, |
| 2315 *(qual_ident->ident), | 2315 *(qual_ident->ident), |
| 2316 NULL)) { | 2316 NULL)) { |
| 2317 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 2317 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
| 2318 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); | 2318 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); |
| 2319 if (!lib_prefix.IsNull()) { | 2319 if (!lib_prefix.IsNull()) { |
| 2320 // We have a library prefix qualified identifier, unless the prefix is | 2320 // We have a library prefix qualified identifier, unless the prefix is |
| 2321 // shadowed by a type parameter in scope. | 2321 // shadowed by a type parameter in scope. |
| 2322 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 2322 if (current_class().IsNull() || |
| 2323 if (scope_class.IsNull() || | 2323 (current_class().LookupTypeParameter(*(qual_ident->ident), |
| 2324 (scope_class.LookupTypeParameter(*(qual_ident->ident), | 2324 TokenPos()) == |
| 2325 TokenPos()) == | |
| 2326 TypeParameter::null())) { | 2325 TypeParameter::null())) { |
| 2327 ConsumeToken(); // Consume the kPERIOD token. | 2326 ConsumeToken(); // Consume the kPERIOD token. |
| 2328 qual_ident->lib_prefix = &lib_prefix; | 2327 qual_ident->lib_prefix = &lib_prefix; |
| 2329 qual_ident->ident_pos = TokenPos(); | 2328 qual_ident->ident_pos = TokenPos(); |
| 2330 qual_ident->ident = | 2329 qual_ident->ident = |
| 2331 ExpectIdentifier("identifier expected after '.'"); | 2330 ExpectIdentifier("identifier expected after '.'"); |
| 2332 } | 2331 } |
| 2333 } | 2332 } |
| 2334 } | 2333 } |
| 2335 } | 2334 } |
| (...skipping 5232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7568 const String& unresolved_class_name = | 7567 const String& unresolved_class_name = |
| 7569 String::Handle(unresolved_class.ident()); | 7568 String::Handle(unresolved_class.ident()); |
| 7570 Class& resolved_type_class = Class::Handle(); | 7569 Class& resolved_type_class = Class::Handle(); |
| 7571 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 7570 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
| 7572 if (!scope_class.IsNull()) { | 7571 if (!scope_class.IsNull()) { |
| 7573 // First check if the type is a type parameter of the given scope class. | 7572 // First check if the type is a type parameter of the given scope class. |
| 7574 const TypeParameter& type_parameter = TypeParameter::Handle( | 7573 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 7575 scope_class.LookupTypeParameter(unresolved_class_name, | 7574 scope_class.LookupTypeParameter(unresolved_class_name, |
| 7576 type->token_pos())); | 7575 type->token_pos())); |
| 7577 if (!type_parameter.IsNull()) { | 7576 if (!type_parameter.IsNull()) { |
| 7577 // A type parameter is considered to be a malformed type when | |
| 7578 // referenced by a static member. | |
| 7579 if (ParsingStaticMember()) { | |
| 7580 ASSERT(scope_class.raw() == current_class().raw()); | |
| 7581 *type = ClassFinalizer::NewFinalizedMalformedType( | |
| 7582 scope_class, | |
| 7583 type->token_pos(), | |
| 7584 "type parameter '%s' cannot be referenced " | |
| 7585 "from static member", | |
| 7586 String::Handle(type_parameter.name()).ToCString()); | |
| 7587 return; | |
| 7588 } | |
| 7589 // TODO(regis): Should this be a malformed type as well? | |
| 7578 // A type parameter cannot be parameterized, so report an error if | 7590 // A type parameter cannot be parameterized, so report an error if |
| 7579 // type arguments have previously been parsed. | 7591 // type arguments have previously been parsed. |
| 7580 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { | 7592 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { |
| 7581 ErrorMsg(type_parameter.token_pos(), | 7593 ErrorMsg(type_parameter.token_pos(), |
| 7582 "type parameter '%s' cannot be parameterized", | 7594 "type parameter '%s' cannot be parameterized", |
| 7583 String::Handle(type_parameter.name()).ToCString()); | 7595 String::Handle(type_parameter.name()).ToCString()); |
| 7584 } | 7596 } |
| 7585 *type = type_parameter.raw(); | 7597 *type = type_parameter.raw(); |
| 7586 return; | 7598 return; |
| 7587 } | 7599 } |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7731 // Fields are not accessible from a static function, except from a | 7743 // Fields are not accessible from a static function, except from a |
| 7732 // constructor, which is considered as non-static by the compiler. | 7744 // constructor, which is considered as non-static by the compiler. |
| 7733 if (current_function().is_static()) { | 7745 if (current_function().is_static()) { |
| 7734 ErrorMsg(field_pos, | 7746 ErrorMsg(field_pos, |
| 7735 "cannot access instance field '%s' from a static function", | 7747 "cannot access instance field '%s' from a static function", |
| 7736 field_name.ToCString()); | 7748 field_name.ToCString()); |
| 7737 } | 7749 } |
| 7738 } | 7750 } |
| 7739 | 7751 |
| 7740 | 7752 |
| 7741 // If type parameters are currently in scope, return their declaring class, | 7753 bool Parser::ParsingStaticMember() const { |
| 7742 // otherwise return null. | |
| 7743 RawClass* Parser::TypeParametersScopeClass() const { | |
| 7744 // Type parameters cannot be referred to from a static function, except from | |
| 7745 // a constructor or from a factory. | |
| 7746 // A constructor is considered as non-static by the compiler. | |
| 7747 if (is_top_level_) { | 7754 if (is_top_level_) { |
| 7748 if ((current_member_ == NULL) || | 7755 return (current_member_ != NULL) && |
| 7749 (current_member_->has_factory || !current_member_->has_static)) { | 7756 current_member_->has_static && !current_member_->has_factory; |
| 7750 return current_class().raw(); | |
| 7751 } | |
| 7752 } else { | |
| 7753 if (!current_function().IsNull()) { | |
| 7754 Function& outer_function = Function::Handle(current_function().raw()); | |
| 7755 while (outer_function.IsLocalFunction()) { | |
| 7756 outer_function = outer_function.parent_function(); | |
| 7757 } | |
| 7758 if (outer_function.IsFactory() || !outer_function.is_static()) { | |
| 7759 return current_class().raw(); | |
| 7760 } | |
| 7761 } | |
| 7762 } | 7757 } |
| 7763 return Class::null(); | 7758 ASSERT(!current_function().IsNull()); |
| 7759 Function& outer_function = Function::Handle(current_function().raw()); | |
|
hausner
2012/10/05 19:57:45
You could have a special case where you don't allo
regis
2012/10/05 20:28:40
Good point.
I optimized Function::IsInFactoryScope
| |
| 7760 while (outer_function.IsLocalFunction()) { | |
| 7761 outer_function = outer_function.parent_function(); | |
| 7762 } | |
| 7763 return outer_function.is_static() && !outer_function.IsFactory(); | |
| 7764 } | 7764 } |
| 7765 | 7765 |
| 7766 | 7766 |
| 7767 const Type* Parser::ReceiverType(intptr_t type_pos) const { | 7767 const Type* Parser::ReceiverType(intptr_t type_pos) const { |
| 7768 ASSERT(!current_class().IsNull()); | 7768 ASSERT(!current_class().IsNull()); |
| 7769 TypeArguments& type_arguments = TypeArguments::Handle(); | 7769 TypeArguments& type_arguments = TypeArguments::Handle(); |
| 7770 if (current_class().NumTypeParameters() > 0) { | 7770 if (current_class().NumTypeParameters() > 0) { |
| 7771 type_arguments = current_class().type_parameters(); | 7771 type_arguments = current_class().type_parameters(); |
| 7772 } | 7772 } |
| 7773 Type& type = Type::ZoneHandle( | 7773 Type& type = Type::ZoneHandle( |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8282 const String& ident, | 8282 const String& ident, |
| 8283 bool allow_closure_names) { | 8283 bool allow_closure_names) { |
| 8284 TRACE_PARSER("ResolveIdent"); | 8284 TRACE_PARSER("ResolveIdent"); |
| 8285 // First try to find the variable in the local scope (block scope or | 8285 // First try to find the variable in the local scope (block scope or |
| 8286 // class scope). | 8286 // class scope). |
| 8287 AstNode* resolved = NULL; | 8287 AstNode* resolved = NULL; |
| 8288 ResolveIdentInLocalScope(ident_pos, ident, &resolved); | 8288 ResolveIdentInLocalScope(ident_pos, ident, &resolved); |
| 8289 if (resolved == NULL) { | 8289 if (resolved == NULL) { |
| 8290 // Check whether the identifier is a type parameter. Type parameters | 8290 // Check whether the identifier is a type parameter. Type parameters |
| 8291 // can never be used in primary expressions. | 8291 // can never be used in primary expressions. |
| 8292 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 8292 if (!current_class().IsNull()) { |
| 8293 if (!scope_class.IsNull()) { | |
| 8294 TypeParameter& type_param = TypeParameter::Handle( | 8293 TypeParameter& type_param = TypeParameter::Handle( |
| 8295 scope_class.LookupTypeParameter(ident, ident_pos)); | 8294 current_class().LookupTypeParameter(ident, ident_pos)); |
| 8296 if (!type_param.IsNull()) { | 8295 if (!type_param.IsNull()) { |
| 8297 String& type_param_name = String::Handle(type_param.name()); | 8296 String& type_param_name = String::Handle(type_param.name()); |
| 8298 ErrorMsg(ident_pos, "illegal use of type parameter %s", | 8297 ErrorMsg(ident_pos, "illegal use of type parameter %s", |
| 8299 type_param_name.ToCString()); | 8298 type_param_name.ToCString()); |
| 8300 } | 8299 } |
| 8301 } | 8300 } |
| 8302 // Not found in the local scope, and the name is not a type parameter. | 8301 // Not found in the local scope, and the name is not a type parameter. |
| 8303 // Try finding the variable in the library scope (current library | 8302 // Try finding the variable in the library scope (current library |
| 8304 // and all libraries imported by it without a library prefix). | 8303 // and all libraries imported by it without a library prefix). |
| 8305 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); | 8304 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8379 // In production mode, malformed type arguments are mapped to Dynamic. | 8378 // In production mode, malformed type arguments are mapped to Dynamic. |
| 8380 // In checked mode, a type with malformed type arguments is malformed. | 8379 // In checked mode, a type with malformed type arguments is malformed. |
| 8381 if (FLAG_enable_type_checks && !malformed_error.IsNull()) { | 8380 if (FLAG_enable_type_checks && !malformed_error.IsNull()) { |
| 8382 Type& parameterized_type = Type::Handle(); | 8381 Type& parameterized_type = Type::Handle(); |
| 8383 parameterized_type ^= type.raw(); | 8382 parameterized_type ^= type.raw(); |
| 8384 parameterized_type.set_type_class(Class::Handle(Object::dynamic_class())); | 8383 parameterized_type.set_type_class(Class::Handle(Object::dynamic_class())); |
| 8385 parameterized_type.set_arguments(AbstractTypeArguments::Handle()); | 8384 parameterized_type.set_arguments(AbstractTypeArguments::Handle()); |
| 8386 parameterized_type.set_malformed_error(malformed_error); | 8385 parameterized_type.set_malformed_error(malformed_error); |
| 8387 } | 8386 } |
| 8388 if (finalization >= ClassFinalizer::kTryResolve) { | 8387 if (finalization >= ClassFinalizer::kTryResolve) { |
| 8389 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 8388 ResolveTypeFromClass(current_class(), finalization, &type); |
| 8390 ResolveTypeFromClass(scope_class, finalization, &type); | |
| 8391 if (finalization >= ClassFinalizer::kCanonicalize) { | 8389 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 8392 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 8390 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
| 8393 } | 8391 } |
| 8394 } | 8392 } |
| 8395 return type.raw(); | 8393 return type.raw(); |
| 8396 } | 8394 } |
| 8397 | 8395 |
| 8398 | 8396 |
| 8399 void Parser::CheckConstructorCallTypeArguments( | 8397 void Parser::CheckConstructorCallTypeArguments( |
| 8400 intptr_t pos, Function& constructor, | 8398 intptr_t pos, Function& constructor, |
| (...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9285 CloseBlock(); | 9283 CloseBlock(); |
| 9286 } else if (IsIdentifier()) { | 9284 } else if (IsIdentifier()) { |
| 9287 QualIdent qual_ident; | 9285 QualIdent qual_ident; |
| 9288 ParseQualIdent(&qual_ident); | 9286 ParseQualIdent(&qual_ident); |
| 9289 if (qual_ident.lib_prefix == NULL) { | 9287 if (qual_ident.lib_prefix == NULL) { |
| 9290 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, | 9288 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, |
| 9291 *qual_ident.ident, | 9289 *qual_ident.ident, |
| 9292 &primary)) { | 9290 &primary)) { |
| 9293 // Check whether the identifier is a type parameter. Type parameters | 9291 // Check whether the identifier is a type parameter. Type parameters |
| 9294 // can never be used as part of primary expressions. | 9292 // can never be used as part of primary expressions. |
| 9295 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 9293 if (!current_class().IsNull()) { |
| 9296 if (!scope_class.IsNull()) { | |
| 9297 TypeParameter& type_param = TypeParameter::ZoneHandle( | 9294 TypeParameter& type_param = TypeParameter::ZoneHandle( |
| 9298 scope_class.LookupTypeParameter(*(qual_ident.ident), | 9295 current_class().LookupTypeParameter(*(qual_ident.ident), |
| 9299 TokenPos())); | 9296 TokenPos())); |
| 9300 if (!type_param.IsNull()) { | 9297 if (!type_param.IsNull()) { |
| 9301 const String& type_param_name = String::Handle(type_param.name()); | 9298 const String& type_param_name = String::Handle(type_param.name()); |
| 9302 ErrorMsg(qual_ident.ident_pos, | 9299 ErrorMsg(qual_ident.ident_pos, |
| 9303 "illegal use of type parameter %s", | 9300 "illegal use of type parameter %s", |
| 9304 type_param_name.ToCString()); | 9301 type_param_name.ToCString()); |
| 9305 } | 9302 } |
| 9306 } | 9303 } |
| 9307 // This is a non-local unqualified identifier so resolve the | 9304 // This is a non-local unqualified identifier so resolve the |
| 9308 // identifier locally in the main app library and all libraries | 9305 // identifier locally in the main app library and all libraries |
| 9309 // imported by it. | 9306 // imported by it. |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9700 void Parser::SkipQualIdent() { | 9697 void Parser::SkipQualIdent() { |
| 9701 ASSERT(IsIdentifier()); | 9698 ASSERT(IsIdentifier()); |
| 9702 ConsumeToken(); | 9699 ConsumeToken(); |
| 9703 if (CurrentToken() == Token::kPERIOD) { | 9700 if (CurrentToken() == Token::kPERIOD) { |
| 9704 ConsumeToken(); // Consume the kPERIOD token. | 9701 ConsumeToken(); // Consume the kPERIOD token. |
| 9705 ExpectIdentifier("identifier expected after '.'"); | 9702 ExpectIdentifier("identifier expected after '.'"); |
| 9706 } | 9703 } |
| 9707 } | 9704 } |
| 9708 | 9705 |
| 9709 } // namespace dart | 9706 } // namespace dart |
| OLD | NEW |