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

Unified Diff: runtime/vm/parser.cc

Issue 10809089: Make sure the "Skip*" functions know about cascades as well. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 9873)
+++ runtime/vm/parser.cc (working copy)
@@ -6264,6 +6264,30 @@
ErrorMsg("identifier or [ expected after ..");
}
expr = ParseSelectors(load_cascade_receiver, true);
+
+ // Assignments after a cascade are part of the cascade. The
+ // assigned expression must not contain cascades.
+ if (Token::IsAssignmentOperator(CurrentToken())) {
+ Token::Kind assignment_op = CurrentToken();
+ const intptr_t assignment_pos = TokenPos();
+ ConsumeToken();
+ AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades);
+ AstNode* left_expr = expr;
+ if (assignment_op != Token::kASSIGN) {
+ // Compound assignment: store inputs with side effects into
+ // temporary locals.
+ left_expr = PrepareCompoundAssignmentNodes(&expr);
+ }
+ right_expr =
+ ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
+ AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr);
+ if (assign_expr == NULL) {
+ ErrorMsg(assignment_pos,
+ "left hand side of '%s' is not assignable",
+ Token::Str(assignment_op));
+ }
+ expr = assign_expr;
+ }
current_block_->statements->Add(expr);
}
// Result of the cascade is the receiver.
@@ -6293,7 +6317,7 @@
if (require_compiletime_const && (assignment_op != Token::kASSIGN)) {
ErrorMsg(right_expr_pos, "expression must be a compile time constant");
}
- AstNode* right_expr = ParseExpr(require_compiletime_const, kConsumeCascades);
+ AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades);
AstNode* left_expr = expr;
if (assignment_op != Token::kASSIGN) {
// Compound assignment: store inputs with side effects into temp. locals.
@@ -6517,32 +6541,6 @@
}
-AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver,
- const String& field_name,
- bool consume_cascades) {
- TRACE_PARSER("ParseInstanceFieldAccess");
- AstNode* access = NULL;
- const intptr_t call_pos = TokenPos();
- if (Token::IsAssignmentOperator(CurrentToken())) {
- Token::Kind assignment_op = CurrentToken();
- ConsumeToken();
- AstNode* value = ParseExpr(kAllowConst, consume_cascades);
- AstNode* load_access =
- new InstanceGetterNode(call_pos, receiver, field_name);
- AstNode* left_load_access = load_access;
- if (assignment_op != Token::kASSIGN) {
- // Compound assignment: store inputs with side effects into temp. locals.
- left_load_access = PrepareCompoundAssignmentNodes(&load_access);
- }
- value = ExpandAssignableOp(call_pos, assignment_op, load_access, value);
- access = CreateAssignmentNode(left_load_access, value);
- } else {
- access = CallGetter(call_pos, receiver, field_name);
- }
- return access;
-}
-
-
AstNode* Parser::GenerateStaticFieldLookup(const Field& field,
intptr_t ident_pos) {
// If the static field has an initializer, initialize the field at compile
@@ -6574,7 +6572,7 @@
const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name));
Function& func = Function::ZoneHandle();
if (Token::IsAssignmentOperator(CurrentToken())) {
- Token::Kind assignment_op = CurrentToken();
+ // Make sure an assignment is legal.
if (field.IsNull()) {
// No field, check if we have an explicit setter function.
const String& setter_name =
@@ -6590,23 +6588,16 @@
// No field or explicit setter function, this is an error.
ErrorMsg(ident_pos, "unknown static field '%s'",
field_name.ToCString());
- return access;
}
- }
- ConsumeToken();
- AstNode* value = ParseExpr(kAllowConst, consume_cascades);
- AstNode* load_access = NULL;
- if (field.IsNull()) {
- // No field found, we must have at least a setter function defined.
- ASSERT(!func.IsNull());
+
// Explicit setter function for the field found, field does not exist.
// Create a getter node first in case it is needed. If getter node
// is used as part of, e.g., "+=", and the explicit getter does not
// exist, and error will be reported by the code generator.
- load_access = new StaticGetterNode(call_pos,
- NULL,
- Class::ZoneHandle(cls.raw()),
- String::ZoneHandle(field_name.raw()));
+ access = new StaticGetterNode(call_pos,
+ NULL,
+ Class::ZoneHandle(cls.raw()),
+ String::ZoneHandle(field_name.raw()));
} else {
// Field exists.
if (field.is_final()) {
@@ -6615,12 +6606,9 @@
ErrorMsg(ident_pos,
"field '%s' is const static, cannot assign to it",
field_name.ToCString());
- return access;
}
- load_access = GenerateStaticFieldLookup(field, TokenPos());
+ access = GenerateStaticFieldLookup(field, TokenPos());
}
- value = ExpandAssignableOp(call_pos, assignment_op, load_access, value);
- access = CreateAssignmentNode(load_access, value);
} else { // Not Token::IsAssignmentOperator(CurrentToken()).
if (field.IsNull()) {
// No field, check if we have an explicit getter function.
@@ -6641,7 +6629,6 @@
// No field or explicit getter function, this is an error.
ErrorMsg(ident_pos,
"unknown static field '%s'", field_name.ToCString());
- return access;
}
access = CreateImplicitClosureNode(func, call_pos, NULL);
} else {
@@ -6652,7 +6639,7 @@
field_name);
}
} else {
- return GenerateStaticFieldLookup(field, TokenPos());
+ access = GenerateStaticFieldLookup(field, TokenPos());
}
}
return access;
@@ -6746,7 +6733,7 @@
}
if (cls.IsNull()) {
// Instance field access.
- selector = ParseInstanceFieldAccess(left, *ident, !is_cascade);
+ selector = CallGetter(ident_pos, left, *ident);
} else {
// Static field access.
selector =
@@ -8632,10 +8619,10 @@
}
-void Parser::SkipPostfixExpr() {
- SkipPrimary();
+void Parser::SkipSelectors() {
while (true) {
- if (CurrentToken() == Token::kPERIOD) {
+ if ((CurrentToken() == Token::kPERIOD) ||
+ (CurrentToken() == Token::kCASCADE)) {
ConsumeToken();
ExpectIdentifier("identifier expected");
} else if (CurrentToken() == Token::kLBRACK) {
@@ -8648,6 +8635,11 @@
break;
}
}
+}
+
+void Parser::SkipPostfixExpr() {
+ SkipPrimary();
+ SkipSelectors();
if (IsIncrementOperator(CurrentToken())) {
ConsumeToken();
}
@@ -8688,6 +8680,9 @@
void Parser::SkipExpr() {
SkipConditionalExpr();
+ if (CurrentToken() == Token::kCASCADE) {
+ SkipSelectors();
+ }
if (Token::IsAssignmentOperator(CurrentToken())) {
ConsumeToken();
SkipExpr();
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698