Chromium Code Reviews| 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/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "vm/scopes.h" | 31 #include "vm/scopes.h" |
| 32 #include "vm/stack_frame.h" | 32 #include "vm/stack_frame.h" |
| 33 #include "vm/symbols.h" | 33 #include "vm/symbols.h" |
| 34 #include "vm/tags.h" | 34 #include "vm/tags.h" |
| 35 #include "vm/timer.h" | 35 #include "vm/timer.h" |
| 36 #include "vm/zone.h" | 36 #include "vm/zone.h" |
| 37 | 37 |
| 38 namespace dart { | 38 namespace dart { |
| 39 | 39 |
| 40 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); | 40 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); |
| 41 DEFINE_FLAG(bool, enable_mirrors, true, | |
| 42 "Disable to make importing dart:mirrors an error."); | |
| 41 DEFINE_FLAG(bool, load_deferred_eagerly, false, | 43 DEFINE_FLAG(bool, load_deferred_eagerly, false, |
| 42 "Load deferred libraries eagerly."); | 44 "Load deferred libraries eagerly."); |
| 43 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 45 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| 44 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); | 46 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
| 47 | |
| 48 DECLARE_FLAG(bool, lazy_dispatchers); | |
| 49 DECLARE_FLAG(bool, load_deferred_eagerly); | |
| 45 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 50 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 46 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 51 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 47 DEFINE_FLAG(bool, enable_mirrors, true, | |
| 48 "Disable to make importing dart:mirrors an error."); | |
| 49 DECLARE_FLAG(bool, lazy_dispatchers); | |
| 50 | 52 |
| 51 // Quick access to the current isolate and zone. | 53 // Quick access to the current isolate and zone. |
| 52 #define I (isolate()) | 54 #define I (isolate()) |
| 53 #define Z (zone()) | 55 #define Z (zone()) |
| 54 | 56 |
| 55 | 57 |
| 56 #if defined(DEBUG) | 58 #if defined(DEBUG) |
| 57 class TraceParser : public ValueObject { | 59 class TraceParser : public ValueObject { |
| 58 public: | 60 public: |
| 59 TraceParser(intptr_t token_pos, | 61 TraceParser(intptr_t token_pos, |
| (...skipping 9993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10053 const Error& error = Error::Handle(Z, type.error()); | 10055 const Error& error = Error::Handle(Z, type.error()); |
| 10054 ASSERT(!error.IsNull()); | 10056 ASSERT(!error.IsNull()); |
| 10055 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, | 10057 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, |
| 10056 Symbols::New(error.ToErrorCString())))); | 10058 Symbols::New(error.ToErrorCString())))); |
| 10057 return MakeStaticCall(Symbols::TypeError(), | 10059 return MakeStaticCall(Symbols::TypeError(), |
| 10058 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 10060 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 10059 arguments); | 10061 arguments); |
| 10060 } | 10062 } |
| 10061 | 10063 |
| 10062 | 10064 |
| 10065 // If 'prefix' is not NULL, then it will be passed to _throwNewIfNotLoaded. | |
| 10063 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, | 10066 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, |
| 10064 const Class& cls, | 10067 const Class& cls, |
| 10065 const String& function_name, | 10068 const String& function_name, |
| 10066 ArgumentListNode* function_arguments, | 10069 ArgumentListNode* function_arguments, |
| 10067 InvocationMirror::Call im_call, | 10070 InvocationMirror::Call im_call, |
| 10068 InvocationMirror::Type im_type, | 10071 InvocationMirror::Type im_type, |
| 10069 const Function* func) { | 10072 const Function* func, |
| 10073 const LibraryPrefix* prefix) { | |
| 10070 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); | 10074 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); |
| 10075 | |
| 10076 String& method_name = String::Handle(); | |
| 10077 if (prefix == NULL) { | |
| 10078 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); | |
| 10079 } else { | |
| 10080 arguments->Add(new(Z) LiteralNode(call_pos, *prefix)); | |
| 10081 method_name = Library::PrivateCoreLibName( | |
| 10082 Symbols::ThrowNewIfNotLoaded()).raw(); | |
| 10083 } | |
| 10071 // Object receiver. | 10084 // Object receiver. |
| 10072 // If the function is external and dynamic, pass the actual receiver, | 10085 // If the function is external and dynamic, pass the actual receiver, |
| 10073 // otherwise, pass a class literal of the unresolved method's owner. | 10086 // otherwise, pass a class literal of the unresolved method's owner. |
| 10074 if ((func != NULL) && !func->IsNull() && | 10087 if ((func != NULL) && !func->IsNull() && |
| 10075 func->is_external() && !func->is_static()) { | 10088 func->is_external() && !func->is_static()) { |
| 10076 arguments->Add(LoadReceiver(func->token_pos())); | 10089 arguments->Add(LoadReceiver(func->token_pos())); |
| 10077 } else { | 10090 } else { |
| 10078 Type& type = Type::ZoneHandle(Z, | 10091 Type& type = Type::ZoneHandle(Z, |
| 10079 Type::New(cls, TypeArguments::Handle(Z), call_pos, Heap::kOld)); | 10092 Type::New(cls, TypeArguments::Handle(Z), call_pos, Heap::kOld)); |
| 10080 type ^= ClassFinalizer::FinalizeType( | 10093 type ^= ClassFinalizer::FinalizeType( |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10133 // descriptive string here and pass it as the only element of the | 10146 // descriptive string here and pass it as the only element of the |
| 10134 // "existingArgumentNames" array of the NoSuchMethodError constructor. | 10147 // "existingArgumentNames" array of the NoSuchMethodError constructor. |
| 10135 // TODO(13471): Separate the implementations of NoSuchMethodError | 10148 // TODO(13471): Separate the implementations of NoSuchMethodError |
| 10136 // between dart2js and VM. Update the constructor to accept a string | 10149 // between dart2js and VM. Update the constructor to accept a string |
| 10137 // describing the formal parameters of an incompatible call target. | 10150 // describing the formal parameters of an incompatible call target. |
| 10138 array = Array::New(1, Heap::kOld); | 10151 array = Array::New(1, Heap::kOld); |
| 10139 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); | 10152 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); |
| 10140 } | 10153 } |
| 10141 arguments->Add(new(Z) LiteralNode(call_pos, array)); | 10154 arguments->Add(new(Z) LiteralNode(call_pos, array)); |
| 10142 | 10155 |
| 10143 return MakeStaticCall(Symbols::NoSuchMethodError(), | 10156 return MakeStaticCall(Symbols::NoSuchMethodError(), method_name, arguments); |
| 10144 Library::PrivateCoreLibName(Symbols::ThrowNew()), | |
| 10145 arguments); | |
| 10146 } | 10157 } |
| 10147 | 10158 |
| 10148 | 10159 |
| 10149 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 10160 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
| 10150 TRACE_PARSER("ParseBinaryExpr"); | 10161 TRACE_PARSER("ParseBinaryExpr"); |
| 10151 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); | 10162 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); |
| 10152 AstNode* left_operand = ParseUnaryExpr(); | 10163 AstNode* left_operand = ParseUnaryExpr(); |
| 10153 if (left_operand->IsPrimaryNode() && | 10164 if (left_operand->IsPrimaryNode() && |
| 10154 (left_operand->AsPrimaryNode()->IsSuper())) { | 10165 (left_operand->AsPrimaryNode()->IsSuper())) { |
| 10155 ReportError(left_operand->token_pos(), "illegal use of 'super'"); | 10166 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
| (...skipping 1653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11809 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { | 11820 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { |
| 11810 // Private names are not exported by libraries. The name mangling | 11821 // Private names are not exported by libraries. The name mangling |
| 11811 // of private names with a library-specific suffix usually ensures | 11822 // of private names with a library-specific suffix usually ensures |
| 11812 // that _x in library A is not found when looked up from library B. | 11823 // that _x in library A is not found when looked up from library B. |
| 11813 // In the pathological case where a library imports itself with | 11824 // In the pathological case where a library imports itself with |
| 11814 // a prefix, the name mangling would not help in hiding the private | 11825 // a prefix, the name mangling would not help in hiding the private |
| 11815 // name, so we need to explicitly reject private names here. | 11826 // name, so we need to explicitly reject private names here. |
| 11816 return NULL; | 11827 return NULL; |
| 11817 } | 11828 } |
| 11818 Object& obj = Object::Handle(Z); | 11829 Object& obj = Object::Handle(Z); |
| 11819 if (prefix.is_loaded()) { | 11830 if (prefix.is_loaded()) { |
|
hausner
2015/07/08 18:19:58
This should maybe be prefix.is_loaded() || FLAG_lo
srdjan
2015/07/09 16:41:44
Done.
| |
| 11820 obj = prefix.LookupObject(ident); | 11831 obj = prefix.LookupObject(ident); |
| 11821 } else { | 11832 } else { |
| 11822 // Remember that this function depends on an import prefix of an | 11833 // Remember that this function depends on an import prefix of an |
| 11823 // unloaded deferred library. Note that parsed_function() can be | 11834 // unloaded deferred library. Note that parsed_function() can be |
| 11824 // NULL when parsing expressions outside the scope of a function. | 11835 // NULL when parsing expressions outside the scope of a function. |
| 11825 if (parsed_function() != NULL) { | 11836 if (parsed_function() != NULL) { |
| 11826 parsed_function()->AddDeferredPrefix(prefix); | 11837 parsed_function()->AddDeferredPrefix(prefix); |
|
hausner
2015/07/08 18:19:58
It's not necessary (or even wrong) to make code de
srdjan
2015/07/09 16:41:44
By adding '|| FLAG_load_deferred_eagerly' above as
| |
| 11827 } | 11838 } |
| 11839 if (FLAG_load_deferred_eagerly) { | |
| 11840 obj = prefix.LookupObject(ident); | |
| 11841 } | |
| 11828 } | 11842 } |
| 11829 const bool is_deferred = prefix.is_deferred_load(); | 11843 const bool is_deferred = prefix.is_deferred_load(); |
| 11830 if (obj.IsNull()) { | 11844 if (obj.IsNull()) { |
| 11831 // Unresolved prefixed primary identifier. | 11845 // Unresolved prefixed primary identifier. |
| 11832 return NULL; | 11846 return NULL; |
| 11833 } else if (obj.IsClass()) { | 11847 } else if (obj.IsClass()) { |
| 11834 const Class& cls = Class::Cast(obj); | 11848 const Class& cls = Class::Cast(obj); |
| 11835 PrimaryNode* primary = | 11849 PrimaryNode* primary = |
| 11836 new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); | 11850 new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); |
| 11837 primary->set_is_deferred(is_deferred); | 11851 primary->set_is_deferred(is_deferred); |
| (...skipping 1238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13076 CurrentToken() == Token::kLPAREN ? | 13090 CurrentToken() == Token::kLPAREN ? |
| 13077 InvocationMirror::kMethod : InvocationMirror::kGetter; | 13091 InvocationMirror::kMethod : InvocationMirror::kGetter; |
| 13078 primary = ThrowNoSuchMethodError(qual_ident_pos, | 13092 primary = ThrowNoSuchMethodError(qual_ident_pos, |
| 13079 current_class(), | 13093 current_class(), |
| 13080 qualified_name, | 13094 qualified_name, |
| 13081 NULL, // No arguments. | 13095 NULL, // No arguments. |
| 13082 InvocationMirror::kTopLevel, | 13096 InvocationMirror::kTopLevel, |
| 13083 call_type, | 13097 call_type, |
| 13084 NULL); // No existing function. | 13098 NULL); // No existing function. |
| 13085 } | 13099 } |
| 13100 } else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) { | |
| 13101 // primary != NULL. | |
| 13102 String& qualified_name = String::ZoneHandle(Z, prefix.name()); | |
| 13103 qualified_name = String::Concat(qualified_name, Symbols::Dot()); | |
| 13104 qualified_name = String::Concat(qualified_name, ident); | |
| 13105 qualified_name = Symbols::New(qualified_name); | |
| 13106 InvocationMirror::Type call_type = | |
| 13107 CurrentToken() == Token::kLPAREN ? | |
| 13108 InvocationMirror::kMethod : InvocationMirror::kGetter; | |
| 13109 current_block_->statements->Add(ThrowNoSuchMethodError( | |
|
hausner
2015/07/08 18:19:58
Can you add a comment here that reminds that addin
srdjan
2015/07/09 16:41:44
Done.
| |
| 13110 qual_ident_pos, | |
| 13111 current_class(), | |
| 13112 qualified_name, | |
| 13113 NULL, // No arguments. | |
| 13114 InvocationMirror::kTopLevel, | |
| 13115 call_type, | |
| 13116 NULL, // No existing function. | |
| 13117 &prefix)); | |
| 13086 } | 13118 } |
| 13087 } | 13119 } |
| 13088 ASSERT(primary != NULL); | 13120 ASSERT(primary != NULL); |
| 13089 } else if (token == Token::kTHIS) { | 13121 } else if (token == Token::kTHIS) { |
| 13090 LocalVariable* local = LookupLocalScope(Symbols::This()); | 13122 LocalVariable* local = LookupLocalScope(Symbols::This()); |
| 13091 if (local == NULL) { | 13123 if (local == NULL) { |
| 13092 ReportError("receiver 'this' is not in scope"); | 13124 ReportError("receiver 'this' is not in scope"); |
| 13093 } | 13125 } |
| 13094 primary = new(Z) LoadLocalNode(TokenPos(), local); | 13126 primary = new(Z) LoadLocalNode(TokenPos(), local); |
| 13095 ConsumeToken(); | 13127 ConsumeToken(); |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13556 void Parser::SkipQualIdent() { | 13588 void Parser::SkipQualIdent() { |
| 13557 ASSERT(IsIdentifier()); | 13589 ASSERT(IsIdentifier()); |
| 13558 ConsumeToken(); | 13590 ConsumeToken(); |
| 13559 if (CurrentToken() == Token::kPERIOD) { | 13591 if (CurrentToken() == Token::kPERIOD) { |
| 13560 ConsumeToken(); // Consume the kPERIOD token. | 13592 ConsumeToken(); // Consume the kPERIOD token. |
| 13561 ExpectIdentifier("identifier expected after '.'"); | 13593 ExpectIdentifier("identifier expected after '.'"); |
| 13562 } | 13594 } |
| 13563 } | 13595 } |
| 13564 | 13596 |
| 13565 } // namespace dart | 13597 } // namespace dart |
| OLD | NEW |