aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-02-11 22:46:09 +0000
committerMichael Williamson <mike@zwobble.org>2016-02-11 22:46:09 +0000
commitf31e1bc8ecd4a2323da72e7e78819d0f733bb27d (patch)
treee8bcdd68d21c44a4cc3d09f347e8ec59dfa2f75a
parentbf211785b33a13146d7eebefbd8291b0e84fdafd (diff)
Read static field initialisers in Java frontend
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java44
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java17
2 files changed, 54 insertions, 7 deletions
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 90723b0..1bf666f 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -65,7 +65,7 @@ public class JavaReader {
TypeName name = generateClassName(ast);
Scope scope = Scope.create().enterClass(name);
TypeDeclaration type = (TypeDeclaration)ast.types().get(0);
- TypeDeclarationBody body = readTypeDeclarationBody(scope, type.bodyDeclarations());
+ TypeDeclarationBody body = readTypeDeclarationBody(scope, name, type.bodyDeclarations());
return ClassNode.declareClass(
name,
superTypes(type),
@@ -146,7 +146,7 @@ public class JavaReader {
GeneratedClosure readAnonymousClass(Scope outerScope, AnonymousClassDeclaration declaration) {
TypeName className = generateAnonymousName(declaration);
Scope scope = outerScope.enterClass(className);
- TypeDeclarationBody bodyDeclarations = readTypeDeclarationBody(scope, declaration.bodyDeclarations());
+ TypeDeclarationBody bodyDeclarations = readTypeDeclarationBody(scope, className, declaration.bodyDeclarations());
AnonymousClass anonymousClass = new AnonymousClass(
superTypes(declaration),
bodyDeclarations.getFields(),
@@ -263,7 +263,7 @@ public class JavaReader {
}
}
- private TypeDeclarationBody readTypeDeclarationBody(Scope scope, List<Object> bodyDeclarations) {
+ private TypeDeclarationBody readTypeDeclarationBody(Scope scope, TypeName type, List<Object> bodyDeclarations) {
ImmutableList.Builder<MethodNode> methods = ImmutableList.builder();
ConstructorNode constructor = ConstructorNode.DEFAULT;
@@ -275,10 +275,7 @@ public class JavaReader {
}
}
// TODO: handle instance initializers
- List<Initializer> initializers = ofType(bodyDeclarations, Initializer.class);
- List<StatementNode> staticConstructor = eagerFlatMap(
- initializers,
- initializer -> readStatement(scope, initializer.getBody()));
+ List<StatementNode> staticConstructor = readStaticConstructor(scope, type, bodyDeclarations);
return new TypeDeclarationBody(
readFields(ofType(bodyDeclarations, FieldDeclaration.class)),
staticConstructor,
@@ -286,6 +283,39 @@ public class JavaReader {
methods.build());
}
+ private List<StatementNode> readStaticConstructor(Scope scope, TypeName type, List<Object> bodyDeclarations) {
+ return eagerFlatMap(
+ bodyDeclarations,
+ declaration -> readStaticConstructorStatements(scope, type, declaration));
+ }
+
+ private Iterable<StatementNode> readStaticConstructorStatements(Scope scope, TypeName type, Object declaration) {
+ if (declaration instanceof Initializer) {
+ return readStatement(scope, ((Initializer) declaration).getBody());
+ } else if (declaration instanceof FieldDeclaration) {
+ FieldDeclaration field = (FieldDeclaration) declaration;
+ if (Modifier.isStatic(field.getModifiers())) {
+ // TODO: remove duplication with readField
+ @SuppressWarnings("unchecked")
+ List<VariableDeclarationFragment> fragments = field.fragments();
+ TypeName fieldType = typeOf(field.getType());
+ return eagerFlatMap(fragments, fragment -> {
+ if (fragment.getInitializer() == null) {
+ return list();
+ } else {
+ ExpressionNode value = readExpression(scope, fieldType, fragment.getInitializer());
+ String name = fragment.getName().getIdentifier();
+ return list(assignStatement(fieldAccess(type, name, fieldType), value));
+ }
+ });
+ } else {
+ return list();
+ }
+ } else {
+ return list();
+ }
+ }
+
private List<FieldDeclarationNode> readFields(List<FieldDeclaration> fields) {
return eagerFlatMap(fields, this::readField);
}
diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
index 99145ee..84a4ea7 100644
--- a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
@@ -667,6 +667,23 @@ public class JavaReaderTests {
literal("Flaws"))),
staticConstructor);
}
+
+ @Test
+ public void staticFieldInitialiserIsTreatedAsAssignmentInStaticConstructor() {
+ ClassNode classNode = readClass(
+ "private static final String name = \"Flaws\";");
+
+ List<StatementNode> staticConstructor = classNode.getStaticConstructor();
+
+ assertEquals(
+ list(assignStatement(
+ fieldAccess(
+ TypeName.of("com.example.Example"),
+ "name",
+ StringValue.REF),
+ literal("Flaws"))),
+ staticConstructor);
+ }
@Test
public void canDeclareStaticMethodWithAnnotation() {