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

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

Issue 9615035: Generate dynamic type errors according to spec. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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 "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 5356 matching lines...) Expand 10 before | Expand all | Expand 10 after
5367 va_list args; 5367 va_list args;
5368 va_start(args, format); 5368 va_start(args, format);
5369 const Error& error = Error::Handle( 5369 const Error& error = Error::Handle(
5370 FormatError(script_, token_index_, "Error", format, args)); 5370 FormatError(script_, token_index_, "Error", format, args));
5371 va_end(args); 5371 va_end(args);
5372 Isolate::Current()->long_jump_base()->Jump(1, error); 5372 Isolate::Current()->long_jump_base()->Jump(1, error);
5373 UNREACHABLE(); 5373 UNREACHABLE();
5374 } 5374 }
5375 5375
5376 5376
5377 void Parser::ErrorMsg(const Error& error) {
5378 Isolate::Current()->long_jump_base()->Jump(1, error);
5379 UNREACHABLE();
5380 }
5381
5382
5377 void Parser::AppendErrorMsg( 5383 void Parser::AppendErrorMsg(
5378 const Error& prev_error, intptr_t token_index, const char* format, ...) { 5384 const Error& prev_error, intptr_t token_index, const char* format, ...) {
5379 va_list args; 5385 va_list args;
5380 va_start(args, format); 5386 va_start(args, format);
5381 const Error& error = Error::Handle(FormatErrorWithAppend( 5387 const Error& error = Error::Handle(FormatErrorWithAppend(
5382 prev_error, script_, token_index, "Error", format, args)); 5388 prev_error, script_, token_index, "Error", format, args));
5383 va_end(args); 5389 va_end(args);
5384 Isolate::Current()->long_jump_base()->Jump(1, error); 5390 Isolate::Current()->long_jump_base()->Jump(1, error);
5385 UNREACHABLE(); 5391 UNREACHABLE();
5386 } 5392 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
5547 const intptr_t type_pos = token_index_; 5553 const intptr_t type_pos = token_index_;
5548 const AbstractType& type = 5554 const AbstractType& type =
5549 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize)); 5555 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize));
5550 if (!type.IsInstantiated() && 5556 if (!type.IsInstantiated() &&
5551 (current_block_->scope->function_level() > 0)) { 5557 (current_block_->scope->function_level() > 0)) {
5552 // Make sure that the instantiator is captured. 5558 // Make sure that the instantiator is captured.
5553 CaptureReceiver(); 5559 CaptureReceiver();
5554 } 5560 }
5555 right_operand = new TypeNode(type_pos, type); 5561 right_operand = new TypeNode(type_pos, type);
5556 if (type.IsMalformed()) { 5562 if (type.IsMalformed()) {
5563 // Note that a type error is thrown even if the tested value is null.
5557 return ThrowTypeError(type_pos, type); 5564 return ThrowTypeError(type_pos, type);
5558 } 5565 }
5559 } 5566 }
5560 if (Token::IsRelationalOperator(op_kind) 5567 if (Token::IsRelationalOperator(op_kind)
5561 || Token::IsInstanceofOperator(op_kind) 5568 || Token::IsInstanceofOperator(op_kind)
5562 || Token::IsEqualityOperator(op_kind)) { 5569 || Token::IsEqualityOperator(op_kind)) {
5563 left_operand = new ComparisonNode( 5570 left_operand = new ComparisonNode(
5564 op_pos, op_kind, left_operand, right_operand); 5571 op_pos, op_kind, left_operand, right_operand);
5565 break; // Equality and relational operators cannot be chained. 5572 break; // Equality and relational operators cannot be chained.
5566 } else { 5573 } else {
(...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after
6421 // At this point, we can only have a parameterized_type. 6428 // At this point, we can only have a parameterized_type.
6422 Type& parameterized_type = Type::Handle(); 6429 Type& parameterized_type = Type::Handle();
6423 parameterized_type ^= type->raw(); 6430 parameterized_type ^= type->raw();
6424 if (!resolved_type_class.IsNull()) { 6431 if (!resolved_type_class.IsNull()) {
6425 Object& type_class = Object::Handle(resolved_type_class.raw()); 6432 Object& type_class = Object::Handle(resolved_type_class.raw());
6426 // Replace unresolved class with resolved type class. 6433 // Replace unresolved class with resolved type class.
6427 parameterized_type.set_type_class(type_class); 6434 parameterized_type.set_type_class(type_class);
6428 } else if (finalization >= ClassFinalizer::kFinalize) { 6435 } else if (finalization >= ClassFinalizer::kFinalize) {
6429 // The type is malformed. 6436 // The type is malformed.
6430 ClassFinalizer::FinalizeMalformedType( 6437 ClassFinalizer::FinalizeMalformedType(
6438 Error::Handle(), // No previous error.
6431 current_class(), parameterized_type, finalization, 6439 current_class(), parameterized_type, finalization,
6432 "type '%s' is not loaded", 6440 "type '%s' is not loaded",
6433 String::Handle(parameterized_type.Name()).ToCString()); 6441 String::Handle(parameterized_type.Name()).ToCString());
6434 } 6442 }
6435 } 6443 }
6436 // Resolve type arguments, if any. 6444 // Resolve type arguments, if any.
6437 const AbstractTypeArguments& arguments = 6445 const AbstractTypeArguments& arguments =
6438 AbstractTypeArguments::Handle(type->arguments()); 6446 AbstractTypeArguments::Handle(type->arguments());
6439 if (!arguments.IsNull()) { 6447 if (!arguments.IsNull()) {
6440 const intptr_t num_arguments = arguments.Length(); 6448 const intptr_t num_arguments = arguments.Length();
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
6995 String::NewSymbol("list literal element")); 7003 String::NewSymbol("list literal element"));
6996 while (CurrentToken() != Token::kRBRACK) { 7004 while (CurrentToken() != Token::kRBRACK) {
6997 const intptr_t element_pos = token_index_; 7005 const intptr_t element_pos = token_index_;
6998 AstNode* element = ParseExpr(is_const); 7006 AstNode* element = ParseExpr(is_const);
6999 if (FLAG_enable_type_checks && 7007 if (FLAG_enable_type_checks &&
7000 !is_const && 7008 !is_const &&
7001 !element_type.IsDynamicType()) { 7009 !element_type.IsDynamicType()) {
7002 // The expression needs to be type checked at runtime. 7010 // The expression needs to be type checked at runtime.
7003 // Eliminate the type check if it can be performed at compile time and 7011 // Eliminate the type check if it can be performed at compile time and
7004 // if it succeeds. 7012 // if it succeeds.
7013 Error& malformed_error = Error::Handle();
7005 if (!element_type.IsInstantiated() || 7014 if (!element_type.IsInstantiated() ||
7006 !element->IsLiteralNode() || 7015 !element->IsLiteralNode() ||
7007 !element->AsLiteralNode()->literal(). 7016 !element->AsLiteralNode()->literal().
7008 IsAssignableTo(element_type, TypeArguments::Handle())) { 7017 IsAssignableTo(element_type,
7018 TypeArguments::Handle(),
7019 &malformed_error)) {
7009 element = new AssignableNode(element_pos, 7020 element = new AssignableNode(element_pos,
7010 element, 7021 element,
7011 element_type, 7022 element_type,
7012 dst_name); 7023 dst_name);
7013 } 7024 }
7014 } 7025 }
7015 list->AddElement(element); 7026 list->AddElement(element);
7016 if (CurrentToken() == Token::kCOMMA) { 7027 if (CurrentToken() == Token::kCOMMA) {
7017 ConsumeToken(); 7028 ConsumeToken();
7018 } else if (CurrentToken() != Token::kRBRACK) { 7029 } else if (CurrentToken() != Token::kRBRACK) {
7019 ErrorMsg("comma or ']' expected"); 7030 ErrorMsg("comma or ']' expected");
7020 } 7031 }
7021 } 7032 }
7022 ExpectToken(Token::kRBRACK); 7033 ExpectToken(Token::kRBRACK);
7023 SetAllowFunctionLiterals(saved_mode); 7034 SetAllowFunctionLiterals(saved_mode);
7024 } 7035 }
7025 7036
7026 if (is_const) { 7037 if (is_const) {
7027 // Allocate and initialize the const list at compile time. 7038 // Allocate and initialize the const list at compile time.
7028 Array& const_list = 7039 Array& const_list =
7029 Array::ZoneHandle(Array::New(list->length(), Heap::kOld)); 7040 Array::ZoneHandle(Array::New(list->length(), Heap::kOld));
7030 const_list.SetTypeArguments(type_arguments); 7041 const_list.SetTypeArguments(type_arguments);
7031 7042 Error& malformed_error = Error::Handle();
7032 for (int i = 0; i < list->length(); i++) { 7043 for (int i = 0; i < list->length(); i++) {
7033 AstNode* elem = list->ElementAt(i); 7044 AstNode* elem = list->ElementAt(i);
7034 // Arguments have been evaluated to a literal value already. 7045 // Arguments have been evaluated to a literal value already.
7035 ASSERT(elem->IsLiteralNode()); 7046 ASSERT(elem->IsLiteralNode());
7036 if (FLAG_enable_type_checks && 7047 if (FLAG_enable_type_checks &&
7037 !element_type.IsDynamicType() && 7048 !element_type.IsDynamicType() &&
7038 !elem->AsLiteralNode()->literal(). 7049 !elem->AsLiteralNode()->literal().IsAssignableTo(
7039 IsAssignableTo(element_type, TypeArguments::Handle())) { 7050 element_type, TypeArguments::Handle(), &malformed_error)) {
7040 ErrorMsg(elem->AsLiteralNode()->token_index(), 7051 // If the failure is due to a malformed type error, display it instead.
7041 "list literal element at index %d must be " 7052 if (!malformed_error.IsNull()) {
7042 "a constant of type '%s'", 7053 ErrorMsg(malformed_error);
7043 i, 7054 } else {
7044 String::Handle(element_type.Name()).ToCString()); 7055 ErrorMsg(elem->AsLiteralNode()->token_index(),
7056 "list literal element at index %d must be "
7057 "a constant of type '%s'",
7058 i,
7059 String::Handle(element_type.Name()).ToCString());
7060 }
7045 } 7061 }
7046 const_list.SetAt(i, elem->AsLiteralNode()->literal()); 7062 const_list.SetAt(i, elem->AsLiteralNode()->literal());
7047 } 7063 }
7048 const_list ^= const_list.Canonicalize(); 7064 const_list ^= const_list.Canonicalize();
7049 const_list.MakeImmutable(); 7065 const_list.MakeImmutable();
7050 return new LiteralNode(literal_pos, const_list); 7066 return new LiteralNode(literal_pos, const_list);
7051 } else { 7067 } else {
7052 // Factory call at runtime. 7068 // Factory call at runtime.
7053 String& list_literal_factory_class_name = String::Handle( 7069 String& list_literal_factory_class_name = String::Handle(
7054 String::NewSymbol(kListLiteralFactoryClassName)); 7070 String::NewSymbol(kListLiteralFactoryClassName));
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
7172 const bool saved_mode = SetAllowFunctionLiterals(true); 7188 const bool saved_mode = SetAllowFunctionLiterals(true);
7173 const intptr_t value_pos = token_index_; 7189 const intptr_t value_pos = token_index_;
7174 AstNode* value = ParseExpr(is_const); 7190 AstNode* value = ParseExpr(is_const);
7175 SetAllowFunctionLiterals(saved_mode); 7191 SetAllowFunctionLiterals(saved_mode);
7176 if (FLAG_enable_type_checks && 7192 if (FLAG_enable_type_checks &&
7177 !is_const && 7193 !is_const &&
7178 !value_type.IsDynamicType()) { 7194 !value_type.IsDynamicType()) {
7179 // The expression needs to be type checked at runtime. 7195 // The expression needs to be type checked at runtime.
7180 // Eliminate the type check if it can be performed at compile time and 7196 // Eliminate the type check if it can be performed at compile time and
7181 // if it succeeds. 7197 // if it succeeds.
7198 Error& malformed_error = Error::Handle();
7182 if (!value_type.IsInstantiated() || 7199 if (!value_type.IsInstantiated() ||
7183 !value->IsLiteralNode() || 7200 !value->IsLiteralNode() ||
7184 !value->AsLiteralNode()->literal(). 7201 !value->AsLiteralNode()->literal().IsAssignableTo(
7185 IsAssignableTo(value_type, TypeArguments::Handle())) { 7202 value_type, TypeArguments::Handle(), &malformed_error)) {
7186 value = new AssignableNode(value_pos, 7203 value = new AssignableNode(value_pos,
7187 value, 7204 value,
7188 value_type, 7205 value_type,
7189 dst_name); 7206 dst_name);
7190 } 7207 }
7191 } 7208 }
7192 AddKeyValuePair(kv_pairs, is_const, key, value); 7209 AddKeyValuePair(kv_pairs, is_const, key, value);
7193 7210
7194 if (CurrentToken() == Token::kCOMMA) { 7211 if (CurrentToken() == Token::kCOMMA) {
7195 ConsumeToken(); 7212 ConsumeToken();
7196 } else if (CurrentToken() != Token::kRBRACE) { 7213 } else if (CurrentToken() != Token::kRBRACE) {
7197 ErrorMsg("comma or '}' expected"); 7214 ErrorMsg("comma or '}' expected");
7198 } 7215 }
7199 } 7216 }
7200 ASSERT(kv_pairs->length() % 2 == 0); 7217 ASSERT(kv_pairs->length() % 2 == 0);
7201 ExpectToken(Token::kRBRACE); 7218 ExpectToken(Token::kRBRACE);
7202 7219
7203 if (is_const) { 7220 if (is_const) {
7204 // Create the key-value pair array, canonicalize it and then create 7221 // Create the key-value pair array, canonicalize it and then create
7205 // the immutable map object with it. This all happens at compile time. 7222 // the immutable map object with it. This all happens at compile time.
7206 // The resulting immutable map object is returned as a literal. 7223 // The resulting immutable map object is returned as a literal.
7207 7224
7208 // First, create the canonicalized key-value pair array. 7225 // First, create the canonicalized key-value pair array.
7209 Array& key_value_array = 7226 Array& key_value_array =
7210 Array::ZoneHandle(Array::New(kv_pairs->length(), Heap::kOld)); 7227 Array::ZoneHandle(Array::New(kv_pairs->length(), Heap::kOld));
7228 Error& malformed_error = Error::Handle();
7211 for (int i = 0; i < kv_pairs->length(); i++) { 7229 for (int i = 0; i < kv_pairs->length(); i++) {
7212 AstNode* arg = kv_pairs->ElementAt(i); 7230 AstNode* arg = kv_pairs->ElementAt(i);
7213 // Arguments have been evaluated to a literal value already. 7231 // Arguments have been evaluated to a literal value already.
7214 ASSERT(arg->IsLiteralNode()); 7232 ASSERT(arg->IsLiteralNode());
7215 if (FLAG_enable_type_checks && 7233 if (FLAG_enable_type_checks &&
7216 ((i % 2) == 1) && // Check values only, not keys. 7234 ((i % 2) == 1) && // Check values only, not keys.
7217 !value_type.IsDynamicType() && 7235 !value_type.IsDynamicType() &&
7218 !arg->AsLiteralNode()->literal(). 7236 !arg->AsLiteralNode()->literal().IsAssignableTo(
7219 IsAssignableTo(value_type, TypeArguments::Handle())) { 7237 value_type, TypeArguments::Handle(), &malformed_error)) {
7220 ErrorMsg(arg->AsLiteralNode()->token_index(), 7238 // If the failure is due to a malformed type error, display it instead.
7221 "map literal value at index %d must be " 7239 if (!malformed_error.IsNull()) {
7222 "a constant of type '%s'", 7240 ErrorMsg(malformed_error);
7223 i >> 1, 7241 } else {
7224 String::Handle(value_type.Name()).ToCString()); 7242 ErrorMsg(arg->AsLiteralNode()->token_index(),
7243 "map literal value at index %d must be "
7244 "a constant of type '%s'",
7245 i >> 1,
7246 String::Handle(value_type.Name()).ToCString());
7247 }
7225 } 7248 }
7226 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); 7249 key_value_array.SetAt(i, arg->AsLiteralNode()->literal());
7227 } 7250 }
7228 key_value_array ^= key_value_array.Canonicalize(); 7251 key_value_array ^= key_value_array.Canonicalize();
7229 key_value_array.MakeImmutable(); 7252 key_value_array.MakeImmutable();
7230 7253
7231 // Construct the map object. 7254 // Construct the map object.
7232 const String& immutable_map_class_name = 7255 const String& immutable_map_class_name =
7233 String::Handle(String::NewSymbol(kImmutableMapName)); 7256 String::Handle(String::NewSymbol(kImmutableMapName));
7234 const Class& immutable_map_class = 7257 const Class& immutable_map_class =
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
7326 TRACE_PARSER("ParseNewOperator"); 7349 TRACE_PARSER("ParseNewOperator");
7327 const intptr_t new_pos = token_index_; 7350 const intptr_t new_pos = token_index_;
7328 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); 7351 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST));
7329 bool is_const = (CurrentToken() == Token::kCONST); 7352 bool is_const = (CurrentToken() == Token::kCONST);
7330 ConsumeToken(); 7353 ConsumeToken();
7331 if (!IsIdentifier()) { 7354 if (!IsIdentifier()) {
7332 ErrorMsg("type name expected"); 7355 ErrorMsg("type name expected");
7333 } 7356 }
7334 intptr_t type_pos = token_index_; 7357 intptr_t type_pos = token_index_;
7335 7358
7359 // TODO(regis): Bounds error should not result in a compile time error,
7360 // but in a dynamic type error. Requesting kFinalizeWellFormed below is too
7361 // strict. See co19 issue 96.
7336 const AbstractType& type = AbstractType::Handle( 7362 const AbstractType& type = AbstractType::Handle(
7337 ParseType(ClassFinalizer::kFinalizeWellFormed)); 7363 ParseType(ClassFinalizer::kFinalizeWellFormed));
7338 if (type.IsTypeParameter()) { 7364 if (type.IsTypeParameter()) {
7339 ErrorMsg(type_pos, 7365 ErrorMsg(type_pos,
7340 "type parameter '%s' cannot be instantiated", 7366 "type parameter '%s' cannot be instantiated",
7341 String::Handle(type.Name()).ToCString()); 7367 String::Handle(type.Name()).ToCString());
7342 } 7368 }
7343 Class& type_class = Class::Handle(type.type_class()); 7369 Class& type_class = Class::Handle(type.type_class());
7344 String& type_class_name = String::Handle(type_class.Name()); 7370 String& type_class_name = String::Handle(type_class.Name());
7345 AbstractTypeArguments& type_arguments = 7371 AbstractTypeArguments& type_arguments =
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
7403 if (!type_class.HasResolvedFactoryClass()) { 7429 if (!type_class.HasResolvedFactoryClass()) {
7404 // This error can occur only with bootstrap classes. 7430 // This error can occur only with bootstrap classes.
7405 const UnresolvedClass& unresolved = 7431 const UnresolvedClass& unresolved =
7406 UnresolvedClass::Handle(type_class.UnresolvedFactoryClass()); 7432 UnresolvedClass::Handle(type_class.UnresolvedFactoryClass());
7407 const String& missing_class_name = String::Handle(unresolved.ident()); 7433 const String& missing_class_name = String::Handle(unresolved.ident());
7408 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); 7434 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString());
7409 } 7435 }
7410 // Only change the class of the constructor to the factory class if the 7436 // Only change the class of the constructor to the factory class if the
7411 // factory class implements the interface 'type'. 7437 // factory class implements the interface 'type'.
7412 const Class& factory_class = Class::Handle(type_class.FactoryClass()); 7438 const Class& factory_class = Class::Handle(type_class.FactoryClass());
7439 Error& malformed_error = Error::Handle();
7413 if (factory_class.IsSubtypeOf(TypeArguments::Handle(), 7440 if (factory_class.IsSubtypeOf(TypeArguments::Handle(),
7414 type_class, 7441 type_class,
7415 TypeArguments::Handle())) { 7442 TypeArguments::Handle(),
7443 &malformed_error)) {
7416 // Class finalization verifies that the factory class has identical type 7444 // Class finalization verifies that the factory class has identical type
7417 // parameters as the interface. 7445 // parameters as the interface.
7418 constructor_class_name = factory_class.Name(); 7446 constructor_class_name = factory_class.Name();
7419 } 7447 }
7420 // Always change the result type of the constructor to the factory type. 7448 // Always change the result type of the constructor to the factory type.
7421 constructor_class = factory_class.raw(); 7449 constructor_class = factory_class.raw();
7422 // The finalized type_arguments are still those of the interface type. 7450 // The finalized type_arguments are still those of the interface type.
7423 ASSERT(!constructor_class.is_interface()); 7451 ASSERT(!constructor_class.is_interface());
7424 } 7452 }
7425 7453
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
7509 } 7537 }
7510 } else { 7538 } else {
7511 CheckFunctionIsCallable(new_pos, constructor); 7539 CheckFunctionIsCallable(new_pos, constructor);
7512 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); 7540 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments);
7513 if (!type_arguments.IsNull() && 7541 if (!type_arguments.IsNull() &&
7514 !type_arguments.IsInstantiated() && 7542 !type_arguments.IsInstantiated() &&
7515 (current_block_->scope->function_level() > 0)) { 7543 (current_block_->scope->function_level() > 0)) {
7516 // Make sure that the instantiator is captured. 7544 // Make sure that the instantiator is captured.
7517 CaptureReceiver(); 7545 CaptureReceiver();
7518 } 7546 }
7547 // TODO(regis): If the type argument vector is not instantiated, we need to
7548 // verify in checked mode at runtime that it is within its declared bounds.
7519 new_object = new ConstructorCallNode( 7549 new_object = new ConstructorCallNode(
7520 new_pos, type_arguments, constructor, arguments); 7550 new_pos, type_arguments, constructor, arguments);
7521 } 7551 }
7522 return new_object; 7552 return new_object;
7523 } 7553 }
7524 7554
7525 7555
7526 String& Parser::Interpolate(ArrayNode* values) { 7556 String& Parser::Interpolate(ArrayNode* values) {
7527 const String& class_name = 7557 const String& class_name =
7528 String::Handle(String::NewSymbol(kStringClassName)); 7558 String::Handle(String::NewSymbol(kStringClassName));
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
8089 void Parser::SkipQualIdent() { 8119 void Parser::SkipQualIdent() {
8090 ASSERT(IsIdentifier()); 8120 ASSERT(IsIdentifier());
8091 ConsumeToken(); 8121 ConsumeToken();
8092 if (CurrentToken() == Token::kPERIOD) { 8122 if (CurrentToken() == Token::kPERIOD) {
8093 ConsumeToken(); // Consume the kPERIOD token. 8123 ConsumeToken(); // Consume the kPERIOD token.
8094 ExpectIdentifier("identifier expected after '.'"); 8124 ExpectIdentifier("identifier expected after '.'");
8095 } 8125 }
8096 } 8126 }
8097 8127
8098 } // namespace dart 8128 } // 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