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

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

Issue 216383004: Merge initial implementation of deferred handling in the VM: (Closed) Base URL: http://dart.googlecode.com/svn/trunk/dart/
Patch Set: Created 6 years, 9 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') | runtime/vm/raw_object.h » ('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 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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698