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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
7 | 7 |
8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 26 matching lines...) Expand all Loading... | |
37 #include "vm/symbols.h" | 37 #include "vm/symbols.h" |
38 #include "vm/tags.h" | 38 #include "vm/tags.h" |
39 #include "vm/timeline.h" | 39 #include "vm/timeline.h" |
40 #include "vm/timer.h" | 40 #include "vm/timer.h" |
41 #include "vm/zone.h" | 41 #include "vm/zone.h" |
42 | 42 |
43 namespace dart { | 43 namespace dart { |
44 | 44 |
45 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); | 45 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); |
46 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 46 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
47 DEFINE_FLAG(bool, warn_new_tearoff_syntax, true, "Warning on new tear off."); | 47 DEFINE_FLAG(bool, |
48 support_new_tearoff_syntax, | |
49 false, | |
50 "Support new tear off syntax."); | |
48 // TODO(floitsch): remove the conditional-directive flag, once we publicly | 51 // TODO(floitsch): remove the conditional-directive flag, once we publicly |
49 // committed to the current version. | 52 // committed to the current version. |
50 DEFINE_FLAG(bool, | 53 DEFINE_FLAG(bool, |
51 conditional_directives, | 54 conditional_directives, |
52 true, | 55 true, |
53 "Enable conditional directives"); | 56 "Enable conditional directives"); |
54 DEFINE_FLAG(bool, generic_method_syntax, true, "Enable generic functions."); | 57 DEFINE_FLAG(bool, generic_method_syntax, true, "Enable generic functions."); |
55 DEFINE_FLAG(bool, | 58 DEFINE_FLAG(bool, |
56 initializing_formal_access, | 59 initializing_formal_access, |
57 true, | 60 true, |
(...skipping 11639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11697 return left; | 11700 return left; |
11698 } | 11701 } |
11699 ASSERT(selector != NULL); | 11702 ASSERT(selector != NULL); |
11700 left = selector; | 11703 left = selector; |
11701 } | 11704 } |
11702 } | 11705 } |
11703 | 11706 |
11704 | 11707 |
11705 // Closurization e#m of getter, setter, method or operator. | 11708 // Closurization e#m of getter, setter, method or operator. |
11706 AstNode* Parser::ParseClosurization(AstNode* primary) { | 11709 AstNode* Parser::ParseClosurization(AstNode* primary) { |
11707 if (FLAG_warn_new_tearoff_syntax) { | 11710 if (!FLAG_support_new_tearoff_syntax) { |
11708 ReportWarning( | 11711 ReportError("Tear-offs using the x#id syntax is a deprecated feature"); |
regis
2016/12/29 18:24:07
I have not followed the discussions about this tea
siva
2016/12/29 20:59:56
Good point, I renamed the flag to --deprecated_tea
| |
11709 "Tear-offs using the x#id syntax is a deprecated feature," | 11712 return NULL; |
11710 "it will not be supported in the next release"); | 11713 } else { |
regis
2016/12/29 18:24:07
I would not use an else here and leave the rest of
siva
2016/12/29 20:59:56
Done.
| |
11711 } | 11714 ExpectToken(Token::kHASH); |
11712 ExpectToken(Token::kHASH); | 11715 TokenPosition property_pos = TokenPos(); |
11713 TokenPosition property_pos = TokenPos(); | 11716 bool is_setter_name = false; |
11714 bool is_setter_name = false; | |
11715 | 11717 |
11716 String& extractor_name = String::ZoneHandle(Z); | 11718 String& extractor_name = String::ZoneHandle(Z); |
11717 if (IsIdentifier()) { | 11719 if (IsIdentifier()) { |
11718 extractor_name = CurrentLiteral()->raw(); | 11720 extractor_name = CurrentLiteral()->raw(); |
11719 ConsumeToken(); | |
11720 if (CurrentToken() == Token::kASSIGN) { | |
11721 ConsumeToken(); | 11721 ConsumeToken(); |
11722 is_setter_name = true; | 11722 if (CurrentToken() == Token::kASSIGN) { |
11723 } | 11723 ConsumeToken(); |
11724 } else if (Token::CanBeOverloaded(CurrentToken())) { | 11724 is_setter_name = true; |
11725 extractor_name = Symbols::Token(CurrentToken()).raw(); | |
11726 ConsumeToken(); | |
11727 } else { | |
11728 ReportError("identifier or operator expected"); | |
11729 } | |
11730 | |
11731 if (primary->IsPrimaryNode() && primary->AsPrimaryNode()->IsSuper()) { | |
11732 // TODO(hausner): implement super#m | |
11733 ReportError("closurization of super method not yet supported"); | |
11734 } | |
11735 | |
11736 // Handle closurization of top-level names from library prefixes, P#m | |
11737 if (primary->IsLiteralNode() && | |
11738 primary->AsLiteralNode()->literal().IsLibraryPrefix()) { | |
11739 const LibraryPrefix& prefix = | |
11740 LibraryPrefix::Cast(primary->AsLiteralNode()->literal()); | |
11741 Object& obj = Object::Handle(Z); | |
11742 const bool is_private_name = | |
11743 (extractor_name.CharAt(0) == Library::kPrivateIdentifierStart); | |
11744 if (!is_private_name) { | |
11745 // Private names are not exported by libraries. The name mangling | |
11746 // of private names with a library-specific suffix usually ensures | |
11747 // that _x in library A is not found when looked up from library B. | |
11748 // In the pathological case where a library imports itself with | |
11749 // a prefix, the name mangling does not help in hiding the private | |
11750 // name, so we explicitly prevent lookup of private names here. | |
11751 if (is_setter_name) { | |
11752 String& setter_name = | |
11753 String::Handle(Z, Field::SetterName(extractor_name)); | |
11754 obj = prefix.LookupObject(setter_name); | |
11755 } | 11725 } |
11756 if (obj.IsNull()) { | 11726 } else if (Token::CanBeOverloaded(CurrentToken())) { |
11757 obj = prefix.LookupObject(extractor_name); | 11727 extractor_name = Symbols::Token(CurrentToken()).raw(); |
11758 } | 11728 ConsumeToken(); |
11759 } | 11729 } else { |
11760 if (!prefix.is_loaded() && (parsed_function() != NULL) && | 11730 ReportError("identifier or operator expected"); |
11761 !FLAG_load_deferred_eagerly) { | |
11762 // Remember that this function depends on an import prefix of an | |
11763 // unloaded deferred library. | |
11764 parsed_function()->AddDeferredPrefix(prefix); | |
11765 } | 11731 } |
11766 | 11732 |
11767 if (obj.IsFunction()) { | 11733 if (primary->IsPrimaryNode() && primary->AsPrimaryNode()->IsSuper()) { |
11768 const Function& func = Function::Cast(obj); | 11734 // TODO(hausner): implement super#m |
11769 if (!func.IsSetterFunction() || is_setter_name) { | 11735 ReportError("closurization of super method not yet supported"); |
11770 return CreateImplicitClosureNode(func, property_pos, NULL); | 11736 } |
11737 | |
11738 // Handle closurization of top-level names from library prefixes, P#m | |
11739 if (primary->IsLiteralNode() && | |
11740 primary->AsLiteralNode()->literal().IsLibraryPrefix()) { | |
11741 const LibraryPrefix& prefix = | |
11742 LibraryPrefix::Cast(primary->AsLiteralNode()->literal()); | |
11743 Object& obj = Object::Handle(Z); | |
11744 const bool is_private_name = | |
11745 (extractor_name.CharAt(0) == Library::kPrivateIdentifierStart); | |
11746 if (!is_private_name) { | |
11747 // Private names are not exported by libraries. The name mangling | |
11748 // of private names with a library-specific suffix usually ensures | |
11749 // that _x in library A is not found when looked up from library B. | |
11750 // In the pathological case where a library imports itself with | |
11751 // a prefix, the name mangling does not help in hiding the private | |
11752 // name, so we explicitly prevent lookup of private names here. | |
11753 if (is_setter_name) { | |
11754 String& setter_name = | |
11755 String::Handle(Z, Field::SetterName(extractor_name)); | |
11756 obj = prefix.LookupObject(setter_name); | |
11757 } | |
11758 if (obj.IsNull()) { | |
11759 obj = prefix.LookupObject(extractor_name); | |
11760 } | |
11771 } | 11761 } |
11772 } else if (obj.IsField()) { | 11762 if (!prefix.is_loaded() && (parsed_function() != NULL) && |
11773 const Field& field = Field::Cast(obj); | 11763 !FLAG_load_deferred_eagerly) { |
11774 if (is_setter_name && !field.is_final()) { | 11764 // Remember that this function depends on an import prefix of an |
11775 Instance& setter_closure = Instance::ZoneHandle(field.SetterClosure()); | 11765 // unloaded deferred library. |
11776 return new (Z) LiteralNode(property_pos, setter_closure); | 11766 parsed_function()->AddDeferredPrefix(prefix); |
11777 } | 11767 } |
11778 if (!is_setter_name) { | |
11779 Instance& getter_closure = Instance::ZoneHandle(field.GetterClosure()); | |
11780 return new (Z) LiteralNode(property_pos, getter_closure); | |
11781 } | |
11782 } | |
11783 return ThrowNoSuchMethodError( | |
11784 property_pos, current_class(), extractor_name, | |
11785 NULL, // No arguments. | |
11786 InvocationMirror::kTopLevel, | |
11787 is_setter_name ? InvocationMirror::kSetter : InvocationMirror::kMethod, | |
11788 NULL); // No existing function. | |
11789 } | |
11790 | 11768 |
11791 // Handle closurization of static properties of classes, C#n. | 11769 if (obj.IsFunction()) { |
11792 if (primary->IsPrimaryNode() && | 11770 const Function& func = Function::Cast(obj); |
11793 primary->AsPrimaryNode()->primary().IsClass()) { | 11771 if (!func.IsSetterFunction() || is_setter_name) { |
11794 const Class& cls = Class::Cast(primary->AsPrimaryNode()->primary()); | 11772 return CreateImplicitClosureNode(func, property_pos, NULL); |
11795 const Field& field = | 11773 } |
11796 Field::Handle(Z, cls.LookupStaticField(extractor_name)); | 11774 } else if (obj.IsField()) { |
11797 if (!field.IsNull()) { | 11775 const Field& field = Field::Cast(obj); |
11798 if (is_setter_name) { | 11776 if (is_setter_name && !field.is_final()) { |
11799 extractor_name = Field::SetterName(extractor_name); | |
11800 if (!field.is_final()) { | |
11801 const Instance& setter_closure = | 11777 const Instance& setter_closure = |
11802 Instance::ZoneHandle(Z, field.SetterClosure()); | 11778 Instance::ZoneHandle(field.SetterClosure()); |
11803 ASSERT(setter_closure.IsClosure()); | |
11804 // Note: the created closure is cached after it's created | |
11805 // once. If eager compilation is desired, the compiler can | |
11806 // be invoked here. The same applies for getters below. | |
11807 return new (Z) LiteralNode(property_pos, setter_closure); | 11779 return new (Z) LiteralNode(property_pos, setter_closure); |
11808 } | 11780 } |
11809 } else { | 11781 if (!is_setter_name) { |
11810 const Instance& getter_closure = | 11782 const Instance& getter_closure = |
11811 Instance::ZoneHandle(Z, field.GetterClosure()); | 11783 Instance::ZoneHandle(field.GetterClosure()); |
11812 ASSERT(getter_closure.IsClosure()); | 11784 return new (Z) LiteralNode(property_pos, getter_closure); |
11813 return new (Z) LiteralNode(property_pos, getter_closure); | |
11814 } | |
11815 } else { | |
11816 Function& func = Function::Handle(Z); | |
11817 if (is_setter_name) { | |
11818 extractor_name = Field::SetterName(extractor_name); | |
11819 func = cls.LookupStaticFunction(extractor_name); | |
11820 } else { | |
11821 func = cls.LookupStaticFunction(extractor_name); | |
11822 if (func.IsNull()) { | |
11823 const String& getter_name = | |
11824 String::Handle(Z, Field::GetterName(extractor_name)); | |
11825 func = cls.LookupStaticFunction(getter_name); | |
11826 } | 11785 } |
11827 } | 11786 } |
11828 if (!func.IsNull()) { | 11787 return ThrowNoSuchMethodError(property_pos, current_class(), |
11829 return CreateImplicitClosureNode(func, property_pos, NULL); | 11788 extractor_name, |
11789 NULL, // No arguments. | |
11790 InvocationMirror::kTopLevel, | |
11791 is_setter_name ? InvocationMirror::kSetter | |
11792 : InvocationMirror::kMethod, | |
11793 NULL); // No existing function. | |
11794 } | |
11795 | |
11796 // Handle closurization of static properties of classes, C#n. | |
11797 if (primary->IsPrimaryNode() && | |
11798 primary->AsPrimaryNode()->primary().IsClass()) { | |
11799 const Class& cls = Class::Cast(primary->AsPrimaryNode()->primary()); | |
11800 const Field& field = | |
11801 Field::Handle(Z, cls.LookupStaticField(extractor_name)); | |
11802 if (!field.IsNull()) { | |
11803 if (is_setter_name) { | |
11804 extractor_name = Field::SetterName(extractor_name); | |
11805 if (!field.is_final()) { | |
11806 const Instance& setter_closure = | |
11807 Instance::ZoneHandle(Z, field.SetterClosure()); | |
11808 ASSERT(setter_closure.IsClosure()); | |
11809 // Note: the created closure is cached after it's created | |
11810 // once. If eager compilation is desired, the compiler can | |
11811 // be invoked here. The same applies for getters below. | |
11812 return new (Z) LiteralNode(property_pos, setter_closure); | |
11813 } | |
11814 } else { | |
11815 const Instance& getter_closure = | |
11816 Instance::ZoneHandle(Z, field.GetterClosure()); | |
11817 ASSERT(getter_closure.IsClosure()); | |
11818 return new (Z) LiteralNode(property_pos, getter_closure); | |
11819 } | |
11820 } else { | |
11821 Function& func = Function::Handle(Z); | |
11822 if (is_setter_name) { | |
11823 extractor_name = Field::SetterName(extractor_name); | |
11824 func = cls.LookupStaticFunction(extractor_name); | |
11825 } else { | |
11826 func = cls.LookupStaticFunction(extractor_name); | |
11827 if (func.IsNull()) { | |
11828 const String& getter_name = | |
11829 String::Handle(Z, Field::GetterName(extractor_name)); | |
11830 func = cls.LookupStaticFunction(getter_name); | |
11831 } | |
11832 } | |
11833 if (!func.IsNull()) { | |
11834 return CreateImplicitClosureNode(func, property_pos, NULL); | |
11835 } | |
11830 } | 11836 } |
11837 return ThrowNoSuchMethodError(property_pos, cls, extractor_name, | |
11838 NULL, // No arguments. | |
11839 InvocationMirror::kStatic, | |
11840 is_setter_name ? InvocationMirror::kSetter | |
11841 : InvocationMirror::kMethod, | |
11842 NULL); // No existing function. | |
11831 } | 11843 } |
11832 return ThrowNoSuchMethodError( | 11844 |
11833 property_pos, cls, extractor_name, | 11845 // Closurization of instance getter, setter, method or operator. |
11834 NULL, // No arguments. | 11846 GrowableHandlePtrArray<const String> pieces(Z, 3); |
11835 InvocationMirror::kStatic, | 11847 pieces.Add(Symbols::HashMark()); |
11836 is_setter_name ? InvocationMirror::kSetter : InvocationMirror::kMethod, | 11848 if (is_setter_name) { |
11837 NULL); // No existing function. | 11849 pieces.Add(Symbols::SetterPrefix()); |
11850 } | |
11851 pieces.Add(extractor_name); | |
11852 extractor_name = Symbols::FromConcatAll(T, pieces); | |
11853 return new (Z) InstanceGetterNode(property_pos, primary, extractor_name); | |
11838 } | 11854 } |
11839 | |
11840 // Closurization of instance getter, setter, method or operator. | |
11841 GrowableHandlePtrArray<const String> pieces(Z, 3); | |
11842 pieces.Add(Symbols::HashMark()); | |
11843 if (is_setter_name) { | |
11844 pieces.Add(Symbols::SetterPrefix()); | |
11845 } | |
11846 pieces.Add(extractor_name); | |
11847 extractor_name = Symbols::FromConcatAll(T, pieces); | |
11848 return new (Z) InstanceGetterNode(property_pos, primary, extractor_name); | |
11849 } | 11855 } |
11850 | 11856 |
11851 | 11857 |
11852 AstNode* Parser::ParsePostfixExpr() { | 11858 AstNode* Parser::ParsePostfixExpr() { |
11853 TRACE_PARSER("ParsePostfixExpr"); | 11859 TRACE_PARSER("ParsePostfixExpr"); |
11854 String* expr_ident = | 11860 String* expr_ident = |
11855 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11861 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
11856 const TokenPosition expr_pos = TokenPos(); | 11862 const TokenPosition expr_pos = TokenPos(); |
11857 AstNode* expr = ParsePrimary(); | 11863 AstNode* expr = ParsePrimary(); |
11858 if (CurrentToken() == Token::kHASH) { | 11864 if (CurrentToken() == Token::kHASH) { |
(...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13341 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); | 13347 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); |
13342 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); | 13348 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); |
13343 AbstractType& type = | 13349 AbstractType& type = |
13344 AbstractType::Handle(Z, ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 13350 AbstractType::Handle(Z, ParseType(ClassFinalizer::kCanonicalizeWellFormed, |
13345 true, // allow deferred type | 13351 true, // allow deferred type |
13346 consume_unresolved_prefix, &prefix)); | 13352 consume_unresolved_prefix, &prefix)); |
13347 // A constructor tear-off closure can only have been created for a | 13353 // A constructor tear-off closure can only have been created for a |
13348 // type that is loaded. | 13354 // type that is loaded. |
13349 ASSERT(prefix.IsNull() || prefix.is_loaded()); | 13355 ASSERT(prefix.IsNull() || prefix.is_loaded()); |
13350 ASSERT(!type.IsMalformed() && !type.IsTypeParameter()); | 13356 ASSERT(!type.IsMalformed() && !type.IsTypeParameter()); |
13351 if (FLAG_warn_new_tearoff_syntax) { | 13357 if (!FLAG_support_new_tearoff_syntax) { |
13352 ReportWarning( | 13358 ReportError("Tear-offs using the x#id syntax is a deprecated feature"); |
13353 "Tear-offs using the x#id syntax is a deprecated feature," | 13359 } else { |
regis
2016/12/29 18:24:07
ditto
siva
2016/12/29 20:59:56
Done.
| |
13354 "it will not be supported in the next release"); | 13360 ExpectToken(Token::kHASH); |
13355 } | 13361 String* named_constructor = NULL; |
13356 ExpectToken(Token::kHASH); | 13362 if (IsIdentifier()) { |
13357 String* named_constructor = NULL; | 13363 named_constructor = CurrentLiteral(); |
13358 if (IsIdentifier()) { | 13364 ConsumeToken(); |
13359 named_constructor = CurrentLiteral(); | 13365 } |
13360 ConsumeToken(); | 13366 // Resolve the type and optional identifier to a constructor or factory. |
13361 } | 13367 Class& type_class = Class::Handle(Z, type.type_class()); |
13362 // Resolve the type and optional identifier to a constructor or factory. | 13368 String& type_class_name = String::Handle(Z, type_class.Name()); |
13363 Class& type_class = Class::Handle(Z, type.type_class()); | 13369 *type_arguments = type.arguments(); |
13364 String& type_class_name = String::Handle(Z, type_class.Name()); | 13370 String& constructor_name = |
13365 *type_arguments = type.arguments(); | 13371 BuildConstructorName(T, type_class_name, named_constructor); |
13366 String& constructor_name = | 13372 *constructor = type_class.LookupConstructor(constructor_name); |
13367 BuildConstructorName(T, type_class_name, named_constructor); | 13373 if (constructor->IsNull()) { |
13368 *constructor = type_class.LookupConstructor(constructor_name); | 13374 *constructor = type_class.LookupFactory(constructor_name); |
13369 if (constructor->IsNull()) { | 13375 ASSERT(!constructor->IsNull()); |
13370 *constructor = type_class.LookupFactory(constructor_name); | 13376 if (constructor->IsRedirectingFactory()) { |
13371 ASSERT(!constructor->IsNull()); | 13377 ClassFinalizer::ResolveRedirectingFactory(type_class, *constructor); |
13372 if (constructor->IsRedirectingFactory()) { | 13378 type = constructor->RedirectionType(); |
13373 ClassFinalizer::ResolveRedirectingFactory(type_class, *constructor); | 13379 ASSERT(!type.IsMalformedOrMalbounded()); |
13374 type = constructor->RedirectionType(); | 13380 if (!type.IsInstantiated()) { |
13375 ASSERT(!type.IsMalformedOrMalbounded()); | 13381 Error& error = Error::Handle(Z); |
13376 if (!type.IsInstantiated()) { | 13382 type ^= type.InstantiateFrom(*type_arguments, &error, |
13377 Error& error = Error::Handle(Z); | 13383 NULL, // instantiation_trail |
13378 type ^= type.InstantiateFrom(*type_arguments, &error, | 13384 NULL, // bound_trail |
13379 NULL, // instantiation_trail | 13385 Heap::kOld); |
13380 NULL, // bound_trail | 13386 ASSERT(error.IsNull()); |
13381 Heap::kOld); | 13387 } |
13382 ASSERT(error.IsNull()); | 13388 *type_arguments = type.arguments(); |
13389 *constructor = constructor->RedirectionTarget(); | |
13383 } | 13390 } |
13384 *type_arguments = type.arguments(); | |
13385 *constructor = constructor->RedirectionTarget(); | |
13386 } | 13391 } |
13387 } | 13392 } |
13388 } | 13393 } |
13389 | 13394 |
13390 | 13395 |
13391 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 13396 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
13392 TRACE_PARSER("ParseNewOperator"); | 13397 TRACE_PARSER("ParseNewOperator"); |
13393 const TokenPosition new_pos = TokenPos(); | 13398 const TokenPosition new_pos = TokenPos(); |
13394 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 13399 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
13395 bool is_const = (op_kind == Token::kCONST); | 13400 bool is_const = (op_kind == Token::kCONST); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13444 // The type can be followed by an optional named constructor identifier. | 13449 // The type can be followed by an optional named constructor identifier. |
13445 // Note that we tell ParseType() above not to consume it as part of | 13450 // Note that we tell ParseType() above not to consume it as part of |
13446 // a misinterpreted qualified identifier. Only a valid library | 13451 // a misinterpreted qualified identifier. Only a valid library |
13447 // prefix is accepted as qualifier. | 13452 // prefix is accepted as qualifier. |
13448 String* named_constructor = NULL; | 13453 String* named_constructor = NULL; |
13449 const bool is_tearoff_expression = (CurrentToken() == Token::kHASH); | 13454 const bool is_tearoff_expression = (CurrentToken() == Token::kHASH); |
13450 if (is_tearoff_expression) { | 13455 if (is_tearoff_expression) { |
13451 if (is_const) { | 13456 if (is_const) { |
13452 ReportError("tear-off closure not allowed with const allocation"); | 13457 ReportError("tear-off closure not allowed with const allocation"); |
13453 } | 13458 } |
13454 if (FLAG_warn_new_tearoff_syntax) { | 13459 if (!FLAG_support_new_tearoff_syntax) { |
13455 ReportWarning( | 13460 ReportError("Tear-offs using the x#id syntax is a deprecated feature"); |
13456 "Tear-offs using the x#id syntax is a deprecated feature," | 13461 } else { |
regis
2016/12/29 18:24:07
ditto
siva
2016/12/29 20:59:56
Done.
| |
13457 "and will not be supported in the next release"); | 13462 ConsumeToken(); |
13458 } | 13463 if (IsIdentifier()) { |
13459 ConsumeToken(); | 13464 named_constructor = ExpectIdentifier("name of constructor expected"); |
13460 if (IsIdentifier()) { | 13465 } |
13461 named_constructor = ExpectIdentifier("name of constructor expected"); | |
13462 } | 13466 } |
13463 } else if (CurrentToken() == Token::kPERIOD) { | 13467 } else if (CurrentToken() == Token::kPERIOD) { |
13464 ConsumeToken(); | 13468 ConsumeToken(); |
13465 named_constructor = ExpectIdentifier("name of constructor expected"); | 13469 named_constructor = ExpectIdentifier("name of constructor expected"); |
13466 } | 13470 } |
13467 | 13471 |
13468 // Parse constructor parameters. | 13472 // Parse constructor parameters. |
13469 TokenPosition call_pos = TokenPos(); | 13473 TokenPosition call_pos = TokenPos(); |
13470 ArgumentListNode* arguments = NULL; | 13474 ArgumentListNode* arguments = NULL; |
13471 if (!is_tearoff_expression) { | 13475 if (!is_tearoff_expression) { |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13886 ASSERT(!is_top_level_); | 13890 ASSERT(!is_top_level_); |
13887 AstNode* primary = NULL; | 13891 AstNode* primary = NULL; |
13888 const Token::Kind token = CurrentToken(); | 13892 const Token::Kind token = CurrentToken(); |
13889 if (IsFunctionLiteral()) { | 13893 if (IsFunctionLiteral()) { |
13890 primary = ParseFunctionStatement(true); | 13894 primary = ParseFunctionStatement(true); |
13891 } else if (IsIdentifier()) { | 13895 } else if (IsIdentifier()) { |
13892 TokenPosition qual_ident_pos = TokenPos(); | 13896 TokenPosition qual_ident_pos = TokenPos(); |
13893 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 13897 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
13894 if (!prefix.IsNull()) { | 13898 if (!prefix.IsNull()) { |
13895 if (CurrentToken() == Token::kHASH) { | 13899 if (CurrentToken() == Token::kHASH) { |
13896 if (FLAG_warn_new_tearoff_syntax) { | 13900 if (!FLAG_support_new_tearoff_syntax) { |
13897 ReportWarning( | 13901 ReportError( |
13898 "Tear-offs using the x#id syntax is a deprecated feature," | 13902 "Tear-offs using the x#id syntax " |
13899 "it will not be supported in the next release"); | 13903 "is a deprecated feature"); |
13904 } else { | |
regis
2016/12/29 18:24:07
ditto
siva
2016/12/29 20:59:56
Done.
| |
13905 // Closurization of top-level entity in prefix scope. | |
13906 return new (Z) LiteralNode(qual_ident_pos, prefix); | |
13900 } | 13907 } |
13901 // Closurization of top-level entity in prefix scope. | |
13902 return new (Z) LiteralNode(qual_ident_pos, prefix); | |
13903 } else { | 13908 } else { |
13904 ExpectToken(Token::kPERIOD); | 13909 ExpectToken(Token::kPERIOD); |
13905 } | 13910 } |
13906 } | 13911 } |
13907 String& ident = *CurrentLiteral(); | 13912 String& ident = *CurrentLiteral(); |
13908 ConsumeToken(); | 13913 ConsumeToken(); |
13909 if (prefix.IsNull()) { | 13914 if (prefix.IsNull()) { |
13910 intptr_t primary_func_level = 0; | 13915 intptr_t primary_func_level = 0; |
13911 ResolveIdentInLocalScope(qual_ident_pos, ident, &primary, | 13916 ResolveIdentInLocalScope(qual_ident_pos, ident, &primary, |
13912 &primary_func_level); | 13917 &primary_func_level); |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14594 const ArgumentListNode& function_args, | 14599 const ArgumentListNode& function_args, |
14595 const LocalVariable* temp_for_last_arg, | 14600 const LocalVariable* temp_for_last_arg, |
14596 bool is_super_invocation) { | 14601 bool is_super_invocation) { |
14597 UNREACHABLE(); | 14602 UNREACHABLE(); |
14598 return NULL; | 14603 return NULL; |
14599 } | 14604 } |
14600 | 14605 |
14601 } // namespace dart | 14606 } // namespace dart |
14602 | 14607 |
14603 #endif // DART_PRECOMPILED_RUNTIME | 14608 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |