OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |