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 2957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2968 // supported yet). | 2968 // supported yet). |
2969 member.type = &AbstractType::ZoneHandle( | 2969 member.type = &AbstractType::ZoneHandle( |
2970 ParseType(ClassFinalizer::kTryResolve)); | 2970 ParseType(ClassFinalizer::kTryResolve)); |
2971 } | 2971 } |
2972 } | 2972 } |
2973 } | 2973 } |
2974 | 2974 |
2975 // Optionally parse a (possibly named) constructor name or factory. | 2975 // Optionally parse a (possibly named) constructor name or factory. |
2976 if (IsIdentifier() && | 2976 if (IsIdentifier() && |
2977 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 2977 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
| 2978 member.name_pos = TokenPos(); |
| 2979 member.name = CurrentLiteral(); // Unqualified identifier. |
| 2980 ConsumeToken(); |
2978 if (member.has_factory) { | 2981 if (member.has_factory) { |
2979 // TODO(regis): Simplify this code once the core library is fixed. | 2982 // The factory name may be qualified, but the first identifier must match |
2980 // See issue 6641. | 2983 // the name of the immediately enclosing class. |
2981 // Per specification, the name of the factory must be the name of the | 2984 if (!member.name->Equals(members->class_name())) { |
2982 // immediately enclosing class. | 2985 ErrorMsg(member.name_pos, "factory name must be '%s'", |
2983 | 2986 members->class_name().ToCString()); |
2984 // The factory name may be qualified. | |
2985 QualIdent factory_name; | |
2986 ParseQualIdent(&factory_name); | |
2987 member.name_pos = factory_name.ident_pos; | |
2988 member.name = factory_name.ident; // Unqualified identifier. | |
2989 // The class of the factory result type is specified by the factory name. | |
2990 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); | |
2991 if (factory_name.lib_prefix != NULL) { | |
2992 lib_prefix = factory_name.lib_prefix->raw(); | |
2993 } | 2987 } |
2994 const Object& result_type_class = Object::Handle( | 2988 const Object& result_type_class = Object::Handle( |
2995 UnresolvedClass::New(lib_prefix, | 2989 UnresolvedClass::New(LibraryPrefix::Handle(), |
2996 *factory_name.ident, | 2990 *member.name, |
2997 factory_name.ident_pos)); | 2991 member.name_pos)); |
2998 // The type arguments of the result type are set during finalization. | 2992 // The type arguments of the result type are set during finalization. |
2999 member.type = &Type::ZoneHandle(Type::New(result_type_class, | 2993 member.type = &Type::ZoneHandle(Type::New(result_type_class, |
3000 TypeArguments::Handle(), | 2994 TypeArguments::Handle(), |
3001 factory_name.ident_pos)); | 2995 member.name_pos)); |
3002 } else { | 2996 } else if (member.has_static) { |
3003 if (member.has_static) { | 2997 ErrorMsg(member.name_pos, "constructor cannot be static"); |
3004 ErrorMsg("constructor cannot be static"); | |
3005 } | |
3006 member.name_pos = TokenPos(); | |
3007 member.name = CurrentLiteral(); | |
3008 ConsumeToken(); | |
3009 } | 2998 } |
3010 // We must be dealing with a constructor or named constructor. | 2999 // We must be dealing with a constructor or named constructor. |
3011 member.kind = RawFunction::kConstructor; | 3000 member.kind = RawFunction::kConstructor; |
3012 String& ctor_suffix = String::ZoneHandle(Symbols::Dot()); | 3001 String& ctor_suffix = String::ZoneHandle(Symbols::Dot()); |
3013 if (CurrentToken() == Token::kPERIOD) { | 3002 if (CurrentToken() == Token::kPERIOD) { |
3014 // Named constructor. | 3003 // Named constructor. |
3015 ConsumeToken(); | 3004 ConsumeToken(); |
3016 member.constructor_name = ExpectIdentifier("identifier expected"); | 3005 member.constructor_name = ExpectIdentifier("identifier expected"); |
3017 ctor_suffix = String::Concat(ctor_suffix, *member.constructor_name); | 3006 ctor_suffix = String::Concat(ctor_suffix, *member.constructor_name); |
3018 } | 3007 } |
(...skipping 5977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8996 constr_args)); | 8985 constr_args)); |
8997 if (constructor_result.IsUnhandledException()) { | 8986 if (constructor_result.IsUnhandledException()) { |
8998 return GenerateRethrow(literal_pos, constructor_result); | 8987 return GenerateRethrow(literal_pos, constructor_result); |
8999 } else { | 8988 } else { |
9000 const Instance& const_instance = Instance::Cast(constructor_result); | 8989 const Instance& const_instance = Instance::Cast(constructor_result); |
9001 return new LiteralNode(literal_pos, | 8990 return new LiteralNode(literal_pos, |
9002 Instance::ZoneHandle(const_instance.raw())); | 8991 Instance::ZoneHandle(const_instance.raw())); |
9003 } | 8992 } |
9004 } else { | 8993 } else { |
9005 // Factory call at runtime. | 8994 // Factory call at runtime. |
9006 String& factory_class_name = String::Handle(Symbols::MapImplementation()); | 8995 String& factory_class_name = String::Handle(Symbols::Map()); |
9007 const Class& factory_class = | 8996 const Class& factory_class = |
9008 Class::Handle(LookupCoreClass(factory_class_name)); | 8997 Class::Handle(LookupCoreClass(factory_class_name)); |
9009 ASSERT(!factory_class.IsNull()); | 8998 ASSERT(!factory_class.IsNull()); |
9010 const String& factory_method_name = | 8999 const String& factory_method_name = |
9011 String::Handle(Symbols::MapLiteralFactory()); | 9000 String::Handle(Symbols::MapLiteralFactory()); |
9012 const Function& factory_method = Function::ZoneHandle( | 9001 const Function& factory_method = Function::ZoneHandle( |
9013 factory_class.LookupFactory(factory_method_name)); | 9002 factory_class.LookupFactory(factory_method_name)); |
9014 ASSERT(!factory_method.IsNull()); | 9003 ASSERT(!factory_method.IsNull()); |
9015 if (!map_type_arguments.IsNull() && | 9004 if (!map_type_arguments.IsNull() && |
9016 !map_type_arguments.IsInstantiated() && | 9005 !map_type_arguments.IsInstantiated() && |
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10029 void Parser::SkipQualIdent() { | 10018 void Parser::SkipQualIdent() { |
10030 ASSERT(IsIdentifier()); | 10019 ASSERT(IsIdentifier()); |
10031 ConsumeToken(); | 10020 ConsumeToken(); |
10032 if (CurrentToken() == Token::kPERIOD) { | 10021 if (CurrentToken() == Token::kPERIOD) { |
10033 ConsumeToken(); // Consume the kPERIOD token. | 10022 ConsumeToken(); // Consume the kPERIOD token. |
10034 ExpectIdentifier("identifier expected after '.'"); | 10023 ExpectIdentifier("identifier expected after '.'"); |
10035 } | 10024 } |
10036 } | 10025 } |
10037 | 10026 |
10038 } // namespace dart | 10027 } // namespace dart |
OLD | NEW |