Chromium Code Reviews| Index: pkg/kernel/lib/interpreter/interpreter.dart |
| diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart |
| index 46453f221a2d8c94fe3797fd4801e3a70650a5ba..8f40bcd60b3372aa989e453d5cca11239aff4e7b 100644 |
| --- a/pkg/kernel/lib/interpreter/interpreter.dart |
| +++ b/pkg/kernel/lib/interpreter/interpreter.dart |
| @@ -4,6 +4,7 @@ |
| library kernel.interpreter; |
| import '../ast.dart'; |
| +import '../ast.dart' as ast show Class; |
| class NotImplemented { |
| String message; |
| @@ -121,25 +122,25 @@ class Evaluator extends ExpressionVisitor1<Value> { |
| Value visitPropertyGet(PropertyGet node, env) { |
| Value receiver = eval(node.receiver, env); |
| - return receiver.classDeclaration.lookupGetter(node.name)(receiver); |
| + return receiver.class_.lookupGetter(node.name)(receiver); |
| } |
| Value visitPropertySet(PropertySet node, env) { |
| Value receiver = eval(node.receiver, env); |
| Value value = eval(node.value, env); |
| - receiver.classDeclaration.lookupSetter(node.name)(receiver, value); |
| + receiver.class_.lookupSetter(node.name)(receiver, value); |
| return value; |
| } |
| Value visitDirectPropertyGet(DirectPropertyGet node, env) { |
| Value receiver = eval(node.receiver, env); |
| - return receiver.classDeclaration.getProperty(receiver, node.target); |
| + return receiver.class_.getProperty(receiver, node.target); |
| } |
| Value visitDirectPropertySet(DirectPropertySet node, env) { |
| Value receiver = eval(node.receiver, env); |
| Value value = eval(node.value, env); |
| - receiver.classDeclaration.setProperty(receiver, node.target, value); |
| + receiver.class_.setProperty(receiver, node.target, value); |
| return value; |
| } |
| @@ -171,19 +172,18 @@ class Evaluator extends ExpressionVisitor1<Value> { |
| } |
| Value visitConstructorInvocation(ConstructorInvocation node, env) { |
| - ClassDeclaration classDeclaration = |
| - new ClassDeclaration(node.target.enclosingClass.reference); |
| + Class class_ = new Class(node.target.enclosingClass.reference); |
| Environment emptyEnv = new Environment.empty(); |
| // Currently we don't support initializers. |
| // TODO: Modify to respect dart semantics for initialization. |
| // 1. Init fields and eval initializers, repeat the same with super. |
| // 2. Eval the Function body of the constructor. |
| - List<Value> fields = classDeclaration.instanceFields |
| - .map((Field f) => eval(f.initializer, emptyEnv)) |
| + List<Value> fields = class_.instanceFields |
| + .map((Field f) => eval(f.initializer ?? new NullLiteral(), emptyEnv)) |
| .toList(growable: false); |
| - return new ObjectValue(classDeclaration, fields); |
| + return new ObjectValue(class_, fields); |
| } |
| Value visitNot(Not node, env) { |
| @@ -246,11 +246,10 @@ typedef void Setter(Value receiver, Value value); |
| // TODO(zhivkag): Change misleading name. |
| // This is representation of a class in the interpreter, not a declaration. |
| -class ClassDeclaration { |
| - static final Map<Reference, ClassDeclaration> _classes = |
| - <Reference, ClassDeclaration>{}; |
| +class Class { |
| + static final Map<Reference, Class> _classes = <Reference, Class>{}; |
| - ClassDeclaration superclass; |
| + Class superclass; |
| List<Field> instanceFields = <Field>[]; |
| List<Field> staticFields = <Field>[]; |
| // Implicit getters and setters for instance Fields. |
| @@ -262,23 +261,25 @@ class ClassDeclaration { |
| List<Procedure> methods = <Procedure>[]; |
| - factory ClassDeclaration(Reference classRef) { |
| + int get classSize => instanceFields.length; |
|
Kevin Millikin (Google)
2017/03/28 06:56:26
This is more like instanceSize.
zhivkag
2017/03/28 09:18:14
Done.
|
| + |
| + factory Class(Reference classRef) { |
| if (_classes.containsKey(classRef)) { |
|
Kevin Millikin (Google)
2017/03/28 06:56:26
This pattern is in the libraries as putIfAbsent so
zhivkag
2017/03/28 09:18:14
Done.
|
| return _classes[classRef]; |
| } |
| - _classes[classRef] = new ClassDeclaration._internal(classRef.asClass); |
| + _classes[classRef] = new Class._internal(classRef.asClass); |
| return _classes[classRef]; |
| } |
| - ClassDeclaration._internal(Class currentClass) { |
| + Class._internal(ast.Class currentClass) { |
| if (currentClass.superclass != null) { |
| - superclass = new ClassDeclaration(currentClass.superclass.reference); |
| + superclass = new Class(currentClass.superclass.reference); |
| } |
| _populateInstanceFields(currentClass); |
| // Populate implicit setters and getters. |
| - for (int i = 0; i < instanceFields.length; i++) { |
| + for (int i = (superclass?.classSize ?? 0); i < instanceFields.length; i++) { |
|
Kevin Millikin (Google)
2017/03/28 06:56:26
I think it makes sense to move this into _populate
zhivkag
2017/03/28 09:18:14
Done.
|
| Field f = instanceFields[i]; |
| assert(f.hasImplicitGetter); |
| getters[f.name] = (Value receiver) => receiver.fields[i]; |
| @@ -327,21 +328,20 @@ class ClassDeclaration { |
| // Populates with the instance fields of the current class and all its |
| // superclasses recursively. |
| - _populateInstanceFields(Class class_) { |
| + _populateInstanceFields(ast.Class class_) { |
| + if (class_.superclass != null) { |
| + _populateInstanceFields(class_.superclass); |
| + } |
| for (Field f in class_.fields) { |
| if (f.isInstanceMember) { |
| instanceFields.add(f); |
| } |
| } |
| - |
| - if (class_.superclass != null) { |
| - _populateInstanceFields(class_.superclass); |
| - } |
| } |
| } |
| abstract class Value { |
| - ClassDeclaration get classDeclaration; |
| + Class get class_; |
| List<Value> get fields; |
| Object get value; |
| @@ -366,15 +366,15 @@ abstract class Value { |
| } |
| class ObjectValue extends Value { |
| - ClassDeclaration classDeclaration; |
| + Class class_; |
| List<Value> fields; |
| Object get value => this; |
| - ObjectValue(this.classDeclaration, this.fields); |
| + ObjectValue(this.class_, this.fields); |
| } |
| abstract class LiteralValue extends Value { |
| - ClassDeclaration get classDeclaration => |
| + Class get class_ => |
| notImplemented(m: "Loading class for literal is not implemented."); |
| List<Value> get fields => |
| notImplemented(m: "Literal value does not have fields"); |