| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 2625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2636 if (is_top_level_ || | 2636 if (is_top_level_ || |
| 2637 !ResolveIdentInLocalScope(qual_ident->ident_pos, | 2637 !ResolveIdentInLocalScope(qual_ident->ident_pos, |
| 2638 *(qual_ident->ident), | 2638 *(qual_ident->ident), |
| 2639 NULL)) { | 2639 NULL)) { |
| 2640 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 2640 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
| 2641 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); | 2641 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); |
| 2642 if (!lib_prefix.IsNull()) { | 2642 if (!lib_prefix.IsNull()) { |
| 2643 // We have a library prefix qualified identifier, unless the prefix is | 2643 // We have a library prefix qualified identifier, unless the prefix is |
| 2644 // shadowed by a type parameter in scope. | 2644 // shadowed by a type parameter in scope. |
| 2645 if (current_class().IsNull() || | 2645 if (current_class().IsNull() || |
| 2646 (current_class().LookupTypeParameter(*(qual_ident->ident), | 2646 (current_class().LookupTypeParameter(*(qual_ident->ident)) == |
| 2647 TokenPos()) == | |
| 2648 TypeParameter::null())) { | 2647 TypeParameter::null())) { |
| 2649 ConsumeToken(); // Consume the kPERIOD token. | 2648 ConsumeToken(); // Consume the kPERIOD token. |
| 2650 qual_ident->lib_prefix = &lib_prefix; | 2649 qual_ident->lib_prefix = &lib_prefix; |
| 2651 qual_ident->ident_pos = TokenPos(); | 2650 qual_ident->ident_pos = TokenPos(); |
| 2652 qual_ident->ident = | 2651 qual_ident->ident = |
| 2653 ExpectIdentifier("identifier expected after '.'"); | 2652 ExpectIdentifier("identifier expected after '.'"); |
| 2654 } | 2653 } |
| 2655 } | 2654 } |
| 2656 } | 2655 } |
| 2657 } | 2656 } |
| (...skipping 3248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5906 AstNode* loop_var_assignment = NULL; | 5905 AstNode* loop_var_assignment = NULL; |
| 5907 if (loop_var != NULL) { | 5906 if (loop_var != NULL) { |
| 5908 // The for loop declares a new variable. Add it to the loop body scope. | 5907 // The for loop declares a new variable. Add it to the loop body scope. |
| 5909 current_block_->scope->AddVariable(loop_var); | 5908 current_block_->scope->AddVariable(loop_var); |
| 5910 loop_var_assignment = | 5909 loop_var_assignment = |
| 5911 new StoreLocalNode(loop_var_pos, loop_var, iterator_current); | 5910 new StoreLocalNode(loop_var_pos, loop_var, iterator_current); |
| 5912 } else { | 5911 } else { |
| 5913 AstNode* loop_var_primary = | 5912 AstNode* loop_var_primary = |
| 5914 ResolveIdent(loop_var_pos, *loop_var_name, false); | 5913 ResolveIdent(loop_var_pos, *loop_var_name, false); |
| 5915 ASSERT(!loop_var_primary->IsPrimaryNode()); | 5914 ASSERT(!loop_var_primary->IsPrimaryNode()); |
| 5916 loop_var_assignment = | 5915 loop_var_assignment = CreateAssignmentNode( |
| 5917 CreateAssignmentNode(loop_var_primary, iterator_current); | 5916 loop_var_primary, iterator_current, loop_var_name, loop_var_pos); |
| 5918 if (loop_var_assignment == NULL) { | 5917 ASSERT(loop_var_assignment != NULL); |
| 5919 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", | |
| 5920 loop_var_name->ToCString()); | |
| 5921 } | |
| 5922 } | 5918 } |
| 5923 current_block_->statements->Add(loop_var_assignment); | 5919 current_block_->statements->Add(loop_var_assignment); |
| 5924 | 5920 |
| 5925 // Now parse the for-in loop statement or block. | 5921 // Now parse the for-in loop statement or block. |
| 5926 if (CurrentToken() == Token::kLBRACE) { | 5922 if (CurrentToken() == Token::kLBRACE) { |
| 5927 ConsumeToken(); | 5923 ConsumeToken(); |
| 5928 ParseStatementSequence(); | 5924 ParseStatementSequence(); |
| 5929 ExpectToken(Token::kRBRACE); | 5925 ExpectToken(Token::kRBRACE); |
| 5930 } else { | 5926 } else { |
| 5931 AstNode* statement = ParseStatement(); | 5927 AstNode* statement = ParseStatement(); |
| (...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7003 left_operand = OptimizeBinaryOpNode( | 6999 left_operand = OptimizeBinaryOpNode( |
| 7004 op_pos, op_kind, left_operand, right_operand); | 7000 op_pos, op_kind, left_operand, right_operand); |
| 7005 } | 7001 } |
| 7006 } | 7002 } |
| 7007 current_preced--; | 7003 current_preced--; |
| 7008 } | 7004 } |
| 7009 return left_operand; | 7005 return left_operand; |
| 7010 } | 7006 } |
| 7011 | 7007 |
| 7012 | 7008 |
| 7013 bool Parser::IsAssignableExpr(AstNode* expr) { | |
| 7014 return (expr->IsLoadLocalNode() | |
| 7015 && (!expr->AsLoadLocalNode()->local().is_final())) | |
| 7016 || expr->IsLoadStaticFieldNode() | |
| 7017 || expr->IsStaticGetterNode() | |
| 7018 || expr->IsInstanceGetterNode() | |
| 7019 || expr->IsLoadIndexedNode() | |
| 7020 || (expr->IsPrimaryNode() && !expr->AsPrimaryNode()->IsSuper()); | |
| 7021 } | |
| 7022 | |
| 7023 | |
| 7024 AstNode* Parser::ParseExprList() { | 7009 AstNode* Parser::ParseExprList() { |
| 7025 TRACE_PARSER("ParseExprList"); | 7010 TRACE_PARSER("ParseExprList"); |
| 7026 AstNode* expressions = ParseExpr(kAllowConst, kConsumeCascades); | 7011 AstNode* expressions = ParseExpr(kAllowConst, kConsumeCascades); |
| 7027 if (CurrentToken() == Token::kCOMMA) { | 7012 if (CurrentToken() == Token::kCOMMA) { |
| 7028 // Collect comma-separated expressions in a non scope owning sequence node. | 7013 // Collect comma-separated expressions in a non scope owning sequence node. |
| 7029 SequenceNode* list = new SequenceNode(TokenPos(), NULL); | 7014 SequenceNode* list = new SequenceNode(TokenPos(), NULL); |
| 7030 list->Add(expressions); | 7015 list->Add(expressions); |
| 7031 while (CurrentToken() == Token::kCOMMA) { | 7016 while (CurrentToken() == Token::kCOMMA) { |
| 7032 ConsumeToken(); | 7017 ConsumeToken(); |
| 7033 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 7018 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7182 } | 7167 } |
| 7183 *expr = new InstanceGetterNode(token_pos, | 7168 *expr = new InstanceGetterNode(token_pos, |
| 7184 receiver, | 7169 receiver, |
| 7185 getter->field_name()); | 7170 getter->field_name()); |
| 7186 return result; | 7171 return result; |
| 7187 } | 7172 } |
| 7188 return result; | 7173 return result; |
| 7189 } | 7174 } |
| 7190 | 7175 |
| 7191 | 7176 |
| 7192 // Ensure that the expression temp is allocated for nodes that may need it. | 7177 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
| 7193 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { | 7178 AstNode* rhs, |
| 7179 const String* left_ident, |
| 7180 intptr_t left_pos) { |
| 7194 AstNode* result = original->MakeAssignmentNode(rhs); | 7181 AstNode* result = original->MakeAssignmentNode(rhs); |
| 7195 if ((result == NULL) && original->IsTypeNode()) { | 7182 if (result == NULL) { |
| 7196 const String& type_name = String::ZoneHandle( | 7183 String& name = String::ZoneHandle(); |
| 7197 original->AsTypeNode()->type().ClassName()); | 7184 if (original->IsTypeNode()) { |
| 7198 // TODO(tball): determine whether NoSuchMethod should be called instead. | 7185 name = Symbols::New(original->Name()); |
| 7186 } else if ((left_ident != NULL) && |
| 7187 (original->IsLiteralNode() || |
| 7188 original->IsLoadLocalNode() || |
| 7189 original->IsLoadStaticFieldNode())) { |
| 7190 name = left_ident->raw(); |
| 7191 } |
| 7192 if (name.IsNull()) { |
| 7193 ErrorMsg(left_pos, "expression is not assignable"); |
| 7194 } |
| 7199 result = ThrowNoSuchMethodError(original->token_pos(), | 7195 result = ThrowNoSuchMethodError(original->token_pos(), |
| 7200 current_class(), | 7196 current_class(), |
| 7201 type_name, | 7197 name, |
| 7202 InvocationMirror::kStatic, | 7198 InvocationMirror::kStatic, |
| 7203 InvocationMirror::kSetter); | 7199 InvocationMirror::kSetter); |
| 7204 } | 7200 } else if (result->IsStoreIndexedNode() || |
| 7205 if ((result != NULL) && | 7201 result->IsInstanceSetterNode() || |
| 7206 (result->IsStoreIndexedNode() || | 7202 result->IsStaticSetterNode() || |
| 7207 result->IsInstanceSetterNode() || | 7203 result->IsStoreStaticFieldNode() || |
| 7208 result->IsStaticSetterNode() || | 7204 result->IsStoreLocalNode()) { |
| 7209 result->IsStoreStaticFieldNode() || | 7205 // Ensure that the expression temp is allocated for nodes that may need it. |
| 7210 result->IsStoreLocalNode())) { | |
| 7211 EnsureExpressionTemp(); | 7206 EnsureExpressionTemp(); |
| 7212 } | 7207 } |
| 7213 return result; | 7208 return result; |
| 7214 } | 7209 } |
| 7215 | 7210 |
| 7216 | 7211 |
| 7217 AstNode* Parser::ParseCascades(AstNode* expr) { | 7212 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 7218 intptr_t cascade_pos = TokenPos(); | 7213 intptr_t cascade_pos = TokenPos(); |
| 7219 LetNode* cascade = new LetNode(cascade_pos); | 7214 LetNode* cascade = new LetNode(cascade_pos); |
| 7220 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 7215 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
| 7221 while (CurrentToken() == Token::kCASCADE) { | 7216 while (CurrentToken() == Token::kCASCADE) { |
| 7222 cascade_pos = TokenPos(); | 7217 cascade_pos = TokenPos(); |
| 7223 LoadLocalNode* load_cascade_receiver = | 7218 LoadLocalNode* load_cascade_receiver = |
| 7224 new LoadLocalNode(cascade_pos, cascade_receiver_var); | 7219 new LoadLocalNode(cascade_pos, cascade_receiver_var); |
| 7225 if (Token::IsIdentifier(LookaheadToken(1))) { | 7220 if (Token::IsIdentifier(LookaheadToken(1))) { |
| 7226 // Replace .. with . for ParseSelectors(). | 7221 // Replace .. with . for ParseSelectors(). |
| 7227 token_kind_ = Token::kPERIOD; | 7222 token_kind_ = Token::kPERIOD; |
| 7228 } else if (LookaheadToken(1) == Token::kLBRACK) { | 7223 } else if (LookaheadToken(1) == Token::kLBRACK) { |
| 7229 ConsumeToken(); | 7224 ConsumeToken(); |
| 7230 } else { | 7225 } else { |
| 7231 ErrorMsg("identifier or [ expected after .."); | 7226 ErrorMsg("identifier or [ expected after .."); |
| 7232 } | 7227 } |
| 7228 String* expr_ident = |
| 7229 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 7230 const intptr_t expr_pos = TokenPos(); |
| 7233 expr = ParseSelectors(load_cascade_receiver, true); | 7231 expr = ParseSelectors(load_cascade_receiver, true); |
| 7234 | 7232 |
| 7235 // Assignments after a cascade are part of the cascade. The | 7233 // Assignments after a cascade are part of the cascade. The |
| 7236 // assigned expression must not contain cascades. | 7234 // assigned expression must not contain cascades. |
| 7237 if (Token::IsAssignmentOperator(CurrentToken())) { | 7235 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 7238 Token::Kind assignment_op = CurrentToken(); | 7236 Token::Kind assignment_op = CurrentToken(); |
| 7239 const intptr_t assignment_pos = TokenPos(); | 7237 const intptr_t assignment_pos = TokenPos(); |
| 7240 ConsumeToken(); | 7238 ConsumeToken(); |
| 7241 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); | 7239 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); |
| 7242 if (assignment_op != Token::kASSIGN) { | 7240 if (assignment_op != Token::kASSIGN) { |
| 7243 // Compound assignment: store inputs with side effects into | 7241 // Compound assignment: store inputs with side effects into |
| 7244 // temporary locals. | 7242 // temporary locals. |
| 7245 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 7243 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 7246 right_expr = | 7244 right_expr = |
| 7247 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 7245 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 7248 AstNode* assign_expr = CreateAssignmentNode(expr, right_expr); | 7246 AstNode* assign_expr = CreateAssignmentNode( |
| 7249 if (assign_expr == NULL) { | 7247 expr, right_expr, expr_ident, expr_pos); |
| 7250 ErrorMsg(assignment_pos, | 7248 ASSERT(assign_expr != NULL); |
| 7251 "left hand side of '%s' is not assignable", | |
| 7252 Token::Str(assignment_op)); | |
| 7253 } | |
| 7254 let_expr->AddNode(assign_expr); | 7249 let_expr->AddNode(assign_expr); |
| 7255 expr = let_expr; | 7250 expr = let_expr; |
| 7256 } else { | 7251 } else { |
| 7257 right_expr = | 7252 right_expr = |
| 7258 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 7253 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 7259 AstNode* assign_expr = CreateAssignmentNode(expr, right_expr); | 7254 AstNode* assign_expr = CreateAssignmentNode( |
| 7260 if (assign_expr == NULL) { | 7255 expr, right_expr, expr_ident, expr_pos); |
| 7261 ErrorMsg(assignment_pos, | 7256 ASSERT(assign_expr != NULL); |
| 7262 "left hand side of '%s' is not assignable", | |
| 7263 Token::Str(assignment_op)); | |
| 7264 } | |
| 7265 expr = assign_expr; | 7257 expr = assign_expr; |
| 7266 } | 7258 } |
| 7267 } | 7259 } |
| 7268 cascade->AddNode(expr); | 7260 cascade->AddNode(expr); |
| 7269 } | 7261 } |
| 7270 // The result is an expression with the (side effects of the) cascade | 7262 // The result is an expression with the (side effects of the) cascade |
| 7271 // sequence followed by the (value of the) receiver temp variable load. | 7263 // sequence followed by the (value of the) receiver temp variable load. |
| 7272 cascade->AddNode(new LoadLocalNode(cascade_pos, cascade_receiver_var)); | 7264 cascade->AddNode(new LoadLocalNode(cascade_pos, cascade_receiver_var)); |
| 7273 return cascade; | 7265 return cascade; |
| 7274 } | 7266 } |
| 7275 | 7267 |
| 7276 | 7268 |
| 7277 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 7269 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
| 7278 bool consume_cascades) { | 7270 bool consume_cascades) { |
| 7279 TRACE_PARSER("ParseExpr"); | 7271 TRACE_PARSER("ParseExpr"); |
| 7272 String* expr_ident = |
| 7273 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 7280 const intptr_t expr_pos = TokenPos(); | 7274 const intptr_t expr_pos = TokenPos(); |
| 7281 | 7275 |
| 7282 if (CurrentToken() == Token::kTHROW) { | 7276 if (CurrentToken() == Token::kTHROW) { |
| 7283 ConsumeToken(); | 7277 ConsumeToken(); |
| 7284 ASSERT(CurrentToken() != Token::kSEMICOLON); | 7278 ASSERT(CurrentToken() != Token::kSEMICOLON); |
| 7285 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 7279 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 7286 return new ThrowNode(expr_pos, expr, NULL); | 7280 return new ThrowNode(expr_pos, expr, NULL); |
| 7287 } | 7281 } |
| 7288 AstNode* expr = ParseConditionalExpr(); | 7282 AstNode* expr = ParseConditionalExpr(); |
| 7289 if (!Token::IsAssignmentOperator(CurrentToken())) { | 7283 if (!Token::IsAssignmentOperator(CurrentToken())) { |
| 7290 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { | 7284 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { |
| 7291 return ParseCascades(expr); | 7285 return ParseCascades(expr); |
| 7292 } | 7286 } |
| 7293 if (require_compiletime_const) { | 7287 if (require_compiletime_const) { |
| 7294 expr = FoldConstExpr(expr_pos, expr); | 7288 expr = FoldConstExpr(expr_pos, expr); |
| 7295 } | 7289 } |
| 7296 return expr; | 7290 return expr; |
| 7297 } | 7291 } |
| 7298 // Assignment expressions. | 7292 // Assignment expressions. |
| 7299 Token::Kind assignment_op = CurrentToken(); | 7293 const Token::Kind assignment_op = CurrentToken(); |
| 7300 const intptr_t assignment_pos = TokenPos(); | 7294 const intptr_t assignment_pos = TokenPos(); |
| 7301 ConsumeToken(); | 7295 ConsumeToken(); |
| 7302 const intptr_t right_expr_pos = TokenPos(); | 7296 const intptr_t right_expr_pos = TokenPos(); |
| 7303 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 7297 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
| 7304 ErrorMsg(right_expr_pos, "expression must be a compile-time constant"); | 7298 ErrorMsg(right_expr_pos, "expression must be a compile-time constant"); |
| 7305 } | 7299 } |
| 7306 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); | 7300 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 7307 if (assignment_op != Token::kASSIGN) { | 7301 if (assignment_op != Token::kASSIGN) { |
| 7308 // Compound assignment: store inputs with side effects into temp. locals. | 7302 // Compound assignment: store inputs with side effects into temp. locals. |
| 7309 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 7303 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 7310 AstNode* assigned_value = | 7304 AstNode* assigned_value = |
| 7311 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 7305 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 7312 AstNode* assign_expr = CreateAssignmentNode(expr, assigned_value); | 7306 AstNode* assign_expr = CreateAssignmentNode( |
| 7313 if (assign_expr == NULL) { | 7307 expr, assigned_value, expr_ident, expr_pos); |
| 7314 ErrorMsg(assignment_pos, | 7308 ASSERT(assign_expr != NULL); |
| 7315 "left hand side of '%s' is not assignable", | |
| 7316 Token::Str(assignment_op)); | |
| 7317 } | |
| 7318 let_expr->AddNode(assign_expr); | 7309 let_expr->AddNode(assign_expr); |
| 7319 return let_expr; | 7310 return let_expr; |
| 7320 } else { | 7311 } else { |
| 7321 AstNode* assigned_value = | 7312 AstNode* assigned_value = |
| 7322 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 7313 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 7323 AstNode* assign_expr = CreateAssignmentNode(expr, assigned_value); | 7314 AstNode* assign_expr = CreateAssignmentNode( |
| 7324 if (assign_expr == NULL) { | 7315 expr, assigned_value, expr_ident, expr_pos); |
| 7325 ErrorMsg(assignment_pos, | 7316 ASSERT(assign_expr != NULL); |
| 7326 "left hand side of '%s' is not assignable", | |
| 7327 Token::Str(assignment_op)); | |
| 7328 } | |
| 7329 return assign_expr; | 7317 return assign_expr; |
| 7330 } | 7318 } |
| 7331 } | 7319 } |
| 7332 | 7320 |
| 7333 | 7321 |
| 7334 LiteralNode* Parser::ParseConstExpr() { | 7322 LiteralNode* Parser::ParseConstExpr() { |
| 7335 TRACE_PARSER("ParseConstExpr"); | 7323 TRACE_PARSER("ParseConstExpr"); |
| 7336 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); | 7324 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
| 7337 ASSERT(expr->IsLiteralNode()); | 7325 ASSERT(expr->IsLiteralNode()); |
| 7338 return expr->AsLiteralNode(); | 7326 return expr->AsLiteralNode(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 7367 ConsumeToken(); | 7355 ConsumeToken(); |
| 7368 expr = ParseUnaryExpr(); | 7356 expr = ParseUnaryExpr(); |
| 7369 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { | 7357 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { |
| 7370 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); | 7358 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); |
| 7371 } else { | 7359 } else { |
| 7372 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 7360 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
| 7373 } | 7361 } |
| 7374 } else if (IsIncrementOperator(CurrentToken())) { | 7362 } else if (IsIncrementOperator(CurrentToken())) { |
| 7375 Token::Kind incr_op = CurrentToken(); | 7363 Token::Kind incr_op = CurrentToken(); |
| 7376 ConsumeToken(); | 7364 ConsumeToken(); |
| 7365 String* expr_ident = |
| 7366 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 7367 const intptr_t expr_pos = TokenPos(); |
| 7377 expr = ParseUnaryExpr(); | 7368 expr = ParseUnaryExpr(); |
| 7378 if (!IsAssignableExpr(expr)) { | |
| 7379 ErrorMsg("expression is not assignable"); | |
| 7380 } | |
| 7381 // Is prefix. | 7369 // Is prefix. |
| 7382 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 7370 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 7383 Token::Kind binary_op = | 7371 Token::Kind binary_op = |
| 7384 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 7372 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 7385 BinaryOpNode* add = new BinaryOpNode( | 7373 BinaryOpNode* add = new BinaryOpNode( |
| 7386 op_pos, | 7374 op_pos, |
| 7387 binary_op, | 7375 binary_op, |
| 7388 expr, | 7376 expr, |
| 7389 new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1)))); | 7377 new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1)))); |
| 7390 AstNode* store = CreateAssignmentNode(expr, add); | 7378 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); |
| 7391 ASSERT(store != NULL); | 7379 ASSERT(store != NULL); |
| 7392 let_expr->AddNode(store); | 7380 let_expr->AddNode(store); |
| 7393 expr = let_expr; | 7381 expr = let_expr; |
| 7394 } else { | 7382 } else { |
| 7395 expr = ParsePostfixExpr(); | 7383 expr = ParsePostfixExpr(); |
| 7396 } | 7384 } |
| 7397 return expr; | 7385 return expr; |
| 7398 } | 7386 } |
| 7399 | 7387 |
| 7400 | 7388 |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7720 | 7708 |
| 7721 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { | 7709 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
| 7722 AstNode* left = primary; | 7710 AstNode* left = primary; |
| 7723 while (true) { | 7711 while (true) { |
| 7724 AstNode* selector = NULL; | 7712 AstNode* selector = NULL; |
| 7725 if (CurrentToken() == Token::kPERIOD) { | 7713 if (CurrentToken() == Token::kPERIOD) { |
| 7726 ConsumeToken(); | 7714 ConsumeToken(); |
| 7727 if (left->IsPrimaryNode()) { | 7715 if (left->IsPrimaryNode()) { |
| 7728 if (left->AsPrimaryNode()->primary().IsFunction()) { | 7716 if (left->AsPrimaryNode()->primary().IsFunction()) { |
| 7729 left = LoadClosure(left->AsPrimaryNode()); | 7717 left = LoadClosure(left->AsPrimaryNode()); |
| 7718 } else if (left->AsPrimaryNode()->primary().IsTypeParameter()) { |
| 7719 if (current_block_->scope->function_level() > 0) { |
| 7720 // Make sure that the instantiator is captured. |
| 7721 CaptureInstantiator(); |
| 7722 } |
| 7723 TypeParameter& type_parameter = TypeParameter::ZoneHandle(); |
| 7724 type_parameter ^= ClassFinalizer::FinalizeType( |
| 7725 current_class(), |
| 7726 TypeParameter::Cast(left->AsPrimaryNode()->primary()), |
| 7727 ClassFinalizer::kFinalize); |
| 7728 ASSERT(!type_parameter.IsMalformed()); |
| 7729 left = new TypeNode(primary->token_pos(), type_parameter); |
| 7730 } else { | 7730 } else { |
| 7731 // Super field access handled in ParseSuperFieldAccess(), | 7731 // Super field access handled in ParseSuperFieldAccess(), |
| 7732 // super calls handled in ParseSuperCall(). | 7732 // super calls handled in ParseSuperCall(). |
| 7733 ASSERT(!left->AsPrimaryNode()->IsSuper()); | 7733 ASSERT(!left->AsPrimaryNode()->IsSuper()); |
| 7734 left = LoadFieldIfUnresolved(left); | 7734 left = LoadFieldIfUnresolved(left); |
| 7735 } | 7735 } |
| 7736 } | 7736 } |
| 7737 const intptr_t ident_pos = TokenPos(); | 7737 const intptr_t ident_pos = TokenPos(); |
| 7738 String* ident = ExpectIdentifier("identifier expected"); | 7738 String* ident = ExpectIdentifier("identifier expected"); |
| 7739 if (CurrentToken() == Token::kLPAREN) { | 7739 if (CurrentToken() == Token::kLPAREN) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7776 const bool saved_mode = SetAllowFunctionLiterals(true); | 7776 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7777 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); | 7777 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); |
| 7778 SetAllowFunctionLiterals(saved_mode); | 7778 SetAllowFunctionLiterals(saved_mode); |
| 7779 ExpectToken(Token::kRBRACK); | 7779 ExpectToken(Token::kRBRACK); |
| 7780 AstNode* array = left; | 7780 AstNode* array = left; |
| 7781 if (left->IsPrimaryNode()) { | 7781 if (left->IsPrimaryNode()) { |
| 7782 PrimaryNode* primary = left->AsPrimaryNode(); | 7782 PrimaryNode* primary = left->AsPrimaryNode(); |
| 7783 if (primary->primary().IsFunction()) { | 7783 if (primary->primary().IsFunction()) { |
| 7784 array = LoadClosure(primary); | 7784 array = LoadClosure(primary); |
| 7785 } else if (primary->primary().IsClass()) { | 7785 } else if (primary->primary().IsClass()) { |
| 7786 ErrorMsg(bracket_pos, "cannot apply index operator to class"); | 7786 const Class& type_class = Class::Cast(primary->primary()); |
| 7787 Type& type = Type::ZoneHandle( |
| 7788 Type::New(type_class, TypeArguments::Handle(), |
| 7789 primary->token_pos(), Heap::kOld)); |
| 7790 type ^= ClassFinalizer::FinalizeType( |
| 7791 current_class(), type, ClassFinalizer::kCanonicalize); |
| 7792 ASSERT(!type.IsMalformed()); |
| 7793 array = new TypeNode(primary->token_pos(), type); |
| 7794 } else if (primary->primary().IsTypeParameter()) { |
| 7795 if (current_block_->scope->function_level() > 0) { |
| 7796 // Make sure that the instantiator is captured. |
| 7797 CaptureInstantiator(); |
| 7798 } |
| 7799 TypeParameter& type_parameter = TypeParameter::ZoneHandle(); |
| 7800 type_parameter ^= ClassFinalizer::FinalizeType( |
| 7801 current_class(), |
| 7802 TypeParameter::Cast(primary->primary()), |
| 7803 ClassFinalizer::kFinalize); |
| 7804 ASSERT(!type_parameter.IsMalformed()); |
| 7805 array = new TypeNode(primary->token_pos(), type_parameter); |
| 7787 } else { | 7806 } else { |
| 7788 UNREACHABLE(); // Internal parser error. | 7807 UNREACHABLE(); // Internal parser error. |
| 7789 } | 7808 } |
| 7790 } | 7809 } |
| 7791 selector = new LoadIndexedNode(bracket_pos, | 7810 selector = new LoadIndexedNode(bracket_pos, |
| 7792 array, | 7811 array, |
| 7793 index, | 7812 index, |
| 7794 Class::ZoneHandle()); | 7813 Class::ZoneHandle()); |
| 7795 } else if (CurrentToken() == Token::kLPAREN) { | 7814 } else if (CurrentToken() == Token::kLPAREN) { |
| 7796 if (left->IsPrimaryNode()) { | 7815 if (left->IsPrimaryNode()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 7823 selector = ThrowNoSuchMethodError(primary->token_pos(), | 7842 selector = ThrowNoSuchMethodError(primary->token_pos(), |
| 7824 current_class(), | 7843 current_class(), |
| 7825 name, | 7844 name, |
| 7826 InvocationMirror::kStatic, | 7845 InvocationMirror::kStatic, |
| 7827 InvocationMirror::kMethod); | 7846 InvocationMirror::kMethod); |
| 7828 } else { | 7847 } else { |
| 7829 // Treat as call to unresolved (instance) method. | 7848 // Treat as call to unresolved (instance) method. |
| 7830 AstNode* receiver = LoadReceiver(primary->token_pos()); | 7849 AstNode* receiver = LoadReceiver(primary->token_pos()); |
| 7831 selector = ParseInstanceCall(receiver, name); | 7850 selector = ParseInstanceCall(receiver, name); |
| 7832 } | 7851 } |
| 7852 } else if (primary->primary().IsTypeParameter()) { |
| 7853 const String& name = String::ZoneHandle( |
| 7854 Symbols::New(primary->Name())); |
| 7855 selector = ThrowNoSuchMethodError(primary->token_pos(), |
| 7856 current_class(), |
| 7857 name, |
| 7858 InvocationMirror::kStatic, |
| 7859 InvocationMirror::kMethod); |
| 7833 } else if (primary->primary().IsClass()) { | 7860 } else if (primary->primary().IsClass()) { |
| 7834 ErrorMsg(left->token_pos(), | 7861 const Class& type_class = Class::Cast(primary->primary()); |
| 7835 "must use 'new' or 'const' to construct new instance"); | 7862 Type& type = Type::ZoneHandle( |
| 7863 Type::New(type_class, TypeArguments::Handle(), |
| 7864 primary->token_pos(), Heap::kOld)); |
| 7865 type ^= ClassFinalizer::FinalizeType( |
| 7866 current_class(), type, ClassFinalizer::kCanonicalize); |
| 7867 ASSERT(!type.IsMalformed()); |
| 7868 selector = new TypeNode(primary->token_pos(), type); |
| 7836 } else { | 7869 } else { |
| 7837 UNREACHABLE(); // Internal parser error. | 7870 UNREACHABLE(); // Internal parser error. |
| 7838 } | 7871 } |
| 7839 } else { | 7872 } else { |
| 7840 // Left is not a primary node; this must be a closure call. | 7873 // Left is not a primary node; this must be a closure call. |
| 7841 AstNode* closure = left; | 7874 AstNode* closure = left; |
| 7842 selector = ParseClosureCall(closure); | 7875 selector = ParseClosureCall(closure); |
| 7843 } | 7876 } |
| 7844 } else { | 7877 } else { |
| 7845 // No (more) selectors to parse. | 7878 // No (more) selectors to parse. |
| 7846 left = LoadFieldIfUnresolved(left); | 7879 left = LoadFieldIfUnresolved(left); |
| 7847 if (left->IsPrimaryNode()) { | 7880 if (left->IsPrimaryNode()) { |
| 7848 PrimaryNode* primary = left->AsPrimaryNode(); | 7881 PrimaryNode* primary = left->AsPrimaryNode(); |
| 7849 if (primary->primary().IsFunction()) { | 7882 if (primary->primary().IsFunction()) { |
| 7850 // Treat as implicit closure. | 7883 // Treat as implicit closure. |
| 7851 left = LoadClosure(primary); | 7884 left = LoadClosure(primary); |
| 7852 } else if (primary->primary().IsClass()) { | 7885 } else if (primary->primary().IsClass()) { |
| 7853 const Class& type_class = Class::Cast(primary->primary()); | 7886 const Class& type_class = Class::Cast(primary->primary()); |
| 7854 Type& type = Type::ZoneHandle( | 7887 Type& type = Type::ZoneHandle( |
| 7855 Type::New(type_class, TypeArguments::Handle(), | 7888 Type::New(type_class, TypeArguments::Handle(), |
| 7856 primary->token_pos(), Heap::kOld)); | 7889 primary->token_pos(), Heap::kOld)); |
| 7857 type ^= ClassFinalizer::FinalizeType( | 7890 type ^= ClassFinalizer::FinalizeType( |
| 7858 current_class(), type, ClassFinalizer::kCanonicalize); | 7891 current_class(), type, ClassFinalizer::kCanonicalize); |
| 7892 ASSERT(!type.IsMalformed()); |
| 7859 left = new TypeNode(primary->token_pos(), type); | 7893 left = new TypeNode(primary->token_pos(), type); |
| 7894 } else if (primary->primary().IsTypeParameter()) { |
| 7895 if (current_block_->scope->function_level() > 0) { |
| 7896 // Make sure that the instantiator is captured. |
| 7897 CaptureInstantiator(); |
| 7898 } |
| 7899 TypeParameter& type_parameter = TypeParameter::ZoneHandle(); |
| 7900 type_parameter ^= ClassFinalizer::FinalizeType( |
| 7901 current_class(), |
| 7902 TypeParameter::Cast(primary->primary()), |
| 7903 ClassFinalizer::kFinalize); |
| 7904 ASSERT(!type_parameter.IsMalformed()); |
| 7905 left = new TypeNode(primary->token_pos(), type_parameter); |
| 7860 } else if (primary->IsSuper()) { | 7906 } else if (primary->IsSuper()) { |
| 7861 // Return "super" to handle unary super operator calls, | 7907 // Return "super" to handle unary super operator calls, |
| 7862 // or to report illegal use of "super" otherwise. | 7908 // or to report illegal use of "super" otherwise. |
| 7863 left = primary; | 7909 left = primary; |
| 7864 } else { | 7910 } else { |
| 7865 UNREACHABLE(); // Internal parser error. | 7911 UNREACHABLE(); // Internal parser error. |
| 7866 } | 7912 } |
| 7867 } | 7913 } |
| 7868 // Done parsing selectors. | 7914 // Done parsing selectors. |
| 7869 return left; | 7915 return left; |
| 7870 } | 7916 } |
| 7871 ASSERT(selector != NULL); | 7917 ASSERT(selector != NULL); |
| 7872 left = selector; | 7918 left = selector; |
| 7873 } | 7919 } |
| 7874 } | 7920 } |
| 7875 | 7921 |
| 7876 | 7922 |
| 7877 AstNode* Parser::ParsePostfixExpr() { | 7923 AstNode* Parser::ParsePostfixExpr() { |
| 7878 TRACE_PARSER("ParsePostfixExpr"); | 7924 TRACE_PARSER("ParsePostfixExpr"); |
| 7879 const intptr_t postfix_expr_pos = TokenPos(); | 7925 String* expr_ident = |
| 7880 AstNode* postfix_expr = ParsePrimary(); | 7926 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 7881 postfix_expr = ParseSelectors(postfix_expr, false); | 7927 const intptr_t expr_pos = TokenPos(); |
| 7928 AstNode* expr = ParsePrimary(); |
| 7929 expr = ParseSelectors(expr, false); |
| 7882 if (IsIncrementOperator(CurrentToken())) { | 7930 if (IsIncrementOperator(CurrentToken())) { |
| 7883 TRACE_PARSER("IncrementOperator"); | 7931 TRACE_PARSER("IncrementOperator"); |
| 7884 Token::Kind incr_op = CurrentToken(); | 7932 Token::Kind incr_op = CurrentToken(); |
| 7885 if (!IsAssignableExpr(postfix_expr)) { | |
| 7886 ErrorMsg("expression is not assignable"); | |
| 7887 } | |
| 7888 ConsumeToken(); | 7933 ConsumeToken(); |
| 7889 // Not prefix. | 7934 // Not prefix. |
| 7890 LetNode* let_expr = PrepareCompoundAssignmentNodes(&postfix_expr); | 7935 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 7891 LocalVariable* temp = let_expr->AddInitializer(postfix_expr); | 7936 LocalVariable* temp = let_expr->AddInitializer(expr); |
| 7892 Token::Kind binary_op = | 7937 Token::Kind binary_op = |
| 7893 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 7938 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 7894 BinaryOpNode* add = new BinaryOpNode( | 7939 BinaryOpNode* add = new BinaryOpNode( |
| 7895 postfix_expr_pos, | 7940 expr_pos, |
| 7896 binary_op, | 7941 binary_op, |
| 7897 new LoadLocalNode(postfix_expr_pos, temp), | 7942 new LoadLocalNode(expr_pos, temp), |
| 7898 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); | 7943 new LiteralNode(expr_pos, Smi::ZoneHandle(Smi::New(1)))); |
| 7899 AstNode* store = CreateAssignmentNode(postfix_expr, add); | 7944 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); |
| 7900 ASSERT(store != NULL); | 7945 ASSERT(store != NULL); |
| 7901 // The result is a pair of the (side effects of the) store followed by | 7946 // The result is a pair of the (side effects of the) store followed by |
| 7902 // the (value of the) initial value temp variable load. | 7947 // the (value of the) initial value temp variable load. |
| 7903 let_expr->AddNode(store); | 7948 let_expr->AddNode(store); |
| 7904 let_expr->AddNode(new LoadLocalNode(postfix_expr_pos, temp)); | 7949 let_expr->AddNode(new LoadLocalNode(expr_pos, temp)); |
| 7905 return let_expr; | 7950 return let_expr; |
| 7906 } | 7951 } |
| 7907 return postfix_expr; | 7952 return expr; |
| 7908 } | 7953 } |
| 7909 | 7954 |
| 7910 | 7955 |
| 7911 // Resolve the given type and its type arguments from the given scope class | 7956 // Resolve the given type and its type arguments from the given scope class |
| 7912 // according to the given type finalization mode. | 7957 // according to the given type finalization mode. |
| 7913 // If the given scope class is null, use the current library, but do not try to | 7958 // If the given scope class is null, use the current library, but do not try to |
| 7914 // resolve type parameters. | 7959 // resolve type parameters. |
| 7915 // Not all involved type classes may get resolved yet, but at least the type | 7960 // Not all involved type classes may get resolved yet, but at least the type |
| 7916 // parameters of the given class will get resolved, thereby relieving the class | 7961 // parameters of the given class will get resolved, thereby relieving the class |
| 7917 // finalizer from resolving type parameters out of context. | 7962 // finalizer from resolving type parameters out of context. |
| 7918 void Parser::ResolveTypeFromClass(const Class& scope_class, | 7963 void Parser::ResolveTypeFromClass(const Class& scope_class, |
| 7919 ClassFinalizer::FinalizationKind finalization, | 7964 ClassFinalizer::FinalizationKind finalization, |
| 7920 AbstractType* type) { | 7965 AbstractType* type) { |
| 7921 ASSERT(finalization >= ClassFinalizer::kTryResolve); | 7966 ASSERT(finalization >= ClassFinalizer::kTryResolve); |
| 7922 ASSERT(type != NULL); | 7967 ASSERT(type != NULL); |
| 7923 if (type->IsResolved()) { | 7968 if (type->IsResolved()) { |
| 7924 return; | 7969 return; |
| 7925 } | 7970 } |
| 7926 // Resolve class. | 7971 // Resolve class. |
| 7927 if (!type->HasResolvedTypeClass()) { | 7972 if (!type->HasResolvedTypeClass()) { |
| 7928 const UnresolvedClass& unresolved_class = | 7973 const UnresolvedClass& unresolved_class = |
| 7929 UnresolvedClass::Handle(type->unresolved_class()); | 7974 UnresolvedClass::Handle(type->unresolved_class()); |
| 7930 const String& unresolved_class_name = | 7975 const String& unresolved_class_name = |
| 7931 String::Handle(unresolved_class.ident()); | 7976 String::Handle(unresolved_class.ident()); |
| 7932 Class& resolved_type_class = Class::Handle(); | 7977 Class& resolved_type_class = Class::Handle(); |
| 7933 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 7978 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
| 7934 if (!scope_class.IsNull()) { | 7979 if (!scope_class.IsNull()) { |
| 7935 // First check if the type is a type parameter of the given scope class. | 7980 // First check if the type is a type parameter of the given scope class. |
| 7936 const TypeParameter& type_parameter = TypeParameter::Handle( | 7981 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 7937 scope_class.LookupTypeParameter(unresolved_class_name, | 7982 scope_class.LookupTypeParameter(unresolved_class_name)); |
| 7938 type->token_pos())); | |
| 7939 if (!type_parameter.IsNull()) { | 7983 if (!type_parameter.IsNull()) { |
| 7940 // A type parameter is considered to be a malformed type when | 7984 // A type parameter is considered to be a malformed type when |
| 7941 // referenced by a static member. | 7985 // referenced by a static member. |
| 7942 if (ParsingStaticMember()) { | 7986 if (ParsingStaticMember()) { |
| 7943 ASSERT(scope_class.raw() == current_class().raw()); | 7987 ASSERT(scope_class.raw() == current_class().raw()); |
| 7944 *type = ClassFinalizer::NewFinalizedMalformedType( | 7988 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 7945 Error::Handle(), // No previous error. | 7989 Error::Handle(), // No previous error. |
| 7946 scope_class, | 7990 scope_class, |
| 7947 type->token_pos(), | 7991 type->token_pos(), |
| 7948 finalization, | 7992 finalization, |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8633 } else { | 8677 } else { |
| 8634 // TODO(hausner): Should this be an error? It is not meaningful to | 8678 // TODO(hausner): Should this be an error? It is not meaningful to |
| 8635 // reference a library prefix defined in an imported library. | 8679 // reference a library prefix defined in an imported library. |
| 8636 ASSERT(obj.IsLibraryPrefix()); | 8680 ASSERT(obj.IsLibraryPrefix()); |
| 8637 } | 8681 } |
| 8638 // Lexically unresolved primary identifiers are referenced by their name. | 8682 // Lexically unresolved primary identifiers are referenced by their name. |
| 8639 return new PrimaryNode(ident_pos, ident); | 8683 return new PrimaryNode(ident_pos, ident); |
| 8640 } | 8684 } |
| 8641 | 8685 |
| 8642 | 8686 |
| 8643 // Resolve identifier, issue an error message if the name refers to | 8687 // Resolve identifier. Issue an error message if |
| 8644 // a class/interface or a type parameter. Issue an error message if | |
| 8645 // the ident refers to a method and allow_closure_names is false. | 8688 // the ident refers to a method and allow_closure_names is false. |
| 8646 // If the name cannot be resolved, turn it into an instance field access | 8689 // If the name cannot be resolved, turn it into an instance field access |
| 8647 // if we're compiling an instance method, or issue an error message | 8690 // if we're compiling an instance method, or issue an error message |
| 8648 // if we're compiling a static method. | 8691 // if we're compiling a static method. |
| 8649 AstNode* Parser::ResolveIdent(intptr_t ident_pos, | 8692 AstNode* Parser::ResolveIdent(intptr_t ident_pos, |
| 8650 const String& ident, | 8693 const String& ident, |
| 8651 bool allow_closure_names) { | 8694 bool allow_closure_names) { |
| 8652 TRACE_PARSER("ResolveIdent"); | 8695 TRACE_PARSER("ResolveIdent"); |
| 8653 // First try to find the variable in the local scope (block scope or | 8696 // First try to find the variable in the local scope (block scope or |
| 8654 // class scope). | 8697 // class scope). |
| 8655 AstNode* resolved = NULL; | 8698 AstNode* resolved = NULL; |
| 8656 ResolveIdentInLocalScope(ident_pos, ident, &resolved); | 8699 ResolveIdentInLocalScope(ident_pos, ident, &resolved); |
| 8657 if (resolved == NULL) { | 8700 if (resolved == NULL) { |
| 8658 // Check whether the identifier is a type parameter. Type parameters | 8701 // Check whether the identifier is a type parameter. |
| 8659 // can never be used in primary expressions. | |
| 8660 if (!current_class().IsNull()) { | 8702 if (!current_class().IsNull()) { |
| 8661 TypeParameter& type_param = TypeParameter::Handle( | 8703 TypeParameter& type_parameter = TypeParameter::ZoneHandle( |
| 8662 current_class().LookupTypeParameter(ident, ident_pos)); | 8704 current_class().LookupTypeParameter(ident)); |
| 8663 if (!type_param.IsNull()) { | 8705 if (!type_parameter.IsNull()) { |
| 8664 String& type_param_name = String::Handle(type_param.name()); | 8706 if (current_block_->scope->function_level() > 0) { |
| 8665 ErrorMsg(ident_pos, "illegal use of type parameter %s", | 8707 // Make sure that the instantiator is captured. |
| 8666 type_param_name.ToCString()); | 8708 CaptureInstantiator(); |
| 8709 } |
| 8710 type_parameter ^= ClassFinalizer::FinalizeType( |
| 8711 current_class(), type_parameter, ClassFinalizer::kFinalize); |
| 8712 ASSERT(!type_parameter.IsMalformed()); |
| 8713 return new TypeNode(ident_pos, type_parameter); |
| 8667 } | 8714 } |
| 8668 } | 8715 } |
| 8669 // Not found in the local scope, and the name is not a type parameter. | 8716 // Not found in the local scope, and the name is not a type parameter. |
| 8670 // Try finding the variable in the library scope (current library | 8717 // Try finding the variable in the library scope (current library |
| 8671 // and all libraries imported by it without a library prefix). | 8718 // and all libraries imported by it without a library prefix). |
| 8672 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); | 8719 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); |
| 8673 } | 8720 } |
| 8674 if (resolved->IsPrimaryNode()) { | 8721 if (resolved->IsPrimaryNode()) { |
| 8675 PrimaryNode* primary = resolved->AsPrimaryNode(); | 8722 PrimaryNode* primary = resolved->AsPrimaryNode(); |
| 8676 if (primary->primary().IsString()) { | 8723 if (primary->primary().IsString()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8689 // Treat as call to unresolved instance field. | 8736 // Treat as call to unresolved instance field. |
| 8690 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 8737 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 8691 } | 8738 } |
| 8692 } else if (primary->primary().IsFunction()) { | 8739 } else if (primary->primary().IsFunction()) { |
| 8693 if (allow_closure_names) { | 8740 if (allow_closure_names) { |
| 8694 resolved = LoadClosure(primary); | 8741 resolved = LoadClosure(primary); |
| 8695 } else { | 8742 } else { |
| 8696 ErrorMsg(ident_pos, "illegal reference to method '%s'", | 8743 ErrorMsg(ident_pos, "illegal reference to method '%s'", |
| 8697 ident.ToCString()); | 8744 ident.ToCString()); |
| 8698 } | 8745 } |
| 8699 } else { | 8746 } else if (primary->primary().IsClass()) { |
| 8700 ASSERT(primary->primary().IsClass()); | 8747 const Class& type_class = Class::Cast(primary->primary()); |
| 8701 ErrorMsg(ident_pos, "illegal reference to class or interface '%s'", | 8748 Type& type = Type::ZoneHandle( |
| 8702 ident.ToCString()); | 8749 Type::New(type_class, TypeArguments::Handle(), |
| 8750 primary->token_pos(), Heap::kOld)); |
| 8751 type ^= ClassFinalizer::FinalizeType( |
| 8752 current_class(), type, ClassFinalizer::kCanonicalize); |
| 8753 ASSERT(!type.IsMalformed()); |
| 8754 resolved = new TypeNode(primary->token_pos(), type); |
| 8703 } | 8755 } |
| 8704 } | 8756 } |
| 8705 return resolved; | 8757 return resolved; |
| 8706 } | 8758 } |
| 8707 | 8759 |
| 8708 | 8760 |
| 8709 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 8761 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
| 8710 // finalize it according to the given type finalization mode. | 8762 // finalize it according to the given type finalization mode. |
| 8711 RawAbstractType* Parser::ParseType( | 8763 RawAbstractType* Parser::ParseType( |
| 8712 ClassFinalizer::FinalizationKind finalization) { | 8764 ClassFinalizer::FinalizationKind finalization) { |
| (...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9545 OpenBlock(); | 9597 OpenBlock(); |
| 9546 primary = ParseFunctionStatement(true); | 9598 primary = ParseFunctionStatement(true); |
| 9547 CloseBlock(); | 9599 CloseBlock(); |
| 9548 } else if (IsIdentifier()) { | 9600 } else if (IsIdentifier()) { |
| 9549 QualIdent qual_ident; | 9601 QualIdent qual_ident; |
| 9550 ParseQualIdent(&qual_ident); | 9602 ParseQualIdent(&qual_ident); |
| 9551 if (qual_ident.lib_prefix == NULL) { | 9603 if (qual_ident.lib_prefix == NULL) { |
| 9552 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, | 9604 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, |
| 9553 *qual_ident.ident, | 9605 *qual_ident.ident, |
| 9554 &primary)) { | 9606 &primary)) { |
| 9555 // Check whether the identifier is a type parameter. Type parameters | 9607 // Check whether the identifier is a type parameter. |
| 9556 // can never be used as part of primary expressions. | |
| 9557 if (!current_class().IsNull()) { | 9608 if (!current_class().IsNull()) { |
| 9558 TypeParameter& type_param = TypeParameter::ZoneHandle( | 9609 TypeParameter& type_param = TypeParameter::ZoneHandle( |
| 9559 current_class().LookupTypeParameter(*(qual_ident.ident), | 9610 current_class().LookupTypeParameter(*(qual_ident.ident))); |
| 9560 TokenPos())); | |
| 9561 if (!type_param.IsNull()) { | 9611 if (!type_param.IsNull()) { |
| 9562 const String& type_param_name = String::Handle(type_param.name()); | 9612 return new PrimaryNode(qual_ident.ident_pos, type_param); |
| 9563 ErrorMsg(qual_ident.ident_pos, | |
| 9564 "illegal use of type parameter %s", | |
| 9565 type_param_name.ToCString()); | |
| 9566 } | 9613 } |
| 9567 } | 9614 } |
| 9568 // This is a non-local unqualified identifier so resolve the | 9615 // This is a non-local unqualified identifier so resolve the |
| 9569 // identifier locally in the main app library and all libraries | 9616 // identifier locally in the main app library and all libraries |
| 9570 // imported by it. | 9617 // imported by it. |
| 9571 primary = ResolveIdentInCurrentLibraryScope(qual_ident.ident_pos, | 9618 primary = ResolveIdentInCurrentLibraryScope(qual_ident.ident_pos, |
| 9572 *qual_ident.ident); | 9619 *qual_ident.ident); |
| 9573 } | 9620 } |
| 9574 } else { | 9621 } else { |
| 9575 // This is a qualified identifier with a library prefix so resolve | 9622 // This is a qualified identifier with a library prefix so resolve |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9979 void Parser::SkipQualIdent() { | 10026 void Parser::SkipQualIdent() { |
| 9980 ASSERT(IsIdentifier()); | 10027 ASSERT(IsIdentifier()); |
| 9981 ConsumeToken(); | 10028 ConsumeToken(); |
| 9982 if (CurrentToken() == Token::kPERIOD) { | 10029 if (CurrentToken() == Token::kPERIOD) { |
| 9983 ConsumeToken(); // Consume the kPERIOD token. | 10030 ConsumeToken(); // Consume the kPERIOD token. |
| 9984 ExpectIdentifier("identifier expected after '.'"); | 10031 ExpectIdentifier("identifier expected after '.'"); |
| 9985 } | 10032 } |
| 9986 } | 10033 } |
| 9987 | 10034 |
| 9988 } // namespace dart | 10035 } // namespace dart |
| OLD | NEW |