From bac463d6b411c2108d56190b5766c9c92eade69d Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 13 Feb 2016 14:53:32 +0000 Subject: Distinguish static and instance fields when checking field exists --- .../couscous/interpreter/values/ConcreteType.java | 12 +++-- .../couscous/interpreter/values/FieldValue.java | 56 ++++++++++++---------- .../interpreter/values/InterpreterFields.java | 22 +++++++-- .../interpreter/values/ObjectInterpreterValue.java | 2 +- .../interpreter/values/StaticReceiverValue.java | 2 +- 5 files changed, 58 insertions(+), 36 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java index 3a4443f..63c1bbe 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java @@ -41,7 +41,7 @@ public class ConcreteType { } public Builder field(String name, TypeName type) { - fields.put(name, new FieldValue(name, type)); + fields.put(name, new FieldValue(false, name, type)); return this; } @@ -92,7 +92,10 @@ public class ConcreteType { } public static ConcreteType fromNode(ClassNode classNode) { - Map fields = classNode.getFields().stream().collect(toMap(field -> field.getName(), field -> new FieldValue(field.getName(), field.getType()))); + Map fields = classNode.getFields().stream() + .collect(toMap( + field -> field.getName(), + field -> new FieldValue(field.isStatic(), field.getName(), field.getType()))); MethodValue constructor = new MethodValue(getArgumentTypes(classNode.getConstructor().getArguments()), (environment, arguments) -> Executor.callMethod(environment, classNode.getConstructor(), Optional.of(arguments.getReceiver()), arguments.getPositionalArguments())); Map methods = classNode.getMethods() .stream() @@ -158,8 +161,9 @@ public class ConcreteType { return superTypes; } - public Optional getField(String fieldName) { - return Optional.ofNullable(fields.get(fieldName)); + public Optional getField(boolean isStatic, String fieldName) { + return Optional.ofNullable(fields.get(fieldName)) + .filter(field -> field.isStatic() == isStatic); } public List getStaticConstructor() { diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/FieldValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/FieldValue.java index 4ee1c95..90a6099 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/FieldValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/FieldValue.java @@ -3,14 +3,20 @@ package org.zwobble.couscous.interpreter.values; import org.zwobble.couscous.ast.TypeName; public final class FieldValue { + private final boolean isStatic; private final String name; private final TypeName type; - public FieldValue(final String name, final TypeName type) { + public FieldValue(final boolean isStatic, final String name, final TypeName type) { + this.isStatic = isStatic; this.name = name; this.type = type; } + public boolean isStatic() { + return isStatic; + } + public String getName() { return this.name; } @@ -19,33 +25,33 @@ public final class FieldValue { return this.type; } - @java.lang.Override - public boolean equals(final java.lang.Object o) { - if (o == this) return true; - if (!(o instanceof FieldValue)) return false; - final FieldValue other = (FieldValue)o; - final java.lang.Object this$name = this.getName(); - final java.lang.Object other$name = other.getName(); - if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false; - final java.lang.Object this$type = this.getType(); - final java.lang.Object other$type = other.getType(); - if (this$type == null ? other$type != null : !this$type.equals(other$type)) return false; - return true; + @Override + public String toString() { + return "FieldValue(" + + "isStatic=" + isStatic + + ", name='" + name + '\'' + + ", type=" + type + + ')'; } - @java.lang.Override - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $name = this.getName(); - result = result * PRIME + ($name == null ? 43 : $name.hashCode()); - final java.lang.Object $type = this.getType(); - result = result * PRIME + ($type == null ? 43 : $type.hashCode()); - return result; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FieldValue that = (FieldValue) o; + + if (isStatic != that.isStatic) return false; + if (!name.equals(that.name)) return false; + return type.equals(that.type); + } - @java.lang.Override - public java.lang.String toString() { - return "FieldValue(name=" + this.getName() + ", type=" + this.getType() + ")"; + @Override + public int hashCode() { + int result = (isStatic ? 1 : 0); + result = 31 * result + name.hashCode(); + result = 31 * result + type.hashCode(); + return result; } } \ No newline at end of file diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterFields.java b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterFields.java index fc082a5..df33d60 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterFields.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterFields.java @@ -8,18 +8,26 @@ import java.util.HashMap; import java.util.Map; public class InterpreterFields { - // TODO: distinguish static and non-static fields + public static InterpreterFields forClass(ConcreteType type) { + return new InterpreterFields(true, type); + } + + public static InterpreterFields forInstanceOf(ConcreteType type) { + return new InterpreterFields(false, type); + } + private final boolean isStatic; private final ConcreteType type; private final Map fields; - public InterpreterFields(ConcreteType type) { + private InterpreterFields(boolean isStatic, ConcreteType type) { + this.isStatic = isStatic; this.type = type; this.fields = new HashMap<>(); } public InterpreterValue getField(String fieldName) { - type.getField(fieldName).orElseThrow(() -> new NoSuchField(fieldName)); + getFieldDefinition(fieldName); if (fields.containsKey(fieldName)) { return fields.get(fieldName); } else { @@ -28,9 +36,13 @@ public class InterpreterFields { } public void setField(String fieldName, InterpreterValue value) { - FieldValue field = type.getField(fieldName) - .orElseThrow(() -> new NoSuchField(fieldName)); + FieldValue field = getFieldDefinition(fieldName); InterpreterTypes.checkIsInstance(field.getType(), value); fields.put(fieldName, value); } + + private FieldValue getFieldDefinition(String fieldName) { + return type.getField(isStatic, fieldName) + .orElseThrow(() -> new NoSuchField(fieldName)); + } } diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java index e46ae45..e15c01d 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java @@ -10,7 +10,7 @@ public class ObjectInterpreterValue implements InterpreterValue { public ObjectInterpreterValue(ConcreteType type) { this.type = type; - this.fields = new InterpreterFields(type); + this.fields = InterpreterFields.forInstanceOf(type); } @Override diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java index 9844e33..2595623 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java @@ -12,7 +12,7 @@ public class StaticReceiverValue implements ReceiverValue { public StaticReceiverValue(ConcreteType type) { this.type = type; - this.fields = new InterpreterFields(type); + this.fields = InterpreterFields.forClass(type); } @Override -- cgit v1.2.3