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

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

Issue 11049038: Change compile-time errors into dynamic errors in instance creation expression (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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/symbols.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 "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 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 if (super_function.IsNull()) { 1506 if (super_function.IsNull()) {
1507 ErrorMsg(field_pos, "field or getter '%s' not found in superclass", 1507 ErrorMsg(field_pos, "field or getter '%s' not found in superclass",
1508 field_name.ToCString()); 1508 field_name.ToCString());
1509 } 1509 }
1510 return CreateImplicitClosureNode(super_function, 1510 return CreateImplicitClosureNode(super_function,
1511 field_pos, 1511 field_pos,
1512 implicit_argument); 1512 implicit_argument);
1513 } 1513 }
1514 1514
1515 return new StaticGetterNode( 1515 return new StaticGetterNode(
1516 field_pos, implicit_argument, true, super_class, field_name); 1516 field_pos, implicit_argument, true, super_class, field_name);
1517 } 1517 }
1518 1518
1519 1519
1520 void Parser::GenerateSuperConstructorCall(const Class& cls, 1520 void Parser::GenerateSuperConstructorCall(const Class& cls,
1521 LocalVariable* receiver) { 1521 LocalVariable* receiver) {
1522 const intptr_t supercall_pos = TokenPos(); 1522 const intptr_t supercall_pos = TokenPos();
1523 const Class& super_class = Class::Handle(cls.SuperClass()); 1523 const Class& super_class = Class::Handle(cls.SuperClass());
1524 // Omit the implicit super() if there is no super class (i.e. 1524 // Omit the implicit super() if there is no super class (i.e.
1525 // we're not compiling class Object), or if the super class is an 1525 // we're not compiling class Object), or if the super class is an
1526 // artificially generated "wrapper class" that has no constructor. 1526 // artificially generated "wrapper class" that has no constructor.
(...skipping 2112 matching lines...) Expand 10 before | Expand all | Expand 10 after
3639 do { 3639 do {
3640 ConsumeToken(); 3640 ConsumeToken();
3641 type = ParseType(finalization); 3641 type = ParseType(finalization);
3642 // Only keep the error for the first malformed type argument. 3642 // Only keep the error for the first malformed type argument.
3643 if (malformed_error->IsNull() && type.IsMalformed()) { 3643 if (malformed_error->IsNull() && type.IsMalformed()) {
3644 *malformed_error = type.malformed_error(); 3644 *malformed_error = type.malformed_error();
3645 } 3645 }
3646 // Map a malformed type argument to Dynamic, so that malformed types with 3646 // Map a malformed type argument to Dynamic, so that malformed types with
3647 // a resolved type class are handled properly in production mode. 3647 // a resolved type class are handled properly in production mode.
3648 if (type.IsMalformed()) { 3648 if (type.IsMalformed()) {
3649 ASSERT(finalization != ClassFinalizer::kCanonicalizeWellFormed);
3650 if (finalization == ClassFinalizer::kCanonicalizeForCreation) {
3651 ErrorMsg(*malformed_error);
3652 }
3649 type = Type::DynamicType(); 3653 type = Type::DynamicType();
3650 } 3654 }
3651 types.Add(type); 3655 types.Add(type);
3652 } while (CurrentToken() == Token::kCOMMA); 3656 } while (CurrentToken() == Token::kCOMMA);
3653 Token::Kind token = CurrentToken(); 3657 Token::Kind token = CurrentToken();
3654 if ((token == Token::kGT) || (token == Token::kSHR)) { 3658 if ((token == Token::kGT) || (token == Token::kSHR)) {
3655 ConsumeRightAngleBracket(); 3659 ConsumeRightAngleBracket();
3656 } else { 3660 } else {
3657 ErrorMsg("right angle bracket expected"); 3661 ErrorMsg("right angle bracket expected");
3658 } 3662 }
(...skipping 3010 matching lines...) Expand 10 before | Expand all | Expand 10 after
6669 // Malformed type error. 6673 // Malformed type error.
6670 const Error& error = Error::Handle(type.malformed_error()); 6674 const Error& error = Error::Handle(type.malformed_error());
6671 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( 6675 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle(
6672 Symbols::New(error.ToErrorCString())))); 6676 Symbols::New(error.ToErrorCString()))));
6673 const String& cls_name = String::Handle(Symbols::TypeError()); 6677 const String& cls_name = String::Handle(Symbols::TypeError());
6674 const String& func_name = String::Handle(Symbols::ThrowNew()); 6678 const String& func_name = String::Handle(Symbols::ThrowNew());
6675 return MakeStaticCall(cls_name, func_name, arguments); 6679 return MakeStaticCall(cls_name, func_name, arguments);
6676 } 6680 }
6677 6681
6678 6682
6683 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, const String& name) {
6684 ArgumentListNode* arguments = new ArgumentListNode(call_pos);
6685 // Location argument.
6686 arguments->Add(new LiteralNode(
6687 call_pos, Integer::ZoneHandle(Integer::New(call_pos))));
6688 // Function name argument.
6689 arguments->Add(new LiteralNode(
6690 call_pos, String::ZoneHandle(Symbols::New(name))));
6691 const String& cls_name = String::Handle(Symbols::NoSuchMethodError());
6692 const String& func_name = String::Handle(Symbols::ThrowNew());
6693 return MakeStaticCall(cls_name, func_name, arguments);
6694 }
6695
6696
6679 AstNode* Parser::ParseBinaryExpr(int min_preced) { 6697 AstNode* Parser::ParseBinaryExpr(int min_preced) {
6680 TRACE_PARSER("ParseBinaryExpr"); 6698 TRACE_PARSER("ParseBinaryExpr");
6681 ASSERT(min_preced >= 4); 6699 ASSERT(min_preced >= 4);
6682 AstNode* left_operand = ParseUnaryExpr(); 6700 AstNode* left_operand = ParseUnaryExpr();
6683 if (IsLiteral("as")) { // Not a reserved word. 6701 if (IsLiteral("as")) { // Not a reserved word.
6684 token_kind_ = Token::kAS; 6702 token_kind_ = Token::kAS;
6685 } 6703 }
6686 int current_preced = Token::Precedence(CurrentToken()); 6704 int current_preced = Token::Precedence(CurrentToken());
6687 while (current_preced >= min_preced) { 6705 while (current_preced >= min_preced) {
6688 while (Token::Precedence(CurrentToken()) == current_preced) { 6706 while (Token::Precedence(CurrentToken()) == current_preced) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
6937 *expr = right_node; 6955 *expr = right_node;
6938 return left_node; 6956 return left_node;
6939 } 6957 }
6940 return *expr; 6958 return *expr;
6941 } 6959 }
6942 6960
6943 6961
6944 // Ensure that the expression temp is allocated for nodes that may need it. 6962 // Ensure that the expression temp is allocated for nodes that may need it.
6945 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { 6963 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) {
6946 AstNode* result = original->MakeAssignmentNode(rhs); 6964 AstNode* result = original->MakeAssignmentNode(rhs);
6965 if ((result == NULL) && original->IsStaticGetterNode()) {
6966 const String& setter_name = String::ZoneHandle(
6967 Field::SetterSymbol(original->AsStaticGetterNode()->field_name()));
6968 result = ThrowNoSuchMethodError(original->token_pos(), setter_name);
6969 }
6947 if ((result != NULL) && 6970 if ((result != NULL) &&
6948 (result->IsStoreIndexedNode() || 6971 (result->IsStoreIndexedNode() ||
6949 result->IsInstanceSetterNode() || 6972 result->IsInstanceSetterNode() ||
6950 result->IsStaticSetterNode() || 6973 result->IsStaticSetterNode() ||
6951 result->IsStoreStaticFieldNode() || 6974 result->IsStoreStaticFieldNode() ||
6952 result->IsStoreLocalNode())) { 6975 result->IsStoreLocalNode())) {
6953 EnsureExpressionTemp(); 6976 EnsureExpressionTemp();
6954 } 6977 }
6955 return result; 6978 return result;
6956 } 6979 }
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
7212 false, 7235 false,
7213 Class::ZoneHandle(cls.raw()), 7236 Class::ZoneHandle(cls.raw()),
7214 func_name); 7237 func_name);
7215 return new ClosureCallNode(call_pos, closure, arguments); 7238 return new ClosureCallNode(call_pos, closure, arguments);
7216 } 7239 }
7217 } else { 7240 } else {
7218 EnsureExpressionTemp(); 7241 EnsureExpressionTemp();
7219 closure = GenerateStaticFieldLookup(field, call_pos); 7242 closure = GenerateStaticFieldLookup(field, call_pos);
7220 return new ClosureCallNode(call_pos, closure, arguments); 7243 return new ClosureCallNode(call_pos, closure, arguments);
7221 } 7244 }
7222 // Could not resolve static method: throw an exception if the arguments 7245 // Could not resolve static method: throw a NoSuchMethodError.
7223 // do not match or compile time error otherwise. 7246 return ThrowNoSuchMethodError(ident_pos, func_name);
7224 const Function& test_func = Function::Handle(
7225 Resolver::ResolveStaticByName(cls, func_name, Resolver::kIsQualified));
7226 if (test_func.IsNull()) {
7227 ErrorMsg(ident_pos, "unresolved static method '%s'",
7228 func_name.ToCString());
7229 } else {
7230 ArgumentListNode* arguments = new ArgumentListNode(ident_pos);
7231 arguments->Add(new LiteralNode(
7232 TokenPos(), Integer::ZoneHandle(Integer::New(ident_pos))));
7233 const String& cls_name =
7234 String::Handle(Symbols::StaticResolutionException());
7235 const String& func_name = String::Handle(Symbols::ThrowNew());
7236 return MakeStaticCall(cls_name, func_name, arguments);
7237 }
7238 } 7247 }
7239 CheckFunctionIsCallable(call_pos, func); 7248 CheckFunctionIsCallable(call_pos, func);
7240 return new StaticCallNode(call_pos, func, arguments); 7249 return new StaticCallNode(call_pos, func, arguments);
7241 } 7250 }
7242 7251
7243 7252
7244 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { 7253 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) {
7245 TRACE_PARSER("ParseInstanceCall"); 7254 TRACE_PARSER("ParseInstanceCall");
7246 const intptr_t call_pos = TokenPos(); 7255 const intptr_t call_pos = TokenPos();
7247 if (CurrentToken() != Token::kLPAREN) { 7256 if (CurrentToken() != Token::kLPAREN) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
7299 const String& setter_name = 7308 const String& setter_name =
7300 String::ZoneHandle(Field::SetterName(field_name)); 7309 String::ZoneHandle(Field::SetterName(field_name));
7301 const int kNumArguments = 1; // value. 7310 const int kNumArguments = 1; // value.
7302 const Array& kNoArgumentNames = Array::Handle(); 7311 const Array& kNoArgumentNames = Array::Handle();
7303 func = Resolver::ResolveStatic(cls, 7312 func = Resolver::ResolveStatic(cls,
7304 setter_name, 7313 setter_name,
7305 kNumArguments, 7314 kNumArguments,
7306 kNoArgumentNames, 7315 kNoArgumentNames,
7307 Resolver::kIsQualified); 7316 Resolver::kIsQualified);
7308 if (func.IsNull()) { 7317 if (func.IsNull()) {
7309 // No field or explicit setter function, this is an error. 7318 // No field or explicit setter function, throw a NoSuchMethodError.
7310 ErrorMsg(ident_pos, "unknown static field '%s'", 7319 return ThrowNoSuchMethodError(ident_pos, field_name);
7311 field_name.ToCString());
7312 } 7320 }
7313 7321
7314 // Explicit setter function for the field found, field does not exist. 7322 // Explicit setter function for the field found, field does not exist.
7315 // Create a getter node first in case it is needed. If getter node 7323 // Create a getter node first in case it is needed. If getter node
7316 // is used as part of, e.g., "+=", and the explicit getter does not 7324 // is used as part of, e.g., "+=", and the explicit getter does not
7317 // exist, and error will be reported by the code generator. 7325 // exist, and error will be reported by the code generator.
7318 access = new StaticGetterNode(call_pos, 7326 access = new StaticGetterNode(call_pos,
7319 NULL, 7327 NULL,
7320 false, 7328 false,
7321 Class::ZoneHandle(cls.raw()), 7329 Class::ZoneHandle(cls.raw()),
(...skipping 19 matching lines...) Expand all
7341 func = Resolver::ResolveStatic(cls, 7349 func = Resolver::ResolveStatic(cls,
7342 getter_name, 7350 getter_name,
7343 kNumArguments, 7351 kNumArguments,
7344 kNoArgumentNames, 7352 kNoArgumentNames,
7345 Resolver::kIsQualified); 7353 Resolver::kIsQualified);
7346 if (func.IsNull()) { 7354 if (func.IsNull()) {
7347 // We might be referring to an implicit closure, check to see if 7355 // We might be referring to an implicit closure, check to see if
7348 // there is a function of the same name. 7356 // there is a function of the same name.
7349 func = cls.LookupStaticFunction(field_name); 7357 func = cls.LookupStaticFunction(field_name);
7350 if (func.IsNull()) { 7358 if (func.IsNull()) {
7351 // No field or explicit getter function, this is an error. 7359 // No field or explicit getter function, throw a NoSuchMethodError.
7352 ErrorMsg(ident_pos, 7360 return ThrowNoSuchMethodError(ident_pos, field_name);
7353 "unknown static field '%s'", field_name.ToCString());
7354 } 7361 }
7355 access = CreateImplicitClosureNode(func, call_pos, NULL); 7362 access = CreateImplicitClosureNode(func, call_pos, NULL);
7356 } else { 7363 } else {
7357 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); 7364 ASSERT(func.kind() != RawFunction::kConstImplicitGetter);
7358 access = new StaticGetterNode(call_pos, 7365 access = new StaticGetterNode(call_pos,
7359 NULL, 7366 NULL,
7360 false, 7367 false,
7361 Class::ZoneHandle(cls.raw()), 7368 Class::ZoneHandle(cls.raw()),
7362 field_name); 7369 field_name);
7363 } 7370 }
7364 } else { 7371 } else {
7365 access = GenerateStaticFieldLookup(field, TokenPos()); 7372 access = GenerateStaticFieldLookup(field, TokenPos());
7366 } 7373 }
7367 } 7374 }
7368 return access; 7375 return access;
7369 } 7376 }
7370 7377
7371 7378
7372 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { 7379 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) {
7373 if (!node->IsPrimaryNode()) { 7380 if (!node->IsPrimaryNode()) {
7374 return node; 7381 return node;
7375 } 7382 }
7376 PrimaryNode* primary = node->AsPrimaryNode(); 7383 PrimaryNode* primary = node->AsPrimaryNode();
7377 if (primary->primary().IsString()) { 7384 if (primary->primary().IsString()) {
7378 // In a static method, an unresolved identifier is an error. 7385 // In a static method, evaluation of an unresolved identifier causes a
7386 // NoSuchMethodError to be thrown.
7379 // In an instance method, we convert this into a getter call 7387 // In an instance method, we convert this into a getter call
7380 // for a field (which may be defined in a subclass.) 7388 // for a field (which may be defined in a subclass.)
7381 String& name = String::CheckedZoneHandle(primary->primary().raw()); 7389 String& name = String::CheckedZoneHandle(primary->primary().raw());
7382 if (current_function().is_static() || 7390 if (current_function().is_static() ||
7383 current_function().IsInFactoryScope()) { 7391 current_function().IsInFactoryScope()) {
7384 ErrorMsg(primary->token_pos(), 7392 return ThrowNoSuchMethodError(primary->token_pos(), name);
7385 "identifier '%s' is not declared in this scope",
7386 name.ToCString());
7387 } else { 7393 } else {
7388 AstNode* receiver = LoadReceiver(primary->token_pos()); 7394 AstNode* receiver = LoadReceiver(primary->token_pos());
7389 return CallGetter(node->token_pos(), receiver, name); 7395 return CallGetter(node->token_pos(), receiver, name);
7390 } 7396 }
7391 } 7397 }
7392 return primary; 7398 return primary;
7393 } 7399 }
7394 7400
7395 7401
7396 AstNode* Parser::LoadClosure(PrimaryNode* primary) { 7402 AstNode* Parser::LoadClosure(PrimaryNode* primary) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
7501 "cannot access instance method '%s' " 7507 "cannot access instance method '%s' "
7502 "from static function", 7508 "from static function",
7503 func_name.ToCString()); 7509 func_name.ToCString());
7504 } 7510 }
7505 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); 7511 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name);
7506 } 7512 }
7507 } else if (primary->primary().IsString()) { 7513 } else if (primary->primary().IsString()) {
7508 // Primary is an unresolved name. 7514 // Primary is an unresolved name.
7509 String& name = String::CheckedZoneHandle(primary->primary().raw()); 7515 String& name = String::CheckedZoneHandle(primary->primary().raw());
7510 if (current_function().is_static()) { 7516 if (current_function().is_static()) {
7511 ErrorMsg(primary->token_pos(), 7517 selector = ThrowNoSuchMethodError(primary->token_pos(), name);
7512 "identifier '%s' is not declared in this scope",
7513 name.ToCString());
7514 } else { 7518 } else {
7515 // Treat as call to unresolved (instance) method. 7519 // Treat as call to unresolved (instance) method.
7516 AstNode* receiver = LoadReceiver(primary->token_pos()); 7520 AstNode* receiver = LoadReceiver(primary->token_pos());
7517 selector = ParseInstanceCall(receiver, name); 7521 selector = ParseInstanceCall(receiver, name);
7518 } 7522 }
7519 } else if (primary->primary().IsClass()) { 7523 } else if (primary->primary().IsClass()) {
7520 ErrorMsg(left->token_pos(), 7524 ErrorMsg(left->token_pos(),
7521 "must use 'new' or 'const' to construct new instance"); 7525 "must use 'new' or 'const' to construct new instance");
7522 } else { 7526 } else {
7523 UNREACHABLE(); // Internal parser error. 7527 UNREACHABLE(); // Internal parser error.
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after
8343 } 8347 }
8344 // Not found in the local scope, and the name is not a type parameter. 8348 // Not found in the local scope, and the name is not a type parameter.
8345 // Try finding the variable in the library scope (current library 8349 // Try finding the variable in the library scope (current library
8346 // and all libraries imported by it without a library prefix). 8350 // and all libraries imported by it without a library prefix).
8347 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); 8351 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident);
8348 } 8352 }
8349 if (resolved->IsPrimaryNode()) { 8353 if (resolved->IsPrimaryNode()) {
8350 PrimaryNode* primary = resolved->AsPrimaryNode(); 8354 PrimaryNode* primary = resolved->AsPrimaryNode();
8351 if (primary->primary().IsString()) { 8355 if (primary->primary().IsString()) {
8352 // We got an unresolved name. If we are compiling a static 8356 // We got an unresolved name. If we are compiling a static
8353 // method, this is an error. In an instance method, we convert 8357 // method, evaluation of an unresolved identifier causes a
8358 // NoSuchMethodError to be thrown. In an instance method, we convert
8354 // the unresolved name to an instance field access, since a 8359 // the unresolved name to an instance field access, since a
8355 // subclass might define a field with this name. 8360 // subclass might define a field with this name.
8356 if (current_function().is_static()) { 8361 if (current_function().is_static()) {
8357 ErrorMsg(ident_pos, "identifier '%s' is not declared in this scope", 8362 resolved = ThrowNoSuchMethodError(ident_pos, ident);
8358 ident.ToCString());
8359 } else { 8363 } else {
8360 // Treat as call to unresolved instance field. 8364 // Treat as call to unresolved instance field.
8361 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); 8365 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
8362 } 8366 }
8363 } else if (primary->primary().IsFunction()) { 8367 } else if (primary->primary().IsFunction()) {
8364 if (allow_closure_names) { 8368 if (allow_closure_names) {
8365 resolved = LoadClosure(primary); 8369 resolved = LoadClosure(primary);
8366 } else { 8370 } else {
8367 ErrorMsg(ident_pos, "illegal reference to method '%s'", 8371 ErrorMsg(ident_pos, "illegal reference to method '%s'",
8368 ident.ToCString()); 8372 ident.ToCString());
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
8857 TRACE_PARSER("ParseNewOperator"); 8861 TRACE_PARSER("ParseNewOperator");
8858 const intptr_t new_pos = TokenPos(); 8862 const intptr_t new_pos = TokenPos();
8859 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); 8863 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST));
8860 bool is_const = (CurrentToken() == Token::kCONST); 8864 bool is_const = (CurrentToken() == Token::kCONST);
8861 ConsumeToken(); 8865 ConsumeToken();
8862 if (!IsIdentifier()) { 8866 if (!IsIdentifier()) {
8863 ErrorMsg("type name expected"); 8867 ErrorMsg("type name expected");
8864 } 8868 }
8865 intptr_t type_pos = TokenPos(); 8869 intptr_t type_pos = TokenPos();
8866 AbstractType& type = AbstractType::Handle( 8870 AbstractType& type = AbstractType::Handle(
8867 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); 8871 ParseType(ClassFinalizer::kCanonicalizeForCreation));
8868 // In case the type is malformed, throw a dynamic type error after finishing 8872 // In case the type is malformed, throw a dynamic type error after finishing
8869 // parsing the instance creation expression. 8873 // parsing the instance creation expression.
8870 if (type.IsTypeParameter() || type.IsDynamicType()) { 8874 if (type.IsTypeParameter() || type.IsDynamicType()) {
8871 // Replace the type with a malformed type. 8875 // Replace the type with a malformed type.
8872 type = ClassFinalizer::NewFinalizedMalformedType( 8876 type = ClassFinalizer::NewFinalizedMalformedType(
8873 current_class(), 8877 current_class(),
8874 type_pos, 8878 type_pos,
8875 "%s'%s' cannot be instantiated", 8879 "%s'%s' cannot be instantiated",
8876 type.IsTypeParameter() ? "type parameter " : "", 8880 type.IsTypeParameter() ? "type parameter " : "",
8877 type.IsTypeParameter() ? 8881 type.IsTypeParameter() ?
(...skipping 10 matching lines...) Expand all
8888 named_constructor = ExpectIdentifier("name of constructor expected"); 8892 named_constructor = ExpectIdentifier("name of constructor expected");
8889 } 8893 }
8890 8894
8891 // Parse constructor parameters. 8895 // Parse constructor parameters.
8892 if (CurrentToken() != Token::kLPAREN) { 8896 if (CurrentToken() != Token::kLPAREN) {
8893 ErrorMsg("'(' expected"); 8897 ErrorMsg("'(' expected");
8894 } 8898 }
8895 intptr_t call_pos = TokenPos(); 8899 intptr_t call_pos = TokenPos();
8896 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); 8900 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const);
8897 8901
8898 // Parsing is complete, so we can return a throw in case of a malformed type. 8902 // Parsing is complete, so we can return a throw in case of a malformed type
8903 // or report a compile-time error if the constructor is const.
8899 if (type.IsMalformed()) { 8904 if (type.IsMalformed()) {
8905 if (is_const) {
8906 const Error& error = Error::Handle(type.malformed_error());
8907 ErrorMsg(error);
8908 }
8900 return ThrowTypeError(type_pos, type); 8909 return ThrowTypeError(type_pos, type);
8901 } 8910 }
8902 8911
8903 // Resolve the type and optional identifier to a constructor or factory. 8912 // Resolve the type and optional identifier to a constructor or factory.
8904 Class& type_class = Class::Handle(type.type_class()); 8913 Class& type_class = Class::Handle(type.type_class());
8905 const String& type_class_name = String::Handle(type_class.Name()); 8914 const String& type_class_name = String::Handle(type_class.Name());
8906 AbstractTypeArguments& type_arguments = 8915 AbstractTypeArguments& type_arguments =
8907 AbstractTypeArguments::ZoneHandle(type.arguments()); 8916 AbstractTypeArguments::ZoneHandle(type.arguments());
8908 8917
8909 // The constructor class and its name are those of the parsed type, unless the 8918 // The constructor class and its name are those of the parsed type, unless the
(...skipping 10 matching lines...) Expand all
8920 if (type_class.is_interface()) { 8929 if (type_class.is_interface()) {
8921 // We need to make sure that an appropriate constructor is 8930 // We need to make sure that an appropriate constructor is
8922 // declared in the interface. 8931 // declared in the interface.
8923 const String& constructor_name = 8932 const String& constructor_name =
8924 BuildConstructorName(type_class_name, named_constructor); 8933 BuildConstructorName(type_class_name, named_constructor);
8925 const String& external_constructor_name = 8934 const String& external_constructor_name =
8926 (named_constructor ? constructor_name : type_class_name); 8935 (named_constructor ? constructor_name : type_class_name);
8927 Function& constructor = Function::ZoneHandle( 8936 Function& constructor = Function::ZoneHandle(
8928 type_class.LookupConstructor(constructor_name)); 8937 type_class.LookupConstructor(constructor_name));
8929 if (constructor.IsNull()) { 8938 if (constructor.IsNull()) {
8930 // Replace the type with a malformed type and compile a throw. 8939 // Replace the type with a malformed type and compile a throw or report
8940 // a compile-time error if the constructor is const.
8931 type = ClassFinalizer::NewFinalizedMalformedType( 8941 type = ClassFinalizer::NewFinalizedMalformedType(
8932 current_class(), 8942 current_class(),
8933 type_pos, 8943 call_pos,
8934 "interface '%s' has no constructor named '%s'", 8944 "interface '%s' has no constructor named '%s'",
8935 type_class_name.ToCString(), 8945 type_class_name.ToCString(),
8936 external_constructor_name.ToCString()); 8946 external_constructor_name.ToCString());
8937 return ThrowTypeError(type_pos, type); 8947 if (is_const) {
8948 const Error& error = Error::Handle(type.malformed_error());
8949 ErrorMsg(error);
8950 }
8951 return ThrowNoSuchMethodError(call_pos, external_constructor_name);
8938 } 8952 }
8939 // TODO(regis): Throw a NoSuchMethodError instead of a TypeError.
8940 String& error_message = String::Handle(); 8953 String& error_message = String::Handle();
8941 if (!constructor.AreValidArguments(arguments_length, 8954 if (!constructor.AreValidArguments(arguments_length,
8942 arguments->names(), 8955 arguments->names(),
8943 &error_message)) { 8956 &error_message)) {
8944 // Replace the type with a malformed type and compile a throw. 8957 if (is_const) {
8945 type = ClassFinalizer::NewFinalizedMalformedType( 8958 ErrorMsg(call_pos,
8946 current_class(), 8959 "invalid arguments passed to constructor '%s' "
8947 call_pos, 8960 "for interface '%s': %s",
8948 "invalid arguments passed to constructor '%s' " 8961 external_constructor_name.ToCString(),
8949 "for interface '%s': %s", 8962 type_class_name.ToCString(),
8950 external_constructor_name.ToCString(), 8963 error_message.ToCString());
8951 type_class_name.ToCString(), 8964 }
8952 error_message.ToCString()); 8965 return ThrowNoSuchMethodError(call_pos, external_constructor_name);
8953 return ThrowTypeError(call_pos, type);
8954 } 8966 }
8955 // TODO(regis): Remove support for obsolete default factory classes. 8967 // TODO(regis): Remove support for obsolete default factory classes.
8956 if (!type_class.HasFactoryClass()) { 8968 if (!type_class.HasFactoryClass()) {
8957 ErrorMsg(type_pos, 8969 ErrorMsg(type_pos,
8958 "cannot allocate interface '%s' without factory class", 8970 "cannot allocate interface '%s' without factory class",
8959 type_class_name.ToCString()); 8971 type_class_name.ToCString());
8960 } 8972 }
8961 if (!type_class.HasResolvedFactoryClass()) { 8973 if (!type_class.HasResolvedFactoryClass()) {
8962 // This error can occur only with bootstrap classes. 8974 // This error can occur only with bootstrap classes.
8963 const UnresolvedClass& unresolved = 8975 const UnresolvedClass& unresolved =
(...skipping 21 matching lines...) Expand all
8985 // Make sure that an appropriate constructor exists. 8997 // Make sure that an appropriate constructor exists.
8986 const String& constructor_name = 8998 const String& constructor_name =
8987 BuildConstructorName(constructor_class_name, named_constructor); 8999 BuildConstructorName(constructor_class_name, named_constructor);
8988 Function& constructor = Function::ZoneHandle( 9000 Function& constructor = Function::ZoneHandle(
8989 constructor_class.LookupConstructor(constructor_name)); 9001 constructor_class.LookupConstructor(constructor_name));
8990 if (constructor.IsNull()) { 9002 if (constructor.IsNull()) {
8991 constructor = constructor_class.LookupFactory(constructor_name); 9003 constructor = constructor_class.LookupFactory(constructor_name);
8992 if (constructor.IsNull()) { 9004 if (constructor.IsNull()) {
8993 const String& external_constructor_name = 9005 const String& external_constructor_name =
8994 (named_constructor ? constructor_name : constructor_class_name); 9006 (named_constructor ? constructor_name : constructor_class_name);
8995 // Replace the type with a malformed type and compile a throw. 9007 // Replace the type with a malformed type and compile a throw or report a
9008 // compile-time error if the constructor is const.
8996 type = ClassFinalizer::NewFinalizedMalformedType( 9009 type = ClassFinalizer::NewFinalizedMalformedType(
8997 current_class(), 9010 current_class(),
8998 type_pos, 9011 call_pos,
8999 "class '%s' has no constructor or factory named '%s'", 9012 "class '%s' has no constructor or factory named '%s'",
9000 String::Handle(constructor_class.Name()).ToCString(), 9013 String::Handle(constructor_class.Name()).ToCString(),
9001 external_constructor_name.ToCString()); 9014 external_constructor_name.ToCString());
9002 return ThrowTypeError(type_pos, type); 9015 if (is_const) {
9016 const Error& error = Error::Handle(type.malformed_error());
9017 ErrorMsg(error);
9018 }
9019 return ThrowNoSuchMethodError(call_pos, external_constructor_name);
9003 } else if (constructor.IsRedirectingFactory()) { 9020 } else if (constructor.IsRedirectingFactory()) {
9004 type = constructor.RedirectionType(); 9021 type = constructor.RedirectionType();
9005 if (type.IsMalformed()) { 9022 if (type.IsMalformed()) {
9023 if (is_const) {
9024 const Error& error = Error::Handle(type.malformed_error());
9025 ErrorMsg(error);
9026 }
9006 return ThrowTypeError(type.token_pos(), type); 9027 return ThrowTypeError(type.token_pos(), type);
9007 } 9028 }
9008 constructor = constructor.RedirectionTarget(); 9029 constructor = constructor.RedirectionTarget();
9009 ASSERT(!constructor.IsNull()); 9030 ASSERT(!constructor.IsNull());
9010 type_class = type.type_class(); 9031 type_class = type.type_class();
9011 type_arguments = type.arguments(); 9032 type_arguments = type.arguments();
9012 constructor_class = constructor.Owner(); 9033 constructor_class = constructor.Owner();
9013 ASSERT(type_class.raw() == constructor_class.raw()); 9034 ASSERT(type_class.raw() == constructor_class.raw());
9014 } 9035 }
9015 if (constructor.IsFactory()) { 9036 if (constructor.IsFactory()) {
(...skipping 10 matching lines...) Expand all
9026 ArgumentListNode* arguments = new ArgumentListNode(type_pos); 9047 ArgumentListNode* arguments = new ArgumentListNode(type_pos);
9027 arguments->Add(new LiteralNode( 9048 arguments->Add(new LiteralNode(
9028 TokenPos(), Integer::ZoneHandle(Integer::New(type_pos)))); 9049 TokenPos(), Integer::ZoneHandle(Integer::New(type_pos))));
9029 arguments->Add(new LiteralNode( 9050 arguments->Add(new LiteralNode(
9030 TokenPos(), String::ZoneHandle(constructor_class_name.raw()))); 9051 TokenPos(), String::ZoneHandle(constructor_class_name.raw())));
9031 const String& cls_name = 9052 const String& cls_name =
9032 String::Handle(Symbols::AbstractClassInstantiationError()); 9053 String::Handle(Symbols::AbstractClassInstantiationError());
9033 const String& func_name = String::Handle(Symbols::ThrowNew()); 9054 const String& func_name = String::Handle(Symbols::ThrowNew());
9034 return MakeStaticCall(cls_name, func_name, arguments); 9055 return MakeStaticCall(cls_name, func_name, arguments);
9035 } 9056 }
9036 // TODO(regis): Throw a NoSuchMethodError instead of a TypeError.
9037 String& error_message = String::Handle(); 9057 String& error_message = String::Handle();
9038 if (!constructor.AreValidArguments(arguments_length, 9058 if (!constructor.AreValidArguments(arguments_length,
9039 arguments->names(), 9059 arguments->names(),
9040 &error_message)) { 9060 &error_message)) {
9041 const String& external_constructor_name = 9061 const String& external_constructor_name =
9042 (named_constructor ? constructor_name : constructor_class_name); 9062 (named_constructor ? constructor_name : constructor_class_name);
9043 // Replace the type with a malformed type and compile a throw when called. 9063 if (is_const) {
9044 type = ClassFinalizer::NewFinalizedMalformedType( 9064 ErrorMsg(call_pos,
9045 current_class(), 9065 "invalid arguments passed to constructor '%s' "
9046 call_pos, 9066 "for class '%s': %s",
9047 "invalid arguments passed to constructor '%s' for class '%s': %s", 9067 external_constructor_name.ToCString(),
9048 external_constructor_name.ToCString(), 9068 String::Handle(constructor_class.Name()).ToCString(),
9049 String::Handle(constructor_class.Name()).ToCString(), 9069 error_message.ToCString());
9050 error_message.ToCString()); 9070 }
9051 return ThrowTypeError(call_pos, type); 9071 return ThrowNoSuchMethodError(call_pos, external_constructor_name);
9052 } 9072 }
9053 9073
9054 // Now that the constructor to be called is identified, finalize the type 9074 // Now that the constructor to be called is identified, finalize the type
9055 // argument vector to be passed. 9075 // argument vector to be passed.
9056 // The type argument vector of the parsed type was finalized in ParseType. 9076 // The type argument vector of the parsed type was finalized in ParseType.
9057 // If the constructor class was changed from the interface class to the 9077 // If the constructor class was changed from the interface class to the
9058 // factory class, we need to finalize the type argument vector again, because 9078 // factory class, we need to finalize the type argument vector again, because
9059 // it may be longer due to the factory class extending a class, or/and because 9079 // it may be longer due to the factory class extending a class, or/and because
9060 // the bounds on the factory class may be tighter than on the interface. 9080 // the bounds on the factory class may be tighter than on the interface.
9061 if (!constructor.IsNull() && (constructor_class.raw() != type_class.raw())) { 9081 if (!constructor.IsNull() && (constructor_class.raw() != type_class.raw())) {
(...skipping 24 matching lines...) Expand all
9086 // of the super type when finalizing the temporary type. 9106 // of the super type when finalizing the temporary type.
9087 type_arguments = temp_type.arguments(); 9107 type_arguments = temp_type.arguments();
9088 // The type parameter bounds of the factory class may be more specific than 9108 // The type parameter bounds of the factory class may be more specific than
9089 // the type parameter bounds of the interface class. Therefore, although 9109 // the type parameter bounds of the interface class. Therefore, although
9090 // type was not malformed, temp_type may be malformed. 9110 // type was not malformed, temp_type may be malformed.
9091 if (!type.IsMalformed() && temp_type.IsMalformed()) { 9111 if (!type.IsMalformed() && temp_type.IsMalformed()) {
9092 const Error& error = Error::Handle(temp_type.malformed_error()); 9112 const Error& error = Error::Handle(temp_type.malformed_error());
9093 type.set_malformed_error(error); 9113 type.set_malformed_error(error);
9094 } 9114 }
9095 } 9115 }
9116 // Return a throw in case of a malformed type or report a compile-time error
9117 // if the constructor is const.
9096 if (type.IsMalformed()) { 9118 if (type.IsMalformed()) {
9097 // Return the throw of a dynamic type error if the type is malformed. 9119 if (is_const) {
9120 const Error& error = Error::Handle(type.malformed_error());
9121 ErrorMsg(error);
9122 }
9098 return ThrowTypeError(type_pos, type); 9123 return ThrowTypeError(type_pos, type);
9099 } 9124 }
9100 type_arguments ^= type_arguments.Canonicalize(); 9125 type_arguments ^= type_arguments.Canonicalize();
9101 // Make the constructor call. 9126 // Make the constructor call.
9102 AstNode* new_object = NULL; 9127 AstNode* new_object = NULL;
9103 if (is_const) { 9128 if (is_const) {
9104 if (!constructor.is_const()) { 9129 if (!constructor.is_const()) {
9105 ErrorMsg("'const' requires const constructor: '%s'", 9130 ErrorMsg("'const' requires const constructor: '%s'",
9106 String::Handle(constructor.name()).ToCString()); 9131 String::Handle(constructor.name()).ToCString());
9107 } 9132 }
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
9721 void Parser::SkipQualIdent() { 9746 void Parser::SkipQualIdent() {
9722 ASSERT(IsIdentifier()); 9747 ASSERT(IsIdentifier());
9723 ConsumeToken(); 9748 ConsumeToken();
9724 if (CurrentToken() == Token::kPERIOD) { 9749 if (CurrentToken() == Token::kPERIOD) {
9725 ConsumeToken(); // Consume the kPERIOD token. 9750 ConsumeToken(); // Consume the kPERIOD token.
9726 ExpectIdentifier("identifier expected after '.'"); 9751 ExpectIdentifier("identifier expected after '.'");
9727 } 9752 }
9728 } 9753 }
9729 9754
9730 } // namespace dart 9755 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698