aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-02-11 21:55:36 +0000
committerMichael Williamson <mike@zwobble.org>2016-02-11 21:55:36 +0000
commit904dff6724e224f24772854fa184f62ca33c1795 (patch)
treee9e4989c0930e3c220f9cfcda7f7bac1cbb4548e /src
parenta34a00ba19f6ffb61762da4629b53b8a633f9d17 (diff)
Read static field accesses and static constructors in Java frontend
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java22
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java25
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java46
3 files changed, 88 insertions, 5 deletions
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
index ba08fd8..3d8e1c0 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
@@ -144,11 +144,18 @@ public class JavaExpressionReader {
}
private ExpressionNode readVariableBinding(IVariableBinding binding) {
- TypeName type = typeOf(binding);
if (binding.getDeclaringClass() == null) {
return scope.reference(binding.getKey());
} else {
- return FieldAccessNode.fieldAccess(ThisReferenceNode.thisReference(typeOf(binding.getDeclaringClass())), binding.getName(), type);
+ boolean isStatic = Modifier.isStatic(binding.getModifiers());
+ TypeName classType = typeOf(binding.getDeclaringClass());
+ Receiver receiver = isStatic
+ ? new StaticReceiver(classType)
+ : new InstanceReceiver(ThisReferenceNode.thisReference(classType));
+ return FieldAccessNode.fieldAccess(
+ receiver,
+ binding.getName(),
+ typeOf(binding));
}
}
@@ -157,7 +164,16 @@ public class JavaExpressionReader {
}
private ExpressionNode readFieldAccess(FieldAccess expression) {
- return FieldAccessNode.fieldAccess(readExpressionWithoutBoxing(expression.getExpression()), expression.getName().getIdentifier(), typeOf(expression));
+ IVariableBinding fieldBinding = expression.resolveFieldBinding();
+ boolean isStatic = Modifier.isStatic(fieldBinding.getModifiers());
+ Receiver receiver = isStatic
+ ? new StaticReceiver(typeOf(fieldBinding.getDeclaringClass()))
+ : new InstanceReceiver(readExpressionWithoutBoxing(expression.getExpression()));
+
+ return FieldAccessNode.fieldAccess(
+ receiver,
+ expression.getName().getIdentifier(),
+ typeOf(expression));
}
private ExpressionNode readMethodInvocation(MethodInvocation expression) {
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 ca0f87a..2f68380 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -70,7 +70,7 @@ public class JavaReader {
name,
superTypes(type),
body.getFields(),
- list(),
+ body.getStaticConstructor(),
body.getConstructor(),
body.getMethods());
}
@@ -231,11 +231,17 @@ public class JavaReader {
private static class TypeDeclarationBody {
private final List<FieldDeclarationNode> fields;
+ private final List<StatementNode> staticConstructor;
private final ConstructorNode constructor;
private final List<MethodNode> methods;
- public TypeDeclarationBody(List<FieldDeclarationNode> fields, ConstructorNode constructor, List<MethodNode> methods) {
+ public TypeDeclarationBody(
+ List<FieldDeclarationNode> fields,
+ List<StatementNode> staticConstructor, ConstructorNode constructor,
+ List<MethodNode> methods)
+ {
this.fields = fields;
+ this.staticConstructor = staticConstructor;
this.constructor = constructor;
this.methods = methods;
}
@@ -244,6 +250,10 @@ public class JavaReader {
return fields;
}
+ public List<StatementNode> getStaticConstructor() {
+ return staticConstructor;
+ }
+
public ConstructorNode getConstructor() {
return constructor;
}
@@ -264,8 +274,14 @@ public class JavaReader {
methods.add((MethodNode) callable);
}
}
+ // TODO: handle instance initializers
+ List<Initializer> initializers = ofType(bodyDeclarations, Initializer.class);
+ List<StatementNode> staticConstructor = eagerFlatMap(
+ initializers,
+ initializer -> readStatement(scope, initializer.getBody()));
return new TypeDeclarationBody(
readFields(ofType(bodyDeclarations, FieldDeclaration.class)),
+ staticConstructor,
constructor,
methods.build());
}
@@ -330,6 +346,11 @@ public class JavaReader {
return readStatements(scope, statements, returnType);
}
+ List<StatementNode> readStatement(Scope scope, Statement statement) {
+ JavaStatementReader statementReader = new JavaStatementReader(scope, expressionReader(scope), Optional.empty());
+ return statementReader.readStatement(statement);
+ }
+
List<StatementNode> readStatements(Scope scope, List<Statement> body, Optional<TypeName> returnType) {
JavaStatementReader statementReader = new JavaStatementReader(scope, expressionReader(scope), returnType);
return eagerFlatMap(body, statementReader::readStatement);
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 6bc0816..13484c2 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
@@ -99,6 +99,32 @@ public class JavaReaderTests {
StringValue.REF),
returnNode.getValue());
}
+
+ @Test
+ public void canReadExplicitStaticFieldReference() {
+ canReadStaticFieldReference("this.name");
+ }
+
+ @Test
+ public void canReadImplicitStaticFieldReference() {
+ canReadStaticFieldReference("name");
+ }
+
+ private void canReadStaticFieldReference(String expression) {
+ ClassNode classNode = readClass(
+ "private static String name;" +
+ "public String getName() {" +
+ " return " + expression + ";" +
+ "}");
+
+ ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get(0);
+ assertEquals(
+ fieldAccess(
+ TypeName.of("com.example.Example"),
+ "name",
+ StringValue.REF),
+ returnNode.getValue());
+ }
@Test
public void canReadInstanceMethodCalls() {
@@ -610,6 +636,26 @@ public class JavaReaderTests {
literal("Flaws"))),
constructor.getBody());
}
+
+ @Test
+ public void canDeclareStaticConstructor() {
+ ClassNode classNode = readClass(
+ "private static final String name;" +
+ "static {" +
+ " 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() {