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

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

Issue 10849004: Fix super getter/setter (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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
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 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 1185
1186 void Parser::CheckFunctionIsCallable(intptr_t token_pos, 1186 void Parser::CheckFunctionIsCallable(intptr_t token_pos,
1187 const Function& function) { 1187 const Function& function) {
1188 if (Class::Handle(function.owner()).is_interface()) { 1188 if (Class::Handle(function.owner()).is_interface()) {
1189 ErrorMsg(token_pos, "cannot call function of interface '%s'", 1189 ErrorMsg(token_pos, "cannot call function of interface '%s'",
1190 function.ToFullyQualifiedCString()); 1190 function.ToFullyQualifiedCString());
1191 } 1191 }
1192 } 1192 }
1193 1193
1194 1194
1195 static RawFunction* ResolveDynamicFunction(const Class& cls,
1196 const String& name) {
1197 Function& func = Function::Handle(cls.LookupDynamicFunction(name));
1198 if (func.IsNull()) {
1199 Class& super_cls = Class::Handle(cls.SuperClass());
1200 while (!super_cls.IsNull()) {
1201 func = super_cls.LookupDynamicFunction(name);
1202 if (!func.IsNull()) {
1203 return func.raw();
1204 }
1205 super_cls = super_cls.SuperClass();
1206 }
1207 }
1208 return func.raw();
1209 }
1210
1211 // Resolve and return the dynamic function of the given name in the superclass. 1195 // Resolve and return the dynamic function of the given name in the superclass.
1212 // If it is not found, return noSuchMethod and set is_no_such_method to true. 1196 // If it is not found, return noSuchMethod and set is_no_such_method to true.
1213 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, 1197 RawFunction* Parser::GetSuperFunction(intptr_t token_pos,
1214 const String& name, 1198 const String& name,
1215 bool* is_no_such_method) { 1199 bool* is_no_such_method) {
1216 const Class& super_class = Class::Handle(current_class().SuperClass()); 1200 const Class& super_class = Class::Handle(current_class().SuperClass());
1217 if (super_class.IsNull()) { 1201 if (super_class.IsNull()) {
1218 ErrorMsg(token_pos, "class '%s' does not have a superclass", 1202 ErrorMsg(token_pos, "class '%s' does not have a superclass",
1219 String::Handle(current_class().Name()).ToCString()); 1203 String::Handle(current_class().Name()).ToCString());
1220 } 1204 }
1221 1205
1222 Function& super_func = 1206 Function& super_func =
1223 Function::Handle(ResolveDynamicFunction(super_class, name)); 1207 Function::Handle(Resolver::ResolveDynamicAnyParams(super_class, name));
1224 if (super_func.IsNull()) { 1208 if (super_func.IsNull()) {
1225 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod()); 1209 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod());
1226 super_func = ResolveDynamicFunction(super_class, no_such_method_name); 1210 super_func =
1211 Resolver::ResolveDynamicAnyParams(super_class, no_such_method_name);
1227 ASSERT(!super_func.IsNull()); 1212 ASSERT(!super_func.IsNull());
1228 *is_no_such_method = true; 1213 *is_no_such_method = true;
1229 } else { 1214 } else {
1230 *is_no_such_method = false; 1215 *is_no_such_method = false;
1231 } 1216 }
1232 CheckFunctionIsCallable(token_pos, super_func); 1217 CheckFunctionIsCallable(token_pos, super_func);
1233 return super_func.raw(); 1218 return super_func.raw();
1234 } 1219 }
1235 1220
1236 1221
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 } 1414 }
1430 } 1415 }
1431 } 1416 }
1432 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); 1417 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL);
1433 } 1418 }
1434 1419
1435 1420
1436 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { 1421 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) {
1437 TRACE_PARSER("ParseSuperFieldAccess"); 1422 TRACE_PARSER("ParseSuperFieldAccess");
1438 const intptr_t field_pos = TokenPos(); 1423 const intptr_t field_pos = TokenPos();
1439 const Class& super_class = Class::Handle(current_class().SuperClass()); 1424 const Class& super_class = Class::ZoneHandle(current_class().SuperClass());
srdjan 2012/08/08 16:44:34 Why ZoneHandle, does the 'super_class' handle esca
hausner 2012/08/08 17:42:02 Yes, it is used in the static getter node in line
1440 if (super_class.IsNull()) { 1425 if (super_class.IsNull()) {
1441 ErrorMsg("class '%s' does not have a superclass", 1426 ErrorMsg("class '%s' does not have a superclass",
1442 String::Handle(current_class().Name()).ToCString()); 1427 String::Handle(current_class().Name()).ToCString());
1443 } 1428 }
1444 AstNode* implicit_argument = LoadReceiver(field_pos); 1429 AstNode* implicit_argument = LoadReceiver(field_pos);
1445 1430
1446 const String& getter_name = 1431 const String& getter_name =
1447 String::ZoneHandle(Field::GetterName(field_name)); 1432 String::ZoneHandle(Field::GetterName(field_name));
1448 const Function& super_getter = Function::ZoneHandle( 1433 const Function& super_getter = Function::ZoneHandle(
1449 ResolveDynamicFunction(super_class, getter_name)); 1434 Resolver::ResolveDynamicAnyParams(super_class, getter_name));
1450 if (super_getter.IsNull()) { 1435 if (super_getter.IsNull()) {
1451 // Check if this is an access to an implicit closure using 'super'. 1436 // Check if this is an access to an implicit closure using 'super'.
1452 // If a function exists of the specified field_name then try 1437 // If a function exists of the specified field_name then try
1453 // accessing it as a getter, at runtime we will handle this by 1438 // accessing it as a getter, at runtime we will handle this by
1454 // creating an implicit closure of the function and returning it. 1439 // creating an implicit closure of the function and returning it.
1455 const Function& super_function = Function::ZoneHandle( 1440 const Function& super_function = Function::ZoneHandle(
1456 ResolveDynamicFunction(super_class, field_name)); 1441 Resolver::ResolveDynamicAnyParams(super_class, field_name));
1457 if (super_function.IsNull()) { 1442 if (super_function.IsNull()) {
1458 ErrorMsg(field_pos, "field or getter '%s' not found in superclass", 1443 ErrorMsg(field_pos, "field or getter '%s' not found in superclass",
1459 field_name.ToCString()); 1444 field_name.ToCString());
1460 } 1445 }
1461 return CreateImplicitClosureNode(super_function, 1446 return CreateImplicitClosureNode(super_function,
1462 field_pos, 1447 field_pos,
1463 implicit_argument); 1448 implicit_argument);
1464 } 1449 }
1465 // All dynamic getters take one argument and no named arguments.
1466 ASSERT(super_getter.AreValidArgumentCounts(1, 0, NULL));
1467 ArgumentListNode* getter_arguments = new ArgumentListNode(field_pos);
1468 getter_arguments->Add(implicit_argument);
1469 AstNode* super_field =
1470 new StaticCallNode(field_pos, super_getter, getter_arguments);
1471 1450
1472 if (Token::IsAssignmentOperator(CurrentToken())) { 1451 return new StaticGetterNode(
1473 const String& setter_name = 1452 field_pos, implicit_argument, true, super_class, field_name);
1474 String::ZoneHandle(Field::SetterName(field_name));
1475 const Function& super_setter = Function::ZoneHandle(
1476 ResolveDynamicFunction(super_class, setter_name));
1477 if (super_setter.IsNull()) {
1478 ErrorMsg(field_pos,
1479 "field '%s' not assignable in superclass",
1480 field_name.ToCString());
1481 }
1482 // All dynamic setters take two arguments and no named arguments.
1483 ASSERT(super_setter.AreValidArgumentCounts(2, 0, NULL));
1484
1485 Token::Kind assignment_op = CurrentToken();
1486 ConsumeToken();
1487 AstNode* value = ParseExpr(kAllowConst, kConsumeCascades);
1488 value = ExpandAssignableOp(field_pos, assignment_op, super_field, value);
1489
1490 ArgumentListNode* setter_arguments = new ArgumentListNode(field_pos);
1491 setter_arguments->Add(implicit_argument);
1492 setter_arguments->Add(value);
1493 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments);
1494 }
1495 return super_field;
1496 } 1453 }
1497 1454
1498 1455
1499 void Parser::GenerateSuperConstructorCall(const Class& cls, 1456 void Parser::GenerateSuperConstructorCall(const Class& cls,
1500 LocalVariable* receiver) { 1457 LocalVariable* receiver) {
1501 const intptr_t supercall_pos = TokenPos(); 1458 const intptr_t supercall_pos = TokenPos();
1502 const Class& super_class = Class::Handle(cls.SuperClass()); 1459 const Class& super_class = Class::Handle(cls.SuperClass());
1503 // Omit the implicit super() if there is no super class (i.e. 1460 // Omit the implicit super() if there is no super class (i.e.
1504 // we're not compiling class Object), or if the super class is an 1461 // we're not compiling class Object), or if the super class is an
1505 // artificially generated "wrapper class" that has no constructor. 1462 // artificially generated "wrapper class" that has no constructor.
(...skipping 5194 matching lines...) Expand 10 before | Expand all | Expand 10 after
6700 func = Resolver::ResolveStatic(cls, 6657 func = Resolver::ResolveStatic(cls,
6701 getter_name, 6658 getter_name,
6702 kNumArguments, 6659 kNumArguments,
6703 kNoArgumentNames, 6660 kNoArgumentNames,
6704 Resolver::kIsQualified); 6661 Resolver::kIsQualified);
6705 if (!func.IsNull()) { 6662 if (!func.IsNull()) {
6706 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); 6663 ASSERT(func.kind() != RawFunction::kConstImplicitGetter);
6707 EnsureExpressionTemp(); 6664 EnsureExpressionTemp();
6708 closure = new StaticGetterNode(call_pos, 6665 closure = new StaticGetterNode(call_pos,
6709 NULL, 6666 NULL,
6667 false,
srdjan 2012/08/08 16:44:34 add comment what false means.
hausner 2012/08/08 17:42:02 I don't think that makes the program more readable
6710 Class::ZoneHandle(cls.raw()), 6668 Class::ZoneHandle(cls.raw()),
6711 func_name); 6669 func_name);
6712 return new ClosureCallNode(call_pos, closure, arguments); 6670 return new ClosureCallNode(call_pos, closure, arguments);
6713 } 6671 }
6714 } else { 6672 } else {
6715 EnsureExpressionTemp(); 6673 EnsureExpressionTemp();
6716 closure = GenerateStaticFieldLookup(field, call_pos); 6674 closure = GenerateStaticFieldLookup(field, call_pos);
6717 return new ClosureCallNode(call_pos, closure, arguments); 6675 return new ClosureCallNode(call_pos, closure, arguments);
6718 } 6676 }
6719 // Could not resolve static method: throw an exception if the arguments 6677 // Could not resolve static method: throw an exception if the arguments
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
6809 ErrorMsg(ident_pos, "unknown static field '%s'", 6767 ErrorMsg(ident_pos, "unknown static field '%s'",
6810 field_name.ToCString()); 6768 field_name.ToCString());
6811 } 6769 }
6812 6770
6813 // Explicit setter function for the field found, field does not exist. 6771 // Explicit setter function for the field found, field does not exist.
6814 // Create a getter node first in case it is needed. If getter node 6772 // Create a getter node first in case it is needed. If getter node
6815 // is used as part of, e.g., "+=", and the explicit getter does not 6773 // is used as part of, e.g., "+=", and the explicit getter does not
6816 // exist, and error will be reported by the code generator. 6774 // exist, and error will be reported by the code generator.
6817 access = new StaticGetterNode(call_pos, 6775 access = new StaticGetterNode(call_pos,
6818 NULL, 6776 NULL,
6777 false,
srdjan 2012/08/08 16:44:34 ditto
6819 Class::ZoneHandle(cls.raw()), 6778 Class::ZoneHandle(cls.raw()),
6820 String::ZoneHandle(field_name.raw())); 6779 String::ZoneHandle(field_name.raw()));
6821 } else { 6780 } else {
6822 // Field exists. 6781 // Field exists.
6823 if (field.is_final()) { 6782 if (field.is_final()) {
6824 // Field has been marked as final, report an error as the field 6783 // Field has been marked as final, report an error as the field
6825 // is not settable. 6784 // is not settable.
6826 ErrorMsg(ident_pos, 6785 ErrorMsg(ident_pos,
6827 "field '%s' is const static, cannot assign to it", 6786 "field '%s' is const static, cannot assign to it",
6828 field_name.ToCString()); 6787 field_name.ToCString());
(...skipping 19 matching lines...) Expand all
6848 if (func.IsNull()) { 6807 if (func.IsNull()) {
6849 // No field or explicit getter function, this is an error. 6808 // No field or explicit getter function, this is an error.
6850 ErrorMsg(ident_pos, 6809 ErrorMsg(ident_pos,
6851 "unknown static field '%s'", field_name.ToCString()); 6810 "unknown static field '%s'", field_name.ToCString());
6852 } 6811 }
6853 access = CreateImplicitClosureNode(func, call_pos, NULL); 6812 access = CreateImplicitClosureNode(func, call_pos, NULL);
6854 } else { 6813 } else {
6855 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); 6814 ASSERT(func.kind() != RawFunction::kConstImplicitGetter);
6856 access = new StaticGetterNode(call_pos, 6815 access = new StaticGetterNode(call_pos,
6857 NULL, 6816 NULL,
6817 false,
srdjan 2012/08/08 16:44:34 ditto
6858 Class::ZoneHandle(cls.raw()), 6818 Class::ZoneHandle(cls.raw()),
6859 field_name); 6819 field_name);
6860 } 6820 }
6861 } else { 6821 } else {
6862 access = GenerateStaticFieldLookup(field, TokenPos()); 6822 access = GenerateStaticFieldLookup(field, TokenPos());
6863 } 6823 }
6864 } 6824 }
6865 return access; 6825 return access;
6866 } 6826 }
6867 6827
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
7248 if (value.raw() == Object::transition_sentinel()) { 7208 if (value.raw() == Object::transition_sentinel()) {
7249 // TODO(hausner): Remove the check for is_final() once we support 7209 // TODO(hausner): Remove the check for is_final() once we support
7250 // non-const final fields. 7210 // non-const final fields.
7251 if (field.is_const() || field.is_final()) { 7211 if (field.is_const() || field.is_final()) {
7252 ErrorMsg("circular dependency while initializing static field '%s'", 7212 ErrorMsg("circular dependency while initializing static field '%s'",
7253 String::Handle(field.name()).ToCString()); 7213 String::Handle(field.name()).ToCString());
7254 } else { 7214 } else {
7255 // The implicit static getter will throw the exception if necessary. 7215 // The implicit static getter will throw the exception if necessary.
7256 return new StaticGetterNode(TokenPos(), 7216 return new StaticGetterNode(TokenPos(),
7257 NULL, 7217 NULL,
7218 false,
srdjan 2012/08/08 16:44:34 ditto
7258 Class::ZoneHandle(field.owner()), 7219 Class::ZoneHandle(field.owner()),
7259 String::ZoneHandle(field.name())); 7220 String::ZoneHandle(field.name()));
7260 } 7221 }
7261 } else if (value.raw() == Object::sentinel()) { 7222 } else if (value.raw() == Object::sentinel()) {
7262 // This field has not been referenced yet and thus the value has 7223 // This field has not been referenced yet and thus the value has
7263 // not been evaluated. If the field is const, call the static getter method 7224 // not been evaluated. If the field is const, call the static getter method
7264 // to evaluate the expression and canonicalize the value. 7225 // to evaluate the expression and canonicalize the value.
7265 // TODO(hausner): Remove the check for is_final() once we support 7226 // TODO(hausner): Remove the check for is_final() once we support
7266 // non-const final fields. 7227 // non-const final fields.
7267 if (field.is_const() || field.is_final()) { 7228 if (field.is_const() || field.is_final()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
7299 ASSERT(const_value.IsNull() || const_value.IsInstance()); 7260 ASSERT(const_value.IsNull() || const_value.IsInstance());
7300 Instance& instance = Instance::Handle(); 7261 Instance& instance = Instance::Handle();
7301 instance ^= const_value.raw(); 7262 instance ^= const_value.raw();
7302 if (!instance.IsNull()) { 7263 if (!instance.IsNull()) {
7303 instance ^= instance.Canonicalize(); 7264 instance ^= instance.Canonicalize();
7304 } 7265 }
7305 field.set_value(instance); 7266 field.set_value(instance);
7306 } else { 7267 } else {
7307 return new StaticGetterNode(TokenPos(), 7268 return new StaticGetterNode(TokenPos(),
7308 NULL, 7269 NULL,
7270 false,
srdjan 2012/08/08 16:44:34 ditto
7309 Class::ZoneHandle(field.owner()), 7271 Class::ZoneHandle(field.owner()),
7310 String::ZoneHandle(field.name())); 7272 String::ZoneHandle(field.name()));
7311 } 7273 }
7312 } 7274 }
7313 return NULL; 7275 return NULL;
7314 } 7276 }
7315 7277
7316 7278
7317 RawObject* Parser::EvaluateConstConstructorCall( 7279 RawObject* Parser::EvaluateConstConstructorCall(
7318 const Class& type_class, 7280 const Class& type_class,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
7422 if (func.IsDynamicFunction()) { 7384 if (func.IsDynamicFunction()) {
7423 if (node != NULL) { 7385 if (node != NULL) {
7424 CheckInstanceFieldAccess(ident_pos, ident); 7386 CheckInstanceFieldAccess(ident_pos, ident);
7425 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 7387 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
7426 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); 7388 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
7427 } 7389 }
7428 return true; 7390 return true;
7429 } else if (func.IsStaticFunction()) { 7391 } else if (func.IsStaticFunction()) {
7430 if (node != NULL) { 7392 if (node != NULL) {
7431 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 7393 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
7432 // The static getter may be changed later into an instance setter. 7394 // The static getter may later be changed into a dynamically
7395 // resolved instance setter if no static setter can
7396 // be found.
7433 AstNode* receiver = NULL; 7397 AstNode* receiver = NULL;
7434 const bool kTestOnly = true; 7398 const bool kTestOnly = true;
7435 ASSERT(!current_function().IsInFactoryScope()); 7399 ASSERT(!current_function().IsInFactoryScope());
7436 if (!current_function().is_static() && 7400 if (!current_function().is_static() &&
7437 (LookupReceiver(current_block_->scope, kTestOnly) != NULL)) { 7401 (LookupReceiver(current_block_->scope, kTestOnly) != NULL)) {
7438 receiver = LoadReceiver(ident_pos); 7402 receiver = LoadReceiver(ident_pos);
7439 } 7403 }
7440 *node = new StaticGetterNode(ident_pos, 7404 *node = new StaticGetterNode(ident_pos,
7441 receiver, 7405 receiver,
7406 false,
srdjan 2012/08/08 16:44:34 ditto and all other places.
7442 Class::ZoneHandle(isolate, cls.raw()), 7407 Class::ZoneHandle(isolate, cls.raw()),
7443 ident); 7408 ident);
7444 } 7409 }
7445 return true; 7410 return true;
7446 } 7411 }
7447 } 7412 }
7448 func = cls.LookupSetterFunction(ident); 7413 func = cls.LookupSetterFunction(ident);
7449 if (!func.IsNull()) { 7414 if (!func.IsNull()) {
7450 if (func.IsDynamicFunction()) { 7415 if (func.IsDynamicFunction()) {
7451 if (node != NULL) { 7416 if (node != NULL) {
7452 // We create a getter node even though a getter doesn't exist as 7417 // We create a getter node even though a getter doesn't exist as
7453 // it could be followed by an assignment which will convert it to 7418 // it could be followed by an assignment which will convert it to
7454 // a setter node. If there is no assignment we will get an error 7419 // a setter node. If there is no assignment we will get an error
7455 // when we try to invoke the getter. 7420 // when we try to invoke the getter.
7456 CheckInstanceFieldAccess(ident_pos, ident); 7421 CheckInstanceFieldAccess(ident_pos, ident);
7457 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 7422 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
7458 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); 7423 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
7459 } 7424 }
7460 return true; 7425 return true;
7461 } else if (func.IsStaticFunction()) { 7426 } else if (func.IsStaticFunction()) {
7462 if (node != NULL) { 7427 if (node != NULL) {
7463 // We create a getter node even though a getter doesn't exist as 7428 // We create a getter node even though a getter doesn't exist as
7464 // it could be followed by an assignment which will convert it to 7429 // it could be followed by an assignment which will convert it to
7465 // a setter node. If there is no assignment we will get an error 7430 // a setter node. If there is no assignment we will get an error
7466 // when we try to invoke the getter. 7431 // when we try to invoke the getter.
7467 *node = new StaticGetterNode(ident_pos, 7432 *node = new StaticGetterNode(ident_pos,
7468 NULL, 7433 NULL,
7434 false,
7469 Class::ZoneHandle(isolate, cls.raw()), 7435 Class::ZoneHandle(isolate, cls.raw()),
7470 ident); 7436 ident);
7471 } 7437 }
7472 return true; 7438 return true;
7473 } 7439 }
7474 } 7440 }
7475 7441
7476 // Nothing found in scope of current class. 7442 // Nothing found in scope of current class.
7477 if (node != NULL) { 7443 if (node != NULL) {
7478 *node = NULL; 7444 *node = NULL;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
7531 obj = lib.LookupObject(accessor_name); 7497 obj = lib.LookupObject(accessor_name);
7532 } 7498 }
7533 } 7499 }
7534 if (!obj.IsNull()) { 7500 if (!obj.IsNull()) {
7535 ASSERT(obj.IsFunction()); 7501 ASSERT(obj.IsFunction());
7536 const Function& func = Function::Cast(obj); 7502 const Function& func = Function::Cast(obj);
7537 ASSERT(func.is_static()); 7503 ASSERT(func.is_static());
7538 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 7504 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
7539 return new StaticGetterNode(qual_ident.ident_pos, 7505 return new StaticGetterNode(qual_ident.ident_pos,
7540 NULL, 7506 NULL,
7507 false,
7541 Class::ZoneHandle(func.owner()), 7508 Class::ZoneHandle(func.owner()),
7542 *qual_ident.ident); 7509 *qual_ident.ident);
7543 } 7510 }
7544 if (qual_ident.lib_prefix != NULL) { 7511 if (qual_ident.lib_prefix != NULL) {
7545 return NULL; 7512 return NULL;
7546 } 7513 }
7547 // Lexically unresolved primary identifiers are referenced by their name. 7514 // Lexically unresolved primary identifiers are referenced by their name.
7548 return new PrimaryNode(qual_ident.ident_pos, *qual_ident.ident); 7515 return new PrimaryNode(qual_ident.ident_pos, *qual_ident.ident);
7549 } 7516 }
7550 7517
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after
8944 void Parser::SkipQualIdent() { 8911 void Parser::SkipQualIdent() {
8945 ASSERT(IsIdentifier()); 8912 ASSERT(IsIdentifier());
8946 ConsumeToken(); 8913 ConsumeToken();
8947 if (CurrentToken() == Token::kPERIOD) { 8914 if (CurrentToken() == Token::kPERIOD) {
8948 ConsumeToken(); // Consume the kPERIOD token. 8915 ConsumeToken(); // Consume the kPERIOD token.
8949 ExpectIdentifier("identifier expected after '.'"); 8916 ExpectIdentifier("identifier expected after '.'");
8950 } 8917 }
8951 } 8918 }
8952 8919
8953 } // namespace dart 8920 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698