Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: runtime/vm/parser.cc

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

Powered by Google App Engine
This is Rietveld 408576698