diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-02-11 20:52:41 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-02-11 20:52:41 +0000 |
| commit | 7df6bc37bfac33770b9758647ab73822d807f0fe (patch) | |
| tree | 21e3dc99f0c66863fc571f9304158a7638daba2b /src/main/java | |
| parent | d403acf6e1266e73a4ed43b63032be04da2c71d8 (diff) | |
Implement static fields and static constructors for C#
Diffstat (limited to 'src/main/java')
5 files changed, 118 insertions, 61 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/ClassNode.java b/src/main/java/org/zwobble/couscous/ast/ClassNode.java index ac304e6..0aaa8c1 100644 --- a/src/main/java/org/zwobble/couscous/ast/ClassNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ClassNode.java @@ -7,6 +7,9 @@ import java.util.List; import java.util.Set; public class ClassNode implements Node { + public static ClassNodeBuilder builder(TypeName name) { + return new ClassNodeBuilder(name); + } public static ClassNodeBuilder builder(String name) { return new ClassNodeBuilder(name); } @@ -14,26 +17,31 @@ public class ClassNode implements Node { TypeName name, Set<TypeName> superTypes, List<FieldDeclarationNode> fields, + List<StatementNode> staticConstructor, ConstructorNode constructor, List<MethodNode> methods) { - return new ClassNode(name, superTypes, fields, constructor, methods); + return new ClassNode(name, superTypes, fields, staticConstructor, constructor, methods); } private final TypeName name; private final Set<TypeName> superTypes; private final List<FieldDeclarationNode> fields; + private final List<StatementNode> staticConstructor; private final ConstructorNode constructor; private final List<MethodNode> methods; private ClassNode( - TypeName name, - Set<TypeName> superTypes, - List<FieldDeclarationNode> fields, - ConstructorNode constructor, - List<MethodNode> methodNodes) { + TypeName name, + Set<TypeName> superTypes, + List<FieldDeclarationNode> fields, + List<StatementNode> staticConstructor, + ConstructorNode constructor, + List<MethodNode> methodNodes) + { this.name = name; this.superTypes = superTypes; this.fields = fields; + this.staticConstructor = staticConstructor; this.constructor = constructor; methods = methodNodes; } @@ -49,7 +57,11 @@ public class ClassNode implements Node { public List<FieldDeclarationNode> getFields() { return fields; } - + + public List<StatementNode> getStaticConstructor() { + return staticConstructor; + } + public ConstructorNode getConstructor() { return constructor; } @@ -72,44 +84,46 @@ public class ClassNode implements Node { transformer.transform(name), transformer.transformTypes(superTypes), transformer.transformFields(fields), - transformer.transformConstructor(constructor), + staticConstructor, transformer.transformConstructor(constructor), transformer.transformMethods(methods)); } @Override - public String toString() { - return "ClassNode(" + - "name=" + name + - ", superTypes=" + superTypes + - ", fields=" + fields + - ", constructor=" + constructor + - ", methods=" + methods + - ')'; - } - - @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ClassNode classNode = (ClassNode) o; - if (name != null ? !name.equals(classNode.name) : classNode.name != null) return false; - if (superTypes != null ? !superTypes.equals(classNode.superTypes) : classNode.superTypes != null) return false; - if (fields != null ? !fields.equals(classNode.fields) : classNode.fields != null) return false; - if (constructor != null ? !constructor.equals(classNode.constructor) : classNode.constructor != null) - return false; - return methods != null ? methods.equals(classNode.methods) : classNode.methods == null; + if (!name.equals(classNode.name)) return false; + if (!superTypes.equals(classNode.superTypes)) return false; + if (!fields.equals(classNode.fields)) return false; + if (!staticConstructor.equals(classNode.staticConstructor)) return false; + if (!constructor.equals(classNode.constructor)) return false; + return methods.equals(classNode.methods); } @Override public int hashCode() { - int result = name != null ? name.hashCode() : 0; - result = 31 * result + (superTypes != null ? superTypes.hashCode() : 0); - result = 31 * result + (fields != null ? fields.hashCode() : 0); - result = 31 * result + (constructor != null ? constructor.hashCode() : 0); - result = 31 * result + (methods != null ? methods.hashCode() : 0); + int result = name.hashCode(); + result = 31 * result + superTypes.hashCode(); + result = 31 * result + fields.hashCode(); + result = 31 * result + staticConstructor.hashCode(); + result = 31 * result + constructor.hashCode(); + 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 f1240f6..a4a268a 100644 --- a/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java +++ b/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java @@ -4,22 +4,26 @@ import com.google.common.collect.ImmutableList; import org.zwobble.couscous.ast.identifiers.Identifier; import org.zwobble.couscous.values.UnitValue; +import java.util.List; import java.util.Optional; import java.util.function.Function; import static java.util.Collections.emptySet; import static org.zwobble.couscous.ast.FormalArgumentNode.formalArg; import static org.zwobble.couscous.ast.VariableDeclaration.var; +import static org.zwobble.couscous.util.ExtraLists.list; public class ClassNodeBuilder { private final TypeName name; private final ImmutableList.Builder<FieldDeclarationNode> fields; + private List<StatementNode> staticConstructor; private Optional<ConstructorNode> constructor; private final ImmutableList.Builder<MethodNode> methods; public ClassNodeBuilder(TypeName name) { this.name = name; this.fields = ImmutableList.builder(); + staticConstructor = list(); this.constructor = Optional.empty(); this.methods = ImmutableList.builder(); } @@ -28,6 +32,10 @@ public class ClassNodeBuilder { this(TypeName.of(name)); } + public ClassNodeBuilder staticField(String name, TypeName type) { + return field(FieldDeclarationNode.staticField(name, type)); + } + public ClassNodeBuilder field(String name, TypeName type) { return field(FieldDeclarationNode.field(name, type)); } @@ -46,6 +54,11 @@ public class ClassNodeBuilder { return constructor(build.apply(constructorBuilder()).build()); } + public ClassNodeBuilder staticConstructor(List<StatementNode> body) { + this.staticConstructor = body; + return this; + } + private MethodBuilder<ConstructorNode> constructorBuilder() { return new MethodBuilder<>(builder -> ConstructorNode.constructor( @@ -86,6 +99,7 @@ public class ClassNodeBuilder { name, emptySet(), fields.build(), + staticConstructor, constructor.orElse(ConstructorNode.DEFAULT), methods.build()); } diff --git a/src/main/java/org/zwobble/couscous/ast/FieldDeclarationNode.java b/src/main/java/org/zwobble/couscous/ast/FieldDeclarationNode.java index 3b27b9e..a9f9b76 100644 --- a/src/main/java/org/zwobble/couscous/ast/FieldDeclarationNode.java +++ b/src/main/java/org/zwobble/couscous/ast/FieldDeclarationNode.java @@ -5,17 +5,31 @@ import org.zwobble.couscous.ast.visitors.NodeTransformer; public class FieldDeclarationNode implements Node { public static FieldDeclarationNode field(String name, TypeName type) { - return new FieldDeclarationNode(name, type); + return field(false, name, type); } - + + public static FieldDeclarationNode staticField(String name, TypeName type) { + return field(true, name, type); + } + + public static FieldDeclarationNode field(boolean isStatic, String name, TypeName type) { + return new FieldDeclarationNode(isStatic, name, type); + } + + private final boolean isStatic; private final String name; private final TypeName type; - private FieldDeclarationNode(String name, TypeName type) { + private FieldDeclarationNode(boolean isStatic, String name, TypeName type) { + this.isStatic = isStatic; this.name = name; this.type = type; } - + + public boolean isStatic() { + return isStatic; + } + public String getName() { return name; } @@ -31,43 +45,37 @@ public class FieldDeclarationNode implements Node { public FieldDeclarationNode transform(NodeTransformer transformer) { return new FieldDeclarationNode( - name, + isStatic, name, transformer.transform(type)); } @Override public String toString() { - return "FieldDeclarationNode(name=" + name + ", type=" + type + ")"; + return "FieldDeclarationNode(" + + "isStatic=" + isStatic + + ", name=" + name + + ", type=" + type + + ')'; } @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FieldDeclarationNode that = (FieldDeclarationNode) o; + + if (isStatic != that.isStatic) return false; + if (!name.equals(that.name)) return false; + return type.equals(that.type); + } @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - FieldDeclarationNode other = (FieldDeclarationNode) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - return true; + public int hashCode() { + int result = (isStatic ? 1 : 0); + result = 31 * result + name.hashCode(); + result = 31 * result + type.hashCode(); + return result; } } diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java index a6bcfc9..c63bbbb 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java @@ -8,6 +8,8 @@ import org.zwobble.couscous.values.UnitValue; import java.util.List; +import static org.zwobble.couscous.util.ExtraLists.list; + public class CsharpSerializer implements NodeVisitor { public static String serialize(Node node) { SourceCodeWriter writer = new SourceCodeWriter( @@ -286,6 +288,10 @@ public class CsharpSerializer implements NodeVisitor { writer.writeStatement(() -> { writer.writeKeyword("internal"); writer.writeSpace(); + if (declaration.isStatic()) { + writer.writeKeyword("static"); + writer.writeSpace(); + } writeTypeReference(declaration.getType()); writer.writeSpace(); writer.writeIdentifier(declaration.getName()); @@ -308,6 +314,7 @@ public class CsharpSerializer implements NodeVisitor { writer.writeIdentifier(classNode.getSimpleName()); writer.startBlock(); writeAll(classNode.getFields()); + writeStaticConstructor(classNode); writeConstructor(classNode, classNode.getConstructor()); writeAll(classNode.getMethods()); writer.endBlock(); @@ -317,6 +324,18 @@ public class CsharpSerializer implements NodeVisitor { }); } + private void writeStaticConstructor(ClassNode classNode) { + if (!classNode.getStaticConstructor().isEmpty()) { + writer.writeStatement(() -> { + writer.writeKeyword("static"); + writer.writeSpace(); + writer.writeIdentifier(classNode.getSimpleName()); + writeFormalArguments(list()); + writeBlock(classNode.getStaticConstructor()); + }); + } + } + private void writeConstructor(ClassNode classNode, ConstructorNode constructor) { if (!constructor.equals(ConstructorNode.DEFAULT)) { writer.writeStatement(() -> { 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 2067381..ca0f87a 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -70,6 +70,7 @@ public class JavaReader { name, superTypes(type), body.getFields(), + list(), body.getConstructor(), body.getMethods()); } @@ -190,6 +191,7 @@ public class JavaReader { className, anonymousClass.getSuperTypes(), fields, + list(), buildConstructor(scope, className, capturedVariables), eagerMap(anonymousClass.getMethods(), method -> method.mapBody(body -> replaceCaptureReferences(className, body, capturedVariables)))); |
