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 #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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |