aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-02-11 20:52:41 +0000
committerMichael Williamson <mike@zwobble.org>2016-02-11 20:52:41 +0000
commit7df6bc37bfac33770b9758647ab73822d807f0fe (patch)
tree21e3dc99f0c66863fc571f9304158a7638daba2b /src/main/java/org
parentd403acf6e1266e73a4ed43b63032be04da2c71d8 (diff)
Implement static fields and static constructors for C#
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ClassNode.java74
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java14
-rw-r--r--src/main/java/org/zwobble/couscous/ast/FieldDeclarationNode.java70
-rw-r--r--src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java19
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java2
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))));