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

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

Issue 471283002: Runtime support for evaluation of static field initializer expressions (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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') | runtime/vm/raw_object.h » ('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 "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 node_sequence = parser.ParseInstanceGetter(func); 821 node_sequence = parser.ParseInstanceGetter(func);
822 break; 822 break;
823 case RawFunction::kImplicitSetter: 823 case RawFunction::kImplicitSetter:
824 ASSERT(!func.is_static()); 824 ASSERT(!func.is_static());
825 node_sequence = parser.ParseInstanceSetter(func); 825 node_sequence = parser.ParseInstanceSetter(func);
826 break; 826 break;
827 case RawFunction::kImplicitStaticFinalGetter: 827 case RawFunction::kImplicitStaticFinalGetter:
828 node_sequence = parser.ParseStaticFinalGetter(func); 828 node_sequence = parser.ParseStaticFinalGetter(func);
829 CompilerStats::num_implicit_final_getters++; 829 CompilerStats::num_implicit_final_getters++;
830 break; 830 break;
831 case RawFunction::kStaticInitializer:
832 node_sequence = parser.ParseStaticInitializer(func);
833 CompilerStats::num_static_initializer_funcs++;
834 break;
835 case RawFunction::kMethodExtractor: 831 case RawFunction::kMethodExtractor:
836 node_sequence = parser.ParseMethodExtractor(func); 832 node_sequence = parser.ParseMethodExtractor(func);
837 break; 833 break;
838 case RawFunction::kNoSuchMethodDispatcher: 834 case RawFunction::kNoSuchMethodDispatcher:
839 node_sequence = 835 node_sequence =
840 parser.ParseNoSuchMethodDispatcher(func, &default_parameter_values); 836 parser.ParseNoSuchMethodDispatcher(func, &default_parameter_values);
841 break; 837 break;
842 case RawFunction::kInvokeFieldDispatcher: 838 case RawFunction::kInvokeFieldDispatcher:
843 node_sequence = 839 node_sequence =
844 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values); 840 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 if (expr->EvalConstExpr() == NULL) { 992 if (expr->EvalConstExpr() == NULL) {
997 ReportError(expr_pos, "expression must be a compile-time constant"); 993 ReportError(expr_pos, "expression must be a compile-time constant");
998 } 994 }
999 const Instance& val = EvaluateConstExpr(expr_pos, expr); 995 const Instance& val = EvaluateConstExpr(expr_pos, expr);
1000 meta_values.Add(val); 996 meta_values.Add(val);
1001 } 997 }
1002 return Array::MakeArray(meta_values); 998 return Array::MakeArray(meta_values);
1003 } 999 }
1004 1000
1005 1001
1002 SequenceNode* Parser::ParseStaticInitializer() {
1003 ExpectIdentifier("field name expected");
1004 CheckToken(Token::kASSIGN, "field initialier expected");
1005 ConsumeToken();
1006 OpenFunctionBlock(parsed_function()->function());
1007 intptr_t expr_pos = TokenPos();
1008 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
1009 ReturnNode* ret = new(I) ReturnNode(expr_pos, expr);
1010 current_block_->statements->Add(ret);
1011 return CloseBlock();
1012 }
1013
1014
1015 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) {
1016 ASSERT(field.is_static());
1017 ASSERT(field.value() == Object::transition_sentinel().raw());
1018 Isolate* isolate = Isolate::Current();
1019
1020 const Class& script_cls = Class::Handle(isolate, field.origin());
1021 const Script& script = Script::Handle(isolate, script_cls.script());
1022
1023 const String& field_name = String::Handle(isolate, field.name());
1024 String& init_name = String::Handle(isolate,
1025 String::Concat(Symbols::InitPrefix(), field_name));
1026 init_name = Symbols::New(init_name);
1027
1028 const Function& initializer = Function::ZoneHandle(isolate,
1029 Function::New(init_name,
1030 RawFunction::kRegularFunction,
1031 true, // static
1032 false, // !const
1033 false, // !abstract
1034 false, // !external
1035 false, // !native
1036 Class::Handle(field.owner()),
1037 field.token_pos()));
1038 initializer.set_result_type(AbstractType::Handle(isolate, field.type()));
1039 // Static initializer functions are hidden from the user.
1040 // Since they are only executed once, we avoid optimizing
1041 // and inlining them. After the field is initialized, the
1042 // compiler can eliminate the call to the static initializer.
1043 initializer.set_is_visible(false);
1044 initializer.SetIsOptimizable(false);
1045 initializer.set_is_inlinable(false);
1046
1047 ParsedFunction* parsed_function = new ParsedFunction(isolate, initializer);
1048 Parser parser(script, parsed_function, field.token_pos());
1049
1050 SequenceNode* body = parser.ParseStaticInitializer();
1051 parsed_function->SetNodeSequence(body);
1052 parsed_function->set_default_parameter_values(Object::null_array());
1053
1054 if (parsed_function->has_expression_temp_var()) {
1055 body->scope()->AddVariable(parsed_function->expression_temp_var());
1056 }
1057 if (parsed_function->has_saved_current_context_var()) {
1058 body->scope()->AddVariable(parsed_function->saved_current_context_var());
1059 }
1060 if (parsed_function->has_finally_return_temp_var()) {
1061 body->scope()->AddVariable(parsed_function->finally_return_temp_var());
1062 }
1063 // The instantiator is not required in a static expression.
1064 ASSERT(!parser.IsInstantiatorRequired());
1065
1066 return parsed_function;
1067 }
1068
1069
1006 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { 1070 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) {
1007 TRACE_PARSER("ParseStaticFinalGetter"); 1071 TRACE_PARSER("ParseStaticFinalGetter");
1008 ParamList params; 1072 ParamList params;
1009 ASSERT(func.num_fixed_parameters() == 0); // static. 1073 ASSERT(func.num_fixed_parameters() == 0); // static.
1010 ASSERT(!func.HasOptionalParameters()); 1074 ASSERT(!func.HasOptionalParameters());
1011 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); 1075 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved());
1012 1076
1013 // Build local scope for function and populate with the formal parameters. 1077 // Build local scope for function and populate with the formal parameters.
1014 OpenFunctionBlock(func); 1078 OpenFunctionBlock(func);
1015 AddFormalParamsToScope(&params, current_block_->scope); 1079 AddFormalParamsToScope(&params, current_block_->scope);
(...skipping 16 matching lines...) Expand all
1032 // leave the evaluation to the getter function. 1096 // leave the evaluation to the getter function.
1033 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 1097 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
1034 // This getter will only be called once at compile time. 1098 // This getter will only be called once at compile time.
1035 if (expr->EvalConstExpr() == NULL) { 1099 if (expr->EvalConstExpr() == NULL) {
1036 ReportError(expr_pos, "initializer is not a valid compile-time constant"); 1100 ReportError(expr_pos, "initializer is not a valid compile-time constant");
1037 } 1101 }
1038 ReturnNode* return_node = new ReturnNode(ident_pos, expr); 1102 ReturnNode* return_node = new ReturnNode(ident_pos, expr);
1039 current_block_->statements->Add(return_node); 1103 current_block_->statements->Add(return_node);
1040 } else { 1104 } else {
1041 // This getter may be called each time the static field is accessed. 1105 // This getter may be called each time the static field is accessed.
1042 // The following generated code lazily initializes the field: 1106 // Call runtime support to parse and evaluate the initializer expression.
1043 // if (field.value === transition_sentinel) { 1107 // The runtime function will detect circular dependencies in expressions
1044 // field.value = null; 1108 // and handle errors while evaluating the expression.
1045 // throw("circular dependency in field initialization"); 1109 current_block_->statements->Add(
1046 // } 1110 new (I) InitStaticFieldNode(ident_pos, field));
1047 // if (field.value === sentinel) {
1048 // field.value = transition_sentinel;
1049 // field.value = expr;
1050 // }
1051 // return field.value; // Type check is executed here in checked mode.
1052
1053 // Generate code checking for circular dependency in field initialization.
1054 AstNode* compare_circular = new ComparisonNode(
1055 ident_pos,
1056 Token::kEQ_STRICT,
1057 new LoadStaticFieldNode(ident_pos, field),
1058 new LiteralNode(ident_pos, Object::transition_sentinel()));
1059 // Set field to null prior to throwing exception, so that subsequent
1060 // accesses to the field do not throw again, since initializers should only
1061 // be executed once.
1062 SequenceNode* report_circular = new SequenceNode(ident_pos, NULL);
1063 report_circular->Add(
1064 new StoreStaticFieldNode(
1065 ident_pos,
1066 field,
1067 new LiteralNode(ident_pos, Instance::ZoneHandle(I))));
1068 // Call CyclicInitializationError._throwNew(field_name).
1069 ArgumentListNode* error_arguments = new ArgumentListNode(ident_pos);
1070 error_arguments->Add(new LiteralNode(ident_pos, field_name));
1071 report_circular->Add(
1072 MakeStaticCall(Symbols::CyclicInitializationError(),
1073 Library::PrivateCoreLibName(Symbols::ThrowNew()),
1074 error_arguments));
1075 AstNode* circular_check =
1076 new IfNode(ident_pos, compare_circular, report_circular, NULL);
1077 current_block_->statements->Add(circular_check);
1078
1079 // Generate code checking for uninitialized field.
1080 AstNode* compare_uninitialized = new ComparisonNode(
1081 ident_pos,
1082 Token::kEQ_STRICT,
1083 new LoadStaticFieldNode(ident_pos, field),
1084 new LiteralNode(ident_pos, Object::sentinel()));
1085 SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL);
1086 initialize_field->Add(
1087 new StoreStaticFieldNode(
1088 ident_pos,
1089 field,
1090 new LiteralNode(ident_pos, Object::transition_sentinel())));
1091 const String& init_name = String::Handle(I, Symbols::New(
1092 String::Handle(I, String::Concat(
1093 Symbols::InitPrefix(), String::Handle(I, field.name())))));
1094 const Function& init_function = Function::ZoneHandle(I,
1095 field_class.LookupStaticFunction(init_name));
1096 ASSERT(!init_function.IsNull());
1097 ArgumentListNode* arguments = new ArgumentListNode(expr_pos);
1098 StaticCallNode* init_call =
1099 new StaticCallNode(expr_pos, init_function, arguments);
1100 initialize_field->Add(init_call);
1101
1102 AstNode* uninitialized_check =
1103 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL);
1104 current_block_->statements->Add(uninitialized_check);
1105
1106 // Generate code returning the field value.
1107 ReturnNode* return_node = 1111 ReturnNode* return_node =
1108 new ReturnNode(ident_pos, new LoadStaticFieldNode(ident_pos, field)); 1112 new ReturnNode(ident_pos,
1113 new LoadStaticFieldNode(ident_pos, field));
1109 current_block_->statements->Add(return_node); 1114 current_block_->statements->Add(return_node);
1110 } 1115 }
1111 return CloseBlock(); 1116 return CloseBlock();
1112 } 1117 }
1113 1118
1114 1119
1115 SequenceNode* Parser::ParseStaticInitializer(const Function& func) {
1116 TRACE_PARSER("ParseStaticInitializer");
1117 ParamList params;
1118 ASSERT(func.num_fixed_parameters() == 0); // static.
1119 ASSERT(!func.HasOptionalParameters());
1120 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved());
1121
1122 // Build local scope for function and populate with the formal parameters.
1123 OpenFunctionBlock(func);
1124 AddFormalParamsToScope(&params, current_block_->scope);
1125
1126 // Move forward to the start of the initializer expression.
1127 intptr_t ident_pos = TokenPos();
1128 ExpectIdentifier("identifier expected");
1129 ExpectToken(Token::kASSIGN);
1130 intptr_t token_pos = TokenPos();
1131
1132 // Synthesize a try-catch block to wrap the initializer expression.
1133 LocalVariable* context_var =
1134 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
1135 if (context_var == NULL) {
1136 context_var = new(I) LocalVariable(
1137 token_pos,
1138 Symbols::SavedTryContextVar(),
1139 Type::ZoneHandle(I, Type::DynamicType()));
1140 current_block_->scope->AddVariable(context_var);
1141 }
1142 LocalVariable* catch_excp_var =
1143 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
1144 if (catch_excp_var == NULL) {
1145 catch_excp_var = new (I) LocalVariable(
1146 token_pos,
1147 Symbols::ExceptionVar(),
1148 Type::ZoneHandle(I, Type::DynamicType()));
1149 current_block_->scope->AddVariable(catch_excp_var);
1150 }
1151 LocalVariable* catch_trace_var =
1152 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar());
1153 if (catch_trace_var == NULL) {
1154 catch_trace_var = new (I) LocalVariable(
1155 token_pos,
1156 Symbols::StackTraceVar(),
1157 Type::ZoneHandle(I, Type::DynamicType()));
1158 current_block_->scope->AddVariable(catch_trace_var);
1159 }
1160
1161 OpenBlock(); // Start try block.
1162 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
1163 const Field& field = Field::ZoneHandle(I, func.saved_static_field());
1164 ASSERT(!field.is_const());
1165 if (FLAG_enable_type_checks) {
1166 expr = new AssignableNode(
1167 field.token_pos(),
1168 expr,
1169 AbstractType::ZoneHandle(I, field.type()),
1170 String::ZoneHandle(I, field.name()));
1171 }
1172 StoreStaticFieldNode* store = new StoreStaticFieldNode(field.token_pos(),
1173 field,
1174 expr);
1175 current_block_->statements->Add(store);
1176 SequenceNode* try_block = CloseBlock(); // End try block.
1177
1178 OpenBlock(); // Start catch handler list.
1179 OpenBlock(); // Start catch clause.
1180 AstNode* compare_transition_sentinel = new ComparisonNode(
1181 token_pos,
1182 Token::kEQ_STRICT,
1183 new LoadStaticFieldNode(ident_pos, field),
1184 new LiteralNode(field.token_pos(), Object::transition_sentinel()));
1185
1186 SequenceNode* store_null = new SequenceNode(token_pos, NULL);
1187 store_null->Add(new StoreStaticFieldNode(
1188 field.token_pos(),
1189 field,
1190 new LiteralNode(token_pos, Instance::ZoneHandle(I))));
1191 AstNode* transition_sentinel_check =
1192 new IfNode(token_pos, compare_transition_sentinel, store_null, NULL);
1193 current_block_->statements->Add(transition_sentinel_check);
1194
1195 current_block_->statements->Add(
1196 new ThrowNode(token_pos,
1197 new LoadLocalNode(token_pos, catch_excp_var),
1198 new LoadLocalNode(token_pos, catch_trace_var)));
1199 SequenceNode* catch_clause = CloseBlock(); // End catch clause.
1200
1201 current_block_->statements->Add(catch_clause);
1202 SequenceNode* catch_handler_list = CloseBlock(); // End catch handler list.
1203 CatchClauseNode* catch_block =
1204 new CatchClauseNode(token_pos,
1205 catch_handler_list,
1206 Array::ZoneHandle(I, Object::empty_array().raw()),
1207 context_var,
1208 catch_excp_var,
1209 catch_trace_var,
1210 CatchClauseNode::kInvalidTryIndex,
1211 false); // No stack trace needed.
1212
1213 AstNode* try_catch_node = new TryCatchNode(token_pos,
1214 try_block,
1215 context_var,
1216 catch_block,
1217 NULL, // No finally block.
1218 AllocateTryIndex());
1219 current_block_->statements->Add(try_catch_node);
1220 return CloseBlock();
1221 }
1222
1223
1224 // Create AstNodes for an implicit instance getter method: 1120 // Create AstNodes for an implicit instance getter method:
1225 // LoadLocalNode 0 ('this'); 1121 // LoadLocalNode 0 ('this');
1226 // LoadInstanceFieldNode (field_name); 1122 // LoadInstanceFieldNode (field_name);
1227 // ReturnNode (field's value); 1123 // ReturnNode (field's value);
1228 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { 1124 SequenceNode* Parser::ParseInstanceGetter(const Function& func) {
1229 TRACE_PARSER("ParseInstanceGetter"); 1125 TRACE_PARSER("ParseInstanceGetter");
1230 ParamList params; 1126 ParamList params;
1231 // func.token_pos() points to the name of the field. 1127 // func.token_pos() points to the name of the field.
1232 const intptr_t ident_pos = func.token_pos(); 1128 const intptr_t ident_pos = func.token_pos();
1233 ASSERT(current_class().raw() == func.Owner()); 1129 ASSERT(current_class().raw() == func.Owner());
(...skipping 2454 matching lines...) Expand 10 before | Expand all | Expand 10 after
3688 RawFunction::kImplicitStaticFinalGetter, 3584 RawFunction::kImplicitStaticFinalGetter,
3689 field->has_static, 3585 field->has_static,
3690 field->has_const, 3586 field->has_const,
3691 /* is_abstract = */ false, 3587 /* is_abstract = */ false,
3692 /* is_external = */ false, 3588 /* is_external = */ false,
3693 /* is_native = */ false, 3589 /* is_native = */ false,
3694 current_class(), 3590 current_class(),
3695 field->name_pos); 3591 field->name_pos);
3696 getter.set_result_type(*field->type); 3592 getter.set_result_type(*field->type);
3697 members->AddFunction(getter); 3593 members->AddFunction(getter);
3698
3699 // Create initializer function for non-const fields.
3700 if (!class_field.is_const()) {
3701 const Function& init_function = Function::ZoneHandle(I,
3702 Function::NewStaticInitializer(class_field));
3703 members->AddFunction(init_function);
3704 }
3705 } 3594 }
3706 } 3595 }
3707 3596
3708 // For instance fields, we create implicit getter and setter methods. 3597 // For instance fields, we create implicit getter and setter methods.
3709 if (!field->has_static) { 3598 if (!field->has_static) {
3710 String& getter_name = String::Handle(I, 3599 String& getter_name = String::Handle(I,
3711 Field::GetterSymbol(*field->name)); 3600 Field::GetterSymbol(*field->name));
3712 getter = Function::New(getter_name, RawFunction::kImplicitGetter, 3601 getter = Function::New(getter_name, RawFunction::kImplicitGetter,
3713 field->has_static, 3602 field->has_static,
3714 field->has_final, 3603 field->has_final,
(...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after
4853 RawFunction::kImplicitStaticFinalGetter, 4742 RawFunction::kImplicitStaticFinalGetter,
4854 is_static, 4743 is_static,
4855 is_const, 4744 is_const,
4856 /* is_abstract = */ false, 4745 /* is_abstract = */ false,
4857 /* is_external = */ false, 4746 /* is_external = */ false,
4858 /* is_native = */ false, 4747 /* is_native = */ false,
4859 current_class(), 4748 current_class(),
4860 name_pos); 4749 name_pos);
4861 getter.set_result_type(type); 4750 getter.set_result_type(type);
4862 top_level->functions.Add(getter); 4751 top_level->functions.Add(getter);
4863
4864 // Create initializer function.
4865 if (!field.is_const()) {
4866 const Function& init_function = Function::ZoneHandle(I,
4867 Function::NewStaticInitializer(field));
4868 top_level->functions.Add(init_function);
4869 }
4870 } 4752 }
4871 } else if (is_final) { 4753 } else if (is_final) {
4872 ReportError(name_pos, "missing initializer for final or const variable"); 4754 ReportError(name_pos, "missing initializer for final or const variable");
4873 } 4755 }
4874 4756
4875 if (CurrentToken() == Token::kCOMMA) { 4757 if (CurrentToken() == Token::kCOMMA) {
4876 ConsumeToken(); 4758 ConsumeToken();
4877 } else if (CurrentToken() == Token::kSEMICOLON) { 4759 } else if (CurrentToken() == Token::kSEMICOLON) {
4878 ConsumeToken(); 4760 ConsumeToken();
4879 break; 4761 break;
(...skipping 6143 matching lines...) Expand 10 before | Expand all | Expand 10 after
11023 ASSERT(field.is_const()); 10905 ASSERT(field.is_const());
11024 ASSERT(field.value() != Object::sentinel().raw()); 10906 ASSERT(field.value() != Object::sentinel().raw());
11025 ASSERT(field.value() != Object::transition_sentinel().raw()); 10907 ASSERT(field.value() != Object::transition_sentinel().raw());
11026 return Instance::ZoneHandle(I, field.value()); 10908 return Instance::ZoneHandle(I, field.value());
11027 } else { 10909 } else {
11028 ASSERT(expr->EvalConstExpr() != NULL); 10910 ASSERT(expr->EvalConstExpr() != NULL);
11029 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr); 10911 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr);
11030 // Compile time constant expressions cannot reference anything from a 10912 // Compile time constant expressions cannot reference anything from a
11031 // local scope. 10913 // local scope.
11032 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0); 10914 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0);
11033 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), 10915 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), empty_scope);
11034 empty_scope);
11035 seq->Add(ret); 10916 seq->Add(ret);
11036 10917
11037 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq)); 10918 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq));
11038 if (result.IsError()) { 10919 if (result.IsError()) {
11039 ReportErrors(Error::Cast(result), 10920 ReportErrors(Error::Cast(result),
11040 script_, expr_pos, 10921 script_, expr_pos,
11041 "error evaluating constant expression"); 10922 "error evaluating constant expression");
11042 } 10923 }
11043 ASSERT(result.IsInstance()); 10924 ASSERT(result.IsInstance());
11044 Instance& value = Instance::ZoneHandle(I); 10925 Instance& value = Instance::ZoneHandle(I);
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
11377 void Parser::SkipQualIdent() { 11258 void Parser::SkipQualIdent() {
11378 ASSERT(IsIdentifier()); 11259 ASSERT(IsIdentifier());
11379 ConsumeToken(); 11260 ConsumeToken();
11380 if (CurrentToken() == Token::kPERIOD) { 11261 if (CurrentToken() == Token::kPERIOD) {
11381 ConsumeToken(); // Consume the kPERIOD token. 11262 ConsumeToken(); // Consume the kPERIOD token.
11382 ExpectIdentifier("identifier expected after '.'"); 11263 ExpectIdentifier("identifier expected after '.'");
11383 } 11264 }
11384 } 11265 }
11385 11266
11386 } // namespace dart 11267 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698