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