| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 2984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2995 if (!owner.IsObjectClass()) { | 2995 if (!owner.IsObjectClass()) { |
| 2996 AddEqualityNullCheck(); | 2996 AddEqualityNullCheck(); |
| 2997 } | 2997 } |
| 2998 } | 2998 } |
| 2999 ParseNativeFunctionBlock(¶ms, func); | 2999 ParseNativeFunctionBlock(¶ms, func); |
| 3000 end_token_pos = TokenPos(); | 3000 end_token_pos = TokenPos(); |
| 3001 ExpectSemicolon(); | 3001 ExpectSemicolon(); |
| 3002 } else if (func.is_external()) { | 3002 } else if (func.is_external()) { |
| 3003 // Body of an external method contains a single throw. | 3003 // Body of an external method contains a single throw. |
| 3004 const String& function_name = String::ZoneHandle(I, func.name()); | 3004 const String& function_name = String::ZoneHandle(I, func.name()); |
| 3005 // TODO(regis): For an instance function, pass the receiver to | |
| 3006 // NoSuchMethodError. | |
| 3007 current_block_->statements->Add( | 3005 current_block_->statements->Add( |
| 3008 ThrowNoSuchMethodError(TokenPos(), | 3006 ThrowNoSuchMethodError(TokenPos(), |
| 3009 current_class(), | 3007 current_class(), |
| 3010 function_name, | 3008 function_name, |
| 3011 NULL, // No arguments. | 3009 NULL, // Ignore arguments. |
| 3012 func.is_static() ? | 3010 func.is_static() ? |
| 3013 InvocationMirror::kStatic : | 3011 InvocationMirror::kStatic : |
| 3014 InvocationMirror::kDynamic, | 3012 InvocationMirror::kDynamic, |
| 3015 InvocationMirror::kMethod, | 3013 InvocationMirror::kMethod, |
| 3016 NULL)); // No existing function. | 3014 &func)); // Unpatched external function. |
| 3017 end_token_pos = TokenPos(); | 3015 end_token_pos = TokenPos(); |
| 3018 } else { | 3016 } else { |
| 3019 UnexpectedToken(); | 3017 UnexpectedToken(); |
| 3020 } | 3018 } |
| 3021 | 3019 |
| 3022 ASSERT(func.end_token_pos() == func.token_pos() || | 3020 ASSERT(func.end_token_pos() == func.token_pos() || |
| 3023 func.end_token_pos() == end_token_pos); | 3021 func.end_token_pos() == end_token_pos); |
| 3024 func.set_end_token_pos(end_token_pos); | 3022 func.set_end_token_pos(end_token_pos); |
| 3025 SequenceNode* body = CloseBlock(); | 3023 SequenceNode* body = CloseBlock(); |
| 3026 current_block_->statements->Add(body); | 3024 current_block_->statements->Add(body); |
| (...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3944 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); | 3942 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); |
| 3945 if (new_type_params_count != orig_type_params_count) { | 3943 if (new_type_params_count != orig_type_params_count) { |
| 3946 ErrorMsg(classname_pos, | 3944 ErrorMsg(classname_pos, |
| 3947 "class '%s' must be patched with identical type parameters", | 3945 "class '%s' must be patched with identical type parameters", |
| 3948 class_name.ToCString()); | 3946 class_name.ToCString()); |
| 3949 } | 3947 } |
| 3950 TypeParameter& new_type_param = TypeParameter::Handle(isolate()); | 3948 TypeParameter& new_type_param = TypeParameter::Handle(isolate()); |
| 3951 TypeParameter& orig_type_param = TypeParameter::Handle(isolate()); | 3949 TypeParameter& orig_type_param = TypeParameter::Handle(isolate()); |
| 3952 String& new_name = String::Handle(isolate()); | 3950 String& new_name = String::Handle(isolate()); |
| 3953 String& orig_name = String::Handle(isolate()); | 3951 String& orig_name = String::Handle(isolate()); |
| 3952 AbstractType& new_bound = AbstractType::Handle(isolate()); |
| 3953 AbstractType& orig_bound = AbstractType::Handle(isolate()); |
| 3954 for (int i = 0; i < new_type_params_count; i++) { | 3954 for (int i = 0; i < new_type_params_count; i++) { |
| 3955 new_type_param ^= new_type_parameters.TypeAt(i); | 3955 new_type_param ^= new_type_parameters.TypeAt(i); |
| 3956 orig_type_param ^= orig_type_parameters.TypeAt(i); | 3956 orig_type_param ^= orig_type_parameters.TypeAt(i); |
| 3957 new_name = new_type_param.name(); | 3957 new_name = new_type_param.name(); |
| 3958 orig_name = orig_type_param.name(); | 3958 orig_name = orig_type_param.name(); |
| 3959 if (!new_name.Equals(orig_name)) { | 3959 if (!new_name.Equals(orig_name)) { |
| 3960 ErrorMsg(new_type_param.token_pos(), | 3960 ErrorMsg(new_type_param.token_pos(), |
| 3961 "type parameter '%s' of patch class '%s' does not match " | 3961 "type parameter '%s' of patch class '%s' does not match " |
| 3962 "original type parameter '%s'", | 3962 "original type parameter '%s'", |
| 3963 new_name.ToCString(), | 3963 new_name.ToCString(), |
| 3964 class_name.ToCString(), | 3964 class_name.ToCString(), |
| 3965 orig_name.ToCString()); | 3965 orig_name.ToCString()); |
| 3966 } | 3966 } |
| 3967 // We do not check that the bounds are repeated. We use the original ones. | 3967 new_bound = new_type_param.bound(); |
| 3968 // TODO(regis): Should we check? | 3968 orig_bound = orig_type_param.bound(); |
| 3969 if (!new_bound.Equals(orig_bound)) { |
| 3970 ErrorMsg(new_type_param.token_pos(), |
| 3971 "bound '%s' of type parameter '%s' of patch class '%s' does " |
| 3972 "not match original type parameter bound '%s'", |
| 3973 String::Handle(new_bound.UserVisibleName()).ToCString(), |
| 3974 new_name.ToCString(), |
| 3975 class_name.ToCString(), |
| 3976 String::Handle(orig_bound.UserVisibleName()).ToCString()); |
| 3977 } |
| 3969 } | 3978 } |
| 3970 cls.set_type_parameters(orig_type_parameters); | 3979 cls.set_type_parameters(orig_type_parameters); |
| 3971 } | 3980 } |
| 3972 | 3981 |
| 3973 if (is_abstract) { | 3982 if (is_abstract) { |
| 3974 cls.set_is_abstract(); | 3983 cls.set_is_abstract(); |
| 3975 } | 3984 } |
| 3976 if (metadata_pos >= 0) { | 3985 if (metadata_pos >= 0) { |
| 3977 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); | 3986 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); |
| 3978 } | 3987 } |
| (...skipping 3649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7628 arguments); | 7637 arguments); |
| 7629 } | 7638 } |
| 7630 | 7639 |
| 7631 | 7640 |
| 7632 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, | 7641 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, |
| 7633 const Class& cls, | 7642 const Class& cls, |
| 7634 const String& function_name, | 7643 const String& function_name, |
| 7635 ArgumentListNode* function_arguments, | 7644 ArgumentListNode* function_arguments, |
| 7636 InvocationMirror::Call im_call, | 7645 InvocationMirror::Call im_call, |
| 7637 InvocationMirror::Type im_type, | 7646 InvocationMirror::Type im_type, |
| 7638 Function* func) { | 7647 const Function* func) { |
| 7639 ArgumentListNode* arguments = new(isolate()) ArgumentListNode(call_pos); | 7648 ArgumentListNode* arguments = new(isolate()) ArgumentListNode(call_pos); |
| 7640 // Object receiver. | 7649 // Object receiver. |
| 7641 // TODO(regis): For now, we pass a class literal of the unresolved | 7650 // If the function is external and dynamic, pass the actual receiver, |
| 7642 // method's owner, but this is not specified and will probably change. | 7651 // otherwise, pass a class literal of the unresolved method's owner. |
| 7643 Type& type = Type::ZoneHandle(I, | 7652 if ((func != NULL) && !func->IsNull() && |
| 7644 Type::New(cls, TypeArguments::Handle(isolate()), call_pos, Heap::kOld)); | 7653 func->is_external() && !func->is_static()) { |
| 7645 type ^= ClassFinalizer::FinalizeType( | 7654 arguments->Add(LoadReceiver(func->token_pos())); |
| 7646 current_class(), type, ClassFinalizer::kCanonicalize); | 7655 } else { |
| 7647 arguments->Add(new(isolate()) LiteralNode(call_pos, type)); | 7656 Type& type = Type::ZoneHandle(I, |
| 7657 Type::New(cls, TypeArguments::Handle(isolate()), call_pos, Heap::kOld)); |
| 7658 type ^= ClassFinalizer::FinalizeType( |
| 7659 current_class(), type, ClassFinalizer::kCanonicalize); |
| 7660 arguments->Add(new(isolate()) LiteralNode(call_pos, type)); |
| 7661 } |
| 7648 // String memberName. | 7662 // String memberName. |
| 7649 arguments->Add(new(isolate()) LiteralNode( | 7663 arguments->Add(new(isolate()) LiteralNode( |
| 7650 call_pos, String::ZoneHandle(I, Symbols::New(function_name)))); | 7664 call_pos, String::ZoneHandle(I, Symbols::New(function_name)))); |
| 7651 // Smi invocation_type. | 7665 // Smi invocation_type. |
| 7652 if (cls.IsTopLevel()) { | 7666 if (cls.IsTopLevel()) { |
| 7653 ASSERT(im_call == InvocationMirror::kStatic || | 7667 ASSERT(im_call == InvocationMirror::kStatic || |
| 7654 im_call == InvocationMirror::kTopLevel); | 7668 im_call == InvocationMirror::kTopLevel); |
| 7655 im_call = InvocationMirror::kTopLevel; | 7669 im_call = InvocationMirror::kTopLevel; |
| 7656 } | 7670 } |
| 7657 arguments->Add(new(isolate()) LiteralNode(call_pos, Smi::ZoneHandle(I, | 7671 arguments->Add(new(isolate()) LiteralNode(call_pos, Smi::ZoneHandle(I, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 7679 // has done the lookup already. If there is a function with the same | 7693 // has done the lookup already. If there is a function with the same |
| 7680 // name but incompatible parameters, inform the NoSuchMethodError what the | 7694 // name but incompatible parameters, inform the NoSuchMethodError what the |
| 7681 // expected parameters are. | 7695 // expected parameters are. |
| 7682 Function& function = Function::Handle(isolate()); | 7696 Function& function = Function::Handle(isolate()); |
| 7683 if (func != NULL) { | 7697 if (func != NULL) { |
| 7684 function = func->raw(); | 7698 function = func->raw(); |
| 7685 } else { | 7699 } else { |
| 7686 function = cls.LookupStaticFunction(function_name); | 7700 function = cls.LookupStaticFunction(function_name); |
| 7687 } | 7701 } |
| 7688 Array& array = Array::ZoneHandle(I); | 7702 Array& array = Array::ZoneHandle(I); |
| 7689 if (!function.IsNull()) { | 7703 // An unpatched external function is treated as an unresolved function. |
| 7704 if (!function.IsNull() && !function.is_external()) { |
| 7690 // The constructor for NoSuchMethodError takes a list of existing | 7705 // The constructor for NoSuchMethodError takes a list of existing |
| 7691 // parameter names to produce a descriptive error message explaining | 7706 // parameter names to produce a descriptive error message explaining |
| 7692 // the parameter mismatch. The problem is that the array of names | 7707 // the parameter mismatch. The problem is that the array of names |
| 7693 // does not describe which parameters are optional positional or | 7708 // does not describe which parameters are optional positional or |
| 7694 // named, which can lead to confusing error messages. | 7709 // named, which can lead to confusing error messages. |
| 7695 // Since the NoSuchMethodError class only uses the list to produce | 7710 // Since the NoSuchMethodError class only uses the list to produce |
| 7696 // a string describing the expected parameters, we construct a more | 7711 // a string describing the expected parameters, we construct a more |
| 7697 // descriptive string here and pass it as the only element of the | 7712 // descriptive string here and pass it as the only element of the |
| 7698 // "existingArgumentNames" array of the NoSuchMethodError constructor. | 7713 // "existingArgumentNames" array of the NoSuchMethodError constructor. |
| 7699 // TODO(13471): Separate the implementations of NoSuchMethodError | 7714 // TODO(13471): Separate the implementations of NoSuchMethodError |
| (...skipping 2476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10176 String::Handle(isolate(), type_class.Name()).ToCString(), | 10191 String::Handle(isolate(), type_class.Name()).ToCString(), |
| 10177 external_constructor_name.ToCString()); | 10192 external_constructor_name.ToCString()); |
| 10178 ErrorMsg(Error::Handle(isolate(), type.error())); | 10193 ErrorMsg(Error::Handle(isolate(), type.error())); |
| 10179 } | 10194 } |
| 10180 return ThrowNoSuchMethodError(call_pos, | 10195 return ThrowNoSuchMethodError(call_pos, |
| 10181 type_class, | 10196 type_class, |
| 10182 external_constructor_name, | 10197 external_constructor_name, |
| 10183 arguments, | 10198 arguments, |
| 10184 InvocationMirror::kConstructor, | 10199 InvocationMirror::kConstructor, |
| 10185 InvocationMirror::kMethod, | 10200 InvocationMirror::kMethod, |
| 10186 &constructor); | 10201 NULL); // No existing function. |
| 10187 } else if (constructor.IsRedirectingFactory()) { | 10202 } else if (constructor.IsRedirectingFactory()) { |
| 10188 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); | 10203 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); |
| 10189 Type& redirect_type = Type::Handle(isolate(), | 10204 Type& redirect_type = Type::Handle(isolate(), |
| 10190 constructor.RedirectionType()); | 10205 constructor.RedirectionType()); |
| 10191 if (!redirect_type.IsMalformedOrMalbounded() && | 10206 if (!redirect_type.IsMalformedOrMalbounded() && |
| 10192 !redirect_type.IsInstantiated()) { | 10207 !redirect_type.IsInstantiated()) { |
| 10193 // The type arguments of the redirection type are instantiated from the | 10208 // The type arguments of the redirection type are instantiated from the |
| 10194 // type arguments of the parsed type of the 'new' or 'const' expression. | 10209 // type arguments of the parsed type of the 'new' or 'const' expression. |
| 10195 Error& error = Error::Handle(isolate()); | 10210 Error& error = Error::Handle(isolate()); |
| 10196 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); | 10211 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11035 void Parser::SkipQualIdent() { | 11050 void Parser::SkipQualIdent() { |
| 11036 ASSERT(IsIdentifier()); | 11051 ASSERT(IsIdentifier()); |
| 11037 ConsumeToken(); | 11052 ConsumeToken(); |
| 11038 if (CurrentToken() == Token::kPERIOD) { | 11053 if (CurrentToken() == Token::kPERIOD) { |
| 11039 ConsumeToken(); // Consume the kPERIOD token. | 11054 ConsumeToken(); // Consume the kPERIOD token. |
| 11040 ExpectIdentifier("identifier expected after '.'"); | 11055 ExpectIdentifier("identifier expected after '.'"); |
| 11041 } | 11056 } |
| 11042 } | 11057 } |
| 11043 | 11058 |
| 11044 } // namespace dart | 11059 } // namespace dart |
| OLD | NEW |