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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 } | 120 } |
121 | 121 |
122 | 122 |
123 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 123 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
124 ASSERT(node_sequence_ == NULL); | 124 ASSERT(node_sequence_ == NULL); |
125 ASSERT(node_sequence != NULL); | 125 ASSERT(node_sequence != NULL); |
126 node_sequence_ = node_sequence; | 126 node_sequence_ = node_sequence; |
127 } | 127 } |
128 | 128 |
129 | 129 |
| 130 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) { |
| 131 ASSERT(prefix.is_deferred_load()); |
| 132 ASSERT(!prefix.is_loaded()); |
| 133 if (deferred_prefixes_ == NULL) { |
| 134 deferred_prefixes_ = |
| 135 &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); |
| 136 } |
| 137 for (intptr_t i = 0; i < deferred_prefixes_->Length(); i++) { |
| 138 if (deferred_prefixes_->At(i) == prefix.raw()) { |
| 139 return; |
| 140 } |
| 141 } |
| 142 deferred_prefixes_->Add(prefix); |
| 143 } |
| 144 |
| 145 |
130 void ParsedFunction::AllocateVariables() { | 146 void ParsedFunction::AllocateVariables() { |
131 LocalScope* scope = node_sequence()->scope(); | 147 LocalScope* scope = node_sequence()->scope(); |
132 const intptr_t num_fixed_params = function().num_fixed_parameters(); | 148 const intptr_t num_fixed_params = function().num_fixed_parameters(); |
133 const intptr_t num_opt_params = function().NumOptionalParameters(); | 149 const intptr_t num_opt_params = function().NumOptionalParameters(); |
134 const intptr_t num_params = num_fixed_params + num_opt_params; | 150 const intptr_t num_params = num_fixed_params + num_opt_params; |
135 // Compute start indices to parameters and locals, and the number of | 151 // Compute start indices to parameters and locals, and the number of |
136 // parameters to copy. | 152 // parameters to copy. |
137 if (num_opt_params == 0) { | 153 if (num_opt_params == 0) { |
138 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and | 154 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and |
139 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. | 155 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. |
(...skipping 4798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4938 const intptr_t import_pos = TokenPos(); | 4954 const intptr_t import_pos = TokenPos(); |
4939 ConsumeToken(); | 4955 ConsumeToken(); |
4940 CheckToken(Token::kSTRING, "library url expected"); | 4956 CheckToken(Token::kSTRING, "library url expected"); |
4941 AstNode* url_literal = ParseStringLiteral(false); | 4957 AstNode* url_literal = ParseStringLiteral(false); |
4942 ASSERT(url_literal->IsLiteralNode()); | 4958 ASSERT(url_literal->IsLiteralNode()); |
4943 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); | 4959 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
4944 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 4960 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
4945 if (url.Length() == 0) { | 4961 if (url.Length() == 0) { |
4946 ErrorMsg("library url expected"); | 4962 ErrorMsg("library url expected"); |
4947 } | 4963 } |
| 4964 bool is_deferred_import = false; |
| 4965 if (is_import && (IsLiteral("deferred"))) { |
| 4966 is_deferred_import = true; |
| 4967 ConsumeToken(); |
| 4968 CheckToken(Token::kAS, "'as' expected"); |
| 4969 } |
4948 String& prefix = String::Handle(); | 4970 String& prefix = String::Handle(); |
| 4971 intptr_t prefix_pos = 0; |
4949 if (is_import && (CurrentToken() == Token::kAS)) { | 4972 if (is_import && (CurrentToken() == Token::kAS)) { |
4950 ConsumeToken(); | 4973 ConsumeToken(); |
| 4974 prefix_pos = TokenPos(); |
4951 prefix = ExpectIdentifier("prefix identifier expected")->raw(); | 4975 prefix = ExpectIdentifier("prefix identifier expected")->raw(); |
4952 } | 4976 } |
4953 | 4977 |
4954 Array& show_names = Array::Handle(); | 4978 Array& show_names = Array::Handle(); |
4955 Array& hide_names = Array::Handle(); | 4979 Array& hide_names = Array::Handle(); |
4956 if (IsLiteral("show") || IsLiteral("hide")) { | 4980 if (is_deferred_import || IsLiteral("show") || IsLiteral("hide")) { |
4957 GrowableObjectArray& show_list = | 4981 GrowableObjectArray& show_list = |
4958 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 4982 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
4959 GrowableObjectArray& hide_list = | 4983 GrowableObjectArray& hide_list = |
4960 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 4984 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 4985 // Libraries imported through deferred import automatically hide |
| 4986 // the name 'loadLibrary'. |
| 4987 if (is_deferred_import) { |
| 4988 hide_list.Add(Symbols::LoadLibrary()); |
| 4989 } |
4961 for (;;) { | 4990 for (;;) { |
4962 if (IsLiteral("show")) { | 4991 if (IsLiteral("show")) { |
4963 ConsumeToken(); | 4992 ConsumeToken(); |
4964 ParseIdentList(&show_list); | 4993 ParseIdentList(&show_list); |
4965 } else if (IsLiteral("hide")) { | 4994 } else if (IsLiteral("hide")) { |
4966 ConsumeToken(); | 4995 ConsumeToken(); |
4967 ParseIdentList(&hide_list); | 4996 ParseIdentList(&hide_list); |
4968 } else { | 4997 } else { |
4969 break; | 4998 break; |
4970 } | 4999 } |
4971 } | 5000 } |
4972 if (show_list.Length() > 0) { | 5001 if (show_list.Length() > 0) { |
4973 show_names = Array::MakeArray(show_list); | 5002 show_names = Array::MakeArray(show_list); |
4974 } | 5003 } |
4975 if (hide_list.Length() > 0) { | 5004 if (hide_list.Length() > 0) { |
4976 hide_names = Array::MakeArray(hide_list); | 5005 hide_names = Array::MakeArray(hide_list); |
4977 } | 5006 } |
4978 } | 5007 } |
4979 ExpectSemicolon(); | 5008 ExpectSemicolon(); |
4980 | 5009 |
4981 // Canonicalize library URL. | 5010 // Canonicalize library URL. |
4982 const String& canon_url = String::CheckedHandle( | 5011 const String& canon_url = String::CheckedHandle( |
4983 CallLibraryTagHandler(Dart_kCanonicalizeUrl, import_pos, url)); | 5012 CallLibraryTagHandler(Dart_kCanonicalizeUrl, import_pos, url)); |
4984 // Lookup the library URL. | 5013 // Lookup the library URL. |
4985 Library& library = Library::Handle(Library::LookupLibrary(canon_url)); | 5014 Library& library = Library::Handle(Library::LookupLibrary(canon_url)); |
4986 if (library.IsNull()) { | 5015 if (library.IsNull()) { |
4987 // Call the library tag handler to load the library. | 5016 // Call the library tag handler to load the library. |
| 5017 // TODO(hausner): do not load eagerly if import is deferred. |
4988 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); | 5018 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); |
4989 // If the library tag handler succeded without registering the | 5019 // If the library tag handler succeded without registering the |
4990 // library we create an empty library to import. | 5020 // library we create an empty library to import. |
4991 library = Library::LookupLibrary(canon_url); | 5021 library = Library::LookupLibrary(canon_url); |
4992 if (library.IsNull()) { | 5022 if (library.IsNull()) { |
4993 library = Library::New(canon_url); | 5023 library = Library::New(canon_url); |
4994 library.Register(); | 5024 library.Register(); |
4995 } | 5025 } |
4996 } | 5026 } |
4997 | 5027 |
4998 Namespace& ns = | 5028 Namespace& ns = |
4999 Namespace::Handle(Namespace::New(library, show_names, hide_names)); | 5029 Namespace::Handle(Namespace::New(library, show_names, hide_names)); |
5000 if (metadata_pos >= 0) { | 5030 if (metadata_pos >= 0) { |
5001 ns.AddMetadata(metadata_pos, current_class()); | 5031 ns.AddMetadata(metadata_pos, current_class()); |
5002 } | 5032 } |
5003 | 5033 |
5004 if (is_import) { | 5034 if (is_import) { |
5005 // Ensure that private dart:_ libraries are only imported into dart: | 5035 // Ensure that private dart:_ libraries are only imported into dart: |
5006 // libraries. | 5036 // libraries. |
5007 const String& lib_url = String::Handle(library_.url()); | 5037 const String& lib_url = String::Handle(library_.url()); |
5008 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && | 5038 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && |
5009 !lib_url.StartsWith(Symbols::DartScheme())) { | 5039 !lib_url.StartsWith(Symbols::DartScheme())) { |
5010 ErrorMsg(import_pos, "private library is not accessible"); | 5040 ErrorMsg(import_pos, "private library is not accessible"); |
5011 } | 5041 } |
5012 if (prefix.IsNull() || (prefix.Length() == 0)) { | 5042 if (prefix.IsNull() || (prefix.Length() == 0)) { |
| 5043 ASSERT(!is_deferred_import); |
5013 library_.AddImport(ns); | 5044 library_.AddImport(ns); |
5014 } else { | 5045 } else { |
5015 LibraryPrefix& library_prefix = LibraryPrefix::Handle(); | 5046 LibraryPrefix& library_prefix = LibraryPrefix::Handle(); |
5016 library_prefix = library_.LookupLocalLibraryPrefix(prefix); | 5047 library_prefix = library_.LookupLocalLibraryPrefix(prefix); |
5017 if (!library_prefix.IsNull()) { | 5048 if (!library_prefix.IsNull()) { |
| 5049 // Check that prefix names of deferred import clauses are |
| 5050 // unique. |
| 5051 if (!is_deferred_import && library_prefix.is_deferred_load()) { |
| 5052 ErrorMsg(prefix_pos, |
| 5053 "prefix '%s' already used in a deferred import clause", |
| 5054 prefix.ToCString()); |
| 5055 } |
| 5056 if (is_deferred_import) { |
| 5057 ErrorMsg(prefix_pos, "prefix of deferred import must be uniqe"); |
| 5058 } |
5018 library_prefix.AddImport(ns); | 5059 library_prefix.AddImport(ns); |
5019 } else { | 5060 } else { |
5020 library_prefix = LibraryPrefix::New(prefix, ns); | 5061 library_prefix = LibraryPrefix::New(prefix, ns, is_deferred_import); |
5021 library_.AddObject(library_prefix, prefix); | 5062 library_.AddObject(library_prefix, prefix); |
5022 } | 5063 } |
5023 } | 5064 } |
5024 } else { | 5065 } else { |
5025 ASSERT(is_export); | 5066 ASSERT(is_export); |
5026 library_.AddExport(ns); | 5067 library_.AddExport(ns); |
5027 } | 5068 } |
5028 } | 5069 } |
5029 | 5070 |
5030 | 5071 |
(...skipping 4158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9189 | 9230 |
9190 | 9231 |
9191 // Do a lookup for the identifier in the scope of the specified | 9232 // Do a lookup for the identifier in the scope of the specified |
9192 // library prefix. This means trying to resolve it locally in all of the | 9233 // library prefix. This means trying to resolve it locally in all of the |
9193 // libraries present in the library prefix. | 9234 // libraries present in the library prefix. |
9194 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, | 9235 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, |
9195 const LibraryPrefix& prefix, | 9236 const LibraryPrefix& prefix, |
9196 const String& ident) { | 9237 const String& ident) { |
9197 TRACE_PARSER("ResolveIdentInPrefixScope"); | 9238 TRACE_PARSER("ResolveIdentInPrefixScope"); |
9198 HANDLESCOPE(isolate()); | 9239 HANDLESCOPE(isolate()); |
9199 Object& obj = Object::Handle(prefix.LookupObject(ident)); | 9240 Object& obj = Object::Handle(); |
| 9241 if (prefix.is_loaded()) { |
| 9242 obj = prefix.LookupObject(ident); |
| 9243 } else { |
| 9244 // Remember that this function depends on an import prefix of an |
| 9245 // unloaded deferred library. |
| 9246 parsed_function()->AddDeferredPrefix(prefix); |
| 9247 } |
9200 if (obj.IsNull()) { | 9248 if (obj.IsNull()) { |
9201 // Unresolved prefixed primary identifier. | 9249 // Unresolved prefixed primary identifier. |
9202 String& qualified_name = String::ZoneHandle(prefix.name()); | 9250 return NULL; |
9203 qualified_name = String::Concat(qualified_name, Symbols::Dot()); | |
9204 qualified_name = String::Concat(qualified_name, ident); | |
9205 qualified_name = Symbols::New(qualified_name); | |
9206 return new PrimaryNode(ident_pos, qualified_name); | |
9207 } else if (obj.IsClass()) { | 9251 } else if (obj.IsClass()) { |
9208 const Class& cls = Class::Cast(obj); | 9252 const Class& cls = Class::Cast(obj); |
9209 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); | 9253 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); |
9210 } else if (obj.IsField()) { | 9254 } else if (obj.IsField()) { |
9211 const Field& field = Field::Cast(obj); | 9255 const Field& field = Field::Cast(obj); |
9212 ASSERT(field.is_static()); | 9256 ASSERT(field.is_static()); |
9213 return GenerateStaticFieldLookup(field, ident_pos); | 9257 return GenerateStaticFieldLookup(field, ident_pos); |
9214 } else if (obj.IsFunction()) { | 9258 } else if (obj.IsFunction()) { |
9215 const Function& func = Function::Cast(obj); | 9259 const Function& func = Function::Cast(obj); |
9216 ASSERT(func.is_static()); | 9260 ASSERT(func.is_static()); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9304 resolved = new TypeNode(primary_pos, type); | 9348 resolved = new TypeNode(primary_pos, type); |
9305 } | 9349 } |
9306 } | 9350 } |
9307 return resolved; | 9351 return resolved; |
9308 } | 9352 } |
9309 | 9353 |
9310 | 9354 |
9311 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 9355 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
9312 // finalize it according to the given type finalization mode. | 9356 // finalize it according to the given type finalization mode. |
9313 RawAbstractType* Parser::ParseType( | 9357 RawAbstractType* Parser::ParseType( |
9314 ClassFinalizer::FinalizationKind finalization) { | 9358 ClassFinalizer::FinalizationKind finalization, |
| 9359 bool allow_deferred_type) { |
9315 TRACE_PARSER("ParseType"); | 9360 TRACE_PARSER("ParseType"); |
9316 CheckToken(Token::kIDENT, "type name expected"); | 9361 CheckToken(Token::kIDENT, "type name expected"); |
9317 QualIdent type_name; | 9362 QualIdent type_name; |
9318 if (finalization == ClassFinalizer::kIgnore) { | 9363 if (finalization == ClassFinalizer::kIgnore) { |
9319 if (!is_top_level_ && (current_block_ != NULL)) { | 9364 if (!is_top_level_ && (current_block_ != NULL)) { |
9320 // Add the library prefix or type class name to the list of referenced | 9365 // Add the library prefix or type class name to the list of referenced |
9321 // names of this scope, even if the type is ignored. | 9366 // names of this scope, even if the type is ignored. |
9322 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); | 9367 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); |
9323 } | 9368 } |
9324 SkipQualIdent(); | 9369 SkipQualIdent(); |
9325 } else { | 9370 } else { |
9326 ParseQualIdent(&type_name); | 9371 ParseQualIdent(&type_name); |
9327 // An identifier cannot be resolved in a local scope when top level parsing. | 9372 // An identifier cannot be resolved in a local scope when top level parsing. |
9328 if (!is_top_level_ && | 9373 if (!is_top_level_ && |
9329 (type_name.lib_prefix == NULL) && | 9374 (type_name.lib_prefix == NULL) && |
9330 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { | 9375 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { |
9331 // The type is malformed. Skip over its type arguments. | 9376 // The type is malformed. Skip over its type arguments. |
9332 ParseTypeArguments(ClassFinalizer::kIgnore); | 9377 ParseTypeArguments(ClassFinalizer::kIgnore); |
9333 return ClassFinalizer::NewFinalizedMalformedType( | 9378 return ClassFinalizer::NewFinalizedMalformedType( |
9334 Error::Handle(), // No previous error. | 9379 Error::Handle(), // No previous error. |
9335 script_, | 9380 script_, |
9336 type_name.ident_pos, | 9381 type_name.ident_pos, |
9337 "using '%s' in this context is invalid", | 9382 "using '%s' in this context is invalid", |
9338 type_name.ident->ToCString()); | 9383 type_name.ident->ToCString()); |
9339 } | 9384 } |
| 9385 if ((type_name.lib_prefix != NULL) && |
| 9386 type_name.lib_prefix->is_deferred_load() && |
| 9387 !allow_deferred_type) { |
| 9388 ParseTypeArguments(ClassFinalizer::kIgnore); |
| 9389 return ClassFinalizer::NewFinalizedMalformedType( |
| 9390 Error::Handle(), // No previous error. |
| 9391 script_, |
| 9392 type_name.ident_pos, |
| 9393 "using deferred type '%s.%s' is invalid", |
| 9394 String::Handle(type_name.lib_prefix->name()).ToCString(), |
| 9395 type_name.ident->ToCString()); |
| 9396 } |
9340 } | 9397 } |
9341 Object& type_class = Object::Handle(isolate()); | 9398 Object& type_class = Object::Handle(isolate()); |
9342 // Leave type_class as null if type finalization mode is kIgnore. | 9399 // Leave type_class as null if type finalization mode is kIgnore. |
9343 if (finalization != ClassFinalizer::kIgnore) { | 9400 if (finalization != ClassFinalizer::kIgnore) { |
9344 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(isolate()); | 9401 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(isolate()); |
9345 if (type_name.lib_prefix != NULL) { | 9402 if (type_name.lib_prefix != NULL) { |
9346 lib_prefix = type_name.lib_prefix->raw(); | 9403 lib_prefix = type_name.lib_prefix->raw(); |
9347 } | 9404 } |
9348 type_class = UnresolvedClass::New(lib_prefix, | 9405 type_class = UnresolvedClass::New(lib_prefix, |
9349 *type_name.ident, | 9406 *type_name.ident, |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9888 | 9945 |
9889 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 9946 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
9890 TRACE_PARSER("ParseNewOperator"); | 9947 TRACE_PARSER("ParseNewOperator"); |
9891 const intptr_t new_pos = TokenPos(); | 9948 const intptr_t new_pos = TokenPos(); |
9892 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 9949 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
9893 bool is_const = (op_kind == Token::kCONST); | 9950 bool is_const = (op_kind == Token::kCONST); |
9894 if (!IsIdentifier()) { | 9951 if (!IsIdentifier()) { |
9895 ErrorMsg("type name expected"); | 9952 ErrorMsg("type name expected"); |
9896 } | 9953 } |
9897 intptr_t type_pos = TokenPos(); | 9954 intptr_t type_pos = TokenPos(); |
| 9955 // Can't allocate const objects of a deferred type. |
| 9956 const bool allow_deferred_type = !is_const; |
9898 AbstractType& type = AbstractType::Handle( | 9957 AbstractType& type = AbstractType::Handle( |
9899 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); | 9958 ParseType(ClassFinalizer::kCanonicalizeWellFormed, allow_deferred_type)); |
9900 // In case the type is malformed, throw a dynamic type error after finishing | 9959 // In case the type is malformed, throw a dynamic type error after finishing |
9901 // parsing the instance creation expression. | 9960 // parsing the instance creation expression. |
9902 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { | 9961 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { |
9903 // Replace the type with a malformed type. | 9962 // Replace the type with a malformed type. |
9904 type = ClassFinalizer::NewFinalizedMalformedType( | 9963 type = ClassFinalizer::NewFinalizedMalformedType( |
9905 Error::Handle(), // No previous error. | 9964 Error::Handle(), // No previous error. |
9906 script_, | 9965 script_, |
9907 type_pos, | 9966 type_pos, |
9908 "%s'%s' cannot be instantiated", | 9967 "%s'%s' cannot be instantiated", |
9909 type.IsTypeParameter() ? "type parameter " : "", | 9968 type.IsTypeParameter() ? "type parameter " : "", |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10275 ASSERT(!is_top_level_); | 10334 ASSERT(!is_top_level_); |
10276 AstNode* primary = NULL; | 10335 AstNode* primary = NULL; |
10277 if (IsFunctionLiteral()) { | 10336 if (IsFunctionLiteral()) { |
10278 // The name of a literal function is visible from inside the function, but | 10337 // The name of a literal function is visible from inside the function, but |
10279 // must not collide with names in the scope declaring the literal. | 10338 // must not collide with names in the scope declaring the literal. |
10280 OpenBlock(); | 10339 OpenBlock(); |
10281 primary = ParseFunctionStatement(true); | 10340 primary = ParseFunctionStatement(true); |
10282 CloseBlock(); | 10341 CloseBlock(); |
10283 } else if (IsIdentifier()) { | 10342 } else if (IsIdentifier()) { |
10284 QualIdent qual_ident; | 10343 QualIdent qual_ident; |
| 10344 intptr_t qual_ident_pos = TokenPos(); |
10285 ParseQualIdent(&qual_ident); | 10345 ParseQualIdent(&qual_ident); |
10286 if (qual_ident.lib_prefix == NULL) { | 10346 if (qual_ident.lib_prefix == NULL) { |
10287 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, | 10347 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, |
10288 *qual_ident.ident, | 10348 *qual_ident.ident, |
10289 &primary)) { | 10349 &primary)) { |
10290 // Check whether the identifier is a type parameter. | 10350 // Check whether the identifier is a type parameter. |
10291 if (!current_class().IsNull()) { | 10351 if (!current_class().IsNull()) { |
10292 TypeParameter& type_param = TypeParameter::ZoneHandle( | 10352 TypeParameter& type_param = TypeParameter::ZoneHandle( |
10293 current_class().LookupTypeParameter(*(qual_ident.ident))); | 10353 current_class().LookupTypeParameter(*(qual_ident.ident))); |
10294 if (!type_param.IsNull()) { | 10354 if (!type_param.IsNull()) { |
(...skipping 10 matching lines...) Expand all Loading... |
10305 // This is a qualified identifier with a library prefix so resolve | 10365 // This is a qualified identifier with a library prefix so resolve |
10306 // the identifier locally in that library (we do not include the | 10366 // the identifier locally in that library (we do not include the |
10307 // libraries imported by that library). | 10367 // libraries imported by that library). |
10308 primary = ResolveIdentInPrefixScope(qual_ident.ident_pos, | 10368 primary = ResolveIdentInPrefixScope(qual_ident.ident_pos, |
10309 *qual_ident.lib_prefix, | 10369 *qual_ident.lib_prefix, |
10310 *qual_ident.ident); | 10370 *qual_ident.ident); |
10311 // If the identifier could not be resolved, throw a NoSuchMethodError. | 10371 // If the identifier could not be resolved, throw a NoSuchMethodError. |
10312 // Note: unlike in the case of an unqualified identifier, do not | 10372 // Note: unlike in the case of an unqualified identifier, do not |
10313 // interpret the unresolved identifier as an instance method or | 10373 // interpret the unresolved identifier as an instance method or |
10314 // instance getter call when compiling an instance method. | 10374 // instance getter call when compiling an instance method. |
10315 // TODO(hausner): Ideally we should generate the NoSuchMethodError | 10375 if (primary == NULL) { |
10316 // later, when we know more about how the unresolved name is used. | 10376 if (qual_ident.lib_prefix->is_deferred_load() && |
10317 // For example, we don't know yet whether the unresolved name | 10377 qual_ident.ident->Equals(Symbols::LoadLibrary())) { |
10318 // refers to a getter or a setter. However, it is more awkward | 10378 // Hack Alert: recognize special 'loadLibrary' call on the |
10319 // to distinuish four NoSuchMethodError cases all over the place | 10379 // prefix object. The prefix is the primary. Rewind parser and |
10320 // in the parser. The four cases are: prefixed vs non-prefixed | 10380 // let ParseSelectors() handle the loadLibrary call. |
10321 // name, static vs dynamic context in which the unresolved name | 10381 SetPosition(qual_ident_pos); |
10322 // is used. We cheat a little here by looking at the next token | 10382 ConsumeToken(); // Prefix name. |
10323 // to determine whether we have an unresolved method call or | 10383 primary = new LiteralNode(qual_ident_pos, *qual_ident.lib_prefix); |
10324 // field access. | 10384 } else { |
10325 if (primary->IsPrimaryNode() && | 10385 // TODO(hausner): Ideally we should generate the NoSuchMethodError |
10326 primary->AsPrimaryNode()->primary().IsString()) { | 10386 // later, when we know more about how the unresolved name is used. |
10327 InvocationMirror::Type call_type = | 10387 // For example, we don't know yet whether the unresolved name |
10328 CurrentToken() == Token::kLPAREN ? | 10388 // refers to a getter or a setter. However, it is more awkward |
10329 InvocationMirror::kMethod : InvocationMirror::kGetter; | 10389 // to distinuish four NoSuchMethodError cases all over the place |
10330 const String& unresolved_name = | 10390 // in the parser. The four cases are: prefixed vs non-prefixed |
10331 String::Cast(primary->AsPrimaryNode()->primary()); | 10391 // name, static vs dynamic context in which the unresolved name |
10332 primary = ThrowNoSuchMethodError(primary->token_pos(), | 10392 // is used. We cheat a little here by looking at the next token |
10333 current_class(), | 10393 // to determine whether we have an unresolved method call or |
10334 unresolved_name, | 10394 // field access. |
10335 NULL, // No arguments. | 10395 String& qualified_name = |
10336 InvocationMirror::kTopLevel, | 10396 String::ZoneHandle(qual_ident.lib_prefix->name()); |
10337 call_type, | 10397 qualified_name = String::Concat(qualified_name, Symbols::Dot()); |
10338 NULL); // No existing function. | 10398 qualified_name = String::Concat(qualified_name, *qual_ident.ident); |
| 10399 qualified_name = Symbols::New(qualified_name); |
| 10400 InvocationMirror::Type call_type = |
| 10401 CurrentToken() == Token::kLPAREN ? |
| 10402 InvocationMirror::kMethod : InvocationMirror::kGetter; |
| 10403 primary = ThrowNoSuchMethodError(qual_ident_pos, |
| 10404 current_class(), |
| 10405 qualified_name, |
| 10406 NULL, // No arguments. |
| 10407 InvocationMirror::kTopLevel, |
| 10408 call_type, |
| 10409 NULL); // No existing function. |
| 10410 } |
10339 } | 10411 } |
10340 } | 10412 } |
10341 ASSERT(primary != NULL); | 10413 ASSERT(primary != NULL); |
10342 } else if (CurrentToken() == Token::kTHIS) { | 10414 } else if (CurrentToken() == Token::kTHIS) { |
10343 LocalVariable* local = LookupLocalScope(Symbols::This()); | 10415 LocalVariable* local = LookupLocalScope(Symbols::This()); |
10344 if (local == NULL) { | 10416 if (local == NULL) { |
10345 ErrorMsg("receiver 'this' is not in scope"); | 10417 ErrorMsg("receiver 'this' is not in scope"); |
10346 } | 10418 } |
10347 primary = new LoadLocalNode(TokenPos(), local); | 10419 primary = new LoadLocalNode(TokenPos(), local); |
10348 ConsumeToken(); | 10420 ConsumeToken(); |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10793 void Parser::SkipQualIdent() { | 10865 void Parser::SkipQualIdent() { |
10794 ASSERT(IsIdentifier()); | 10866 ASSERT(IsIdentifier()); |
10795 ConsumeToken(); | 10867 ConsumeToken(); |
10796 if (CurrentToken() == Token::kPERIOD) { | 10868 if (CurrentToken() == Token::kPERIOD) { |
10797 ConsumeToken(); // Consume the kPERIOD token. | 10869 ConsumeToken(); // Consume the kPERIOD token. |
10798 ExpectIdentifier("identifier expected after '.'"); | 10870 ExpectIdentifier("identifier expected after '.'"); |
10799 } | 10871 } |
10800 } | 10872 } |
10801 | 10873 |
10802 } // namespace dart | 10874 } // namespace dart |
OLD | NEW |