| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 "Class '%s' has no field '%s'", | 925 "Class '%s' has no field '%s'", |
| 926 cls.ToCString(), | 926 cls.ToCString(), |
| 927 ident->ToCString()); | 927 ident->ToCString()); |
| 928 } | 928 } |
| 929 if (!field.is_const()) { | 929 if (!field.is_const()) { |
| 930 ErrorMsg(ident_pos, | 930 ErrorMsg(ident_pos, |
| 931 "Field '%s' of class '%s' is not const", | 931 "Field '%s' of class '%s' is not const", |
| 932 ident->ToCString(), | 932 ident->ToCString(), |
| 933 cls.ToCString()); | 933 cls.ToCString()); |
| 934 } | 934 } |
| 935 expr = GenerateStaticFieldLookup(field, TokenPos()); | 935 expr = GenerateStaticFieldLookup(field, ident_pos); |
| 936 } | 936 } |
| 937 } | 937 } |
| 938 if (expr->EvalConstExpr() == NULL) { | 938 if (expr->EvalConstExpr() == NULL) { |
| 939 ErrorMsg(expr_pos, "expression must be a compile-time constant"); | 939 ErrorMsg(expr_pos, "expression must be a compile-time constant"); |
| 940 } | 940 } |
| 941 const Instance& val = EvaluateConstExpr(expr_pos, expr); | 941 const Instance& val = EvaluateConstExpr(expr_pos, expr); |
| 942 meta_values.Add(val); | 942 meta_values.Add(val); |
| 943 } | 943 } |
| 944 return Array::MakeArray(meta_values); | 944 return Array::MakeArray(meta_values); |
| 945 } | 945 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 ParamList params; | 1060 ParamList params; |
| 1061 ASSERT(func.num_fixed_parameters() == 0); // static. | 1061 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 1062 ASSERT(!func.HasOptionalParameters()); | 1062 ASSERT(!func.HasOptionalParameters()); |
| 1063 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 1063 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 1064 | 1064 |
| 1065 // Build local scope for function and populate with the formal parameters. | 1065 // Build local scope for function and populate with the formal parameters. |
| 1066 OpenFunctionBlock(func); | 1066 OpenFunctionBlock(func); |
| 1067 AddFormalParamsToScope(¶ms, current_block_->scope); | 1067 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1068 | 1068 |
| 1069 // Move forward to the start of the initializer expression. | 1069 // Move forward to the start of the initializer expression. |
| 1070 intptr_t ident_pos = TokenPos(); |
| 1070 ExpectIdentifier("identifier expected"); | 1071 ExpectIdentifier("identifier expected"); |
| 1071 ExpectToken(Token::kASSIGN); | 1072 ExpectToken(Token::kASSIGN); |
| 1072 intptr_t token_pos = TokenPos(); | 1073 intptr_t token_pos = TokenPos(); |
| 1073 | 1074 |
| 1074 // Synthesize a try-catch block to wrap the initializer expression. | 1075 // Synthesize a try-catch block to wrap the initializer expression. |
| 1075 LocalVariable* context_var = | 1076 LocalVariable* context_var = |
| 1076 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 1077 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 1077 if (context_var == NULL) { | 1078 if (context_var == NULL) { |
| 1078 context_var = new LocalVariable(token_pos, | 1079 context_var = new LocalVariable(token_pos, |
| 1079 Symbols::SavedTryContextVar(), | 1080 Symbols::SavedTryContextVar(), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1105 field, | 1106 field, |
| 1106 expr); | 1107 expr); |
| 1107 current_block_->statements->Add(store); | 1108 current_block_->statements->Add(store); |
| 1108 SequenceNode* try_block = CloseBlock(); // End try block. | 1109 SequenceNode* try_block = CloseBlock(); // End try block. |
| 1109 | 1110 |
| 1110 OpenBlock(); // Start catch handler list. | 1111 OpenBlock(); // Start catch handler list. |
| 1111 OpenBlock(); // Start catch clause. | 1112 OpenBlock(); // Start catch clause. |
| 1112 AstNode* compare_transition_sentinel = new ComparisonNode( | 1113 AstNode* compare_transition_sentinel = new ComparisonNode( |
| 1113 token_pos, | 1114 token_pos, |
| 1114 Token::kEQ_STRICT, | 1115 Token::kEQ_STRICT, |
| 1115 new LoadStaticFieldNode(token_pos, field), | 1116 new LoadStaticFieldNode(ident_pos, field), |
| 1116 new LiteralNode(field.token_pos(), Object::transition_sentinel())); | 1117 new LiteralNode(field.token_pos(), Object::transition_sentinel())); |
| 1117 | 1118 |
| 1118 SequenceNode* store_null = new SequenceNode(token_pos, NULL); | 1119 SequenceNode* store_null = new SequenceNode(token_pos, NULL); |
| 1119 store_null->Add(new StoreStaticFieldNode( | 1120 store_null->Add(new StoreStaticFieldNode( |
| 1120 field.token_pos(), | 1121 field.token_pos(), |
| 1121 field, | 1122 field, |
| 1122 new LiteralNode(token_pos, Instance::ZoneHandle()))); | 1123 new LiteralNode(token_pos, Instance::ZoneHandle()))); |
| 1123 AstNode* transition_sentinel_check = | 1124 AstNode* transition_sentinel_check = |
| 1124 new IfNode(token_pos, compare_transition_sentinel, store_null, NULL); | 1125 new IfNode(token_pos, compare_transition_sentinel, store_null, NULL); |
| 1125 current_block_->statements->Add(transition_sentinel_check); | 1126 current_block_->statements->Add(transition_sentinel_check); |
| (...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 implicit_closure_function.signature_class()); | 1994 implicit_closure_function.signature_class()); |
| 1994 if (signature_class.NumTypeParameters() > 0) { | 1995 if (signature_class.NumTypeParameters() > 0) { |
| 1995 CaptureInstantiator(); | 1996 CaptureInstantiator(); |
| 1996 } | 1997 } |
| 1997 } | 1998 } |
| 1998 } | 1999 } |
| 1999 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 2000 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
| 2000 } | 2001 } |
| 2001 | 2002 |
| 2002 | 2003 |
| 2003 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { | 2004 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, |
| 2005 intptr_t field_pos) { |
| 2004 TRACE_PARSER("ParseSuperFieldAccess"); | 2006 TRACE_PARSER("ParseSuperFieldAccess"); |
| 2005 const intptr_t field_pos = TokenPos(); | |
| 2006 const Class& super_class = Class::ZoneHandle(current_class().SuperClass()); | 2007 const Class& super_class = Class::ZoneHandle(current_class().SuperClass()); |
| 2007 if (super_class.IsNull()) { | 2008 if (super_class.IsNull()) { |
| 2008 ErrorMsg("class '%s' does not have a superclass", | 2009 ErrorMsg("class '%s' does not have a superclass", |
| 2009 String::Handle(current_class().Name()).ToCString()); | 2010 String::Handle(current_class().Name()).ToCString()); |
| 2010 } | 2011 } |
| 2011 AstNode* implicit_argument = LoadReceiver(field_pos); | 2012 AstNode* implicit_argument = LoadReceiver(field_pos); |
| 2012 | 2013 |
| 2013 const String& getter_name = | 2014 const String& getter_name = |
| 2014 String::ZoneHandle(Field::GetterName(field_name)); | 2015 String::ZoneHandle(Field::GetterName(field_name)); |
| 2015 const Function& super_getter = Function::ZoneHandle( | 2016 const Function& super_getter = Function::ZoneHandle( |
| (...skipping 5769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7785 } | 7786 } |
| 7786 *expr = new InstanceGetterNode(token_pos, | 7787 *expr = new InstanceGetterNode(token_pos, |
| 7787 receiver, | 7788 receiver, |
| 7788 getter->field_name()); | 7789 getter->field_name()); |
| 7789 return result; | 7790 return result; |
| 7790 } | 7791 } |
| 7791 return result; | 7792 return result; |
| 7792 } | 7793 } |
| 7793 | 7794 |
| 7794 | 7795 |
| 7796 // Check whether the syntax of expression expr is a grammatically legal |
| 7797 // assignable expression. This check is used to detect situations where |
| 7798 // the expression itself is assignable, but the source is grammatically |
| 7799 // wrong. The AST representation of an expression cannot distinguish |
| 7800 // between x = 0 and (x) = 0. The latter is illegal. |
| 7801 // A syntactically legal assignable expression always ends with an |
| 7802 // identifier token or a ] token. We rewind the token iterator and |
| 7803 // check whether the token before end_pos is an identifier or ]. |
| 7804 bool Parser::IsLegalAssignableSyntax(AstNode* expr, intptr_t end_pos) { |
| 7805 ASSERT(expr->token_pos() >= 0); |
| 7806 ASSERT(expr->token_pos() < end_pos); |
| 7807 SetPosition(expr->token_pos()); |
| 7808 Token::Kind token = Token::kILLEGAL; |
| 7809 while (TokenPos() < end_pos) { |
| 7810 token = CurrentToken(); |
| 7811 ConsumeToken(); |
| 7812 } |
| 7813 ASSERT(TokenPos() == end_pos); |
| 7814 return Token::IsIdentifier(token) || (token == Token::kRBRACK); |
| 7815 } |
| 7816 |
| 7817 |
| 7795 AstNode* Parser::CreateAssignmentNode(AstNode* original, | 7818 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
| 7796 AstNode* rhs, | 7819 AstNode* rhs, |
| 7797 const String* left_ident, | 7820 const String* left_ident, |
| 7798 intptr_t left_pos) { | 7821 intptr_t left_pos) { |
| 7799 AstNode* result = original->MakeAssignmentNode(rhs); | 7822 AstNode* result = original->MakeAssignmentNode(rhs); |
| 7800 if (result == NULL) { | 7823 if (result == NULL) { |
| 7801 String& name = String::ZoneHandle(); | 7824 String& name = String::ZoneHandle(); |
| 7802 const Class* target_cls = ¤t_class(); | 7825 const Class* target_cls = ¤t_class(); |
| 7803 if (original->IsTypeNode()) { | 7826 if (original->IsTypeNode()) { |
| 7804 name = Symbols::New(original->AsTypeNode()->TypeName()); | 7827 name = Symbols::New(original->AsTypeNode()->TypeName()); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7925 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { | 7948 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { |
| 7926 return ParseCascades(expr); | 7949 return ParseCascades(expr); |
| 7927 } | 7950 } |
| 7928 expr = LiteralIfStaticConst(expr); | 7951 expr = LiteralIfStaticConst(expr); |
| 7929 if (require_compiletime_const) { | 7952 if (require_compiletime_const) { |
| 7930 expr = FoldConstExpr(expr_pos, expr); | 7953 expr = FoldConstExpr(expr_pos, expr); |
| 7931 } | 7954 } |
| 7932 return expr; | 7955 return expr; |
| 7933 } | 7956 } |
| 7934 // Assignment expressions. | 7957 // Assignment expressions. |
| 7958 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 7959 ErrorMsg(expr_pos, "expression is not assignable"); |
| 7960 } |
| 7935 const Token::Kind assignment_op = CurrentToken(); | 7961 const Token::Kind assignment_op = CurrentToken(); |
| 7936 const intptr_t assignment_pos = TokenPos(); | 7962 const intptr_t assignment_pos = TokenPos(); |
| 7937 ConsumeToken(); | 7963 ConsumeToken(); |
| 7938 const intptr_t right_expr_pos = TokenPos(); | 7964 const intptr_t right_expr_pos = TokenPos(); |
| 7939 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 7965 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
| 7940 ErrorMsg(right_expr_pos, "expression is not a valid compile-time constant"); | 7966 ErrorMsg(right_expr_pos, "expression is not a valid compile-time constant"); |
| 7941 } | 7967 } |
| 7942 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); | 7968 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 7943 if (assignment_op != Token::kASSIGN) { | 7969 if (assignment_op != Token::kASSIGN) { |
| 7944 // Compound assignment: store inputs with side effects into temp. locals. | 7970 // Compound assignment: store inputs with side effects into temp. locals. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8003 } else { | 8029 } else { |
| 8004 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 8030 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
| 8005 } | 8031 } |
| 8006 } else if (IsIncrementOperator(CurrentToken())) { | 8032 } else if (IsIncrementOperator(CurrentToken())) { |
| 8007 Token::Kind incr_op = CurrentToken(); | 8033 Token::Kind incr_op = CurrentToken(); |
| 8008 ConsumeToken(); | 8034 ConsumeToken(); |
| 8009 String* expr_ident = | 8035 String* expr_ident = |
| 8010 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8036 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8011 const intptr_t expr_pos = TokenPos(); | 8037 const intptr_t expr_pos = TokenPos(); |
| 8012 expr = ParseUnaryExpr(); | 8038 expr = ParseUnaryExpr(); |
| 8039 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 8040 ErrorMsg(expr_pos, "expression is not assignable"); |
| 8041 } |
| 8013 // Is prefix. | 8042 // Is prefix. |
| 8014 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 8043 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 8015 Token::Kind binary_op = | 8044 Token::Kind binary_op = |
| 8016 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 8045 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 8017 BinaryOpNode* add = new BinaryOpNode( | 8046 BinaryOpNode* add = new BinaryOpNode( |
| 8018 op_pos, | 8047 op_pos, |
| 8019 binary_op, | 8048 binary_op, |
| 8020 expr, | 8049 expr, |
| 8021 new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1)))); | 8050 new LiteralNode(op_pos, Smi::ZoneHandle(Smi::New(1)))); |
| 8022 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); | 8051 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8165 EnsureSavedCurrentContext(); | 8194 EnsureSavedCurrentContext(); |
| 8166 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 8195 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 8167 return new ClosureCallNode(call_pos, closure, arguments); | 8196 return new ClosureCallNode(call_pos, closure, arguments); |
| 8168 } | 8197 } |
| 8169 | 8198 |
| 8170 | 8199 |
| 8171 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 8200 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
| 8172 intptr_t ident_pos) { | 8201 intptr_t ident_pos) { |
| 8173 // If the static field has an initializer, initialize the field at compile | 8202 // If the static field has an initializer, initialize the field at compile |
| 8174 // time, which is only possible if the field is const. | 8203 // time, which is only possible if the field is const. |
| 8175 AstNode* initializing_getter = RunStaticFieldInitializer(field); | 8204 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
| 8176 if (initializing_getter != NULL) { | 8205 if (initializing_getter != NULL) { |
| 8177 // The field is not yet initialized and could not be initialized at compile | 8206 // The field is not yet initialized and could not be initialized at compile |
| 8178 // time. The getter will initialize the field. | 8207 // time. The getter will initialize the field. |
| 8179 return initializing_getter; | 8208 return initializing_getter; |
| 8180 } | 8209 } |
| 8181 // The field is initialized. | 8210 // The field is initialized. |
| 8182 ASSERT(field.is_static()); | 8211 ASSERT(field.is_static()); |
| 8183 const Class& field_owner = Class::ZoneHandle(field.owner()); | 8212 const Class& field_owner = Class::ZoneHandle(field.owner()); |
| 8184 const String& field_name = String::ZoneHandle(field.name()); | 8213 const String& field_name = String::ZoneHandle(field.name()); |
| 8185 const String& getter_name = String::Handle(Field::GetterName(field_name)); | 8214 const String& getter_name = String::Handle(Field::GetterName(field_name)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8198 } | 8227 } |
| 8199 } | 8228 } |
| 8200 | 8229 |
| 8201 | 8230 |
| 8202 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, | 8231 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, |
| 8203 const String& field_name, | 8232 const String& field_name, |
| 8204 intptr_t ident_pos, | 8233 intptr_t ident_pos, |
| 8205 bool consume_cascades) { | 8234 bool consume_cascades) { |
| 8206 TRACE_PARSER("ParseStaticFieldAccess"); | 8235 TRACE_PARSER("ParseStaticFieldAccess"); |
| 8207 AstNode* access = NULL; | 8236 AstNode* access = NULL; |
| 8208 const intptr_t call_pos = TokenPos(); | |
| 8209 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); | 8237 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); |
| 8210 Function& func = Function::ZoneHandle(); | 8238 Function& func = Function::ZoneHandle(); |
| 8211 if (field.IsNull()) { | 8239 if (field.IsNull()) { |
| 8212 // No field, check if we have an explicit getter function. | 8240 // No field, check if we have an explicit getter function. |
| 8213 const String& getter_name = | 8241 const String& getter_name = |
| 8214 String::ZoneHandle(Field::GetterName(field_name)); | 8242 String::ZoneHandle(Field::GetterName(field_name)); |
| 8215 const int kNumArguments = 0; // no arguments. | 8243 const int kNumArguments = 0; // no arguments. |
| 8216 func = Resolver::ResolveStatic(cls, | 8244 func = Resolver::ResolveStatic(cls, |
| 8217 getter_name, | 8245 getter_name, |
| 8218 kNumArguments, | 8246 kNumArguments, |
| 8219 Object::empty_array()); | 8247 Object::empty_array()); |
| 8220 if (func.IsNull()) { | 8248 if (func.IsNull()) { |
| 8221 // We might be referring to an implicit closure, check to see if | 8249 // We might be referring to an implicit closure, check to see if |
| 8222 // there is a function of the same name. | 8250 // there is a function of the same name. |
| 8223 func = cls.LookupStaticFunction(field_name); | 8251 func = cls.LookupStaticFunction(field_name); |
| 8224 if (!func.IsNull()) { | 8252 if (!func.IsNull()) { |
| 8225 access = CreateImplicitClosureNode(func, call_pos, NULL); | 8253 access = CreateImplicitClosureNode(func, ident_pos, NULL); |
| 8226 } else { | 8254 } else { |
| 8227 // No function to closurize found found. | 8255 // No function to closurize found found. |
| 8228 // This field access may turn out to be a call to the setter. | 8256 // This field access may turn out to be a call to the setter. |
| 8229 // Create a getter call, which may later be turned into | 8257 // Create a getter call, which may later be turned into |
| 8230 // a setter call, or else the backend will generate | 8258 // a setter call, or else the backend will generate |
| 8231 // a throw NoSuchMethodError(). | 8259 // a throw NoSuchMethodError(). |
| 8232 access = new StaticGetterNode(call_pos, | 8260 access = new StaticGetterNode(ident_pos, |
| 8233 NULL, | 8261 NULL, |
| 8234 false, | 8262 false, |
| 8235 Class::ZoneHandle(cls.raw()), | 8263 Class::ZoneHandle(cls.raw()), |
| 8236 field_name); | 8264 field_name); |
| 8237 } | 8265 } |
| 8238 } else { | 8266 } else { |
| 8239 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 8267 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
| 8240 access = new StaticGetterNode(call_pos, | 8268 access = new StaticGetterNode(ident_pos, |
| 8241 NULL, | 8269 NULL, |
| 8242 false, | 8270 false, |
| 8243 Class::ZoneHandle(cls.raw()), | 8271 Class::ZoneHandle(cls.raw()), |
| 8244 field_name); | 8272 field_name); |
| 8245 } | 8273 } |
| 8246 } else { | 8274 } else { |
| 8247 access = GenerateStaticFieldLookup(field, TokenPos()); | 8275 access = GenerateStaticFieldLookup(field, ident_pos); |
| 8248 } | 8276 } |
| 8249 return access; | 8277 return access; |
| 8250 } | 8278 } |
| 8251 | 8279 |
| 8252 | 8280 |
| 8253 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 8281 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
| 8254 if (!node->IsPrimaryNode()) { | 8282 if (!node->IsPrimaryNode()) { |
| 8255 return node; | 8283 return node; |
| 8256 } | 8284 } |
| 8257 PrimaryNode* primary = node->AsPrimaryNode(); | 8285 PrimaryNode* primary = node->AsPrimaryNode(); |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8540 | 8568 |
| 8541 AstNode* Parser::ParsePostfixExpr() { | 8569 AstNode* Parser::ParsePostfixExpr() { |
| 8542 TRACE_PARSER("ParsePostfixExpr"); | 8570 TRACE_PARSER("ParsePostfixExpr"); |
| 8543 String* expr_ident = | 8571 String* expr_ident = |
| 8544 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8572 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8545 const intptr_t expr_pos = TokenPos(); | 8573 const intptr_t expr_pos = TokenPos(); |
| 8546 AstNode* expr = ParsePrimary(); | 8574 AstNode* expr = ParsePrimary(); |
| 8547 expr = ParseSelectors(expr, false); | 8575 expr = ParseSelectors(expr, false); |
| 8548 if (IsIncrementOperator(CurrentToken())) { | 8576 if (IsIncrementOperator(CurrentToken())) { |
| 8549 TRACE_PARSER("IncrementOperator"); | 8577 TRACE_PARSER("IncrementOperator"); |
| 8578 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 8579 ErrorMsg(expr_pos, "expression is not assignable"); |
| 8580 } |
| 8550 Token::Kind incr_op = CurrentToken(); | 8581 Token::Kind incr_op = CurrentToken(); |
| 8551 ConsumeToken(); | 8582 ConsumeToken(); |
| 8552 // Not prefix. | 8583 // Not prefix. |
| 8553 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 8584 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 8554 LocalVariable* temp = let_expr->AddInitializer(expr); | 8585 LocalVariable* temp = let_expr->AddInitializer(expr); |
| 8555 Token::Kind binary_op = | 8586 Token::Kind binary_op = |
| 8556 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 8587 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 8557 BinaryOpNode* add = new BinaryOpNode( | 8588 BinaryOpNode* add = new BinaryOpNode( |
| 8558 expr_pos, | 8589 expr_pos, |
| 8559 binary_op, | 8590 binary_op, |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8746 if (result.IsNull()) { | 8777 if (result.IsNull()) { |
| 8747 ErrorMsg(token_pos, "Invalid const object %s", error_str); | 8778 ErrorMsg(token_pos, "Invalid const object %s", error_str); |
| 8748 } | 8779 } |
| 8749 return result.raw(); | 8780 return result.raw(); |
| 8750 } | 8781 } |
| 8751 | 8782 |
| 8752 | 8783 |
| 8753 // If the field is already initialized, return no ast (NULL). | 8784 // If the field is already initialized, return no ast (NULL). |
| 8754 // Otherwise, if the field is constant, initialize the field and return no ast. | 8785 // Otherwise, if the field is constant, initialize the field and return no ast. |
| 8755 // If the field is not initialized and not const, return the ast for the getter. | 8786 // If the field is not initialized and not const, return the ast for the getter. |
| 8756 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { | 8787 AstNode* Parser::RunStaticFieldInitializer(const Field& field, |
| 8788 intptr_t field_ref_pos) { |
| 8757 ASSERT(field.is_static()); | 8789 ASSERT(field.is_static()); |
| 8758 const Class& field_owner = Class::ZoneHandle(field.owner()); | 8790 const Class& field_owner = Class::ZoneHandle(field.owner()); |
| 8759 const String& field_name = String::ZoneHandle(field.name()); | 8791 const String& field_name = String::ZoneHandle(field.name()); |
| 8760 const String& getter_name = String::Handle(Field::GetterName(field_name)); | 8792 const String& getter_name = String::Handle(Field::GetterName(field_name)); |
| 8761 const Function& getter = | 8793 const Function& getter = |
| 8762 Function::Handle(field_owner.LookupStaticFunction(getter_name)); | 8794 Function::Handle(field_owner.LookupStaticFunction(getter_name)); |
| 8763 const Instance& value = Instance::Handle(field.value()); | 8795 const Instance& value = Instance::Handle(field.value()); |
| 8764 if (value.raw() == Object::transition_sentinel().raw()) { | 8796 if (value.raw() == Object::transition_sentinel().raw()) { |
| 8765 if (field.is_const()) { | 8797 if (field.is_const()) { |
| 8766 ErrorMsg("circular dependency while initializing static field '%s'", | 8798 ErrorMsg("circular dependency while initializing static field '%s'", |
| 8767 field_name.ToCString()); | 8799 field_name.ToCString()); |
| 8768 } else { | 8800 } else { |
| 8769 // The implicit static getter will throw the exception if necessary. | 8801 // The implicit static getter will throw the exception if necessary. |
| 8770 return new StaticGetterNode(TokenPos(), | 8802 return new StaticGetterNode(field_ref_pos, |
| 8771 NULL, | 8803 NULL, |
| 8772 false, | 8804 false, |
| 8773 field_owner, | 8805 field_owner, |
| 8774 field_name); | 8806 field_name); |
| 8775 } | 8807 } |
| 8776 } else if (value.raw() == Object::sentinel().raw()) { | 8808 } else if (value.raw() == Object::sentinel().raw()) { |
| 8777 // This field has not been referenced yet and thus the value has | 8809 // This field has not been referenced yet and thus the value has |
| 8778 // not been evaluated. If the field is const, call the static getter method | 8810 // not been evaluated. If the field is const, call the static getter method |
| 8779 // to evaluate the expression and canonicalize the value. | 8811 // to evaluate the expression and canonicalize the value. |
| 8780 if (field.is_const()) { | 8812 if (field.is_const()) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 8792 if (const_value.IsError()) { | 8824 if (const_value.IsError()) { |
| 8793 const Error& error = Error::Cast(const_value); | 8825 const Error& error = Error::Cast(const_value); |
| 8794 if (error.IsUnhandledException()) { | 8826 if (error.IsUnhandledException()) { |
| 8795 // An exception may not occur in every parse attempt, i.e., the | 8827 // An exception may not occur in every parse attempt, i.e., the |
| 8796 // generated AST is not deterministic. Therefore mark the function as | 8828 // generated AST is not deterministic. Therefore mark the function as |
| 8797 // not optimizable. | 8829 // not optimizable. |
| 8798 current_function().set_is_optimizable(false); | 8830 current_function().set_is_optimizable(false); |
| 8799 field.set_value(Object::null_instance()); | 8831 field.set_value(Object::null_instance()); |
| 8800 // It is a compile-time error if evaluation of a compile-time constant | 8832 // It is a compile-time error if evaluation of a compile-time constant |
| 8801 // would raise an exception. | 8833 // would raise an exception. |
| 8802 AppendErrorMsg(error, TokenPos(), | 8834 AppendErrorMsg(error, field_ref_pos, |
| 8803 "error initializing const field '%s'", | 8835 "error initializing const field '%s'", |
| 8804 String::Handle(field.name()).ToCString()); | 8836 String::Handle(field.name()).ToCString()); |
| 8805 } else { | 8837 } else { |
| 8806 isolate()->long_jump_base()->Jump(1, error); | 8838 isolate()->long_jump_base()->Jump(1, error); |
| 8807 } | 8839 } |
| 8808 } | 8840 } |
| 8809 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 8841 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 8810 Instance& instance = Instance::Handle(); | 8842 Instance& instance = Instance::Handle(); |
| 8811 instance ^= const_value.raw(); | 8843 instance ^= const_value.raw(); |
| 8812 instance = TryCanonicalize(instance, TokenPos()); | 8844 instance = TryCanonicalize(instance, field_ref_pos); |
| 8813 field.set_value(instance); | 8845 field.set_value(instance); |
| 8814 return NULL; // Constant | 8846 return NULL; // Constant |
| 8815 } else { | 8847 } else { |
| 8816 return new StaticGetterNode(TokenPos(), | 8848 return new StaticGetterNode(field_ref_pos, |
| 8817 NULL, | 8849 NULL, |
| 8818 false, | 8850 false, |
| 8819 field_owner, | 8851 field_owner, |
| 8820 field_name); | 8852 field_name); |
| 8821 } | 8853 } |
| 8822 } | 8854 } |
| 8823 if (getter.IsNull() || | 8855 if (getter.IsNull() || |
| 8824 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { | 8856 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { |
| 8825 return NULL; | 8857 return NULL; |
| 8826 } | 8858 } |
| 8827 ASSERT(getter.kind() == RawFunction::kImplicitGetter); | 8859 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
| 8828 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); | 8860 return new StaticGetterNode(field_ref_pos, |
| 8861 NULL, |
| 8862 false, |
| 8863 field_owner, |
| 8864 field_name); |
| 8829 } | 8865 } |
| 8830 | 8866 |
| 8831 | 8867 |
| 8832 RawObject* Parser::EvaluateConstConstructorCall( | 8868 RawObject* Parser::EvaluateConstConstructorCall( |
| 8833 const Class& type_class, | 8869 const Class& type_class, |
| 8834 const AbstractTypeArguments& type_arguments, | 8870 const AbstractTypeArguments& type_arguments, |
| 8835 const Function& constructor, | 8871 const Function& constructor, |
| 8836 ArgumentListNode* arguments) { | 8872 ArgumentListNode* arguments) { |
| 8837 // Factories have one extra argument: the type arguments. | 8873 // Factories have one extra argument: the type arguments. |
| 8838 // Constructors have 2 extra arguments: rcvr and construction phase. | 8874 // Constructors have 2 extra arguments: rcvr and construction phase. |
| (...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10334 const Type& mixin_type = Type::Handle(current_class().mixin()); | 10370 const Type& mixin_type = Type::Handle(current_class().mixin()); |
| 10335 if (mixin_type.type_class() == current_function().origin()) { | 10371 if (mixin_type.type_class() == current_function().origin()) { |
| 10336 ErrorMsg("method of mixin class '%s' may not refer to 'super'", | 10372 ErrorMsg("method of mixin class '%s' may not refer to 'super'", |
| 10337 String::Handle(Class::Handle( | 10373 String::Handle(Class::Handle( |
| 10338 current_function().origin()).Name()).ToCString()); | 10374 current_function().origin()).Name()).ToCString()); |
| 10339 } | 10375 } |
| 10340 } | 10376 } |
| 10341 ConsumeToken(); | 10377 ConsumeToken(); |
| 10342 if (CurrentToken() == Token::kPERIOD) { | 10378 if (CurrentToken() == Token::kPERIOD) { |
| 10343 ConsumeToken(); | 10379 ConsumeToken(); |
| 10380 const intptr_t ident_pos = TokenPos(); |
| 10344 const String& ident = *ExpectIdentifier("identifier expected"); | 10381 const String& ident = *ExpectIdentifier("identifier expected"); |
| 10345 if (CurrentToken() == Token::kLPAREN) { | 10382 if (CurrentToken() == Token::kLPAREN) { |
| 10346 primary = ParseSuperCall(ident); | 10383 primary = ParseSuperCall(ident); |
| 10347 } else { | 10384 } else { |
| 10348 primary = ParseSuperFieldAccess(ident); | 10385 primary = ParseSuperFieldAccess(ident, ident_pos); |
| 10349 } | 10386 } |
| 10350 } else if ((CurrentToken() == Token::kLBRACK) || | 10387 } else if ((CurrentToken() == Token::kLBRACK) || |
| 10351 Token::CanBeOverloaded(CurrentToken()) || | 10388 Token::CanBeOverloaded(CurrentToken()) || |
| 10352 (CurrentToken() == Token::kNE)) { | 10389 (CurrentToken() == Token::kNE)) { |
| 10353 primary = ParseSuperOperator(); | 10390 primary = ParseSuperOperator(); |
| 10354 } else { | 10391 } else { |
| 10355 primary = new PrimaryNode(TokenPos(), Symbols::Super()); | 10392 primary = new PrimaryNode(TokenPos(), Symbols::Super()); |
| 10356 } | 10393 } |
| 10357 } else { | 10394 } else { |
| 10358 UnexpectedToken(); | 10395 UnexpectedToken(); |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10716 void Parser::SkipQualIdent() { | 10753 void Parser::SkipQualIdent() { |
| 10717 ASSERT(IsIdentifier()); | 10754 ASSERT(IsIdentifier()); |
| 10718 ConsumeToken(); | 10755 ConsumeToken(); |
| 10719 if (CurrentToken() == Token::kPERIOD) { | 10756 if (CurrentToken() == Token::kPERIOD) { |
| 10720 ConsumeToken(); // Consume the kPERIOD token. | 10757 ConsumeToken(); // Consume the kPERIOD token. |
| 10721 ExpectIdentifier("identifier expected after '.'"); | 10758 ExpectIdentifier("identifier expected after '.'"); |
| 10722 } | 10759 } |
| 10723 } | 10760 } |
| 10724 | 10761 |
| 10725 } // namespace dart | 10762 } // namespace dart |
| OLD | NEW |