From 3bfe9eaf41f994221dc11090c5c3a283a49310ab Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 22 Apr 2016 21:34:36 +0100 Subject: Add support for this references in anonymous types --- .../zwobble/couscous/ast/sugar/AnonymousClass.java | 10 ++++++- .../couscous/frontends/java/AnonymousType.java | 35 ++++++++++++++++++++++ .../couscous/frontends/java/JavaReader.java | 15 ++++++++-- .../zwobble/couscous/frontends/java/JavaTypes.java | 2 +- 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/frontends/java/AnonymousType.java (limited to 'src/main/java') diff --git a/src/main/java/org/zwobble/couscous/ast/sugar/AnonymousClass.java b/src/main/java/org/zwobble/couscous/ast/sugar/AnonymousClass.java index edf71d4..08bb9a3 100644 --- a/src/main/java/org/zwobble/couscous/ast/sugar/AnonymousClass.java +++ b/src/main/java/org/zwobble/couscous/ast/sugar/AnonymousClass.java @@ -2,27 +2,35 @@ package org.zwobble.couscous.ast.sugar; import org.zwobble.couscous.ast.FieldDeclarationNode; import org.zwobble.couscous.ast.MethodNode; +import org.zwobble.couscous.frontends.java.AnonymousType; import org.zwobble.couscous.types.Type; import java.util.List; +import java.util.Optional; import java.util.Set; public class AnonymousClass { + private final Optional type; private final Set superTypes; private final List fields; private final List methods; public AnonymousClass( + Optional type, Set superTypes, List fields, List methods) { - + this.type = type; this.superTypes = superTypes; this.fields = fields; this.methods = methods; } + public Optional getType() { + return type; + } + public Set getSuperTypes() { return superTypes; } diff --git a/src/main/java/org/zwobble/couscous/frontends/java/AnonymousType.java b/src/main/java/org/zwobble/couscous/frontends/java/AnonymousType.java new file mode 100644 index 0000000..845c6f9 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/frontends/java/AnonymousType.java @@ -0,0 +1,35 @@ +package org.zwobble.couscous.frontends.java; + +import org.zwobble.couscous.types.Type; + +public class AnonymousType implements Type { + public static Type anonymousType(String key) { + return new AnonymousType(key); + } + + private final String key; + + public AnonymousType(String key) { + this.key = key; + } + + @Override + public T accept(Visitor visitor) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AnonymousType that = (AnonymousType) o; + + return key.equals(that.key); + } + + @Override + public int hashCode() { + return key.hashCode(); + } +} diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java index 08adbcc..7fae204 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -49,6 +49,7 @@ import static org.zwobble.couscous.types.Types.erasure; import static org.zwobble.couscous.util.Casts.tryCast; import static org.zwobble.couscous.util.ExtraIterables.lazyMap; import static org.zwobble.couscous.util.ExtraLists.*; +import static org.zwobble.couscous.util.ExtraMaps.map; public class JavaReader { public static List readClassesFromFiles(List sourcePaths, List sourceFiles) throws IOException { @@ -183,6 +184,7 @@ public class JavaReader { overrides(functionalInterfaceMethod)); return new AnonymousClass( + Optional.empty(), superTypesAndSelf(functionalInterfaceMethod.getDeclaringClass()), list(), list(method)); @@ -233,6 +235,7 @@ public class JavaReader { Scope scope = outerScope.enterClass(className); TypeDeclarationBody bodyDeclarations = readTypeDeclarationBody(scope, className, declaration.bodyDeclarations()); AnonymousClass anonymousClass = new AnonymousClass( + Optional.of((AnonymousType) typeOf(declaration.resolveBinding())), superTypes(declaration), bodyDeclarations.getFields(), bodyDeclarations.getMethods()); @@ -305,14 +308,22 @@ public class JavaReader { ScalarType className, AnonymousClass anonymousClass ) { - return classWithCapture(scope, ClassNode.declareClass( + ClassNode classNode = ClassNode.declareClass( className, list(), anonymousClass.getSuperTypes(), anonymousClass.getFields(), list(), ConstructorNode.DEFAULT, - anonymousClass.getMethods())); + anonymousClass.getMethods()); + if (anonymousClass.getType().isPresent()) { + NodeTransformer nodeTransformer = NodeTransformer.replaceExpressions(map( + thisReference(anonymousClass.getType().get()), + thisReference(className) + )); + classNode = classNode.transform(nodeTransformer); + } + return classWithCapture(scope, classNode); } private FieldDeclarationNode fieldForCapture(ReferenceNode freeVariable) { diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java index 1421e83..9b634b9 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java @@ -37,7 +37,7 @@ public class JavaTypes { static Type typeOf(ITypeBinding typeBinding) { if (typeBinding.isAnonymous()) { - throw new RuntimeException("Cannot get type of anonymous type binding"); + return new AnonymousType(typeBinding.getKey()); } if (typeBinding.isArray()) { return Types.array(typeOf(typeBinding.getElementType())); -- cgit v1.2.3