From 95669601271985c89a10d673571dd89133f1e2e8 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Tue, 8 Mar 2016 11:01:29 +0000 Subject: Read formal type parameters --- .../java/org/zwobble/couscous/ast/ClassNode.java | 57 ++++++++++++++-------- .../org/zwobble/couscous/ast/ClassNodeBuilder.java | 9 ++++ .../couscous/ast/FormalTypeParameterNode.java | 43 ++++++++++++++++ .../org/zwobble/couscous/ast/InterfaceNode.java | 32 ++++++++---- .../java/org/zwobble/couscous/ast/TypeNode.java | 1 + .../couscous/frontends/java/JavaReader.java | 13 ++++- 6 files changed, 125 insertions(+), 30 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/ast/FormalTypeParameterNode.java (limited to 'src/main/java') diff --git a/src/main/java/org/zwobble/couscous/ast/ClassNode.java b/src/main/java/org/zwobble/couscous/ast/ClassNode.java index bdb3499..745fb64 100644 --- a/src/main/java/org/zwobble/couscous/ast/ClassNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ClassNode.java @@ -15,16 +15,19 @@ public class ClassNode implements TypeNode { } public static ClassNode declareClass( - TypeName name, - Set superTypes, - List fields, - List staticConstructor, - ConstructorNode constructor, - List methods) { - return new ClassNode(name, superTypes, fields, staticConstructor, constructor, methods); + TypeName name, + List typeParameters, + Set superTypes, + List fields, + List staticConstructor, + ConstructorNode constructor, + List methods) + { + return new ClassNode(name, typeParameters, superTypes, fields, staticConstructor, constructor, methods); } private final TypeName name; + private final List typeParameters; private final Set superTypes; private final List fields; private final List staticConstructor; @@ -33,6 +36,7 @@ public class ClassNode implements TypeNode { public ClassNode( TypeName name, + List typeParameters, Set superTypes, List fields, List staticConstructor, @@ -40,6 +44,7 @@ public class ClassNode implements TypeNode { List methodNodes) { this.name = name; + this.typeParameters = typeParameters; this.superTypes = superTypes; this.fields = fields; this.staticConstructor = staticConstructor; @@ -52,6 +57,11 @@ public class ClassNode implements TypeNode { return name; } + @Override + public List getTypeParameters() { + return typeParameters; + } + @Override public Set getSuperTypes() { return superTypes; @@ -87,12 +97,29 @@ public class ClassNode implements TypeNode { public ClassNode transform(NodeTransformer transformer) { return new ClassNode( transformer.transform(name), + // TODO: transform + typeParameters, transformer.transformTypes(superTypes), transformer.transformFields(fields), - staticConstructor, transformer.transformConstructor(constructor), + // TODO: transform + staticConstructor, + transformer.transformConstructor(constructor), transformer.transformMethods(methods)); } + @Override + public String toString() { + return "ClassNode(" + + "name=" + name + + ", typeParameters=" + typeParameters + + ", superTypes=" + superTypes + + ", fields=" + fields + + ", staticConstructor=" + staticConstructor + + ", constructor=" + constructor + + ", methods=" + methods + + ')'; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -101,6 +128,7 @@ public class ClassNode implements TypeNode { ClassNode classNode = (ClassNode) o; if (!name.equals(classNode.name)) return false; + if (!typeParameters.equals(classNode.typeParameters)) return false; if (!superTypes.equals(classNode.superTypes)) return false; if (!fields.equals(classNode.fields)) return false; if (!staticConstructor.equals(classNode.staticConstructor)) return false; @@ -112,6 +140,7 @@ public class ClassNode implements TypeNode { @Override public int hashCode() { int result = name.hashCode(); + result = 31 * result + typeParameters.hashCode(); result = 31 * result + superTypes.hashCode(); result = 31 * result + fields.hashCode(); result = 31 * result + staticConstructor.hashCode(); @@ -119,16 +148,4 @@ public class ClassNode implements TypeNode { result = 31 * result + methods.hashCode(); return result; } - - @Override - public String toString() { - return "ClassNode(" + - "name=" + name + - ", superTypes=" + superTypes + - ", fields=" + fields + - ", staticConstructor=" + staticConstructor + - ", constructor=" + constructor + - ", methods=" + methods + - ')'; - } } diff --git a/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java b/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java index 04491ab..3a1b81b 100644 --- a/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java +++ b/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java @@ -104,6 +104,7 @@ public class ClassNodeBuilder { public ClassNode build() { return ClassNode.declareClass( name, + list(), superTypes.build(), fields.build(), staticConstructor, @@ -111,6 +112,14 @@ public class ClassNodeBuilder { methods.build()); } + public InterfaceNode buildInterface() { + return InterfaceNode.declareInterface( + name, + list(), + superTypes.build(), + methods.build()); + } + public class MethodBuilder { private final Function, T> build; private final ImmutableList.Builder annotations; diff --git a/src/main/java/org/zwobble/couscous/ast/FormalTypeParameterNode.java b/src/main/java/org/zwobble/couscous/ast/FormalTypeParameterNode.java new file mode 100644 index 0000000..4056548 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/FormalTypeParameterNode.java @@ -0,0 +1,43 @@ +package org.zwobble.couscous.ast; + +import org.zwobble.couscous.ast.visitors.NodeMapper; + +public class FormalTypeParameterNode implements Node { + public static FormalTypeParameterNode formalTypeParameter(String name) { + return new FormalTypeParameterNode(name); + } + + private final String name; + + public FormalTypeParameterNode(String name) { + this.name = name; + } + + @Override + public T accept(NodeMapper visitor) { + throw new UnsupportedOperationException(); + } + + @Override + public String toString() { + return "FormalTypeParameterNode(" + + "name=" + name + + ')'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FormalTypeParameterNode that = (FormalTypeParameterNode) o; + + return name.equals(that.name); + + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} diff --git a/src/main/java/org/zwobble/couscous/ast/InterfaceNode.java b/src/main/java/org/zwobble/couscous/ast/InterfaceNode.java index 854728f..6353a45 100644 --- a/src/main/java/org/zwobble/couscous/ast/InterfaceNode.java +++ b/src/main/java/org/zwobble/couscous/ast/InterfaceNode.java @@ -9,22 +9,26 @@ import java.util.Set; public class InterfaceNode implements TypeNode { public static InterfaceNode declareInterface( TypeName name, + List typeParameters, Set superTypes, List methods) { - return new InterfaceNode(name, superTypes, methods); + return new InterfaceNode(name, typeParameters, superTypes, methods); } private final TypeName name; + private final List typeParameters; private final Set superTypes; private final List methods; private InterfaceNode( TypeName name, + List typeParameters, Set superTypes, List methodNodes) { this.name = name; + this.typeParameters = typeParameters; this.superTypes = superTypes; methods = methodNodes; } @@ -34,6 +38,11 @@ public class InterfaceNode implements TypeNode { return name; } + @Override + public List getTypeParameters() { + return typeParameters; + } + @Override public Set getSuperTypes() { return superTypes; @@ -49,23 +58,26 @@ public class InterfaceNode implements TypeNode { return visitor.visit(this); } - @Override - public InterfaceNode transform(NodeTransformer transformer) { - return new InterfaceNode( - transformer.transform(name), - transformer.transformTypes(superTypes), - transformer.transformMethods(methods)); - } - @Override public String toString() { return "InterfaceNode(" + "name=" + name + + ", typeParameters=" + typeParameters + ", superTypes=" + superTypes + ", methods=" + methods + ')'; } + @Override + public InterfaceNode transform(NodeTransformer transformer) { + return new InterfaceNode( + transformer.transform(name), + // TODO: transform + typeParameters, + transformer.transformTypes(superTypes), + transformer.transformMethods(methods)); + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -74,6 +86,7 @@ public class InterfaceNode implements TypeNode { InterfaceNode that = (InterfaceNode) o; if (!name.equals(that.name)) return false; + if (!typeParameters.equals(that.typeParameters)) return false; if (!superTypes.equals(that.superTypes)) return false; return methods.equals(that.methods); @@ -82,6 +95,7 @@ public class InterfaceNode implements TypeNode { @Override public int hashCode() { int result = name.hashCode(); + result = 31 * result + typeParameters.hashCode(); result = 31 * result + superTypes.hashCode(); result = 31 * result + methods.hashCode(); return result; diff --git a/src/main/java/org/zwobble/couscous/ast/TypeNode.java b/src/main/java/org/zwobble/couscous/ast/TypeNode.java index 8277cda..e3a78af 100644 --- a/src/main/java/org/zwobble/couscous/ast/TypeNode.java +++ b/src/main/java/org/zwobble/couscous/ast/TypeNode.java @@ -7,6 +7,7 @@ import java.util.Set; public interface TypeNode extends Node { TypeName getName(); + List getTypeParameters(); Set getSuperTypes(); List getMethods(); TypeNode transform(NodeTransformer transformer); 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 a071127..73cf749 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -25,6 +25,7 @@ import static org.zwobble.couscous.ast.AssignmentNode.assignStatement; import static org.zwobble.couscous.ast.ConstructorNode.constructor; import static org.zwobble.couscous.ast.FieldAccessNode.fieldAccess; import static org.zwobble.couscous.ast.FieldDeclarationNode.field; +import static org.zwobble.couscous.ast.FormalTypeParameterNode.formalTypeParameter; import static org.zwobble.couscous.ast.InstanceReceiver.instanceReceiver; import static org.zwobble.couscous.ast.StaticReceiver.staticReceiver; import static org.zwobble.couscous.ast.ThisReferenceNode.thisReference; @@ -82,14 +83,16 @@ public class JavaReader { private TypeNode readTypeDeclaration(TypeDeclaration type) { TypeName name = typeOf(type.resolveBinding()); Scope scope = topScope.enterClass(name); + List typeParameters = readTypeParameters(type); TypeDeclarationBody body = readTypeDeclarationBody(scope, name, type.bodyDeclarations()); Set superTypes = superTypes(type); if (type.isInterface()) { // TODO: throw exception if other parts of body are declared - return InterfaceNode.declareInterface(name, superTypes, body.getMethods()); + return InterfaceNode.declareInterface(name, typeParameters, superTypes, body.getMethods()); } else { return ClassNode.declareClass( name, + typeParameters, superTypes, body.getFields(), body.getStaticConstructor(), @@ -98,6 +101,12 @@ public class JavaReader { } } + private List readTypeParameters(TypeDeclaration typeDeclaration) { + return eagerMap( + asList(typeDeclaration.resolveBinding().getTypeParameters()), + parameter -> formalTypeParameter(parameter.getName())); + } + GeneratedClosure readExpressionMethodReference(Scope outerScope, ExpressionMethodReference expression) { return readLambda( outerScope, @@ -226,6 +235,7 @@ public class JavaReader { ClassNode generatedClass = new ClassNode( classNode.getName(), + classNode.getTypeParameters(), classNode.getSuperTypes(), fields, list(), @@ -248,6 +258,7 @@ public class JavaReader { ) { return classWithCapture(scope, ClassNode.declareClass( className, + list(), anonymousClass.getSuperTypes(), anonymousClass.getFields(), list(), -- cgit v1.2.3