| 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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 4906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4917 no_args); | 4917 no_args); |
| 4918 | 4918 |
| 4919 // Generate assignment of next iterator value to loop variable. | 4919 // Generate assignment of next iterator value to loop variable. |
| 4920 AstNode* loop_var_assignment = NULL; | 4920 AstNode* loop_var_assignment = NULL; |
| 4921 if (loop_var != NULL) { | 4921 if (loop_var != NULL) { |
| 4922 // The for loop declares a new variable. Add it to the loop body scope. | 4922 // The for loop declares a new variable. Add it to the loop body scope. |
| 4923 current_block_->scope->AddVariable(loop_var); | 4923 current_block_->scope->AddVariable(loop_var); |
| 4924 loop_var_assignment = | 4924 loop_var_assignment = |
| 4925 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next); | 4925 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next); |
| 4926 } else { | 4926 } else { |
| 4927 AstNode* loop_var_primary = ResolveVarOrField(loop_var_pos, *loop_var_name); | 4927 AstNode* loop_var_primary = |
| 4928 ResolveIdent(loop_var_pos, *loop_var_name, false); |
| 4928 ASSERT(!loop_var_primary->IsPrimaryNode()); | 4929 ASSERT(!loop_var_primary->IsPrimaryNode()); |
| 4929 loop_var_assignment = | 4930 loop_var_assignment = |
| 4930 CreateAssignmentNode(loop_var_primary, iterator_next); | 4931 CreateAssignmentNode(loop_var_primary, iterator_next); |
| 4931 if (loop_var_assignment == NULL) { | 4932 if (loop_var_assignment == NULL) { |
| 4932 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", | 4933 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", |
| 4933 loop_var_name->ToCString()); | 4934 loop_var_name->ToCString()); |
| 4934 } | 4935 } |
| 4935 } | 4936 } |
| 4936 current_block_->statements->Add(loop_var_assignment); | 4937 current_block_->statements->Add(loop_var_assignment); |
| 4937 | 4938 |
| (...skipping 2287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7225 // an error. | 7226 // an error. |
| 7226 ErrorMsg(qual_ident.ident_pos, "identifier '%s.%s' cannot be resolved", | 7227 ErrorMsg(qual_ident.ident_pos, "identifier '%s.%s' cannot be resolved", |
| 7227 String::Handle(qual_ident.lib_prefix->name()).ToCString(), | 7228 String::Handle(qual_ident.lib_prefix->name()).ToCString(), |
| 7228 qual_ident.ident->ToCString()); | 7229 qual_ident.ident->ToCString()); |
| 7229 } | 7230 } |
| 7230 return result; | 7231 return result; |
| 7231 } | 7232 } |
| 7232 | 7233 |
| 7233 | 7234 |
| 7234 // Resolve identifier, issue an error message if the name refers to | 7235 // Resolve identifier, issue an error message if the name refers to |
| 7235 // a method or a class/interface. | 7236 // a class/interface or a type parameter. Issue an error message if |
| 7237 // the ident refers to a method and allow_closure_names is false. |
| 7236 // If the name cannot be resolved, turn it into an instance field access | 7238 // If the name cannot be resolved, turn it into an instance field access |
| 7237 // if we're compiling an instance method, or issue an error message | 7239 // if we're compiling an instance method, or issue an error message |
| 7238 // if we're compiling a static method. | 7240 // if we're compiling a static method. |
| 7239 AstNode* Parser::ResolveVarOrField(intptr_t ident_pos, const String& ident) { | 7241 AstNode* Parser::ResolveIdent(intptr_t ident_pos, |
| 7240 TRACE_PARSER("ResolveVarOrField"); | 7242 const String& ident, |
| 7243 bool allow_closure_names) { |
| 7244 TRACE_PARSER("ResolveIdent"); |
| 7241 // First try to find the variable in the local scope (block scope or | 7245 // First try to find the variable in the local scope (block scope or |
| 7242 // class scope). | 7246 // class scope). |
| 7243 AstNode* var_or_field = NULL; | 7247 AstNode* resolved = NULL; |
| 7244 ResolveIdentInLocalScope(ident_pos, ident, &var_or_field); | 7248 ResolveIdentInLocalScope(ident_pos, ident, &resolved); |
| 7245 if (var_or_field == NULL) { | 7249 if (resolved == NULL) { |
| 7246 // Check whether the identifier is a type parameter. Type parameters | 7250 // Check whether the identifier is a type parameter. Type parameters |
| 7247 // can never be used in primary expressions. | 7251 // can never be used in primary expressions. |
| 7248 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 7252 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
| 7249 if (!scope_class.IsNull()) { | 7253 if (!scope_class.IsNull()) { |
| 7250 TypeParameter& type_param = TypeParameter::Handle( | 7254 TypeParameter& type_param = TypeParameter::Handle( |
| 7251 scope_class.LookupTypeParameter(ident, ident_pos)); | 7255 scope_class.LookupTypeParameter(ident, ident_pos)); |
| 7252 if (!type_param.IsNull()) { | 7256 if (!type_param.IsNull()) { |
| 7253 String& type_param_name = String::Handle(type_param.Name()); | 7257 String& type_param_name = String::Handle(type_param.Name()); |
| 7254 ErrorMsg(ident_pos, "illegal use of type parameter %s", | 7258 ErrorMsg(ident_pos, "illegal use of type parameter %s", |
| 7255 type_param_name.ToCString()); | 7259 type_param_name.ToCString()); |
| 7256 } | 7260 } |
| 7257 } | 7261 } |
| 7258 // Not found in the local scope, and the name is not a type parameter. | 7262 // Not found in the local scope, and the name is not a type parameter. |
| 7259 // Try finding the variable in the library scope (current library | 7263 // Try finding the variable in the library scope (current library |
| 7260 // and all libraries imported by it). | 7264 // and all libraries imported by it). |
| 7261 QualIdent qual_ident; | 7265 QualIdent qual_ident; |
| 7262 qual_ident.lib_prefix = NULL; | 7266 qual_ident.lib_prefix = NULL; |
| 7263 qual_ident.ident_pos = ident_pos; | 7267 qual_ident.ident_pos = ident_pos; |
| 7264 qual_ident.ident = &(String::ZoneHandle(ident.raw())); | 7268 qual_ident.ident = &(String::ZoneHandle(ident.raw())); |
| 7265 var_or_field = ResolveIdentInLibraryScope(library_, | 7269 resolved = ResolveIdentInLibraryScope(library_, |
| 7266 qual_ident, | 7270 qual_ident, |
| 7267 kResolveIncludingImports); | 7271 kResolveIncludingImports); |
| 7268 } | 7272 } |
| 7269 if (var_or_field->IsPrimaryNode()) { | 7273 if (resolved->IsPrimaryNode()) { |
| 7270 PrimaryNode* primary = var_or_field->AsPrimaryNode(); | 7274 PrimaryNode* primary = resolved->AsPrimaryNode(); |
| 7271 if (primary->primary().IsString()) { | 7275 if (primary->primary().IsString()) { |
| 7272 // We got an unresolved name. If we are compiling a static | 7276 // We got an unresolved name. If we are compiling a static |
| 7273 // method, this is an error. In an instance method, we convert | 7277 // method, this is an error. In an instance method, we convert |
| 7274 // the unresolved name to an instance field access, since a | 7278 // the unresolved name to an instance field access, since a |
| 7275 // subclass might define a field with this name. | 7279 // subclass might define a field with this name. |
| 7276 if (current_function().is_static()) { | 7280 if (current_function().is_static()) { |
| 7277 ErrorMsg(ident_pos, "identifier '%s' is not declared in this scope", | 7281 ErrorMsg(ident_pos, "identifier '%s' is not declared in this scope", |
| 7278 ident.ToCString()); | 7282 ident.ToCString()); |
| 7279 } else { | 7283 } else { |
| 7280 // Treat as call to unresolved instance field. | 7284 // Treat as call to unresolved instance field. |
| 7281 var_or_field = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 7285 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 7282 } | 7286 } |
| 7283 } else if (primary->primary().IsFunction()) { | 7287 } else if (primary->primary().IsFunction()) { |
| 7284 ErrorMsg(ident_pos, "illegal reference to method '%s'", | 7288 if (allow_closure_names) { |
| 7285 ident.ToCString()); | 7289 resolved = LoadClosure(primary); |
| 7290 } else { |
| 7291 ErrorMsg(ident_pos, "illegal reference to method '%s'", |
| 7292 ident.ToCString()); |
| 7293 } |
| 7286 } else { | 7294 } else { |
| 7287 ASSERT(primary->primary().IsClass()); | 7295 ASSERT(primary->primary().IsClass()); |
| 7288 ErrorMsg(ident_pos, "illegal reference to class or interface '%s'", | 7296 ErrorMsg(ident_pos, "illegal reference to class or interface '%s'", |
| 7289 ident.ToCString()); | 7297 ident.ToCString()); |
| 7290 } | 7298 } |
| 7291 } | 7299 } |
| 7292 return var_or_field; | 7300 return resolved; |
| 7293 } | 7301 } |
| 7294 | 7302 |
| 7295 | 7303 |
| 7296 // Resolve variables used in an import string literal. | 7304 // Resolve variables used in an import string literal. |
| 7297 // If the variable name cannot be resolved issue an error message. | 7305 // If the variable name cannot be resolved issue an error message. |
| 7298 // Currently we only resolve against the global map which is passed in | 7306 // Currently we only resolve against the global map which is passed in |
| 7299 // when the script is loaded. | 7307 // when the script is loaded. |
| 7300 RawString* Parser::ResolveImportVar(intptr_t ident_pos, const String& ident) { | 7308 RawString* Parser::ResolveImportVar(intptr_t ident_pos, const String& ident) { |
| 7301 TRACE_PARSER("ResolveImportVar"); | 7309 TRACE_PARSER("ResolveImportVar"); |
| 7302 const Array& import_map = | 7310 const Array& import_map = |
| (...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8076 bool is_compiletime_const = true; | 8084 bool is_compiletime_const = true; |
| 8077 ArrayNode* values = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); | 8085 ArrayNode* values = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); |
| 8078 while (CurrentToken() == Token::kSTRING) { | 8086 while (CurrentToken() == Token::kSTRING) { |
| 8079 values->AddElement(new LiteralNode(token_index_, *CurrentLiteral())); | 8087 values->AddElement(new LiteralNode(token_index_, *CurrentLiteral())); |
| 8080 ConsumeToken(); | 8088 ConsumeToken(); |
| 8081 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 8089 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
| 8082 (CurrentToken() == Token::kINTERPOL_START)) { | 8090 (CurrentToken() == Token::kINTERPOL_START)) { |
| 8083 AstNode* expr = NULL; | 8091 AstNode* expr = NULL; |
| 8084 const intptr_t expr_pos = token_index_; | 8092 const intptr_t expr_pos = token_index_; |
| 8085 if (CurrentToken() == Token::kINTERPOL_VAR) { | 8093 if (CurrentToken() == Token::kINTERPOL_VAR) { |
| 8086 expr = ResolveVarOrField(token_index_, *CurrentLiteral()); | 8094 expr = ResolveIdent(token_index_, *CurrentLiteral(), true); |
| 8087 ASSERT(!expr->IsPrimaryNode()); | |
| 8088 ConsumeToken(); | 8095 ConsumeToken(); |
| 8089 } else { | 8096 } else { |
| 8090 ASSERT(CurrentToken() == Token::kINTERPOL_START); | 8097 ASSERT(CurrentToken() == Token::kINTERPOL_START); |
| 8091 ConsumeToken(); | 8098 ConsumeToken(); |
| 8092 expr = ParseExpr(kAllowConst); | 8099 expr = ParseExpr(kAllowConst); |
| 8093 ExpectToken(Token::kINTERPOL_END); | 8100 ExpectToken(Token::kINTERPOL_END); |
| 8094 } | 8101 } |
| 8095 // Check if this interpolated string is still considered a compile time | 8102 // Check if this interpolated string is still considered a compile time |
| 8096 // constant. If it is we need to evaluate if the current string part is | 8103 // constant. If it is we need to evaluate if the current string part is |
| 8097 // a constant or not. | 8104 // a constant or not. |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8580 void Parser::SkipQualIdent() { | 8587 void Parser::SkipQualIdent() { |
| 8581 ASSERT(IsIdentifier()); | 8588 ASSERT(IsIdentifier()); |
| 8582 ConsumeToken(); | 8589 ConsumeToken(); |
| 8583 if (CurrentToken() == Token::kPERIOD) { | 8590 if (CurrentToken() == Token::kPERIOD) { |
| 8584 ConsumeToken(); // Consume the kPERIOD token. | 8591 ConsumeToken(); // Consume the kPERIOD token. |
| 8585 ExpectIdentifier("identifier expected after '.'"); | 8592 ExpectIdentifier("identifier expected after '.'"); |
| 8586 } | 8593 } |
| 8587 } | 8594 } |
| 8588 | 8595 |
| 8589 } // namespace dart | 8596 } // namespace dart |
| OLD | NEW |