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

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

Issue 18209024: Correct handling of named optional parameters with noSuchMethod invocations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments Created 7 years, 5 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') | no next file » | 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 "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/class_finalizer.h" 9 #include "vm/class_finalizer.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 ASSERT(!func.is_static()); 766 ASSERT(!func.is_static());
767 node_sequence = parser.ParseInstanceSetter(func); 767 node_sequence = parser.ParseInstanceSetter(func);
768 break; 768 break;
769 case RawFunction::kConstImplicitGetter: 769 case RawFunction::kConstImplicitGetter:
770 node_sequence = parser.ParseStaticConstGetter(func); 770 node_sequence = parser.ParseStaticConstGetter(func);
771 break; 771 break;
772 case RawFunction::kMethodExtractor: 772 case RawFunction::kMethodExtractor:
773 node_sequence = parser.ParseMethodExtractor(func); 773 node_sequence = parser.ParseMethodExtractor(func);
774 break; 774 break;
775 case RawFunction::kNoSuchMethodDispatcher: 775 case RawFunction::kNoSuchMethodDispatcher:
776 node_sequence = parser.ParseNoSuchMethodDispatcher(func); 776 node_sequence =
777 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values);
777 break; 778 break;
778 default: 779 default:
779 UNREACHABLE(); 780 UNREACHABLE();
780 } 781 }
781 782
782 if (!HasReturnNode(node_sequence)) { 783 if (!HasReturnNode(node_sequence)) {
783 // Add implicit return node. 784 // Add implicit return node.
784 node_sequence->Add(new ReturnNode(func.end_token_pos())); 785 node_sequence->Add(new ReturnNode(func.end_token_pos()));
785 } 786 }
786 if (parsed_function->has_expression_temp_var()) { 787 if (parsed_function->has_expression_temp_var()) {
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 Function::ZoneHandle(func.extracted_method_closure()), 1101 Function::ZoneHandle(func.extracted_method_closure()),
1101 load_receiver, 1102 load_receiver,
1102 NULL); 1103 NULL);
1103 1104
1104 ReturnNode* return_node = new ReturnNode(ident_pos, closure); 1105 ReturnNode* return_node = new ReturnNode(ident_pos, closure);
1105 current_block_->statements->Add(return_node); 1106 current_block_->statements->Add(return_node);
1106 return CloseBlock(); 1107 return CloseBlock();
1107 } 1108 }
1108 1109
1109 1110
1110 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { 1111 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func,
1112 Array& default_values) {
1111 TRACE_PARSER("ParseNoSuchMethodDispatcher"); 1113 TRACE_PARSER("ParseNoSuchMethodDispatcher");
1112 1114
1113 ASSERT(func.IsNoSuchMethodDispatcher()); 1115 ASSERT(func.IsNoSuchMethodDispatcher());
1114 intptr_t token_pos = func.token_pos(); 1116 intptr_t token_pos = func.token_pos();
1115 ASSERT(func.token_pos() == 0); 1117 ASSERT(func.token_pos() == 0);
1116 ASSERT(current_class().raw() == func.Owner()); 1118 ASSERT(current_class().raw() == func.Owner());
1117 1119
1118 ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc())); 1120 ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc()));
1119 ASSERT(desc.Count() > 0); 1121 ASSERT(desc.Count() > 0);
1122
1123 // Create parameter list. Receiver first.
1120 ParamList params; 1124 ParamList params;
1121 params.AddReceiver(ReceiverType(), token_pos); 1125 params.AddReceiver(ReceiverType(), token_pos);
1122 for (intptr_t i = 1; i < desc.Count(); ++i) { 1126
1127 // Remaining positional parameters.
1128 intptr_t i = 1;
1129 for (; i < desc.PositionalCount(); ++i) {
1123 ParamDesc p; 1130 ParamDesc p;
1124 char name[64]; 1131 char name[64];
1125 OS::SNPrint(name, 64, ":p%"Pd, i); 1132 OS::SNPrint(name, 64, ":p%"Pd, i);
1126 p.name = &String::ZoneHandle(Symbols::New(name)); 1133 p.name = &String::ZoneHandle(Symbols::New(name));
1127 p.type = &Type::ZoneHandle(Type::DynamicType()); 1134 p.type = &Type::ZoneHandle(Type::DynamicType());
1128 params.parameters->Add(p); 1135 params.parameters->Add(p);
1136 params.num_fixed_parameters++;
1129 } 1137 }
1130 ASSERT(!func.HasOptionalParameters()); 1138 // Named parameters.
1139 for (; i < desc.Count(); ++i) {
1140 ParamDesc p;
1141 intptr_t index = i - desc.PositionalCount();
1142 p.name = &String::ZoneHandle(desc.NameAt(index));
1143 p.type = &Type::ZoneHandle(Type::DynamicType());
1144 p.default_value = &Object::ZoneHandle();
1145 params.parameters->Add(p);
1146 params.num_optional_parameters++;
1147 params.has_optional_named_parameters = true;
1148 }
1149
1150 SetupDefaultsForOptionalParams(&params, default_values);
1131 1151
1132 // Build local scope for function and populate with the formal parameters. 1152 // Build local scope for function and populate with the formal parameters.
1133 OpenFunctionBlock(func); 1153 OpenFunctionBlock(func);
1134 LocalScope* scope = current_block_->scope; 1154 LocalScope* scope = current_block_->scope;
1135 AddFormalParamsToScope(&params, scope); 1155 AddFormalParamsToScope(&params, scope);
1136 1156
1137 // Receiver is local 0. 1157 // Receiver is local 0.
1138 ArgumentListNode* func_args = new ArgumentListNode(token_pos); 1158 ArgumentListNode* func_args = new ArgumentListNode(token_pos);
1139 for (intptr_t i = 0; i < desc.Count(); ++i) { 1159 for (intptr_t i = 0; i < desc.Count(); ++i) {
1140 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); 1160 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
1141 } 1161 }
1142 1162
1163 if (params.num_optional_parameters > 0) {
1164 const Array& arg_names =
1165 Array::ZoneHandle(Array::New(params.num_optional_parameters));
1166 for (intptr_t i = 0; i < arg_names.Length(); ++i) {
1167 arg_names.SetAt(i, String::Handle(desc.NameAt(i)));
1168 }
1169 func_args->set_names(arg_names);
1170 }
1171
1143 const String& func_name = String::ZoneHandle(func.name()); 1172 const String& func_name = String::ZoneHandle(func.name());
1144 ArgumentListNode* arguments = BuildNoSuchMethodArguments(token_pos, 1173 ArgumentListNode* arguments = BuildNoSuchMethodArguments(token_pos,
1145 func_name, 1174 func_name,
1146 *func_args); 1175 *func_args);
1147 const Function& no_such_method = Function::ZoneHandle( 1176 const Function& no_such_method = Function::ZoneHandle(
1148 Resolver::ResolveDynamicAnyArgs(Class::Handle(func.Owner()), 1177 Resolver::ResolveDynamicAnyArgs(Class::Handle(func.Owner()),
1149 Symbols::NoSuchMethod())); 1178 Symbols::NoSuchMethod()));
1150 StaticCallNode* call = 1179 StaticCallNode* call =
1151 new StaticCallNode(token_pos, no_such_method, arguments); 1180 new StaticCallNode(token_pos, no_such_method, arguments);
1152 1181
(...skipping 8883 matching lines...) Expand 10 before | Expand all | Expand 10 after
10036 void Parser::SkipQualIdent() { 10065 void Parser::SkipQualIdent() {
10037 ASSERT(IsIdentifier()); 10066 ASSERT(IsIdentifier());
10038 ConsumeToken(); 10067 ConsumeToken();
10039 if (CurrentToken() == Token::kPERIOD) { 10068 if (CurrentToken() == Token::kPERIOD) {
10040 ConsumeToken(); // Consume the kPERIOD token. 10069 ConsumeToken(); // Consume the kPERIOD token.
10041 ExpectIdentifier("identifier expected after '.'"); 10070 ExpectIdentifier("identifier expected after '.'");
10042 } 10071 }
10043 } 10072 }
10044 10073
10045 } // namespace dart 10074 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698