| Index: pkg/kernel/lib/interpreter/interpreter.dart
|
| diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
|
| index b61da18fa505d16957082fe1f153cd96fb45323b..a64fe581f12f7be928f4f34308138c6a63545c48 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;
|
| @@ -103,25 +104,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;
|
| }
|
|
|
| @@ -153,19 +154,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) {
|
| @@ -274,11 +274,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.
|
| @@ -290,31 +289,19 @@ class ClassDeclaration {
|
|
|
| List<Procedure> methods = <Procedure>[];
|
|
|
| - factory ClassDeclaration(Reference classRef) {
|
| - if (_classes.containsKey(classRef)) {
|
| - return _classes[classRef];
|
| - }
|
| - _classes[classRef] = new ClassDeclaration._internal(classRef.asClass);
|
| - return _classes[classRef];
|
| + int get instanceSize => instanceFields.length;
|
| +
|
| + factory Class(Reference classRef) {
|
| + return _classes.putIfAbsent(
|
| + classRef, () => new Class._internal(classRef.asClass));
|
| }
|
|
|
| - 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++) {
|
| - Field f = instanceFields[i];
|
| - assert(f.hasImplicitGetter);
|
| - getters[f.name] = (Value receiver) => receiver.fields[i];
|
| - if (f.hasImplicitSetter) {
|
| - setters[f.name] =
|
| - (Value receiver, Value value) => receiver.fields[i] = value;
|
| - }
|
| - }
|
| // TODO: Populate methods.
|
| }
|
|
|
| @@ -353,23 +340,33 @@ class ClassDeclaration {
|
| return notImplemented(obj: member);
|
| }
|
|
|
| - // Populates with the instance fields of the current class and all its
|
| - // superclasses recursively.
|
| - _populateInstanceFields(Class class_) {
|
| - for (Field f in class_.fields) {
|
| - if (f.isInstanceMember) {
|
| - instanceFields.add(f);
|
| - }
|
| - }
|
| -
|
| + /// Populates instance variables and the corresponding implicit getters and
|
| + /// setters for the current class and its superclass recursively.
|
| + _populateInstanceFields(ast.Class class_) {
|
| if (class_.superclass != null) {
|
| _populateInstanceFields(class_.superclass);
|
| }
|
| +
|
| + for (Field f in class_.fields) {
|
| + if (f.isStatic) continue;
|
| + instanceFields.add(f);
|
| + assert(f.hasImplicitGetter);
|
| +
|
| + int currentFieldIndex = instanceFields.length - 1;
|
| +
|
| + // Shadowing an inherited getter with the same name.
|
| + getters[f.name] = (Value receiver) => receiver.fields[currentFieldIndex];
|
| + if (f.hasImplicitSetter) {
|
| + // Shadowing an inherited setter with the same name.
|
| + setters[f.name] = (Value receiver, Value value) =>
|
| + receiver.fields[currentFieldIndex] = value;
|
| + }
|
| + }
|
| }
|
| }
|
|
|
| abstract class Value {
|
| - ClassDeclaration get classDeclaration;
|
| + Class get class_;
|
| List<Value> get fields;
|
| Object get value;
|
|
|
| @@ -394,15 +391,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");
|
|
|