Chromium Code Reviews| 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 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1173 AddFormalParamsToFunction(&func_params, signature_function); | 1173 AddFormalParamsToFunction(&func_params, signature_function); |
| 1174 const String& signature = String::Handle(signature_function.Signature()); | 1174 const String& signature = String::Handle(signature_function.Signature()); |
| 1175 // Lookup the signature class, i.e. the class whose name is the signature. | 1175 // Lookup the signature class, i.e. the class whose name is the signature. |
| 1176 // We only lookup in the current library, but not in its imports, and only | 1176 // We only lookup in the current library, but not in its imports, and only |
| 1177 // create a new canonical signature class if it does not exist yet. | 1177 // create a new canonical signature class if it does not exist yet. |
| 1178 Class& signature_class = Class::ZoneHandle( | 1178 Class& signature_class = Class::ZoneHandle( |
| 1179 library_.LookupLocalClass(signature)); | 1179 library_.LookupLocalClass(signature)); |
| 1180 if (signature_class.IsNull()) { | 1180 if (signature_class.IsNull()) { |
| 1181 signature_class = Class::NewSignatureClass(signature, | 1181 signature_class = Class::NewSignatureClass(signature, |
| 1182 signature_function, | 1182 signature_function, |
| 1183 script_); | 1183 script_, |
| 1184 parameter.name_pos); | |
| 1184 // Record the function signature class in the current library. | 1185 // Record the function signature class in the current library. |
| 1185 library_.AddClass(signature_class); | 1186 library_.AddClass(signature_class); |
| 1186 } else { | 1187 } else { |
| 1187 signature_function.set_signature_class(signature_class); | 1188 signature_function.set_signature_class(signature_class); |
| 1188 } | 1189 } |
| 1189 ASSERT(signature_function.signature_class() == signature_class.raw()); | 1190 ASSERT(signature_function.signature_class() == signature_class.raw()); |
| 1190 Type& signature_type = Type::ZoneHandle(signature_class.SignatureType()); | 1191 Type& signature_type = Type::ZoneHandle(signature_class.SignatureType()); |
| 1191 if (!is_top_level_ && !signature_type.IsFinalized()) { | 1192 if (!is_top_level_ && !signature_type.IsFinalized()) { |
| 1192 signature_type ^= ClassFinalizer::FinalizeType( | 1193 signature_type ^= ClassFinalizer::FinalizeType( |
| 1193 signature_class, signature_type, ClassFinalizer::kCanonicalize); | 1194 signature_class, signature_type, ClassFinalizer::kCanonicalize); |
| (...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2150 } | 2151 } |
| 2151 } | 2152 } |
| 2152 OpenBlock(); // Block to collect constructor body nodes. | 2153 OpenBlock(); // Block to collect constructor body nodes. |
| 2153 | 2154 |
| 2154 // Insert the implicit super call to the super constructor body. | 2155 // Insert the implicit super call to the super constructor body. |
| 2155 if (super_call != NULL) { | 2156 if (super_call != NULL) { |
| 2156 ArgumentListNode* initializer_args = super_call->arguments(); | 2157 ArgumentListNode* initializer_args = super_call->arguments(); |
| 2157 const Function& super_ctor = super_call->function(); | 2158 const Function& super_ctor = super_call->function(); |
| 2158 // Patch the initializer call so it only executes the super initializer. | 2159 // Patch the initializer call so it only executes the super initializer. |
| 2159 initializer_args->SetNodeAt(1, | 2160 initializer_args->SetNodeAt(1, |
| 2160 new LiteralNode(TokenPos(), | 2161 new LiteralNode(TokenPos(), |
| 2161 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); | 2162 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); |
| 2162 | 2163 |
| 2163 ArgumentListNode* super_call_args = new ArgumentListNode(TokenPos()); | 2164 ArgumentListNode* super_call_args = new ArgumentListNode(TokenPos()); |
| 2164 // First argument is the receiver. | 2165 // First argument is the receiver. |
| 2165 super_call_args->Add(new LoadLocalNode(TokenPos(), receiver)); | 2166 super_call_args->Add(new LoadLocalNode(TokenPos(), receiver)); |
| 2166 // Second argument is the construction phase argument. | 2167 // Second argument is the construction phase argument. |
| 2167 AstNode* phase_parameter = | 2168 AstNode* phase_parameter = |
| 2168 new LiteralNode(TokenPos(), | 2169 new LiteralNode(TokenPos(), |
| 2169 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); | 2170 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); |
| 2170 super_call_args->Add(phase_parameter); | 2171 super_call_args->Add(phase_parameter); |
| (...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3119 ConsumeToken(); | 3120 ConsumeToken(); |
| 3120 } | 3121 } |
| 3121 const intptr_t class_pos = TokenPos(); | 3122 const intptr_t class_pos = TokenPos(); |
| 3122 ExpectToken(Token::kCLASS); | 3123 ExpectToken(Token::kCLASS); |
| 3123 const intptr_t classname_pos = TokenPos(); | 3124 const intptr_t classname_pos = TokenPos(); |
| 3124 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 3125 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 3125 if (FLAG_trace_parser) { | 3126 if (FLAG_trace_parser) { |
| 3126 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 3127 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 3127 } | 3128 } |
| 3128 Class& cls = Class::Handle(); | 3129 Class& cls = Class::Handle(); |
| 3130 TypeArguments& orig_type_parameters = TypeArguments::Handle(); | |
| 3129 Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); | 3131 Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); |
| 3130 if (obj.IsNull()) { | 3132 if (obj.IsNull()) { |
| 3131 if (is_patch) { | 3133 if (is_patch) { |
| 3132 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", | 3134 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", |
| 3133 class_name.ToCString()); | 3135 class_name.ToCString()); |
| 3134 } | 3136 } |
| 3135 cls = Class::New(class_name, script_, classname_pos); | 3137 cls = Class::New(class_name, script_, classname_pos); |
| 3136 library_.AddClass(cls); | 3138 library_.AddClass(cls); |
| 3137 } else { | 3139 } else { |
| 3138 if (!obj.IsClass()) { | 3140 if (!obj.IsClass()) { |
| 3139 ErrorMsg(classname_pos, "'%s' is already defined", | 3141 ErrorMsg(classname_pos, "'%s' is already defined", |
| 3140 class_name.ToCString()); | 3142 class_name.ToCString()); |
| 3141 } | 3143 } |
| 3142 cls ^= obj.raw(); | 3144 cls ^= obj.raw(); |
| 3143 if (is_patch) { | 3145 if (is_patch) { |
| 3146 // Preserve and reuse the original type parameters and bounds since the | |
| 3147 // ones defined in the patch class will not be finalized. | |
| 3148 orig_type_parameters = cls.type_parameters(); | |
| 3144 String& patch = String::Handle( | 3149 String& patch = String::Handle( |
| 3145 String::Concat(Symbols::PatchSpace(), class_name)); | 3150 String::Concat(Symbols::PatchSpace(), class_name)); |
| 3146 patch = Symbols::New(patch); | 3151 patch = Symbols::New(patch); |
| 3147 cls = Class::New(patch, script_, classname_pos); | 3152 cls = Class::New(patch, script_, classname_pos); |
| 3148 cls.set_library(library_); | 3153 cls.set_library(library_); |
| 3149 } else { | 3154 } else { |
| 3150 // Not patching a class, but it has been found. This must be one of the | 3155 // Not patching a class, but it has been found. This must be one of the |
| 3151 // pre-registered classes from object.cc or a duplicate definition. | 3156 // pre-registered classes from object.cc or a duplicate definition. |
| 3152 if (cls.functions() != Object::empty_array().raw()) { | 3157 if (cls.functions() != Object::empty_array().raw()) { |
| 3153 ErrorMsg(classname_pos, "class '%s' is already defined", | 3158 ErrorMsg(classname_pos, "class '%s' is already defined", |
| 3154 class_name.ToCString()); | 3159 class_name.ToCString()); |
| 3155 } | 3160 } |
| 3156 // Pre-registered classes need their scripts connected at this time. | 3161 // Pre-registered classes need their scripts connected at this time. |
| 3157 cls.set_script(script_); | 3162 cls.set_script(script_); |
| 3158 } | 3163 } |
| 3159 } | 3164 } |
| 3160 ASSERT(!cls.IsNull()); | 3165 ASSERT(!cls.IsNull()); |
| 3161 ASSERT(cls.functions() == Object::empty_array().raw()); | 3166 ASSERT(cls.functions() == Object::empty_array().raw()); |
| 3162 set_current_class(cls); | 3167 set_current_class(cls); |
| 3163 ParseTypeParameters(cls); | 3168 ParseTypeParameters(cls); |
| 3169 if (is_patch) { | |
| 3170 // Check that the new type parameters are identical to the original ones. | |
| 3171 const TypeArguments& new_type_parameters = | |
| 3172 TypeArguments::Handle(cls.type_parameters()); | |
| 3173 const int new_type_params_count = | |
| 3174 new_type_parameters.IsNull() ? 0 : new_type_parameters.Length(); | |
| 3175 const int orig_type_params_count = | |
| 3176 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); | |
| 3177 if (new_type_params_count != orig_type_params_count) { | |
| 3178 ErrorMsg(classname_pos, | |
| 3179 "class '%s' must be patched with identical type parameters", | |
| 3180 class_name.ToCString()); | |
| 3181 } | |
| 3182 TypeParameter& new_type_param = TypeParameter::Handle(); | |
| 3183 TypeParameter& orig_type_param = TypeParameter::Handle(); | |
| 3184 String& new_name = String::Handle(); | |
| 3185 String& orig_name = String::Handle(); | |
| 3186 for (int i = 0; i < new_type_params_count; i++) { | |
| 3187 new_type_param ^= new_type_parameters.TypeAt(i); | |
| 3188 orig_type_param ^= orig_type_parameters.TypeAt(i); | |
| 3189 new_name = new_type_param.name(); | |
| 3190 orig_name = orig_type_param.name(); | |
| 3191 if (!new_name.Equals(orig_name)) { | |
| 3192 ErrorMsg(new_type_param.token_pos(), | |
| 3193 "type parameter '%s' of patch class '%s' does not match " | |
| 3194 "original type parameter '%s'", | |
| 3195 new_name.ToCString(), | |
| 3196 class_name.ToCString(), | |
| 3197 orig_name.ToCString()); | |
| 3198 } | |
| 3199 // We do not check that the bounds are repeated. We use the original ones. | |
| 3200 // TODO(regis): Should we check? | |
| 3201 } | |
| 3202 cls.set_type_parameters(orig_type_parameters); | |
| 3203 } | |
| 3164 Type& super_type = Type::Handle(); | 3204 Type& super_type = Type::Handle(); |
| 3165 if (CurrentToken() == Token::kEXTENDS) { | 3205 if (CurrentToken() == Token::kEXTENDS) { |
| 3166 ConsumeToken(); | 3206 ConsumeToken(); |
| 3167 const intptr_t type_pos = TokenPos(); | 3207 const intptr_t type_pos = TokenPos(); |
| 3168 const AbstractType& type = AbstractType::Handle( | 3208 const AbstractType& type = AbstractType::Handle( |
| 3169 ParseType(ClassFinalizer::kTryResolve)); | 3209 ParseType(ClassFinalizer::kTryResolve)); |
| 3170 if (type.IsTypeParameter()) { | 3210 if (type.IsTypeParameter()) { |
| 3171 ErrorMsg(type_pos, | 3211 ErrorMsg(type_pos, |
| 3172 "class '%s' may not extend type parameter '%s'", | 3212 "class '%s' may not extend type parameter '%s'", |
| 3173 class_name.ToCString(), | 3213 class_name.ToCString(), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3211 array = Array::MakeArray(members.fields()); | 3251 array = Array::MakeArray(members.fields()); |
| 3212 cls.SetFields(array); | 3252 cls.SetFields(array); |
| 3213 | 3253 |
| 3214 // Creating a new array for functions marks the class as parsed. | 3254 // Creating a new array for functions marks the class as parsed. |
| 3215 array = Array::MakeArray(members.functions()); | 3255 array = Array::MakeArray(members.functions()); |
| 3216 cls.SetFunctions(array); | 3256 cls.SetFunctions(array); |
| 3217 | 3257 |
| 3218 if (!is_patch) { | 3258 if (!is_patch) { |
| 3219 pending_classes.Add(cls, Heap::kOld); | 3259 pending_classes.Add(cls, Heap::kOld); |
| 3220 } else { | 3260 } else { |
| 3221 // Lookup the patched class and apply the changes. | 3261 // Apply the changes to the patched class looked up above. |
| 3222 obj = library_.LookupLocalObject(class_name); | 3262 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); |
| 3263 // The patched class must not be finalized yet. | |
| 3264 ASSERT(!Class::Cast(obj).is_finalized()); | |
| 3223 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); | 3265 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); |
| 3224 if (err_msg != NULL) { | 3266 if (err_msg != NULL) { |
| 3225 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); | 3267 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); |
| 3226 } | 3268 } |
| 3227 } | 3269 } |
| 3228 } | 3270 } |
| 3229 | 3271 |
| 3230 | 3272 |
| 3231 // Add an implicit constructor if no explicit constructor is present. | 3273 // Add an implicit constructor if no explicit constructor is present. |
| 3232 void Parser::AddImplicitConstructor(ClassDesc* class_desc) { | 3274 void Parser::AddImplicitConstructor(ClassDesc* class_desc) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3323 SetPosition(saved_pos); | 3365 SetPosition(saved_pos); |
| 3324 return is_alias_name; | 3366 return is_alias_name; |
| 3325 } | 3367 } |
| 3326 | 3368 |
| 3327 | 3369 |
| 3328 void Parser::ParseFunctionTypeAlias( | 3370 void Parser::ParseFunctionTypeAlias( |
| 3329 const GrowableObjectArray& pending_classes) { | 3371 const GrowableObjectArray& pending_classes) { |
| 3330 TRACE_PARSER("ParseFunctionTypeAlias"); | 3372 TRACE_PARSER("ParseFunctionTypeAlias"); |
| 3331 ExpectToken(Token::kTYPEDEF); | 3373 ExpectToken(Token::kTYPEDEF); |
| 3332 | 3374 |
| 3333 // Allocate an abstract class to hold the type parameters and their bounds. | |
| 3334 // Make it the owner of the function type descriptor. | |
| 3335 const Class& alias_owner = Class::Handle( | |
| 3336 Class::New(Symbols::AliasOwner(), Script::Handle(), TokenPos())); | |
| 3337 | |
| 3338 alias_owner.set_is_abstract(); | |
| 3339 alias_owner.set_library(library_); | |
| 3340 set_current_class(alias_owner); | |
| 3341 | |
| 3342 // Parse the result type of the function type. | 3375 // Parse the result type of the function type. |
| 3343 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 3376 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 3344 if (CurrentToken() == Token::kVOID) { | 3377 if (CurrentToken() == Token::kVOID) { |
| 3345 ConsumeToken(); | 3378 ConsumeToken(); |
| 3346 result_type = Type::VoidType(); | 3379 result_type = Type::VoidType(); |
| 3347 } else if (!IsFunctionTypeAliasName()) { | 3380 } else if (!IsFunctionTypeAliasName()) { |
| 3348 // Type annotations in typedef are never ignored, even in unchecked mode. | 3381 // Type annotations in typedef are never ignored, even in unchecked mode. |
| 3349 // Wait until we have an owner class before resolving the result type. | 3382 // Wait until we have an owner class before resolving the result type. |
| 3350 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 3383 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
| 3351 } | 3384 } |
| 3352 | 3385 |
| 3353 const intptr_t alias_name_pos = TokenPos(); | 3386 const intptr_t alias_name_pos = TokenPos(); |
| 3354 const String* alias_name = | 3387 const String* alias_name = |
| 3355 ExpectUserDefinedTypeIdentifier("function alias name expected"); | 3388 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
| 3356 | 3389 |
| 3390 // Lookup alias name and report an error if it is already defined in | |
| 3391 // the library scope. | |
| 3392 const Object& obj = Object::Handle(library_.LookupLocalObject(*alias_name)); | |
| 3393 if (!obj.IsNull()) { | |
| 3394 ErrorMsg(alias_name_pos, | |
| 3395 "'%s' is already defined", alias_name->ToCString()); | |
| 3396 } | |
| 3397 | |
| 3398 // Create the function type alias signature class. It will be linked to its | |
| 3399 // signature function after it has been parsed. The type parameters, in order | |
| 3400 // to be properly finalized, need to be associated to this signature class as | |
| 3401 // they are parsed. | |
| 3402 Class& function_type_alias = Class::Handle( | |
|
siva
2013/02/01 00:31:57
const Class& function_type......
regis
2013/02/01 02:03:44
Done.
| |
| 3403 Class::NewSignatureClass(*alias_name, | |
| 3404 Function::Handle(), | |
| 3405 script_, | |
| 3406 alias_name_pos)); | |
| 3407 library_.AddClass(function_type_alias); | |
| 3408 set_current_class(function_type_alias); | |
| 3357 // Parse the type parameters of the function type. | 3409 // Parse the type parameters of the function type. |
| 3358 ParseTypeParameters(alias_owner); | 3410 ParseTypeParameters(function_type_alias); |
| 3359 // At this point, the type parameters have been parsed, so we can resolve the | 3411 // At this point, the type parameters have been parsed, so we can resolve the |
| 3360 // result type. | 3412 // result type. |
| 3361 if (!result_type.IsNull()) { | 3413 if (!result_type.IsNull()) { |
| 3362 ResolveTypeFromClass(alias_owner, | 3414 ResolveTypeFromClass(function_type_alias, |
| 3363 ClassFinalizer::kTryResolve, | 3415 ClassFinalizer::kTryResolve, |
| 3364 &result_type); | 3416 &result_type); |
| 3365 } | 3417 } |
| 3366 // Parse the formal parameters of the function type. | 3418 // Parse the formal parameters of the function type. |
| 3367 if (CurrentToken() != Token::kLPAREN) { | 3419 if (CurrentToken() != Token::kLPAREN) { |
| 3368 ErrorMsg("formal parameter list expected"); | 3420 ErrorMsg("formal parameter list expected"); |
| 3369 } | 3421 } |
| 3370 ParamList func_params; | 3422 ParamList func_params; |
| 3371 | 3423 |
| 3372 // Add implicit closure object parameter. | 3424 // Add implicit closure object parameter. |
| 3373 func_params.AddFinalParameter( | 3425 func_params.AddFinalParameter( |
| 3374 TokenPos(), | 3426 TokenPos(), |
| 3375 &Symbols::ClosureParameter(), | 3427 &Symbols::ClosureParameter(), |
| 3376 &Type::ZoneHandle(Type::DynamicType())); | 3428 &Type::ZoneHandle(Type::DynamicType())); |
| 3377 | 3429 |
| 3378 const bool no_explicit_default_values = false; | 3430 const bool no_explicit_default_values = false; |
| 3379 ParseFormalParameterList(no_explicit_default_values, &func_params); | 3431 ParseFormalParameterList(no_explicit_default_values, &func_params); |
| 3432 ExpectSemicolon(); | |
| 3380 // The field 'is_static' has no meaning for signature functions. | 3433 // The field 'is_static' has no meaning for signature functions. |
| 3381 Function& signature_function = Function::Handle( | 3434 Function& signature_function = Function::Handle( |
| 3382 Function::New(*alias_name, | 3435 Function::New(*alias_name, |
| 3383 RawFunction::kSignatureFunction, | 3436 RawFunction::kSignatureFunction, |
| 3384 /* is_static = */ false, | 3437 /* is_static = */ false, |
| 3385 /* is_const = */ false, | 3438 /* is_const = */ false, |
| 3386 /* is_abstract = */ false, | 3439 /* is_abstract = */ false, |
| 3387 /* is_external = */ false, | 3440 /* is_external = */ false, |
| 3388 alias_owner, | 3441 function_type_alias, |
| 3389 alias_name_pos)); | 3442 alias_name_pos)); |
| 3390 signature_function.set_result_type(result_type); | 3443 signature_function.set_result_type(result_type); |
| 3391 AddFormalParamsToFunction(&func_params, signature_function); | 3444 AddFormalParamsToFunction(&func_params, signature_function); |
| 3445 | |
| 3446 // Patch the signature function in the signature class. | |
| 3447 function_type_alias.PatchSignatureFunction(signature_function); | |
| 3448 | |
| 3392 const String& signature = String::Handle(signature_function.Signature()); | 3449 const String& signature = String::Handle(signature_function.Signature()); |
| 3393 if (FLAG_trace_parser) { | 3450 if (FLAG_trace_parser) { |
| 3394 OS::Print("TopLevel parsing function type alias '%s'\n", | 3451 OS::Print("TopLevel parsing function type alias '%s'\n", |
| 3395 signature.ToCString()); | 3452 signature.ToCString()); |
| 3396 } | 3453 } |
| 3397 // Lookup the signature class, i.e. the class whose name is the signature. | 3454 // Lookup the signature class, i.e. the class whose name is the signature. |
| 3398 // We only lookup in the current library, but not in its imports, and only | 3455 // We only lookup in the current library, but not in its imports, and only |
| 3399 // create a new canonical signature class if it does not exist yet. | 3456 // create a new canonical signature class if it does not exist yet. |
| 3400 Class& signature_class = Class::ZoneHandle( | 3457 Class& signature_class = Class::ZoneHandle( |
| 3401 library_.LookupLocalClass(signature)); | 3458 library_.LookupLocalClass(signature)); |
| 3402 if (signature_class.IsNull()) { | 3459 if (signature_class.IsNull()) { |
| 3403 signature_class = Class::NewSignatureClass(signature, | 3460 signature_class = Class::NewSignatureClass(signature, |
| 3404 signature_function, | 3461 signature_function, |
| 3405 script_); | 3462 script_, |
| 3463 alias_name_pos); | |
| 3406 // Record the function signature class in the current library. | 3464 // Record the function signature class in the current library. |
| 3407 library_.AddClass(signature_class); | 3465 library_.AddClass(signature_class); |
| 3408 } else { | 3466 } else { |
| 3409 // Forget the just created signature function and use the existing one. | 3467 // Forget the just created signature function and use the existing one. |
| 3410 signature_function = signature_class.signature_function(); | 3468 signature_function = signature_class.signature_function(); |
| 3469 function_type_alias.PatchSignatureFunction(signature_function); | |
| 3411 } | 3470 } |
| 3412 ASSERT(signature_function.signature_class() == signature_class.raw()); | 3471 ASSERT(signature_function.signature_class() == signature_class.raw()); |
| 3413 | 3472 |
| 3414 // Lookup alias name and report an error if it is already defined in | 3473 // The alias should not be marked as finalized yet, since it needs to be |
| 3415 // the library scope. | |
| 3416 const Object& obj = Object::Handle(library_.LookupLocalObject(*alias_name)); | |
| 3417 if (!obj.IsNull()) { | |
| 3418 ErrorMsg(alias_name_pos, | |
| 3419 "'%s' is already defined", alias_name->ToCString()); | |
| 3420 } | |
| 3421 | |
| 3422 // Create the function type alias, but share the signature function of the | |
| 3423 // canonical signature class. | |
| 3424 Class& function_type_alias = Class::Handle( | |
| 3425 Class::NewSignatureClass(*alias_name, | |
| 3426 signature_function, | |
| 3427 script_)); | |
| 3428 // This alias should not be marked as finalized yet, since it needs to be | |
| 3429 // checked in the class finalizer for illegal self references. | 3474 // checked in the class finalizer for illegal self references. |
| 3430 ASSERT(!function_type_alias.IsCanonicalSignatureClass()); | 3475 ASSERT(!function_type_alias.IsCanonicalSignatureClass()); |
| 3431 ASSERT(!function_type_alias.is_finalized()); | 3476 ASSERT(!function_type_alias.is_finalized()); |
| 3432 library_.AddClass(function_type_alias); | |
| 3433 ExpectSemicolon(); | |
| 3434 pending_classes.Add(function_type_alias, Heap::kOld); | 3477 pending_classes.Add(function_type_alias, Heap::kOld); |
| 3435 } | 3478 } |
| 3436 | 3479 |
| 3437 | 3480 |
| 3438 // Consumes exactly one right angle bracket. If the current token is a single | 3481 // Consumes exactly one right angle bracket. If the current token is a single |
| 3439 // bracket token, it is consumed normally. However, if it is a double or triple | 3482 // bracket token, it is consumed normally. However, if it is a double or triple |
| 3440 // bracket, it is replaced by a single or double bracket token without | 3483 // bracket, it is replaced by a single or double bracket token without |
| 3441 // incrementing the token index. | 3484 // incrementing the token index. |
| 3442 void Parser::ConsumeRightAngleBracket() { | 3485 void Parser::ConsumeRightAngleBracket() { |
| 3443 if (token_kind_ == Token::kGT) { | 3486 if (token_kind_ == Token::kGT) { |
| (...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4361 ParsePartHeader(); | 4404 ParsePartHeader(); |
| 4362 } | 4405 } |
| 4363 | 4406 |
| 4364 while (true) { | 4407 while (true) { |
| 4365 set_current_class(Class::Handle()); // No current class. | 4408 set_current_class(Class::Handle()); // No current class. |
| 4366 SkipMetadata(); | 4409 SkipMetadata(); |
| 4367 if (CurrentToken() == Token::kCLASS) { | 4410 if (CurrentToken() == Token::kCLASS) { |
| 4368 ParseClassDefinition(pending_classes); | 4411 ParseClassDefinition(pending_classes); |
| 4369 } else if ((CurrentToken() == Token::kTYPEDEF) && | 4412 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 4370 (LookaheadToken(1) != Token::kLPAREN)) { | 4413 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4414 set_current_class(toplevel_class); | |
| 4371 ParseFunctionTypeAlias(pending_classes); | 4415 ParseFunctionTypeAlias(pending_classes); |
| 4372 } else if ((CurrentToken() == Token::kABSTRACT) && | 4416 } else if ((CurrentToken() == Token::kABSTRACT) && |
| 4373 (LookaheadToken(1) == Token::kCLASS)) { | 4417 (LookaheadToken(1) == Token::kCLASS)) { |
| 4374 ParseClassDefinition(pending_classes); | 4418 ParseClassDefinition(pending_classes); |
| 4375 } else if (is_patch_source() && IsLiteral("patch") && | 4419 } else if (is_patch_source() && IsLiteral("patch") && |
| 4376 (LookaheadToken(1) == Token::kCLASS)) { | 4420 (LookaheadToken(1) == Token::kCLASS)) { |
| 4377 ParseClassDefinition(pending_classes); | 4421 ParseClassDefinition(pending_classes); |
| 4378 } else { | 4422 } else { |
| 4379 set_current_class(toplevel_class); | 4423 set_current_class(toplevel_class); |
| 4380 if (IsVariableDeclaration()) { | 4424 if (IsVariableDeclaration()) { |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4852 } | 4896 } |
| 4853 if (signature_class.IsNull()) { | 4897 if (signature_class.IsNull()) { |
| 4854 signature_class = library_.LookupLocalClass(signature); | 4898 signature_class = library_.LookupLocalClass(signature); |
| 4855 } | 4899 } |
| 4856 if (signature_class.IsNull()) { | 4900 if (signature_class.IsNull()) { |
| 4857 // If we don't have a signature class yet, this must be a closure we | 4901 // If we don't have a signature class yet, this must be a closure we |
| 4858 // have not parsed before. | 4902 // have not parsed before. |
| 4859 ASSERT(is_new_closure); | 4903 ASSERT(is_new_closure); |
| 4860 signature_class = Class::NewSignatureClass(signature, | 4904 signature_class = Class::NewSignatureClass(signature, |
| 4861 function, | 4905 function, |
| 4862 script_); | 4906 script_, |
| 4907 function.token_pos()); | |
| 4863 // Record the function signature class in the current library. | 4908 // Record the function signature class in the current library. |
| 4864 library_.AddClass(signature_class); | 4909 library_.AddClass(signature_class); |
| 4865 } else if (is_new_closure) { | 4910 } else if (is_new_closure) { |
| 4866 function.set_signature_class(signature_class); | 4911 function.set_signature_class(signature_class); |
| 4867 } | 4912 } |
| 4868 ASSERT(function.signature_class() == signature_class.raw()); | 4913 ASSERT(function.signature_class() == signature_class.raw()); |
| 4869 | 4914 |
| 4870 // Local functions are registered in the enclosing class, but | 4915 // Local functions are registered in the enclosing class, but |
| 4871 // ignored during class finalization. The enclosing class has | 4916 // ignored during class finalization. The enclosing class has |
| 4872 // already been finalized. | 4917 // already been finalized. |
| (...skipping 2940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7813 } | 7858 } |
| 7814 | 7859 |
| 7815 | 7860 |
| 7816 const Type* Parser::ReceiverType(intptr_t type_pos) const { | 7861 const Type* Parser::ReceiverType(intptr_t type_pos) const { |
| 7817 ASSERT(!current_class().IsNull()); | 7862 ASSERT(!current_class().IsNull()); |
| 7818 TypeArguments& type_arguments = TypeArguments::Handle(); | 7863 TypeArguments& type_arguments = TypeArguments::Handle(); |
| 7819 if (current_class().NumTypeParameters() > 0) { | 7864 if (current_class().NumTypeParameters() > 0) { |
| 7820 type_arguments = current_class().type_parameters(); | 7865 type_arguments = current_class().type_parameters(); |
| 7821 } | 7866 } |
| 7822 Type& type = Type::ZoneHandle( | 7867 Type& type = Type::ZoneHandle( |
| 7823 Type::New(current_class(), type_arguments, type_pos)); | 7868 Type::New(current_class(), type_arguments, type_pos)); |
| 7824 if (!is_top_level_) { | 7869 if (!is_top_level_) { |
| 7825 type ^= ClassFinalizer::FinalizeType( | 7870 type ^= ClassFinalizer::FinalizeType( |
| 7826 current_class(), type, ClassFinalizer::kCanonicalizeWellFormed); | 7871 current_class(), type, ClassFinalizer::kCanonicalizeWellFormed); |
| 7827 } | 7872 } |
| 7828 return &type; | 7873 return &type; |
| 7829 } | 7874 } |
| 7830 | 7875 |
| 7831 | 7876 |
| 7832 bool Parser::IsInstantiatorRequired() const { | 7877 bool Parser::IsInstantiatorRequired() const { |
| 7833 ASSERT(!current_function().IsNull()); | 7878 ASSERT(!current_function().IsNull()); |
| (...skipping 1866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9700 void Parser::SkipQualIdent() { | 9745 void Parser::SkipQualIdent() { |
| 9701 ASSERT(IsIdentifier()); | 9746 ASSERT(IsIdentifier()); |
| 9702 ConsumeToken(); | 9747 ConsumeToken(); |
| 9703 if (CurrentToken() == Token::kPERIOD) { | 9748 if (CurrentToken() == Token::kPERIOD) { |
| 9704 ConsumeToken(); // Consume the kPERIOD token. | 9749 ConsumeToken(); // Consume the kPERIOD token. |
| 9705 ExpectIdentifier("identifier expected after '.'"); | 9750 ExpectIdentifier("identifier expected after '.'"); |
| 9706 } | 9751 } |
| 9707 } | 9752 } |
| 9708 | 9753 |
| 9709 } // namespace dart | 9754 } // namespace dart |
| OLD | NEW |