Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: runtime/vm/parser.cc

Issue 11030056: Implement new scope rules for type variables (issue 5230). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698