| 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 1941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1952 "static method '%s' cannot be abstract", | 1952 "static method '%s' cannot be abstract", |
| 1953 method->name->ToCString()); | 1953 method->name->ToCString()); |
| 1954 } | 1954 } |
| 1955 if (method->has_const && !(method->IsConstructor() || method->IsFactory())) { | 1955 if (method->has_const && !(method->IsConstructor() || method->IsFactory())) { |
| 1956 ErrorMsg(method->name_pos, "'const' not allowed for methods"); | 1956 ErrorMsg(method->name_pos, "'const' not allowed for methods"); |
| 1957 } | 1957 } |
| 1958 if (method->IsConstructor() && method->has_static) { | 1958 if (method->IsConstructor() && method->has_static) { |
| 1959 ErrorMsg(method->name_pos, "constructor cannot be 'static'"); | 1959 ErrorMsg(method->name_pos, "constructor cannot be 'static'"); |
| 1960 } | 1960 } |
| 1961 if (method->IsConstructor() && method->has_const) { | 1961 if (method->IsConstructor() && method->has_const) { |
| 1962 Class& cls = Class::ZoneHandle(LookupClass(members->class_name())); | 1962 Class& cls = Class::ZoneHandle(library_.LookupClass(members->class_name())); |
| 1963 cls.set_is_const(); | 1963 cls.set_is_const(); |
| 1964 } | 1964 } |
| 1965 if (method->has_abstract && members->is_interface()) { | 1965 if (method->has_abstract && members->is_interface()) { |
| 1966 ErrorMsg(method->name_pos, | 1966 ErrorMsg(method->name_pos, |
| 1967 "'abstract' method only allowed in class definition"); | 1967 "'abstract' method only allowed in class definition"); |
| 1968 } | 1968 } |
| 1969 | 1969 |
| 1970 if (members->FunctionNameExists(*method->name, method->kind)) { | 1970 if (members->FunctionNameExists(*method->name, method->kind)) { |
| 1971 ErrorMsg(method->name_pos, | 1971 ErrorMsg(method->name_pos, |
| 1972 "field or method '%s' already defined", method->name->ToCString()); | 1972 "field or method '%s' already defined", method->name->ToCString()); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2321 // Optionally parse a (possibly named) constructor name or factory. | 2321 // Optionally parse a (possibly named) constructor name or factory. |
| 2322 if (IsIdentifier() && | 2322 if (IsIdentifier() && |
| 2323 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 2323 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
| 2324 if (member.has_factory) { | 2324 if (member.has_factory) { |
| 2325 // The factory name may be qualified. | 2325 // The factory name may be qualified. |
| 2326 QualIdent factory_name; | 2326 QualIdent factory_name; |
| 2327 ParseQualIdent(&factory_name); | 2327 ParseQualIdent(&factory_name); |
| 2328 member.name_pos = factory_name.ident_pos; | 2328 member.name_pos = factory_name.ident_pos; |
| 2329 member.name = factory_name.ident; // Unqualified identifier. | 2329 member.name = factory_name.ident; // Unqualified identifier. |
| 2330 // The class of the factory result type is specified by the factory name. | 2330 // The class of the factory result type is specified by the factory name. |
| 2331 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); |
| 2332 if (factory_name.lib_prefix != NULL) { |
| 2333 lib_prefix = factory_name.lib_prefix->raw(); |
| 2334 } |
| 2331 const Object& result_type_class = Object::Handle( | 2335 const Object& result_type_class = Object::Handle( |
| 2332 LookupTypeClass(factory_name, kCanResolve)); | 2336 UnresolvedClass::New(lib_prefix, |
| 2337 *factory_name.ident, |
| 2338 factory_name.ident_pos)); |
| 2333 // The type arguments of the result type are set during finalization. | 2339 // The type arguments of the result type are set during finalization. |
| 2334 member.type = &Type::ZoneHandle(Type::New(result_type_class, | 2340 member.type = &Type::ZoneHandle(Type::New(result_type_class, |
| 2335 TypeArguments::Handle(), | 2341 TypeArguments::Handle(), |
| 2336 factory_name.ident_pos)); | 2342 factory_name.ident_pos)); |
| 2337 } else { | 2343 } else { |
| 2338 member.name_pos = token_index_; | 2344 member.name_pos = token_index_; |
| 2339 member.name = CurrentLiteral(); | 2345 member.name = CurrentLiteral(); |
| 2340 ConsumeToken(); | 2346 ConsumeToken(); |
| 2341 } | 2347 } |
| 2342 // We must be dealing with a constructor or named constructor. | 2348 // We must be dealing with a constructor or named constructor. |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2683 signature_function, | 2689 signature_function, |
| 2684 script_); | 2690 script_); |
| 2685 // Record the function signature class in the current library. | 2691 // Record the function signature class in the current library. |
| 2686 library_.AddClass(signature_class); | 2692 library_.AddClass(signature_class); |
| 2687 } else { | 2693 } else { |
| 2688 // Forget the just created signature function and use the existing one. | 2694 // Forget the just created signature function and use the existing one. |
| 2689 signature_function = signature_class.signature_function(); | 2695 signature_function = signature_class.signature_function(); |
| 2690 } | 2696 } |
| 2691 ASSERT(signature_function.signature_class() == signature_class.raw()); | 2697 ASSERT(signature_function.signature_class() == signature_class.raw()); |
| 2692 // Lookup the class by its alias name and report an error if it exists. | 2698 // Lookup the class by its alias name and report an error if it exists. |
| 2693 Class& function_type_alias = Class::ZoneHandle(LookupClass(*alias_name)); | 2699 Class& function_type_alias = |
| 2700 Class::ZoneHandle(library_.LookupClass(*alias_name)); |
| 2694 if (function_type_alias.IsNull()) { | 2701 if (function_type_alias.IsNull()) { |
| 2695 // Create the function type alias, but share the signature function of the | 2702 // Create the function type alias, but share the signature function of the |
| 2696 // canonical signature class. | 2703 // canonical signature class. |
| 2697 function_type_alias = Class::NewSignatureClass(*alias_name, | 2704 function_type_alias = Class::NewSignatureClass(*alias_name, |
| 2698 signature_function, | 2705 signature_function, |
| 2699 script_); | 2706 script_); |
| 2700 library_.AddClass(function_type_alias); | 2707 library_.AddClass(function_type_alias); |
| 2701 } else { | 2708 } else { |
| 2702 const char* format = function_type_alias.is_interface() ? | 2709 const char* format = function_type_alias.is_interface() ? |
| 2703 "'%s' is already defined" : "'%s' is already defined as class"; | 2710 "'%s' is already defined" : "'%s' is already defined as class"; |
| (...skipping 1822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4526 String& name = String::Handle(class_name.raw()); | 4533 String& name = String::Handle(class_name.raw()); |
| 4527 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { | 4534 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { |
| 4528 // Private identifiers are mangled on a per script basis. | 4535 // Private identifiers are mangled on a per script basis. |
| 4529 name = String::Concat(name, String::Handle(core_lib.private_key())); | 4536 name = String::Concat(name, String::Handle(core_lib.private_key())); |
| 4530 name = String::NewSymbol(name); | 4537 name = String::NewSymbol(name); |
| 4531 } | 4538 } |
| 4532 return core_lib.LookupClass(name); | 4539 return core_lib.LookupClass(name); |
| 4533 } | 4540 } |
| 4534 | 4541 |
| 4535 | 4542 |
| 4536 RawClass* Parser::LookupClass(const String& class_name) { | |
| 4537 return library_.LookupClass(class_name); | |
| 4538 } | |
| 4539 | |
| 4540 | |
| 4541 // Calling VM-internal helpers, uses implementation core library. | 4543 // Calling VM-internal helpers, uses implementation core library. |
| 4542 AstNode* Parser::MakeStaticCall(const char* class_name, | 4544 AstNode* Parser::MakeStaticCall(const char* class_name, |
| 4543 const char* function_name, | 4545 const char* function_name, |
| 4544 ArgumentListNode* arguments) { | 4546 ArgumentListNode* arguments) { |
| 4545 const String& cls_name = | 4547 const String& cls_name = |
| 4546 String::Handle(String::NewSymbol(class_name)); | 4548 String::Handle(String::NewSymbol(class_name)); |
| 4547 const Class& cls = Class::Handle(LookupImplClass(cls_name)); | 4549 const Class& cls = Class::Handle(LookupImplClass(cls_name)); |
| 4548 ASSERT(!cls.IsNull()); | 4550 ASSERT(!cls.IsNull()); |
| 4549 const String& func_name = | 4551 const String& func_name = |
| 4550 String::ZoneHandle(String::NewSymbol(function_name)); | 4552 String::ZoneHandle(String::NewSymbol(function_name)); |
| (...skipping 1595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6146 // If the given scope class is null, use the current library, but do not try to | 6148 // If the given scope class is null, use the current library, but do not try to |
| 6147 // resolve type parameters. | 6149 // resolve type parameters. |
| 6148 // Not all involved type classes may get resolved yet, but at least the type | 6150 // Not all involved type classes may get resolved yet, but at least the type |
| 6149 // parameters of the given class will get resolved, thereby relieving the class | 6151 // parameters of the given class will get resolved, thereby relieving the class |
| 6150 // finalizer from resolving type parameters out of context. | 6152 // finalizer from resolving type parameters out of context. |
| 6151 void Parser::ResolveTypeFromClass(const Class& scope_class, | 6153 void Parser::ResolveTypeFromClass(const Class& scope_class, |
| 6152 TypeResolution type_resolution, | 6154 TypeResolution type_resolution, |
| 6153 AbstractType* type) { | 6155 AbstractType* type) { |
| 6154 ASSERT((type_resolution == kCanResolve) || (type_resolution == kMustResolve)); | 6156 ASSERT((type_resolution == kCanResolve) || (type_resolution == kMustResolve)); |
| 6155 ASSERT(type != NULL); | 6157 ASSERT(type != NULL); |
| 6158 if (type->IsResolved()) { |
| 6159 return; |
| 6160 } |
| 6156 // Resolve class. | 6161 // Resolve class. |
| 6157 if (!type->HasResolvedTypeClass()) { | 6162 if (!type->HasResolvedTypeClass()) { |
| 6158 const UnresolvedClass& unresolved_class = | 6163 const UnresolvedClass& unresolved_class = |
| 6159 UnresolvedClass::Handle(type->unresolved_class()); | 6164 UnresolvedClass::Handle(type->unresolved_class()); |
| 6160 const String& unresolved_class_name = | 6165 const String& unresolved_class_name = |
| 6161 String::Handle(unresolved_class.ident()); | 6166 String::Handle(unresolved_class.ident()); |
| 6162 // First resolve library prefix if any. | |
| 6163 Library& lib = Library::Handle(); | 6167 Library& lib = Library::Handle(); |
| 6164 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 6168 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
| 6165 if (scope_class.IsNull()) { | 6169 if (!scope_class.IsNull()) { |
| 6166 lib = library_.raw(); | |
| 6167 } else { | |
| 6168 lib = scope_class.library(); | |
| 6169 // First check if the type is a type parameter of the given scope class. | 6170 // First check if the type is a type parameter of the given scope class. |
| 6170 const TypeParameter& type_parameter = TypeParameter::Handle( | 6171 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 6171 scope_class.LookupTypeParameter(unresolved_class_name, | 6172 scope_class.LookupTypeParameter(unresolved_class_name, |
| 6172 type->token_index())); | 6173 type->token_index())); |
| 6173 if (!type_parameter.IsNull()) { | 6174 if (!type_parameter.IsNull()) { |
| 6174 // A type parameter cannot be parameterized, so report an error if | 6175 // A type parameter cannot be parameterized, so report an error if |
| 6175 // type arguments have previously been parsed. | 6176 // type arguments have previously been parsed. |
| 6176 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { | 6177 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { |
| 6177 ErrorMsg(type_parameter.token_index(), | 6178 ErrorMsg(type_parameter.token_index(), |
| 6178 "type parameter '%s' cannot be parameterized", | 6179 "type parameter '%s' cannot be parameterized", |
| 6179 String::Handle(type_parameter.Name()).ToCString()); | 6180 String::Handle(type_parameter.Name()).ToCString()); |
| 6180 } | 6181 } |
| 6181 *type = type_parameter.raw(); | 6182 *type = type_parameter.raw(); |
| 6182 return; | 6183 return; |
| 6183 } | 6184 } |
| 6184 } | 6185 } |
| 6185 } else { | 6186 } else { |
| 6186 LibraryPrefix& lib_prefix = | 6187 LibraryPrefix& lib_prefix = |
| 6187 LibraryPrefix::Handle(unresolved_class.library_prefix()); | 6188 LibraryPrefix::Handle(unresolved_class.library_prefix()); |
| 6188 lib = lib_prefix.library(); | 6189 lib = lib_prefix.library(); |
| 6189 } | 6190 } |
| 6190 if (!lib.IsNull()) { | 6191 Class& resolved_type_class = Class::Handle(); |
| 6191 const Class& resolved_type_class = Class::Handle( | 6192 if (lib.IsNull()) { |
| 6192 lib.LookupLocalClass(unresolved_class_name)); | 6193 // Global lookup in current library. |
| 6193 if (!resolved_type_class.IsNull()) { | 6194 resolved_type_class = library_.LookupClass(unresolved_class_name); |
| 6194 Object& type_class = Object::Handle(resolved_type_class.raw()); | 6195 } else { |
| 6195 ASSERT(type->IsType()); | 6196 // Local lookup in imported library. |
| 6196 // Replace unresolved class with resolved type class. | 6197 resolved_type_class = lib.LookupLocalClass(unresolved_class_name); |
| 6197 Type& parameterized_type = Type::Handle(); | 6198 } |
| 6198 parameterized_type ^= type->raw(); | 6199 if (!resolved_type_class.IsNull()) { |
| 6199 parameterized_type.set_type_class(type_class); | 6200 Object& type_class = Object::Handle(resolved_type_class.raw()); |
| 6200 } else if (type_resolution == kMustResolve) { | 6201 ASSERT(type->IsType()); |
| 6201 ErrorMsg(type->token_index(), "type '%s' is not loaded", | 6202 // Replace unresolved class with resolved type class. |
| 6202 String::Handle(type->Name()).ToCString()); | 6203 Type& parameterized_type = Type::Handle(); |
| 6203 } | 6204 parameterized_type ^= type->raw(); |
| 6205 parameterized_type.set_type_class(type_class); |
| 6206 } else if (type_resolution == kMustResolve) { |
| 6207 ErrorMsg(type->token_index(), "type '%s' is not loaded", |
| 6208 String::Handle(type->Name()).ToCString()); |
| 6204 } | 6209 } |
| 6205 } | 6210 } |
| 6206 // Resolve type arguments, if any. | 6211 // Resolve type arguments, if any. |
| 6207 const AbstractTypeArguments& arguments = | 6212 const AbstractTypeArguments& arguments = |
| 6208 AbstractTypeArguments::Handle(type->arguments()); | 6213 AbstractTypeArguments::Handle(type->arguments()); |
| 6209 if (!arguments.IsNull()) { | 6214 if (!arguments.IsNull()) { |
| 6210 const intptr_t num_arguments = arguments.Length(); | 6215 const intptr_t num_arguments = arguments.Length(); |
| 6211 for (intptr_t i = 0; i < num_arguments; i++) { | 6216 for (intptr_t i = 0; i < num_arguments; i++) { |
| 6212 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); | 6217 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); |
| 6213 ResolveTypeFromClass(scope_class, | 6218 ResolveTypeFromClass(scope_class, |
| 6214 type_resolution, | 6219 type_resolution, |
| 6215 &type_argument); | 6220 &type_argument); |
| 6216 arguments.SetTypeAt(i, type_argument); | 6221 arguments.SetTypeAt(i, type_argument); |
| 6217 } | 6222 } |
| 6218 } | 6223 } |
| 6219 } | 6224 } |
| 6220 | 6225 |
| 6221 | 6226 |
| 6222 // Return class for type name. If the name cannot be resolved (yet), give an | |
| 6223 // error (if type_resolution == kMustResolve) or return the unresolved name. | |
| 6224 RawObject* Parser::LookupTypeClass(const QualIdent& type_name, | |
| 6225 TypeResolution type_resolution) { | |
| 6226 ASSERT(type_name.ident != NULL); | |
| 6227 ASSERT((type_resolution == kCanResolve) || (type_resolution == kMustResolve)); | |
| 6228 Class& type_class = Class::Handle(); | |
| 6229 if (type_name.lib_prefix != NULL) { | |
| 6230 Library& lib = Library::Handle(type_name.lib_prefix->library()); | |
| 6231 type_class = lib.LookupLocalClass(*type_name.ident); | |
| 6232 } else { | |
| 6233 type_class = LookupClass(*type_name.ident); | |
| 6234 } | |
| 6235 if (!type_class.IsNull()) { | |
| 6236 return type_class.raw(); | |
| 6237 } | |
| 6238 // Type name could not be resolved (yet). | |
| 6239 if (type_resolution == kMustResolve) { | |
| 6240 ErrorMsg(type_name.ident_pos, "type '%s' is not loaded", | |
| 6241 type_name.ident->ToCString()); | |
| 6242 return Object::null_class(); | |
| 6243 } | |
| 6244 // We have an unresolved name, create an UnresolvedClass object for this case. | |
| 6245 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); | |
| 6246 if (type_name.lib_prefix != NULL) { | |
| 6247 lib_prefix = type_name.lib_prefix->raw(); | |
| 6248 } | |
| 6249 return UnresolvedClass::New(lib_prefix, | |
| 6250 *type_name.ident, | |
| 6251 type_name.ident_pos); | |
| 6252 } | |
| 6253 | |
| 6254 | |
| 6255 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 6227 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
| 6256 if (current_block_ == NULL) { | 6228 if (current_block_ == NULL) { |
| 6257 return NULL; | 6229 return NULL; |
| 6258 } | 6230 } |
| 6259 // A found name is treated as accessed and possibly marked as captured. | 6231 // A found name is treated as accessed and possibly marked as captured. |
| 6260 const bool kTestOnly = false; | 6232 const bool kTestOnly = false; |
| 6261 return current_block_->scope->LookupVariable(ident, kTestOnly); | 6233 return current_block_->scope->LookupVariable(ident, kTestOnly); |
| 6262 } | 6234 } |
| 6263 | 6235 |
| 6264 | 6236 |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6655 String& map_name = String::Handle(library_.LookupImportMap(ident)); | 6627 String& map_name = String::Handle(library_.LookupImportMap(ident)); |
| 6656 if (!map_name.IsNull()) { | 6628 if (!map_name.IsNull()) { |
| 6657 return map_name.raw(); | 6629 return map_name.raw(); |
| 6658 } | 6630 } |
| 6659 ErrorMsg(ident_pos, "import variable '%s' has not been defined", | 6631 ErrorMsg(ident_pos, "import variable '%s' has not been defined", |
| 6660 ident.ToCString()); | 6632 ident.ToCString()); |
| 6661 return String::null(); | 6633 return String::null(); |
| 6662 } | 6634 } |
| 6663 | 6635 |
| 6664 | 6636 |
| 6665 // Parses type = [ident "."] ident ["<" type { "," type } ">"]. | 6637 // Parses type = [ident "."] ident ["<" type { "," type } ">"] and resolve it |
| 6666 // Returns the class object if the type can be resolved. Otherwise, either give | 6638 // according to the given type_resolution. |
| 6667 // an error if type resolution was required, or return the unresolved name as a | |
| 6668 // string object. | |
| 6669 RawAbstractType* Parser::ParseType(TypeResolution type_resolution) { | 6639 RawAbstractType* Parser::ParseType(TypeResolution type_resolution) { |
| 6670 if (CurrentToken() != Token::kIDENT) { | 6640 if (CurrentToken() != Token::kIDENT) { |
| 6671 ErrorMsg("type name expected"); | 6641 ErrorMsg("type name expected"); |
| 6672 } | 6642 } |
| 6673 QualIdent type_name; | 6643 QualIdent type_name; |
| 6674 if (type_resolution == kIgnore) { | 6644 if (type_resolution == kIgnore) { |
| 6675 SkipQualIdent(); | 6645 SkipQualIdent(); |
| 6676 } else { | 6646 } else { |
| 6677 ParseQualIdent(&type_name); | 6647 ParseQualIdent(&type_name); |
| 6678 // An identifier cannot be resolved in a local scope when top level parsing. | 6648 // An identifier cannot be resolved in a local scope when top level parsing. |
| 6679 if (!is_top_level_ && | 6649 if (!is_top_level_ && |
| 6680 (type_name.lib_prefix == NULL) && | 6650 (type_name.lib_prefix == NULL) && |
| 6681 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { | 6651 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { |
| 6682 ErrorMsg(type_name.ident_pos, "using '%s' in this context is invalid", | 6652 ErrorMsg(type_name.ident_pos, "using '%s' in this context is invalid", |
| 6683 type_name.ident->ToCString()); | 6653 type_name.ident->ToCString()); |
| 6684 } | 6654 } |
| 6685 } | 6655 } |
| 6686 Class& scope_class = Class::Handle(); | |
| 6687 Object& type_class = Object::Handle(); | 6656 Object& type_class = Object::Handle(); |
| 6688 if (type_resolution == kIgnore) { | 6657 // Leave type_class as null if type_resolution equals kIgnore. |
| 6689 // Leave type_class as null. | 6658 if (type_resolution != kIgnore) { |
| 6690 } else if (type_resolution == kDoNotResolve) { | |
| 6691 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); | 6659 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); |
| 6692 if (type_name.lib_prefix != NULL) { | 6660 if (type_name.lib_prefix != NULL) { |
| 6693 lib_prefix = type_name.lib_prefix->raw(); | 6661 lib_prefix = type_name.lib_prefix->raw(); |
| 6694 } | 6662 } |
| 6695 type_class = UnresolvedClass::New(lib_prefix, | 6663 type_class = UnresolvedClass::New(lib_prefix, |
| 6696 *type_name.ident, | 6664 *type_name.ident, |
| 6697 type_name.ident_pos); | 6665 type_name.ident_pos); |
| 6698 } else { | |
| 6699 // TODO(regis): Use ResolveTypeFromClass(). | |
| 6700 ASSERT((type_resolution == kCanResolve) || | |
| 6701 (type_resolution == kMustResolve)); | |
| 6702 scope_class = TypeParametersScopeClass(); | |
| 6703 if (!scope_class.IsNull()) { | |
| 6704 if (type_name.lib_prefix == NULL) { | |
| 6705 // Check if ident is a type parameter in scope. | |
| 6706 TypeParameter& type_parameter = TypeParameter::Handle( | |
| 6707 scope_class.LookupTypeParameter(*type_name.ident, | |
| 6708 type_name.ident_pos)); | |
| 6709 if (!type_parameter.IsNull()) { | |
| 6710 if (CurrentToken() == Token::kLT) { | |
| 6711 // A type parameter cannot be parameterized. | |
| 6712 ErrorMsg(type_parameter.token_index(), | |
| 6713 "type parameter '%s' cannot be parameterized", | |
| 6714 String::Handle(type_parameter.Name()).ToCString()); | |
| 6715 } | |
| 6716 if (type_resolution == kMustResolve) { | |
| 6717 type_parameter ^= | |
| 6718 ClassFinalizer::FinalizeType(current_class(), type_parameter); | |
| 6719 } | |
| 6720 return type_parameter.raw(); | |
| 6721 } | |
| 6722 } | |
| 6723 } | |
| 6724 // Try to resolve the type class. | |
| 6725 type_class = LookupTypeClass(type_name, type_resolution); | |
| 6726 } | 6666 } |
| 6727 AbstractTypeArguments& type_arguments = | 6667 AbstractTypeArguments& type_arguments = |
| 6728 AbstractTypeArguments::Handle(ParseTypeArguments(type_resolution)); | 6668 AbstractTypeArguments::Handle(ParseTypeArguments(type_resolution)); |
| 6729 if (type_resolution == kIgnore) { | 6669 if (type_resolution == kIgnore) { |
| 6730 return Type::DynamicType(); | 6670 return Type::DynamicType(); |
| 6731 } | 6671 } |
| 6732 Type& type = Type::Handle( | 6672 AbstractType& type = AbstractType::Handle( |
| 6733 Type::New(type_class, type_arguments, type_name.ident_pos)); | 6673 Type::New(type_class, type_arguments, type_name.ident_pos)); |
| 6734 if (type_resolution == kMustResolve) { | 6674 if ((type_resolution == kCanResolve) || (type_resolution == kMustResolve)) { |
| 6735 ASSERT(type_class.IsClass()); // Must be resolved. | 6675 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
| 6736 type ^= ClassFinalizer::FinalizeType(current_class(), type); | 6676 ResolveTypeFromClass(scope_class, type_resolution, &type); |
| 6677 if (type_resolution == kMustResolve) { |
| 6678 type ^= ClassFinalizer::FinalizeType(current_class(), type); |
| 6679 } |
| 6737 } | 6680 } |
| 6738 return type.raw(); | 6681 return type.raw(); |
| 6739 } | 6682 } |
| 6740 | 6683 |
| 6741 | 6684 |
| 6742 void Parser::CheckConstructorCallTypeArguments( | 6685 void Parser::CheckConstructorCallTypeArguments( |
| 6743 intptr_t pos, Function& constructor, | 6686 intptr_t pos, Function& constructor, |
| 6744 const AbstractTypeArguments& type_arguments) { | 6687 const AbstractTypeArguments& type_arguments) { |
| 6745 if (!type_arguments.IsNull()) { | 6688 if (!type_arguments.IsNull()) { |
| 6746 const Class& constructor_class = Class::Handle(constructor.owner()); | 6689 const Class& constructor_class = Class::Handle(constructor.owner()); |
| (...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7830 void Parser::SkipQualIdent() { | 7773 void Parser::SkipQualIdent() { |
| 7831 ASSERT(IsIdentifier()); | 7774 ASSERT(IsIdentifier()); |
| 7832 ConsumeToken(); | 7775 ConsumeToken(); |
| 7833 if (CurrentToken() == Token::kPERIOD) { | 7776 if (CurrentToken() == Token::kPERIOD) { |
| 7834 ConsumeToken(); // Consume the kPERIOD token. | 7777 ConsumeToken(); // Consume the kPERIOD token. |
| 7835 ExpectIdentifier("identifier expected after '.'"); | 7778 ExpectIdentifier("identifier expected after '.'"); |
| 7836 } | 7779 } |
| 7837 } | 7780 } |
| 7838 | 7781 |
| 7839 } // namespace dart | 7782 } // namespace dart |
| OLD | NEW |