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

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-runtime.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 2624 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698