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

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

Issue 11696005: Improve line info accuracy in debugging (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 break; 752 break;
753 case RawFunction::kConstImplicitGetter: 753 case RawFunction::kConstImplicitGetter:
754 node_sequence = parser.ParseStaticConstGetter(func); 754 node_sequence = parser.ParseStaticConstGetter(func);
755 break; 755 break;
756 default: 756 default:
757 UNREACHABLE(); 757 UNREACHABLE();
758 } 758 }
759 759
760 if (!HasReturnNode(node_sequence)) { 760 if (!HasReturnNode(node_sequence)) {
761 // Add implicit return node. 761 // Add implicit return node.
762 node_sequence->Add(new ReturnNode(parser.TokenPos())); 762 node_sequence->Add(new ReturnNode(func.end_token_pos()));
763 } 763 }
764 if (parser.expression_temp_ != NULL) { 764 if (parser.expression_temp_ != NULL) {
765 parsed_function->set_expression_temp_var(parser.expression_temp_); 765 parsed_function->set_expression_temp_var(parser.expression_temp_);
766 } 766 }
767 if (parsed_function->has_expression_temp_var()) { 767 if (parsed_function->has_expression_temp_var()) {
768 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); 768 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var());
769 } 769 }
770 parsed_function->SetNodeSequence(node_sequence); 770 parsed_function->SetNodeSequence(node_sequence);
771 771
772 // The instantiator may be required at run time for generic type checks or 772 // The instantiator may be required at run time for generic type checks or
(...skipping 27 matching lines...) Expand all
800 TRACE_PARSER("ParseStaticConstGetter"); 800 TRACE_PARSER("ParseStaticConstGetter");
801 ParamList params; 801 ParamList params;
802 ASSERT(func.num_fixed_parameters() == 0); // static. 802 ASSERT(func.num_fixed_parameters() == 0); // static.
803 ASSERT(!func.HasOptionalParameters()); 803 ASSERT(!func.HasOptionalParameters());
804 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 804 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
805 805
806 // Build local scope for function and populate with the formal parameters. 806 // Build local scope for function and populate with the formal parameters.
807 OpenFunctionBlock(func); 807 OpenFunctionBlock(func);
808 AddFormalParamsToScope(&params, current_block_->scope); 808 AddFormalParamsToScope(&params, current_block_->scope);
809 809
810 intptr_t ident_pos = TokenPos();
810 const String& field_name = *ExpectIdentifier("field name expected"); 811 const String& field_name = *ExpectIdentifier("field name expected");
811 const Class& field_class = Class::Handle(func.Owner()); 812 const Class& field_class = Class::Handle(func.Owner());
812 const Field& field = 813 const Field& field =
813 Field::ZoneHandle(field_class.LookupStaticField(field_name)); 814 Field::ZoneHandle(field_class.LookupStaticField(field_name));
814 815
815 // Static const fields must have an initializer. 816 // Static const fields must have an initializer.
816 ExpectToken(Token::kASSIGN); 817 ExpectToken(Token::kASSIGN);
817 818
818 // We don't want to use ParseConstExpr() here because we don't want 819 // We don't want to use ParseConstExpr() here because we don't want
819 // the constant folding code to create, compile and execute a code 820 // the constant folding code to create, compile and execute a code
820 // fragment to evaluate the expression. Instead, we just make sure 821 // fragment to evaluate the expression. Instead, we just make sure
821 // the static const field initializer is a constant expression and 822 // the static const field initializer is a constant expression and
822 // leave the evaluation to the getter function. 823 // leave the evaluation to the getter function.
823 const intptr_t expr_pos = TokenPos(); 824 const intptr_t expr_pos = TokenPos();
824 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 825 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
825 826
826 if (field.is_const()) { 827 if (field.is_const()) {
827 // This getter will only be called once at compile time. 828 // This getter will only be called once at compile time.
828 if (expr->EvalConstExpr() == NULL) { 829 if (expr->EvalConstExpr() == NULL) {
829 ErrorMsg(expr_pos, "initializer must be a compile-time constant"); 830 ErrorMsg(expr_pos, "initializer must be a compile-time constant");
830 } 831 }
831 ReturnNode* return_node = new ReturnNode(TokenPos(), expr); 832 ReturnNode* return_node = new ReturnNode(ident_pos, expr);
832 current_block_->statements->Add(return_node); 833 current_block_->statements->Add(return_node);
833 } else { 834 } else {
834 // This getter may be called each time the static field is accessed. 835 // This getter may be called each time the static field is accessed.
835 // The following generated code lazily initializes the field: 836 // The following generated code lazily initializes the field:
836 // if (field.value === transition_sentinel) { 837 // if (field.value === transition_sentinel) {
837 // field.value = null; 838 // field.value = null;
838 // throw("circular dependency in field initialization"); 839 // throw("circular dependency in field initialization");
839 // } 840 // }
840 // if (field.value === sentinel) { 841 // if (field.value === sentinel) {
841 // field.value = transition_sentinel; 842 // field.value = transition_sentinel;
842 // field.value = expr; 843 // field.value = expr;
843 // } 844 // }
844 // return field.value; // Type check is executed here in checked mode. 845 // return field.value; // Type check is executed here in checked mode.
845 846
846 // Generate code checking for circular dependency in field initialization. 847 // Generate code checking for circular dependency in field initialization.
847 AstNode* compare_circular = new ComparisonNode( 848 AstNode* compare_circular = new ComparisonNode(
848 TokenPos(), 849 ident_pos,
849 Token::kEQ_STRICT, 850 Token::kEQ_STRICT,
850 new LoadStaticFieldNode(TokenPos(), field), 851 new LoadStaticFieldNode(ident_pos, field),
851 new LiteralNode(TokenPos(), Object::transition_sentinel())); 852 new LiteralNode(ident_pos, Object::transition_sentinel()));
852 // Set field to null prior to throwing exception, so that subsequent 853 // Set field to null prior to throwing exception, so that subsequent
853 // accesses to the field do not throw again, since initializers should only 854 // accesses to the field do not throw again, since initializers should only
854 // be executed once. 855 // be executed once.
855 SequenceNode* report_circular = new SequenceNode(TokenPos(), NULL); 856 SequenceNode* report_circular = new SequenceNode(ident_pos, NULL);
856 report_circular->Add( 857 report_circular->Add(
857 new StoreStaticFieldNode( 858 new StoreStaticFieldNode(
858 TokenPos(), 859 ident_pos,
859 field, 860 field,
860 new LiteralNode(TokenPos(), Instance::ZoneHandle()))); 861 new LiteralNode(ident_pos, Instance::ZoneHandle())));
861 // TODO(regis): Exception to throw is not specified by spec. 862 // TODO(regis): Exception to throw is not specified by spec.
862 const String& circular_error = String::ZoneHandle( 863 const String& circular_error = String::ZoneHandle(
863 Symbols::New("circular dependency in field initialization")); 864 Symbols::New("circular dependency in field initialization"));
864 report_circular->Add( 865 report_circular->Add(
865 new ThrowNode(TokenPos(), 866 new ThrowNode(ident_pos,
866 new LiteralNode(TokenPos(), circular_error), 867 new LiteralNode(ident_pos, circular_error),
867 NULL)); 868 NULL));
868 AstNode* circular_check = 869 AstNode* circular_check =
869 new IfNode(TokenPos(), compare_circular, report_circular, NULL); 870 new IfNode(ident_pos, compare_circular, report_circular, NULL);
870 current_block_->statements->Add(circular_check); 871 current_block_->statements->Add(circular_check);
871 872
872 // Generate code checking for uninitialized field. 873 // Generate code checking for uninitialized field.
873 AstNode* compare_uninitialized = new ComparisonNode( 874 AstNode* compare_uninitialized = new ComparisonNode(
874 TokenPos(), 875 ident_pos,
875 Token::kEQ_STRICT, 876 Token::kEQ_STRICT,
876 new LoadStaticFieldNode(TokenPos(), field), 877 new LoadStaticFieldNode(ident_pos, field),
877 new LiteralNode(TokenPos(), Object::sentinel())); 878 new LiteralNode(ident_pos, Object::sentinel()));
878 SequenceNode* initialize_field = new SequenceNode(TokenPos(), NULL); 879 SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL);
879 initialize_field->Add( 880 initialize_field->Add(
880 new StoreStaticFieldNode( 881 new StoreStaticFieldNode(
881 TokenPos(), 882 ident_pos,
882 field, 883 field,
883 new LiteralNode( 884 new LiteralNode(ident_pos, Object::transition_sentinel())));
884 TokenPos(), Object::transition_sentinel())));
885 // TODO(hausner): If evaluation of the field value throws an exception, 885 // TODO(hausner): If evaluation of the field value throws an exception,
886 // we leave the field value as 'transition_sentinel', which is wrong. 886 // we leave the field value as 'transition_sentinel', which is wrong.
887 // A second reference to the field later throws a circular dependency 887 // A second reference to the field later throws a circular dependency
888 // exception. The field should instead be set to null after an exception. 888 // exception. The field should instead be set to null after an exception.
889 initialize_field->Add(new StoreStaticFieldNode(TokenPos(), field, expr)); 889 initialize_field->Add(new StoreStaticFieldNode(ident_pos, field, expr));
890 AstNode* uninitialized_check = 890 AstNode* uninitialized_check =
891 new IfNode(TokenPos(), compare_uninitialized, initialize_field, NULL); 891 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL);
892 current_block_->statements->Add(uninitialized_check); 892 current_block_->statements->Add(uninitialized_check);
893 893
894 // Generate code returning the field value. 894 // Generate code returning the field value.
895 ReturnNode* return_node = 895 ReturnNode* return_node =
896 new ReturnNode(TokenPos(), 896 new ReturnNode(ident_pos,
897 new LoadStaticFieldNode(TokenPos(), field)); 897 new LoadStaticFieldNode(ident_pos, field));
898 current_block_->statements->Add(return_node); 898 current_block_->statements->Add(return_node);
899 } 899 }
900 return CloseBlock(); 900 return CloseBlock();
901 } 901 }
902 902
903 903
904 // Create AstNodes for an implicit instance getter method: 904 // Create AstNodes for an implicit instance getter method:
905 // LoadLocalNode 0 ('this'); 905 // LoadLocalNode 0 ('this');
906 // LoadInstanceFieldNode (field_name); 906 // LoadInstanceFieldNode (field_name);
907 // ReturnNode (field's value); 907 // ReturnNode (field's value);
908 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { 908 SequenceNode* Parser::ParseInstanceGetter(const Function& func) {
909 TRACE_PARSER("ParseInstanceGetter"); 909 TRACE_PARSER("ParseInstanceGetter");
910 ParamList params; 910 ParamList params;
911 // func.token_pos() points to the name of the field.
912 intptr_t ident_pos = func.token_pos();
911 ASSERT(current_class().raw() == func.Owner()); 913 ASSERT(current_class().raw() == func.Owner());
912 params.AddReceiver(ReceiverType(TokenPos())); 914 params.AddReceiver(ReceiverType(ident_pos));
913 ASSERT(func.num_fixed_parameters() == 1); // receiver. 915 ASSERT(func.num_fixed_parameters() == 1); // receiver.
914 ASSERT(!func.HasOptionalParameters()); 916 ASSERT(!func.HasOptionalParameters());
915 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 917 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
916 918
917 // Build local scope for function and populate with the formal parameters. 919 // Build local scope for function and populate with the formal parameters.
918 OpenFunctionBlock(func); 920 OpenFunctionBlock(func);
919 AddFormalParamsToScope(&params, current_block_->scope); 921 AddFormalParamsToScope(&params, current_block_->scope);
920 922
921 // Receiver is local 0. 923 // Receiver is local 0.
922 LocalVariable* receiver = current_block_->scope->VariableAt(0); 924 LocalVariable* receiver = current_block_->scope->VariableAt(0);
923 LoadLocalNode* load_receiver = new LoadLocalNode(TokenPos(), receiver); 925 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver);
924 // TokenPos() returns the function's token position which points to the
925 // name of the field;
926 ASSERT(IsIdentifier()); 926 ASSERT(IsIdentifier());
927 const String& field_name = *CurrentLiteral(); 927 const String& field_name = *CurrentLiteral();
928 const Class& field_class = Class::Handle(func.Owner()); 928 const Class& field_class = Class::Handle(func.Owner());
929 const Field& field = 929 const Field& field =
930 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); 930 Field::ZoneHandle(field_class.LookupInstanceField(field_name));
931 931
932 LoadInstanceFieldNode* load_field = 932 LoadInstanceFieldNode* load_field =
933 new LoadInstanceFieldNode(TokenPos(), load_receiver, field); 933 new LoadInstanceFieldNode(ident_pos, load_receiver, field);
934 934
935 ReturnNode* return_node = new ReturnNode(TokenPos(), load_field); 935 ReturnNode* return_node = new ReturnNode(ident_pos, load_field);
936 current_block_->statements->Add(return_node); 936 current_block_->statements->Add(return_node);
937 return CloseBlock(); 937 return CloseBlock();
938 } 938 }
939 939
940 940
941 // Create AstNodes for an implicit instance setter method: 941 // Create AstNodes for an implicit instance setter method:
942 // LoadLocalNode 0 ('this') 942 // LoadLocalNode 0 ('this')
943 // LoadLocalNode 1 ('value') 943 // LoadLocalNode 1 ('value')
944 // SetInstanceField (field_name); 944 // SetInstanceField (field_name);
945 // ReturnNode (void); 945 // ReturnNode (void);
946 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { 946 SequenceNode* Parser::ParseInstanceSetter(const Function& func) {
947 TRACE_PARSER("ParseInstanceSetter"); 947 TRACE_PARSER("ParseInstanceSetter");
948 // TokenPos() returns the function's token position which points to 948 // func.token_pos() points to the name of the field.
949 // the name of the field; we can use it to form the field_name. 949 intptr_t ident_pos = func.token_pos();
950 const String& field_name = *CurrentLiteral(); 950 const String& field_name = *CurrentLiteral();
951 const Class& field_class = Class::ZoneHandle(func.Owner()); 951 const Class& field_class = Class::ZoneHandle(func.Owner());
952 const Field& field = 952 const Field& field =
953 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); 953 Field::ZoneHandle(field_class.LookupInstanceField(field_name));
954 const AbstractType& field_type = AbstractType::ZoneHandle(field.type()); 954 const AbstractType& field_type = AbstractType::ZoneHandle(field.type());
955 955
956 ParamList params; 956 ParamList params;
957 ASSERT(current_class().raw() == func.Owner()); 957 ASSERT(current_class().raw() == func.Owner());
958 params.AddReceiver(ReceiverType(TokenPos())); 958 params.AddReceiver(ReceiverType(ident_pos));
959 params.AddFinalParameter(TokenPos(), 959 params.AddFinalParameter(ident_pos,
960 &String::ZoneHandle(Symbols::Value()), 960 &String::ZoneHandle(Symbols::Value()),
961 &field_type); 961 &field_type);
962 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. 962 ASSERT(func.num_fixed_parameters() == 2); // receiver, value.
963 ASSERT(!func.HasOptionalParameters()); 963 ASSERT(!func.HasOptionalParameters());
964 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType()); 964 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType());
965 965
966 // Build local scope for function and populate with the formal parameters. 966 // Build local scope for function and populate with the formal parameters.
967 OpenFunctionBlock(func); 967 OpenFunctionBlock(func);
968 AddFormalParamsToScope(&params, current_block_->scope); 968 AddFormalParamsToScope(&params, current_block_->scope);
969 969
970 LoadLocalNode* receiver = 970 LoadLocalNode* receiver =
971 new LoadLocalNode(TokenPos(), current_block_->scope->VariableAt(0)); 971 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0));
972 LoadLocalNode* value = 972 LoadLocalNode* value =
973 new LoadLocalNode(TokenPos(), current_block_->scope->VariableAt(1)); 973 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1));
974 974
975 StoreInstanceFieldNode* store_field = 975 StoreInstanceFieldNode* store_field =
976 new StoreInstanceFieldNode(TokenPos(), receiver, field, value); 976 new StoreInstanceFieldNode(ident_pos, receiver, field, value);
977 977
978 current_block_->statements->Add(store_field); 978 current_block_->statements->Add(store_field);
979 current_block_->statements->Add(new ReturnNode(TokenPos())); 979 current_block_->statements->Add(new ReturnNode(ident_pos));
980 return CloseBlock(); 980 return CloseBlock();
981 } 981 }
982 982
983 983
984 void Parser::SkipBlock() { 984 void Parser::SkipBlock() {
985 ASSERT(CurrentToken() == Token::kLBRACE); 985 ASSERT(CurrentToken() == Token::kLBRACE);
986 GrowableArray<Token::Kind> token_stack(8); 986 GrowableArray<Token::Kind> token_stack(8);
987 const intptr_t block_start_pos = TokenPos(); 987 const intptr_t block_start_pos = TokenPos();
988 bool is_match = true; 988 bool is_match = true;
989 bool unexpected_token_found = false; 989 bool unexpected_token_found = false;
(...skipping 1604 matching lines...) Expand 10 before | Expand all | Expand 10 after
2594 ErrorMsg(method->name_pos, 2594 ErrorMsg(method->name_pos,
2595 "Constructor with redirection may not have a function body"); 2595 "Constructor with redirection may not have a function body");
2596 } 2596 }
2597 if (CurrentToken() == Token::kLBRACE) { 2597 if (CurrentToken() == Token::kLBRACE) {
2598 SkipBlock(); 2598 SkipBlock();
2599 } else { 2599 } else {
2600 ConsumeToken(); 2600 ConsumeToken();
2601 SkipExpr(); 2601 SkipExpr();
2602 ExpectSemicolon(); 2602 ExpectSemicolon();
2603 } 2603 }
2604 method_end_pos = TokenPos(); 2604 method_end_pos = TokenPos() - 1;
2605 } else if (IsLiteral("native")) { 2605 } else if (IsLiteral("native")) {
2606 if (method->has_abstract) { 2606 if (method->has_abstract) {
2607 ErrorMsg(method->name_pos, 2607 ErrorMsg(method->name_pos,
2608 "abstract method '%s' may not have a function body", 2608 "abstract method '%s' may not have a function body",
2609 method->name->ToCString()); 2609 method->name->ToCString());
2610 } else if (method->IsFactoryOrConstructor() && method->has_const) { 2610 } else if (method->IsFactoryOrConstructor() && method->has_const) {
2611 ErrorMsg(method->name_pos, 2611 ErrorMsg(method->name_pos,
2612 "const constructor or factory '%s' may not be native", 2612 "const constructor or factory '%s' may not be native",
2613 method->name->ToCString()); 2613 method->name->ToCString());
2614 } 2614 }
(...skipping 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after
3788 const intptr_t function_pos = TokenPos(); 3788 const intptr_t function_pos = TokenPos();
3789 ParamList params; 3789 ParamList params;
3790 const bool allow_explicit_default_values = true; 3790 const bool allow_explicit_default_values = true;
3791 ParseFormalParameterList(allow_explicit_default_values, &params); 3791 ParseFormalParameterList(allow_explicit_default_values, &params);
3792 3792
3793 intptr_t function_end_pos = function_pos; 3793 intptr_t function_end_pos = function_pos;
3794 if (is_external) { 3794 if (is_external) {
3795 ExpectSemicolon(); 3795 ExpectSemicolon();
3796 } else if (CurrentToken() == Token::kLBRACE) { 3796 } else if (CurrentToken() == Token::kLBRACE) {
3797 SkipBlock(); 3797 SkipBlock();
3798 function_end_pos = TokenPos(); 3798 function_end_pos = TokenPos() - 1;
3799 } else if (CurrentToken() == Token::kARROW) { 3799 } else if (CurrentToken() == Token::kARROW) {
3800 ConsumeToken(); 3800 ConsumeToken();
3801 SkipExpr(); 3801 SkipExpr();
3802 ExpectSemicolon(); 3802 ExpectSemicolon();
3803 function_end_pos = TokenPos(); 3803 function_end_pos = TokenPos() - 1;
3804 } else if (IsLiteral("native")) { 3804 } else if (IsLiteral("native")) {
3805 ParseNativeDeclaration(); 3805 ParseNativeDeclaration();
3806 } else { 3806 } else {
3807 ErrorMsg("function block expected"); 3807 ErrorMsg("function block expected");
3808 } 3808 }
3809 Function& func = Function::Handle( 3809 Function& func = Function::Handle(
3810 Function::New(func_name, 3810 Function::New(func_name,
3811 RawFunction::kRegularFunction, 3811 RawFunction::kRegularFunction,
3812 is_static, 3812 is_static,
3813 /* is_const = */ false, 3813 /* is_const = */ false,
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after
4825 if (!current_block_->scope->AddVariable(function_variable)) { 4825 if (!current_block_->scope->AddVariable(function_variable)) {
4826 ErrorMsg(ident_pos, "identifier '%s' already defined", 4826 ErrorMsg(ident_pos, "identifier '%s' already defined",
4827 function_variable->name().ToCString()); 4827 function_variable->name().ToCString());
4828 } 4828 }
4829 } 4829 }
4830 4830
4831 // Parse the local function. 4831 // Parse the local function.
4832 Array& default_parameter_values = Array::Handle(); 4832 Array& default_parameter_values = Array::Handle();
4833 SequenceNode* statements = Parser::ParseFunc(function, 4833 SequenceNode* statements = Parser::ParseFunc(function,
4834 default_parameter_values); 4834 default_parameter_values);
4835 ASSERT(is_new_closure || (function.end_token_pos() == TokenPos())); 4835 ASSERT(is_new_closure || (function.end_token_pos() == (TokenPos() - 1)));
4836 function.set_end_token_pos(TokenPos()); 4836 function.set_end_token_pos(TokenPos() - 1);
4837 4837
4838 // Now that the local function has formal parameters, lookup the signature 4838 // Now that the local function has formal parameters, lookup the signature
4839 // class in the current library (but not in its imports) and only create a new 4839 // class in the current library (but not in its imports) and only create a new
4840 // canonical signature class if it does not exist yet. 4840 // canonical signature class if it does not exist yet.
4841 const String& signature = String::Handle(function.Signature()); 4841 const String& signature = String::Handle(function.Signature());
4842 Class& signature_class = Class::ZoneHandle(); 4842 Class& signature_class = Class::ZoneHandle();
4843 if (!is_new_closure) { 4843 if (!is_new_closure) {
4844 signature_class = function.signature_class(); 4844 signature_class = function.signature_class();
4845 } 4845 }
4846 if (signature_class.IsNull()) { 4846 if (signature_class.IsNull()) {
(...skipping 4860 matching lines...) Expand 10 before | Expand all | Expand 10 after
9707 void Parser::SkipQualIdent() { 9707 void Parser::SkipQualIdent() {
9708 ASSERT(IsIdentifier()); 9708 ASSERT(IsIdentifier());
9709 ConsumeToken(); 9709 ConsumeToken();
9710 if (CurrentToken() == Token::kPERIOD) { 9710 if (CurrentToken() == Token::kPERIOD) {
9711 ConsumeToken(); // Consume the kPERIOD token. 9711 ConsumeToken(); // Consume the kPERIOD token.
9712 ExpectIdentifier("identifier expected after '.'"); 9712 ExpectIdentifier("identifier expected after '.'");
9713 } 9713 }
9714 } 9714 }
9715 9715
9716 } // namespace dart 9716 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698