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

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

Issue 2416513003: Fix issues with argument evaluation order and noSuchMethod errors. (Closed)
Patch Set: Created 4 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
« no previous file with comments | « runtime/lib/mirrors.cc ('k') | tests/language/deferred_not_loaded_check_test.dart » ('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 #include "vm/flags.h" 6 #include "vm/flags.h"
7 7
8 #ifndef DART_PRECOMPILED_RUNTIME 8 #ifndef DART_PRECOMPILED_RUNTIME
9 9
10 #include "lib/invocation_mirror.h" 10 #include "lib/invocation_mirror.h"
(...skipping 11260 matching lines...) Expand 10 before | Expand all | Expand 10 after
11271 target_cls = &Class::Handle(Z, 11271 target_cls = &Class::Handle(Z,
11272 original->AsLoadStaticFieldNode()->field().Owner()); 11272 original->AsLoadStaticFieldNode()->field().Owner());
11273 } else if ((left_ident != NULL) && 11273 } else if ((left_ident != NULL) &&
11274 (original->IsLiteralNode() || 11274 (original->IsLiteralNode() ||
11275 original->IsLoadLocalNode())) { 11275 original->IsLoadLocalNode())) {
11276 name = left_ident->raw(); 11276 name = left_ident->raw();
11277 } 11277 }
11278 if (name.IsNull()) { 11278 if (name.IsNull()) {
11279 ReportError(left_pos, "expression is not assignable"); 11279 ReportError(left_pos, "expression is not assignable");
11280 } 11280 }
11281 LetNode* let_node = new(Z) LetNode(left_pos); 11281 ArgumentListNode* error_arguments =
11282 let_node->AddInitializer(rhs); 11282 new(Z) ArgumentListNode(rhs->token_pos());
11283 let_node->AddNode(ThrowNoSuchMethodError( 11283 error_arguments->Add(rhs);
11284 result = ThrowNoSuchMethodError(
11284 original->token_pos(), 11285 original->token_pos(),
11285 *target_cls, 11286 *target_cls,
11286 String::Handle(Z, Field::SetterName(name)), 11287 String::Handle(Z, Field::SetterName(name)),
11287 NULL, // No arguments. 11288 error_arguments,
11288 InvocationMirror::kStatic, 11289 InvocationMirror::kStatic,
11289 original->IsLoadLocalNode() ? 11290 original->IsLoadLocalNode() ?
11290 InvocationMirror::kLocalVar : InvocationMirror::kSetter, 11291 InvocationMirror::kLocalVar : InvocationMirror::kSetter,
11291 NULL)); // No existing function. 11292 NULL); // No existing function.
11292 result = let_node;
11293 } 11293 }
11294 // The compound assignment operator a ??= b is different from other 11294 // The compound assignment operator a ??= b is different from other
11295 // a op= b assignments. If a is non-null, the assignment to a must be 11295 // a op= b assignments. If a is non-null, the assignment to a must be
11296 // dropped: 11296 // dropped:
11297 // normally: a op= b ==> a = a op b 11297 // normally: a op= b ==> a = a op b
11298 // however: a ??= b ==> a ?? (a = b) 11298 // however: a ??= b ==> a ?? (a = b)
11299 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) 11299 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b)
11300 if (is_compound && 11300 if (is_compound &&
11301 rhs->IsBinaryOpNode() && 11301 rhs->IsBinaryOpNode() &&
11302 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { 11302 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) {
(...skipping 2637 matching lines...) Expand 10 before | Expand all | Expand 10 after
13940 arguments = new(Z) ArgumentListNode(TokenPos()); 13940 arguments = new(Z) ArgumentListNode(TokenPos());
13941 } 13941 }
13942 13942
13943 // Parsing is complete, so we can return a throw in case of a malformed or 13943 // Parsing is complete, so we can return a throw in case of a malformed or
13944 // malbounded type or report a compile-time error if the constructor is const. 13944 // malbounded type or report a compile-time error if the constructor is const.
13945 if (type.IsMalformedOrMalbounded()) { 13945 if (type.IsMalformedOrMalbounded()) {
13946 if (is_const) { 13946 if (is_const) {
13947 const Error& error = Error::Handle(Z, type.error()); 13947 const Error& error = Error::Handle(Z, type.error());
13948 ReportError(error); 13948 ReportError(error);
13949 } 13949 }
13950 if (arguments->length() > 0) {
13951 // Evaluate arguments for side-effects and throw.
13952 LetNode* error_result = new(Z) LetNode(type_pos);
13953 for (intptr_t i = 0; i < arguments->length(); ++i) {
13954 error_result->AddNode(arguments->NodeAt(i));
13955 }
13956 error_result->AddNode(ThrowTypeError(type_pos, type));
13957 return error_result;
13958 }
13950 return ThrowTypeError(type_pos, type); 13959 return ThrowTypeError(type_pos, type);
13951 } 13960 }
13952 13961
13953 // Resolve the type and optional identifier to a constructor or factory. 13962 // Resolve the type and optional identifier to a constructor or factory.
13954 String& type_class_name = String::Handle(Z, type_class.Name()); 13963 String& type_class_name = String::Handle(Z, type_class.Name());
13955 TypeArguments& type_arguments = 13964 TypeArguments& type_arguments =
13956 TypeArguments::ZoneHandle(Z, type.arguments()); 13965 TypeArguments::ZoneHandle(Z, type.arguments());
13957 13966
13958 // A constructor has an implicit 'this' parameter (instance to construct) 13967 // A constructor has an implicit 'this' parameter (instance to construct)
13959 // and a factory has an implicit 'this' parameter (type_arguments). 13968 // and a factory has an implicit 'this' parameter (type_arguments).
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
14432 if (primary == NULL) { 14441 if (primary == NULL) {
14433 if (prefix.is_deferred_load() && 14442 if (prefix.is_deferred_load() &&
14434 ident.Equals(Symbols::LoadLibrary())) { 14443 ident.Equals(Symbols::LoadLibrary())) {
14435 // Hack Alert: recognize special 'loadLibrary' call on the 14444 // Hack Alert: recognize special 'loadLibrary' call on the
14436 // prefix object. The prefix is the primary. Rewind parser and 14445 // prefix object. The prefix is the primary. Rewind parser and
14437 // let ParseSelectors() handle the loadLibrary call. 14446 // let ParseSelectors() handle the loadLibrary call.
14438 SetPosition(qual_ident_pos); 14447 SetPosition(qual_ident_pos);
14439 ConsumeToken(); // Prefix name. 14448 ConsumeToken(); // Prefix name.
14440 primary = new(Z) LiteralNode(qual_ident_pos, prefix); 14449 primary = new(Z) LiteralNode(qual_ident_pos, prefix);
14441 } else { 14450 } else {
14442 // TODO(hausner): Ideally we should generate the NoSuchMethodError
14443 // later, when we know more about how the unresolved name is used.
14444 // For example, we don't know yet whether the unresolved name
14445 // refers to a getter or a setter. However, it is more awkward
14446 // to distinuish four NoSuchMethodError cases all over the place
14447 // in the parser. The four cases are: prefixed vs non-prefixed
14448 // name, static vs dynamic context in which the unresolved name
14449 // is used. We cheat a little here by looking at the next token
14450 // to determine whether we have an unresolved method call or
14451 // field access.
14452 GrowableHandlePtrArray<const String> pieces(Z, 3); 14451 GrowableHandlePtrArray<const String> pieces(Z, 3);
14453 pieces.Add(String::Handle(Z, prefix.name())); 14452 pieces.Add(String::Handle(Z, prefix.name()));
14454 pieces.Add(Symbols::Dot()); 14453 pieces.Add(Symbols::Dot());
14455 pieces.Add(ident); 14454 pieces.Add(ident);
14456 const String& qualified_name = String::ZoneHandle(Z, 14455 const String& qualified_name = String::ZoneHandle(Z,
14457 Symbols::FromConcatAll(T, pieces)); 14456 Symbols::FromConcatAll(T, pieces));
14458 InvocationMirror::Type call_type = 14457 primary = new(Z) PrimaryNode(qual_ident_pos, qualified_name);
14459 CurrentToken() == Token::kLPAREN ?
14460 InvocationMirror::kMethod : InvocationMirror::kGetter;
14461 primary = ThrowNoSuchMethodError(qual_ident_pos,
14462 current_class(),
14463 qualified_name,
14464 NULL, // No arguments.
14465 InvocationMirror::kTopLevel,
14466 call_type,
14467 NULL); // No existing function.
14468 } 14458 }
14469 } else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) { 14459 } else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) {
14470 // primary != NULL. 14460 // primary != NULL.
14471 GrowableHandlePtrArray<const String> pieces(Z, 3); 14461 GrowableHandlePtrArray<const String> pieces(Z, 3);
14472 pieces.Add(String::Handle(Z, prefix.name())); 14462 pieces.Add(String::Handle(Z, prefix.name()));
14473 pieces.Add(Symbols::Dot()); 14463 pieces.Add(Symbols::Dot());
14474 pieces.Add(ident); 14464 pieces.Add(ident);
14475 const String& qualified_name = String::ZoneHandle(Z, 14465 const String& qualified_name = String::ZoneHandle(Z,
14476 Symbols::FromConcatAll(T, pieces)); 14466 Symbols::FromConcatAll(T, pieces));
14477 InvocationMirror::Type call_type = 14467 InvocationMirror::Type call_type =
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after
15094 const ArgumentListNode& function_args, 15084 const ArgumentListNode& function_args,
15095 const LocalVariable* temp_for_last_arg, 15085 const LocalVariable* temp_for_last_arg,
15096 bool is_super_invocation) { 15086 bool is_super_invocation) {
15097 UNREACHABLE(); 15087 UNREACHABLE();
15098 return NULL; 15088 return NULL;
15099 } 15089 }
15100 15090
15101 } // namespace dart 15091 } // namespace dart
15102 15092
15103 #endif // DART_PRECOMPILED_RUNTIME 15093 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/lib/mirrors.cc ('k') | tests/language/deferred_not_loaded_check_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698