| 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 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1912 qual_ident->lib_prefix = NULL; | 1912 qual_ident->lib_prefix = NULL; |
| 1913 qual_ident->qualifier = NULL; | 1913 qual_ident->qualifier = NULL; |
| 1914 ConsumeToken(); | 1914 ConsumeToken(); |
| 1915 if (CurrentToken() == Token::kPERIOD) { | 1915 if (CurrentToken() == Token::kPERIOD) { |
| 1916 if (!ResolveIdentInLocalScope(qual_ident->ident_pos, | 1916 if (!ResolveIdentInLocalScope(qual_ident->ident_pos, |
| 1917 *(qual_ident->ident), | 1917 *(qual_ident->ident), |
| 1918 NULL)) { | 1918 NULL)) { |
| 1919 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 1919 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
| 1920 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); | 1920 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); |
| 1921 if (!lib_prefix.IsNull()) { | 1921 if (!lib_prefix.IsNull()) { |
| 1922 // We have a library prefix qualified identifier. | 1922 // We have a library prefix qualified identifier, unless the prefix is |
| 1923 ConsumeToken(); // Consume the kPERIOD token. | 1923 // shadowed by a type parameter in scope. |
| 1924 qual_ident->lib_prefix = &lib_prefix; | 1924 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
| 1925 qual_ident->qualifier = qual_ident->ident; | 1925 if (scope_class.IsNull() || |
| 1926 qual_ident->ident_pos = token_index_; | 1926 (scope_class.LookupTypeParameter(*(qual_ident->ident)) == |
| 1927 qual_ident->ident = ExpectIdentifier("identifier expected after '.'"); | 1927 TypeParameter::null())) { |
| 1928 ConsumeToken(); // Consume the kPERIOD token. |
| 1929 qual_ident->lib_prefix = &lib_prefix; |
| 1930 qual_ident->qualifier = qual_ident->ident; |
| 1931 qual_ident->ident_pos = token_index_; |
| 1932 qual_ident->ident = |
| 1933 ExpectIdentifier("identifier expected after '.'"); |
| 1934 } |
| 1928 } | 1935 } |
| 1929 } | 1936 } |
| 1930 } | 1937 } |
| 1931 } else { | 1938 } else { |
| 1932 qual_ident->ident_pos = token_index_; | 1939 qual_ident->ident_pos = token_index_; |
| 1933 qual_ident->ident = CurrentLiteral(); | 1940 qual_ident->ident = CurrentLiteral(); |
| 1934 qual_ident->lib_prefix = NULL; | 1941 qual_ident->lib_prefix = NULL; |
| 1935 qual_ident->qualifier = NULL; | 1942 qual_ident->qualifier = NULL; |
| 1936 ConsumeToken(); | 1943 ConsumeToken(); |
| 1937 if (CurrentToken() == Token::kPERIOD) { | 1944 if (CurrentToken() == Token::kPERIOD) { |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2326 // supported yet). | 2333 // supported yet). |
| 2327 member.type = &AbstractType::ZoneHandle(ParseType(kCanResolve)); | 2334 member.type = &AbstractType::ZoneHandle(ParseType(kCanResolve)); |
| 2328 } | 2335 } |
| 2329 } | 2336 } |
| 2330 } | 2337 } |
| 2331 // Optionally parse a (possibly named) constructor name or factory. | 2338 // Optionally parse a (possibly named) constructor name or factory. |
| 2332 if (IsIdentifier() && | 2339 if (IsIdentifier() && |
| 2333 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 2340 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
| 2334 member.name = CurrentLiteral(); | 2341 member.name = CurrentLiteral(); |
| 2335 member.name_pos = this->token_index_; | 2342 member.name_pos = this->token_index_; |
| 2343 // TODO(regis): Simplify the following code by calling ParseQualIdent(). |
| 2336 ConsumeToken(); | 2344 ConsumeToken(); |
| 2337 if (member.has_factory) { | 2345 if (member.has_factory) { |
| 2338 String& qualifier = String::Handle(); | 2346 String& qualifier = String::Handle(); |
| 2339 if (CurrentToken() == Token::kPERIOD) { | 2347 if (CurrentToken() == Token::kPERIOD) { |
| 2340 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 2348 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
| 2341 lib_prefix = current_class().LookupLibraryPrefix(*member.name); | 2349 lib_prefix = current_class().LookupLibraryPrefix(*member.name); |
| 2342 if (!lib_prefix.IsNull()) { | 2350 if (!lib_prefix.IsNull()) { |
| 2343 // We have a library prefix qualified identifier. | 2351 // We have a library prefix qualified identifier. |
| 2344 ConsumeToken(); // Consume the kPERIOD token. | 2352 ConsumeToken(); // Consume the kPERIOD token. |
| 2345 qualifier ^= member.name->raw(); | 2353 qualifier ^= member.name->raw(); |
| 2346 member.name = ExpectIdentifier("identifier expected"); | 2354 member.name = ExpectIdentifier("identifier expected"); |
| 2347 } | 2355 } |
| 2348 } | 2356 } |
| 2349 // TODO(regis): Stop postponing resolution of the factory result type | 2357 // TODO(regis): Stop postponing resolution of the factory result type |
| 2350 // until class finalization. Use TryResolveTypeFromClass. | 2358 // until class finalization. Use ResolveTypeFromClass instead. |
| 2351 // Factory result type is the same as the type name of the factory. | 2359 // Factory result type is the same as the type name of the factory. |
| 2352 const UnresolvedClass& unresolved_factory_class = | 2360 const UnresolvedClass& unresolved_factory_class = |
| 2353 UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos, | 2361 UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos, |
| 2354 qualifier, | 2362 qualifier, |
| 2355 *member.name)); | 2363 *member.name)); |
| 2356 // The type arguments of the result type are set during finalization. | 2364 // The type arguments of the result type are set during finalization. |
| 2357 member.type = &Type::ZoneHandle( | 2365 member.type = &Type::ZoneHandle( |
| 2358 Type::NewParameterizedType(unresolved_factory_class, | 2366 Type::NewParameterizedType(unresolved_factory_class, |
| 2359 TypeArguments::Handle())); | 2367 TypeArguments::Handle())); |
| 2360 } | 2368 } |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2661 alias_owner.set_is_interface(); | 2669 alias_owner.set_is_interface(); |
| 2662 set_current_class(alias_owner); | 2670 set_current_class(alias_owner); |
| 2663 ParseTypeParameters(alias_owner); | 2671 ParseTypeParameters(alias_owner); |
| 2664 if (CurrentToken() != Token::kLPAREN) { | 2672 if (CurrentToken() != Token::kLPAREN) { |
| 2665 ErrorMsg("formal parameter list expected"); | 2673 ErrorMsg("formal parameter list expected"); |
| 2666 } | 2674 } |
| 2667 | 2675 |
| 2668 // At this point, the type parameters have been parsed, so we can resolve the | 2676 // At this point, the type parameters have been parsed, so we can resolve the |
| 2669 // result type. | 2677 // result type. |
| 2670 if (!result_type.IsNull()) { | 2678 if (!result_type.IsNull()) { |
| 2671 TryResolveTypeFromClass(result_type_pos, alias_owner, &result_type); | 2679 ResolveTypeFromClass(result_type_pos, |
| 2680 alias_owner, |
| 2681 kCanResolve, |
| 2682 &result_type); |
| 2672 } | 2683 } |
| 2673 ParamList func_params; | 2684 ParamList func_params; |
| 2674 const bool no_explicit_default_values = false; | 2685 const bool no_explicit_default_values = false; |
| 2675 ParseFormalParameterList(no_explicit_default_values, &func_params); | 2686 ParseFormalParameterList(no_explicit_default_values, &func_params); |
| 2676 // The field 'is_static' has no meaning for signature functions. | 2687 // The field 'is_static' has no meaning for signature functions. |
| 2677 Function& signature_function = Function::Handle( | 2688 Function& signature_function = Function::Handle( |
| 2678 Function::New(*alias_name, | 2689 Function::New(*alias_name, |
| 2679 RawFunction::kSignatureFunction, | 2690 RawFunction::kSignatureFunction, |
| 2680 /* is_static = */ false, | 2691 /* is_static = */ false, |
| 2681 /* is_const = */ false, | 2692 /* is_const = */ false, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2780 const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle( | 2791 const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle( |
| 2781 UnresolvedClass::New(factory_pos, qualifier, *factory_name.ident)); | 2792 UnresolvedClass::New(factory_pos, qualifier, *factory_name.ident)); |
| 2782 const Class& factory_class = Class::Handle( | 2793 const Class& factory_class = Class::Handle( |
| 2783 Class::New(String::Handle(String::NewSymbol(":factory_signature")), | 2794 Class::New(String::Handle(String::NewSymbol(":factory_signature")), |
| 2784 script_)); | 2795 script_)); |
| 2785 factory_class.set_library(library_); | 2796 factory_class.set_library(library_); |
| 2786 factory_class.set_is_finalized(); | 2797 factory_class.set_is_finalized(); |
| 2787 ParseTypeParameters(factory_class); | 2798 ParseTypeParameters(factory_class); |
| 2788 unresolved_factory_class.set_factory_signature_class(factory_class); | 2799 unresolved_factory_class.set_factory_signature_class(factory_class); |
| 2789 interface.set_factory_class(unresolved_factory_class); | 2800 interface.set_factory_class(unresolved_factory_class); |
| 2790 // Verify that the type parameters of the factory class and of the interface | 2801 // If a type parameter list is included in the default factory clause (it |
| 2791 // have identical names. | 2802 // can be omitted), verify that it matches the list of type parameters of |
| 2792 String& interface_type_param_name = String::Handle(); | 2803 // the interface in number and names. |
| 2793 String& factory_type_param_name = String::Handle(); | 2804 const intptr_t num_default_type_params = factory_class.NumTypeParameters(); |
| 2794 const Array& interface_type_param_names = | 2805 if (num_default_type_params > 0) { |
| 2795 Array::Handle(interface.type_parameters()); | 2806 String& interface_type_param_name = String::Handle(); |
| 2796 const Array& factory_type_param_names = | 2807 String& factory_type_param_name = String::Handle(); |
| 2797 Array::Handle(factory_class.type_parameters()); | 2808 const Array& interface_type_param_names = |
| 2798 const intptr_t num_type_params = factory_class.NumTypeParameters(); | 2809 Array::Handle(interface.type_parameters()); |
| 2799 bool mismatch = interface.NumTypeParameters() != num_type_params; | 2810 const Array& factory_type_param_names = |
| 2800 for (intptr_t i = 0; !mismatch && (i < num_type_params); i++) { | 2811 Array::Handle(factory_class.type_parameters()); |
| 2801 interface_type_param_name ^= interface_type_param_names.At(i); | 2812 bool mismatch = interface.NumTypeParameters() != num_default_type_params; |
| 2802 factory_type_param_name ^= factory_type_param_names.At(i); | 2813 for (intptr_t i = 0; !mismatch && (i < num_default_type_params); i++) { |
| 2803 if (!interface_type_param_name.Equals(factory_type_param_name)) { | 2814 interface_type_param_name ^= interface_type_param_names.At(i); |
| 2804 mismatch = true; | 2815 factory_type_param_name ^= factory_type_param_names.At(i); |
| 2816 if (!interface_type_param_name.Equals(factory_type_param_name)) { |
| 2817 mismatch = true; |
| 2818 } |
| 2805 } | 2819 } |
| 2806 } | 2820 if (mismatch) { |
| 2807 // The list of type parameters in the default factory clause can be omitted. | 2821 const String& interface_name = String::Handle(interface.Name()); |
| 2808 if (mismatch && (num_type_params > 0)) { | 2822 const String& factory_name = String::Handle(factory_class.Name()); |
| 2809 const String& interface_name = String::Handle(interface.Name()); | 2823 ErrorMsg(factory_pos, |
| 2810 const String& factory_name = String::Handle(factory_class.Name()); | 2824 "mismatch in number or names of type parameters between " |
| 2811 ErrorMsg(factory_pos, | 2825 "interface '%s' and default factory class '%s'.\n", |
| 2812 "mismatch in number or names of type parameters between " | 2826 interface_name.ToCString(), |
| 2813 "interface '%s' and default factory class '%s'.\n", | 2827 factory_name.ToCString()); |
| 2814 interface_name.ToCString(), | 2828 } |
| 2815 factory_name.ToCString()); | |
| 2816 } | 2829 } |
| 2817 } | 2830 } |
| 2818 | 2831 |
| 2819 ExpectToken(Token::kLBRACE); | 2832 ExpectToken(Token::kLBRACE); |
| 2820 ClassDesc members(interface, interface_name, true, interface_pos); | 2833 ClassDesc members(interface, interface_name, true, interface_pos); |
| 2821 while (CurrentToken() != Token::kRBRACE) { | 2834 while (CurrentToken() != Token::kRBRACE) { |
| 2822 ParseClassMemberDefinition(&members); | 2835 ParseClassMemberDefinition(&members); |
| 2823 } | 2836 } |
| 2824 ExpectToken(Token::kRBRACE); | 2837 ExpectToken(Token::kRBRACE); |
| 2825 | 2838 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2909 cls.set_type_parameters(Array::Handle(NewArray<String>(type_parameters))); | 2922 cls.set_type_parameters(Array::Handle(NewArray<String>(type_parameters))); |
| 2910 const TypeArguments& extends_array = | 2923 const TypeArguments& extends_array = |
| 2911 TypeArguments::Handle(NewTypeArguments(type_parameter_extends)); | 2924 TypeArguments::Handle(NewTypeArguments(type_parameter_extends)); |
| 2912 cls.set_type_parameter_extends(extends_array); | 2925 cls.set_type_parameter_extends(extends_array); |
| 2913 // Try to resolve the upper bounds, which will at least resolve the | 2926 // Try to resolve the upper bounds, which will at least resolve the |
| 2914 // referenced type parameters. | 2927 // referenced type parameters. |
| 2915 AbstractType& type_extends = AbstractType::Handle(); | 2928 AbstractType& type_extends = AbstractType::Handle(); |
| 2916 const intptr_t num_types = extends_array.Length(); | 2929 const intptr_t num_types = extends_array.Length(); |
| 2917 for (intptr_t i = 0; i < num_types; i++) { | 2930 for (intptr_t i = 0; i < num_types; i++) { |
| 2918 type_extends = extends_array.TypeAt(i); | 2931 type_extends = extends_array.TypeAt(i); |
| 2919 TryResolveTypeFromClass(type_pos, cls, &type_extends); | 2932 ResolveTypeFromClass(type_pos, cls, kCanResolve, &type_extends); |
| 2920 extends_array.SetTypeAt(i, type_extends); | 2933 extends_array.SetTypeAt(i, type_extends); |
| 2921 } | 2934 } |
| 2922 } | 2935 } |
| 2923 } | 2936 } |
| 2924 | 2937 |
| 2925 | 2938 |
| 2926 RawAbstractTypeArguments* Parser::ParseTypeArguments( | 2939 RawAbstractTypeArguments* Parser::ParseTypeArguments( |
| 2927 TypeResolution type_resolution) { | 2940 TypeResolution type_resolution) { |
| 2928 if (CurrentToken() == Token::kLT) { | 2941 if (CurrentToken() == Token::kLT) { |
| 2929 GrowableArray<AbstractType*> types; | 2942 GrowableArray<AbstractType*> types; |
| (...skipping 3190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6120 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false); | 6133 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false); |
| 6121 if (incr_op_node == NULL) { | 6134 if (incr_op_node == NULL) { |
| 6122 Unimplemented("incr op not implemented"); | 6135 Unimplemented("incr op not implemented"); |
| 6123 } | 6136 } |
| 6124 postfix_expr = incr_op_node; | 6137 postfix_expr = incr_op_node; |
| 6125 } | 6138 } |
| 6126 return postfix_expr; | 6139 return postfix_expr; |
| 6127 } | 6140 } |
| 6128 | 6141 |
| 6129 | 6142 |
| 6130 // Try to resolve the given type and its type arguments from the given class. | 6143 // Resolve the given type and its type arguments from the given class according |
| 6144 // to the given type_resolution. |
| 6131 // Not all involved type classes may get resolved yet, but at least the type | 6145 // Not all involved type classes may get resolved yet, but at least the type |
| 6132 // parameters of the given class will get resolved, thereby relieving the class | 6146 // parameters of the given class will get resolved, thereby relieving the class |
| 6133 // finalizer from resolving type parameters out of context. | 6147 // finalizer from resolving type parameters out of context. |
| 6134 void Parser::TryResolveTypeFromClass(intptr_t type_pos, | 6148 void Parser::ResolveTypeFromClass(intptr_t type_pos, |
| 6135 const Class& cls, | 6149 const Class& cls, |
| 6136 AbstractType* type) { | 6150 TypeResolution type_resolution, |
| 6151 AbstractType* type) { |
| 6152 // TODO(regis): Implement kMustResolve functionality and consolidate with |
| 6153 // other resolution code. For now, only support kCanResolve functionality. |
| 6154 ASSERT(type_resolution == kCanResolve); |
| 6137 ASSERT(type != NULL); | 6155 ASSERT(type != NULL); |
| 6138 // Resolve class. | 6156 // Resolve class. |
| 6139 if (!type->HasResolvedTypeClass()) { | 6157 if (!type->HasResolvedTypeClass()) { |
| 6140 const UnresolvedClass& unresolved_class = | 6158 const UnresolvedClass& unresolved_class = |
| 6141 UnresolvedClass::Handle(type->unresolved_class()); | 6159 UnresolvedClass::Handle(type->unresolved_class()); |
| 6142 const String& unresolved_class_name = | 6160 const String& unresolved_class_name = |
| 6143 String::Handle(unresolved_class.ident()); | 6161 String::Handle(unresolved_class.ident()); |
| 6144 // First check if the type is a type parameter of the given class. | 6162 // First check if the type is a type parameter of the given class. |
| 6145 const TypeParameter& type_parameter = TypeParameter::Handle( | 6163 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 6146 cls.LookupTypeParameter(unresolved_class_name)); | 6164 cls.LookupTypeParameter(unresolved_class_name)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 6165 parameterized_type.set_type_class(type_class); | 6183 parameterized_type.set_type_class(type_class); |
| 6166 } | 6184 } |
| 6167 } | 6185 } |
| 6168 // Resolve type arguments, if any. | 6186 // Resolve type arguments, if any. |
| 6169 const AbstractTypeArguments& arguments = | 6187 const AbstractTypeArguments& arguments = |
| 6170 AbstractTypeArguments::Handle(type->arguments()); | 6188 AbstractTypeArguments::Handle(type->arguments()); |
| 6171 if (!arguments.IsNull()) { | 6189 if (!arguments.IsNull()) { |
| 6172 const intptr_t num_arguments = arguments.Length(); | 6190 const intptr_t num_arguments = arguments.Length(); |
| 6173 for (intptr_t i = 0; i < num_arguments; i++) { | 6191 for (intptr_t i = 0; i < num_arguments; i++) { |
| 6174 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); | 6192 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); |
| 6175 TryResolveTypeFromClass(type_pos, cls, &type_argument); | 6193 ResolveTypeFromClass(type_pos, cls, type_resolution, &type_argument); |
| 6176 arguments.SetTypeAt(i, type_argument); | 6194 arguments.SetTypeAt(i, type_argument); |
| 6177 } | 6195 } |
| 6178 } | 6196 } |
| 6179 } | 6197 } |
| 6180 | 6198 |
| 6181 | 6199 |
| 6182 // Return class for type name. If the name cannot be resolved (yet), give an | 6200 // Return class for type name. If the name cannot be resolved (yet), give an |
| 6183 // error (if type_resolution == kMustResolve) or return the unresolved name. | 6201 // error (if type_resolution == kMustResolve) or return the unresolved name. |
| 6184 RawObject* Parser::LookupTypeClass(const QualIdent& type_name, | 6202 RawObject* Parser::LookupTypeClass(const QualIdent& type_name, |
| 6185 TypeResolution type_resolution) { | 6203 TypeResolution type_resolution) { |
| 6186 ASSERT(type_name.ident != NULL); | 6204 ASSERT(type_name.ident != NULL); |
| 6205 ASSERT((type_resolution == kCanResolve) || (type_resolution == kMustResolve)); |
| 6187 Class& type_class = Class::Handle(); | 6206 Class& type_class = Class::Handle(); |
| 6188 if (type_name.lib_prefix != NULL) { | 6207 if (type_name.lib_prefix != NULL) { |
| 6189 Library& lib = Library::Handle(type_name.lib_prefix->library()); | 6208 Library& lib = Library::Handle(type_name.lib_prefix->library()); |
| 6190 type_class ^= lib.LookupLocalClass(*type_name.ident); | 6209 type_class = lib.LookupLocalClass(*type_name.ident); |
| 6191 } else { | 6210 } else { |
| 6192 type_class ^= LookupClass(*type_name.ident); | 6211 type_class = LookupClass(*type_name.ident); |
| 6193 } | 6212 } |
| 6194 if (!type_class.IsNull()) { | 6213 if (!type_class.IsNull()) { |
| 6195 return type_class.raw(); | 6214 return type_class.raw(); |
| 6196 } | 6215 } |
| 6197 // Type name could not be resolved (yet). | 6216 // Type name could not be resolved (yet). |
| 6198 if (type_resolution == kMustResolve) { | 6217 if (type_resolution == kMustResolve) { |
| 6199 ErrorMsg(type_name.ident_pos, "type '%s' is not loaded", | 6218 ErrorMsg(type_name.ident_pos, "type '%s' is not loaded", |
| 6200 type_name.ident->ToCString()); | 6219 type_name.ident->ToCString()); |
| 6201 return Object::null_class(); | 6220 return Object::null_class(); |
| 6202 } | 6221 } |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6612 Object& type_class = Object::Handle(); | 6631 Object& type_class = Object::Handle(); |
| 6613 if (type_resolution == kIgnore) { | 6632 if (type_resolution == kIgnore) { |
| 6614 // Leave type_class as null. | 6633 // Leave type_class as null. |
| 6615 } else if (type_resolution == kDoNotResolve) { | 6634 } else if (type_resolution == kDoNotResolve) { |
| 6616 String& qualifier = String::Handle(); | 6635 String& qualifier = String::Handle(); |
| 6617 if (type_name.qualifier != NULL) { | 6636 if (type_name.qualifier != NULL) { |
| 6618 qualifier ^= type_name.qualifier->raw(); | 6637 qualifier ^= type_name.qualifier->raw(); |
| 6619 } | 6638 } |
| 6620 type_class = UnresolvedClass::New(type_pos, qualifier, *type_name.ident); | 6639 type_class = UnresolvedClass::New(type_pos, qualifier, *type_name.ident); |
| 6621 } else { | 6640 } else { |
| 6641 ASSERT((type_resolution == kCanResolve) || |
| 6642 (type_resolution == kMustResolve)); |
| 6622 scope_class = TypeParametersScopeClass(); | 6643 scope_class = TypeParametersScopeClass(); |
| 6623 if (!scope_class.IsNull()) { | 6644 if (!scope_class.IsNull()) { |
| 6624 TypeParameter& type_parameter = TypeParameter::Handle(); | |
| 6625 // Check if qualifier is a type parameter in scope. | |
| 6626 if (type_name.qualifier != NULL) { | 6645 if (type_name.qualifier != NULL) { |
| 6627 type_parameter = scope_class.LookupTypeParameter(*type_name.qualifier); | 6646 // Check if qualifier is a type parameter in scope, unless it was |
| 6628 if (!type_parameter.IsNull()) { | 6647 // already checked by ParseQualIdent when !is_top_level_. |
| 6629 ErrorMsg(type_pos, "type Parameter '%s' cannot be used as qualifier", | 6648 if (is_top_level_) { |
| 6630 type_name.qualifier->ToCString()); | 6649 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 6650 scope_class.LookupTypeParameter(*type_name.qualifier)); |
| 6651 if (!type_parameter.IsNull()) { |
| 6652 ErrorMsg(type_pos, |
| 6653 "type Parameter '%s' cannot be used as qualifier", |
| 6654 type_name.qualifier->ToCString()); |
| 6655 } |
| 6631 } | 6656 } |
| 6632 } else { | 6657 } else { |
| 6633 // Check if ident is a type parameter in scope. | 6658 // Check if ident is a type parameter in scope. |
| 6634 type_parameter = scope_class.LookupTypeParameter(*type_name.ident); | 6659 TypeParameter& type_parameter = TypeParameter::Handle( |
| 6660 scope_class.LookupTypeParameter(*type_name.ident)); |
| 6635 if (!type_parameter.IsNull()) { | 6661 if (!type_parameter.IsNull()) { |
| 6636 if (CurrentToken() == Token::kLT) { | 6662 if (CurrentToken() == Token::kLT) { |
| 6637 // A type parameter cannot be parameterized. | 6663 // A type parameter cannot be parameterized. |
| 6638 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", | 6664 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", |
| 6639 String::Handle(type_parameter.Name()).ToCString()); | 6665 String::Handle(type_parameter.Name()).ToCString()); |
| 6640 } | 6666 } |
| 6641 if (type_resolution == kMustResolve) { | 6667 if (type_resolution == kMustResolve) { |
| 6642 Error& error = Error::Handle(); | 6668 Error& error = Error::Handle(); |
| 6643 type_parameter ^= | 6669 type_parameter ^= |
| 6644 ClassFinalizer::FinalizeAndCanonicalizeType(scope_class, | 6670 ClassFinalizer::FinalizeAndCanonicalizeType(scope_class, |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7061 AstNode* Parser::ParseNewOperator() { | 7087 AstNode* Parser::ParseNewOperator() { |
| 7062 TRACE_PARSER("ParseNewOperator"); | 7088 TRACE_PARSER("ParseNewOperator"); |
| 7063 const intptr_t new_pos = token_index_; | 7089 const intptr_t new_pos = token_index_; |
| 7064 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 7090 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 7065 bool is_const = (CurrentToken() == Token::kCONST); | 7091 bool is_const = (CurrentToken() == Token::kCONST); |
| 7066 ConsumeToken(); | 7092 ConsumeToken(); |
| 7067 if (!IsIdentifier()) { | 7093 if (!IsIdentifier()) { |
| 7068 ErrorMsg("type name expected"); | 7094 ErrorMsg("type name expected"); |
| 7069 } | 7095 } |
| 7070 | 7096 |
| 7071 // The grammar allows for an optional ('.' identifier)?, which is a named | 7097 const AbstractType& type = AbstractType::Handle(ParseType(kMustResolve)); |
| 7072 // constructor. For that reason, we cannot unconditionally call | 7098 if (type.IsTypeParameter()) { |
| 7073 // ParseType(kMustResolve) after we see an identifier, because the named | 7099 // TODO(regis): Use type position once supported. |
| 7074 // constructor would be misinterpreted as a qualified type name. | 7100 ErrorMsg(new_pos, "type parameter '%s' cannot be instantiated", |
| 7075 // TODO(regis): Revisit once we correctly support qualified identifiers. | 7101 String::Handle(type.Name()).ToCString()); |
| 7076 // For now, we inline a customized version of ParseType(kMustResolve). | |
| 7077 const intptr_t type_pos = token_index_; | |
| 7078 QualIdent type_name; | |
| 7079 ParseQualIdent(&type_name); | |
| 7080 ASSERT(!is_top_level_); | |
| 7081 if ((type_name.qualifier == NULL) && | |
| 7082 ResolveIdentInLocalScope(type_pos, *type_name.ident, NULL)) { | |
| 7083 ErrorMsg(type_pos, "using '%s' in this context is invalid", | |
| 7084 type_name.ident->ToCString()); | |
| 7085 } | 7102 } |
| 7103 Class& type_class = Class::Handle(type.type_class()); |
| 7104 String& type_class_name = String::Handle(type_class.Name()); |
| 7105 AbstractTypeArguments& type_arguments = |
| 7106 AbstractTypeArguments::ZoneHandle(type.arguments()); |
| 7107 |
| 7108 // The constructor class and its name are those of the parsed type, unless the |
| 7109 // parsed type is an interface and a default factory class is specified, in |
| 7110 // which case constructor_class and constructor_class_name are modified below. |
| 7111 Class& constructor_class = Class::ZoneHandle(type_class.raw()); |
| 7112 String& constructor_class_name = String::Handle(type_class_name.raw()); |
| 7113 |
| 7114 // The grammar allows for an optional ('.' identifier)? after the type, which |
| 7115 // is a named constructor. Note that ParseType(kMustResolve) above will not |
| 7116 // consume it as part of a misinterpreted qualified identifier, because only a |
| 7117 // valid library prefix is accepted as qualifier. |
| 7086 String* named_constructor = NULL; | 7118 String* named_constructor = NULL; |
| 7087 if (CurrentToken() == Token::kPERIOD) { | 7119 if (CurrentToken() == Token::kPERIOD) { |
| 7088 ConsumeToken(); | 7120 ConsumeToken(); |
| 7089 named_constructor = ExpectIdentifier("identifier expected after '.'"); | |
| 7090 } | |
| 7091 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | |
| 7092 if (!scope_class.IsNull()) { | |
| 7093 TypeParameter& type_parameter = TypeParameter::Handle(); | |
| 7094 if (type_name.lib_prefix != NULL) { | |
| 7095 // Check if qualifier is a type parameter in scope. | |
| 7096 type_parameter ^= scope_class.LookupTypeParameter(*type_name.qualifier); | |
| 7097 if (!type_parameter.IsNull()) { | |
| 7098 ErrorMsg(type_pos, "type parameter '%s' cannot be used as qualifier", | |
| 7099 String::Handle(type_parameter.Name()).ToCString()); | |
| 7100 } | |
| 7101 } | |
| 7102 // Check if ident is a type parameter in scope. | |
| 7103 type_parameter = scope_class.LookupTypeParameter(*type_name.ident); | |
| 7104 if (!type_parameter.IsNull()) { | |
| 7105 ErrorMsg(type_pos, "type parameter '%s' cannot be instantiated", | |
| 7106 String::Handle(type_parameter.Name()).ToCString()); | |
| 7107 } | |
| 7108 } | |
| 7109 Class& type_class = Class::ZoneHandle(); | |
| 7110 type_class ^= LookupTypeClass(type_name, kMustResolve); | |
| 7111 String& type_class_name = String::Handle(); | |
| 7112 type_class_name = type_class.Name(); | |
| 7113 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | |
| 7114 // Type arguments are not allowed after the optional constructor name. | |
| 7115 if (named_constructor == NULL) { | |
| 7116 type_arguments = ParseTypeArguments(kMustResolve); | |
| 7117 } | |
| 7118 if ((named_constructor == NULL) && (CurrentToken() == Token::kPERIOD)) { | |
| 7119 ConsumeToken(); | |
| 7120 named_constructor = ExpectIdentifier("name of constructor expected"); | 7121 named_constructor = ExpectIdentifier("name of constructor expected"); |
| 7121 } | 7122 } |
| 7122 | 7123 |
| 7123 // Parse constructor parameters. | 7124 // Parse constructor parameters. |
| 7124 if (CurrentToken() != Token::kLPAREN) { | 7125 if (CurrentToken() != Token::kLPAREN) { |
| 7125 ErrorMsg("'(' expected"); | 7126 ErrorMsg("'(' expected"); |
| 7126 } | 7127 } |
| 7127 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 7128 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
| 7128 | 7129 |
| 7129 // A constructor has an implicit 'this' parameter (instance to construct) | 7130 // A constructor has an implicit 'this' parameter (instance to construct) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7163 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); | 7164 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); |
| 7164 } | 7165 } |
| 7165 // Only change the class of the constructor to the factory class if the | 7166 // Only change the class of the constructor to the factory class if the |
| 7166 // factory class implements the interface 'type'. | 7167 // factory class implements the interface 'type'. |
| 7167 const Class& factory_class = Class::Handle(type_class.FactoryClass()); | 7168 const Class& factory_class = Class::Handle(type_class.FactoryClass()); |
| 7168 if (factory_class.IsSubtypeOf(TypeArguments::Handle(), | 7169 if (factory_class.IsSubtypeOf(TypeArguments::Handle(), |
| 7169 type_class, | 7170 type_class, |
| 7170 TypeArguments::Handle())) { | 7171 TypeArguments::Handle())) { |
| 7171 // Class finalization verifies that the factory class has identical type | 7172 // Class finalization verifies that the factory class has identical type |
| 7172 // parameters as the interface. | 7173 // parameters as the interface. |
| 7173 type_class_name = factory_class.Name(); | 7174 constructor_class_name = factory_class.Name(); |
| 7174 } | 7175 } |
| 7175 // Always change the result type of the constructor to the factory type. | 7176 // Always change the result type of the constructor to the factory type. |
| 7176 type_class = factory_class.raw(); | 7177 constructor_class = factory_class.raw(); |
| 7177 ASSERT(!type_class.is_interface()); | 7178 // The finalized type_arguments are still those of the interface type. |
| 7179 ASSERT(!constructor_class.is_interface()); |
| 7178 } | 7180 } |
| 7179 | 7181 |
| 7180 // Make sure that an appropriate constructor exists. | 7182 // Make sure that an appropriate constructor exists. |
| 7181 const String& constructor_name = | 7183 const String& constructor_name = |
| 7182 BuildConstructorName(type_class_name, named_constructor); | 7184 BuildConstructorName(constructor_class_name, named_constructor); |
| 7183 const String& external_constructor_name = | |
| 7184 (named_constructor ? constructor_name : type_class_name); | |
| 7185 Function& constructor = Function::ZoneHandle( | 7185 Function& constructor = Function::ZoneHandle( |
| 7186 type_class.LookupConstructor(constructor_name)); | 7186 constructor_class.LookupConstructor(constructor_name)); |
| 7187 if (constructor.IsNull()) { | 7187 if (constructor.IsNull()) { |
| 7188 constructor = type_class.LookupFactory(constructor_name); | 7188 constructor = constructor_class.LookupFactory(constructor_name); |
| 7189 // A factory does not have the implicit 'phase' parameter. | 7189 // A factory does not have the implicit 'phase' parameter. |
| 7190 arguments_length -= 1; | 7190 arguments_length -= 1; |
| 7191 } | 7191 } |
| 7192 if (constructor.IsNull()) { | 7192 if (constructor.IsNull()) { |
| 7193 const String& external_constructor_name = |
| 7194 (named_constructor ? constructor_name : constructor_class_name); |
| 7193 ErrorMsg(new_pos, "class '%s' has no constructor or factory named '%s'", | 7195 ErrorMsg(new_pos, "class '%s' has no constructor or factory named '%s'", |
| 7194 String::Handle(type_class.Name()).ToCString(), | 7196 String::Handle(constructor_class.Name()).ToCString(), |
| 7195 external_constructor_name.ToCString()); | 7197 external_constructor_name.ToCString()); |
| 7196 } | 7198 } |
| 7197 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { | 7199 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { |
| 7200 const String& external_constructor_name = |
| 7201 (named_constructor ? constructor_name : constructor_class_name); |
| 7198 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' " | 7202 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' " |
| 7199 "for class '%s'", | 7203 "for class '%s'", |
| 7200 external_constructor_name.ToCString(), | 7204 external_constructor_name.ToCString(), |
| 7201 String::Handle(type_class.Name()).ToCString()); | 7205 String::Handle(constructor_class.Name()).ToCString()); |
| 7202 } | 7206 } |
| 7203 | 7207 |
| 7204 // Now that the constructor to be called is identified, finalize the type | 7208 // Now that the constructor to be called is identified, finalize the type |
| 7205 // argument vector to be passed. | 7209 // argument vector to be passed. |
| 7206 { | 7210 // The type argument vector of the parsed type was finalized in ParseType. |
| 7207 ASSERT(constructor.owner() == type_class.raw()); | 7211 // If the constructor class was changed from the interface class to the |
| 7212 // factory class, we need to finalize the type argument vector again, because |
| 7213 // it may be longer due to the factory class extending a class, or/and because |
| 7214 // the bounds on the factory class may be tighter than on the interface. |
| 7215 if (constructor_class.raw() != type_class.raw()) { |
| 7216 const intptr_t num_type_parameters = constructor_class.NumTypeParameters(); |
| 7217 // TODO(regis): Temporary type args should be allocated in new gen heap. |
| 7218 TypeArguments& temp_type_arguments = TypeArguments::Handle(); |
| 7219 if (!type_arguments.IsNull()) { |
| 7220 // Copy the parsed type arguments starting at offset 0, because interfaces |
| 7221 // have no super types. |
| 7222 ASSERT(type_class.NumTypeArguments() == type_class.NumTypeParameters()); |
| 7223 const intptr_t num_type_arguments = type_arguments.Length(); |
| 7224 temp_type_arguments = TypeArguments::New(num_type_parameters); |
| 7225 AbstractType& type_argument = AbstractType::Handle(); |
| 7226 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 7227 if (i < num_type_arguments) { |
| 7228 type_argument = type_arguments.TypeAt(i); |
| 7229 } else { |
| 7230 type_argument = Type::DynamicType(); |
| 7231 } |
| 7232 temp_type_arguments.SetTypeAt(i, type_argument); |
| 7233 } |
| 7234 } |
| 7208 // TODO(regis): Temporary type should be allocated in new gen heap. | 7235 // TODO(regis): Temporary type should be allocated in new gen heap. |
| 7209 Type& type = Type::Handle( | 7236 Type& temp_type = Type::Handle( |
| 7210 Type::NewParameterizedType(type_class, type_arguments)); | 7237 Type::NewParameterizedType(constructor_class, temp_type_arguments)); |
| 7211 Error& error = Error::Handle(); | 7238 Error& error = Error::Handle(); |
| 7212 type ^= ClassFinalizer::FinalizeAndCanonicalizeType(type_class, | 7239 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
| 7213 type, | 7240 temp_type ^= ClassFinalizer::FinalizeAndCanonicalizeType(scope_class, |
| 7214 &error); | 7241 temp_type, |
| 7242 &error); |
| 7215 if (!error.IsNull()) { | 7243 if (!error.IsNull()) { |
| 7216 ErrorMsg(error.ToErrorCString()); | 7244 ErrorMsg(error.ToErrorCString()); |
| 7217 } | 7245 } |
| 7218 // The type argument vector may have been expanded with the type arguments | 7246 // The type argument vector may have been expanded with the type arguments |
| 7219 // of the super type when finalizing the type. | 7247 // of the super type when finalizing the temporary type. |
| 7220 type_arguments = type.arguments(); | 7248 type_arguments = temp_type.arguments(); |
| 7221 } | 7249 } |
| 7222 | 7250 |
| 7223 type_arguments ^= type_arguments.Canonicalize(); | 7251 type_arguments ^= type_arguments.Canonicalize(); |
| 7224 // Make the constructor call. | 7252 // Make the constructor call. |
| 7225 AstNode* new_object = NULL; | 7253 AstNode* new_object = NULL; |
| 7226 if (is_const) { | 7254 if (is_const) { |
| 7227 if (!constructor.is_const()) { | 7255 if (!constructor.is_const()) { |
| 7228 ErrorMsg("'const' requires const constructor: '%s'", | 7256 ErrorMsg("'const' requires const constructor: '%s'", |
| 7229 String::Handle(constructor.name()).ToCString()); | 7257 String::Handle(constructor.name()).ToCString()); |
| 7230 } | 7258 } |
| 7231 const Instance& const_instance = Instance::ZoneHandle( | 7259 const Instance& const_instance = Instance::ZoneHandle( |
| 7232 EvaluateConstConstructorCall(type_class, | 7260 EvaluateConstConstructorCall(constructor_class, |
| 7233 type_arguments, | 7261 type_arguments, |
| 7234 constructor, | 7262 constructor, |
| 7235 arguments)); | 7263 arguments)); |
| 7236 if (const_instance.IsUnhandledException()) { | 7264 if (const_instance.IsUnhandledException()) { |
| 7237 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance); | 7265 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance); |
| 7238 } else { | 7266 } else { |
| 7239 new_object = new LiteralNode(new_pos, const_instance); | 7267 new_object = new LiteralNode(new_pos, const_instance); |
| 7240 } | 7268 } |
| 7241 } else { | 7269 } else { |
| 7242 CheckFunctionIsCallable(new_pos, constructor); | 7270 CheckFunctionIsCallable(new_pos, constructor); |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7701 void Parser::SkipQualIdent() { | 7729 void Parser::SkipQualIdent() { |
| 7702 ASSERT(IsIdentifier()); | 7730 ASSERT(IsIdentifier()); |
| 7703 ConsumeToken(); | 7731 ConsumeToken(); |
| 7704 if (CurrentToken() == Token::kPERIOD) { | 7732 if (CurrentToken() == Token::kPERIOD) { |
| 7705 ConsumeToken(); // Consume the kPERIOD token. | 7733 ConsumeToken(); // Consume the kPERIOD token. |
| 7706 ExpectIdentifier("identifier expected after '.'"); | 7734 ExpectIdentifier("identifier expected after '.'"); |
| 7707 } | 7735 } |
| 7708 } | 7736 } |
| 7709 | 7737 |
| 7710 } // namespace dart | 7738 } // namespace dart |
| OLD | NEW |