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 |