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

Unified Diff: runtime/vm/parser.cc

Issue 10919263: Re-land r12289. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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/ast.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 82dd39defcfc2b6626ca1a30ef3193164ea8f605..cb8a59b65b92d2704c2b592d7753731a682a4d8e 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -766,8 +766,6 @@ void Parser::ParseFunction(ParsedFunction* parsed_function) {
}
-// TODO(regis): Implement support for non-const final static fields (currently
-// supported "final" fields are actually const fields).
// TODO(regis): Since a const variable is implicitly final,
// rename ParseStaticConstGetter to ParseStaticFinalGetter and
// rename kConstImplicitGetter to kImplicitFinalGetter.
@@ -797,12 +795,11 @@ SequenceNode* Parser::ParseStaticConstGetter(const Function& func) {
// leave the evaluation to the getter function.
const intptr_t expr_pos = TokenPos();
AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
- // TODO(hausner): Remove is_final check below once we support
- // non-const finals.
- if (field.is_const() || field.is_final()) {
+
+ if (field.is_const()) {
// This getter will only be called once at compile time.
if (expr->EvalConstExpr() == NULL) {
- ErrorMsg(expr_pos, "initializer must be a compile time constant");
+ ErrorMsg(expr_pos, "initializer must be a compile-time constant");
}
ReturnNode* return_node = new ReturnNode(TokenPos(), expr);
current_block_->statements->Add(return_node);
@@ -819,11 +816,6 @@ SequenceNode* Parser::ParseStaticConstGetter(const Function& func) {
// }
// return field.value; // Type check is executed here in checked mode.
- // TODO(regis): Remove this check once we support proper const fields.
- if (expr->EvalConstExpr() == NULL) {
- ErrorMsg(expr_pos, "initializer must be a compile time constant");
- }
-
// Generate code checking for circular dependency in field initialization.
AstNode* compare_circular = new ComparisonNode(
TokenPos(),
@@ -866,6 +858,10 @@ SequenceNode* Parser::ParseStaticConstGetter(const Function& func) {
new LiteralNode(
TokenPos(),
Instance::ZoneHandle(Object::transition_sentinel()))));
+ // TODO(hausner): If evaluation of the field value throws an exception,
+ // we leave the field value as 'transition_sentinel', which is wrong.
+ // A second reference to the field later throws a circular dependency
+ // exception. The field should instead be set to null after an exception.
initialize_field->Add(new StoreStaticFieldNode(TokenPos(), field, expr));
AstNode* uninitialized_check =
new IfNode(TokenPos(), compare_uninitialized, initialize_field, NULL);
@@ -2672,12 +2668,10 @@ void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) {
}
// Create the field object.
- // TODO(hausner): For now, all static final fields are constant. Remove
- // this when lazy init of static variables is implemented.
class_field = Field::New(*field->name,
field->has_static,
field->has_final,
- field->has_const || field->has_final,
+ field->has_const,
current_class(),
field->name_pos);
class_field.set_type(*field->type);
@@ -2693,7 +2687,7 @@ void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) {
getter = Function::New(getter_name,
RawFunction::kConstImplicitGetter,
field->has_static,
- field->has_final,
+ field->has_const,
/* is_abstract = */ false,
/* is_external = */ false,
current_class(),
@@ -3735,8 +3729,9 @@ void Parser::AddInterfaces(intptr_t interfaces_pos,
void Parser::ParseTopLevelVariable(TopLevel* top_level) {
TRACE_PARSER("ParseTopLevelVariable");
- const bool is_final = (CurrentToken() == Token::kFINAL);
const bool is_const = (CurrentToken() == Token::kCONST);
+ // Const fields are implicitly final.
+ const bool is_final = is_const || (CurrentToken() == Token::kFINAL);
const bool is_static = true;
const AbstractType& type =
AbstractType::ZoneHandle(ParseConstFinalVarOrType(
@@ -3762,13 +3757,8 @@ void Parser::ParseTopLevelVariable(TopLevel* top_level) {
var_name.ToCString());
}
- // TODO(hausner): const and final are equivalent at the moment.
- field = Field::New(var_name,
- is_static,
- is_final || is_const, // Const fields are also final.
- is_const || is_final,
- current_class(),
- name_pos);
+ field = Field::New(var_name, is_static, is_final, is_const,
+ current_class(), name_pos);
field.set_type(type);
field.set_value(Instance::Handle(Instance::null()));
top_level->fields.Add(field);
@@ -3777,7 +3767,7 @@ void Parser::ParseTopLevelVariable(TopLevel* top_level) {
ConsumeToken();
Instance& field_value = Instance::Handle(Object::sentinel());
bool has_simple_literal = false;
- if ((is_final || is_const) && (LookaheadToken(1) == Token::kSEMICOLON)) {
+ if (is_final && (LookaheadToken(1) == Token::kSEMICOLON)) {
has_simple_literal = IsSimpleLiteral(type, &field_value);
}
SkipExpr();
@@ -3788,7 +3778,7 @@ void Parser::ParseTopLevelVariable(TopLevel* top_level) {
getter = Function::New(getter_name,
RawFunction::kConstImplicitGetter,
is_static,
- is_final,
+ is_const,
/* is_abstract = */ false,
/* is_external = */ false,
current_class(),
@@ -3796,8 +3786,7 @@ void Parser::ParseTopLevelVariable(TopLevel* top_level) {
getter.set_result_type(type);
top_level->functions.Add(getter);
}
-
- } else if (is_final || is_const) {
+ } else if (is_final) {
ErrorMsg(name_pos, "missing initializer for final or const variable");
}
@@ -6787,7 +6776,7 @@ AstNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) {
return expr;
}
if (expr->EvalConstExpr() == NULL) {
- ErrorMsg(expr_pos, "expression must be a compile time constant");
+ ErrorMsg(expr_pos, "expression must be a compile-time constant");
}
return new LiteralNode(expr_pos, EvaluateConstExpr(expr));
}
@@ -6942,7 +6931,7 @@ AstNode* Parser::ParseExpr(bool require_compiletime_const,
ConsumeToken();
const intptr_t right_expr_pos = TokenPos();
if (require_compiletime_const && (assignment_op != Token::kASSIGN)) {
- ErrorMsg(right_expr_pos, "expression must be a compile time constant");
+ ErrorMsg(right_expr_pos, "expression must be a compile-time constant");
}
AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades);
AstNode* left_expr = expr;
@@ -7181,9 +7170,7 @@ AstNode* Parser::GenerateStaticFieldLookup(const Field& field,
return initializing_getter;
}
// The field is initialized.
- // TODO(hausner): Remove the is_final check when we support non-const
- // final static variables.
- if (field.is_const() || field.is_final()) {
+ if (field.is_const()) {
ASSERT(field.value() != Object::sentinel());
ASSERT(field.value() != Object::transition_sentinel());
return new LiteralNode(ident_pos, Instance::ZoneHandle(field.value()));
@@ -7752,9 +7739,7 @@ AstNode* Parser::RunStaticFieldInitializer(const Field& field) {
ASSERT(field.is_static());
const Instance& value = Instance::Handle(field.value());
if (value.raw() == Object::transition_sentinel()) {
- // TODO(hausner): Remove the check for is_final() once we support
- // non-const final fields.
- if (field.is_const() || field.is_final()) {
+ if (field.is_const()) {
ErrorMsg("circular dependency while initializing static field '%s'",
String::Handle(field.name()).ToCString());
} else {
@@ -7769,9 +7754,7 @@ AstNode* Parser::RunStaticFieldInitializer(const Field& field) {
// This field has not been referenced yet and thus the value has
// not been evaluated. If the field is const, call the static getter method
// to evaluate the expression and canonicalize the value.
- // TODO(hausner): Remove the check for is_final() once we support
- // non-const final fields.
- if (field.is_const() || field.is_final()) {
+ if (field.is_const()) {
field.set_value(Instance::Handle(Object::transition_sentinel()));
const String& field_name = String::Handle(field.name());
const String& getter_name =
@@ -7797,7 +7780,7 @@ AstNode* Parser::RunStaticFieldInitializer(const Field& field) {
// It is a compile-time error if evaluation of a compile-time constant
// would raise an exception.
AppendErrorMsg(error, TokenPos(),
- "error initializing final field '%s'",
+ "error initializing const field '%s'",
String::Handle(field.name()).ToCString());
} else {
Isolate::Current()->long_jump_base()->Jump(1, error);
@@ -8567,7 +8550,7 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos,
if (key == NULL) {
ErrorMsg("map entry key must be string literal");
} else if (is_const && !key->IsLiteralNode()) {
- ErrorMsg("map entry key must be compile time constant string");
+ ErrorMsg("map entry key must be compile-time constant string");
}
ExpectToken(Token::kCOLON);
const bool saved_mode = SetAllowFunctionLiterals(true);
« no previous file with comments | « runtime/vm/ast.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698