Chromium Code Reviews| 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 |