diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-02-13 14:27:28 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-02-13 14:27:28 +0000 |
| commit | 0102779512e4475a32c95f0d84d704bcef7d38fe (patch) | |
| tree | b09286a8624ea3fc05fff0d4c767aacf47b293d4 | |
| parent | f31e1bc8ecd4a2323da72e7e78819d0f733bb27d (diff) | |
Tidy up reading of class bodies
| -rw-r--r-- | src/main/java/org/zwobble/couscous/ast/sugar/TypeDeclarationBody.java | 82 | ||||
| -rw-r--r-- | src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java | 124 |
2 files changed, 110 insertions, 96 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/sugar/TypeDeclarationBody.java b/src/main/java/org/zwobble/couscous/ast/sugar/TypeDeclarationBody.java new file mode 100644 index 0000000..666d777 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/sugar/TypeDeclarationBody.java @@ -0,0 +1,82 @@ +package org.zwobble.couscous.ast.sugar; + +import com.google.common.collect.ImmutableList; +import org.zwobble.couscous.ast.*; + +import java.util.List; + +public class TypeDeclarationBody { + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private final ImmutableList.Builder<FieldDeclarationNode> fields = ImmutableList.builder(); + private final ImmutableList.Builder<StatementNode> staticConstructor = ImmutableList.builder(); + private ConstructorNode constructor = ConstructorNode.DEFAULT; + private final ImmutableList.Builder<MethodNode> methods = ImmutableList.builder(); + + private Builder() { + } + + public void field(FieldDeclarationNode field) { + fields.add(field); + } + + public void addStaticInitializer(List<StatementNode> statements) { + staticConstructor.addAll(statements); + } + + public void addStaticInitializer(StatementNode statement) { + staticConstructor.add(statement); + } + + public void constructor(ConstructorNode constructor) { + this.constructor = constructor; + } + + public void addMethod(MethodNode method) { + this.methods.add(method); + } + + public TypeDeclarationBody build() { + return new TypeDeclarationBody( + fields.build(), + staticConstructor.build(), + constructor, + methods.build()); + } + } + + private final List<FieldDeclarationNode> fields; + private final List<StatementNode> staticConstructor; + private final ConstructorNode constructor; + private final 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; + } + + public List<FieldDeclarationNode> getFields() { + return fields; + } + + public List<StatementNode> getStaticConstructor() { + return staticConstructor; + } + + public ConstructorNode getConstructor() { + return constructor; + } + + public List<MethodNode> getMethods() { + return methods; + } +} 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 1bf666f..b66fe0d 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -7,7 +7,9 @@ import org.eclipse.jdt.core.dom.*; import org.zwobble.couscous.ast.*; import org.zwobble.couscous.ast.sugar.AnonymousClass; import org.zwobble.couscous.ast.sugar.Lambda; +import org.zwobble.couscous.ast.sugar.TypeDeclarationBody; import org.zwobble.couscous.ast.visitors.NodeTransformer; +import org.zwobble.couscous.util.Casts; import org.zwobble.couscous.util.ExtraLists; import java.io.IOException; @@ -229,110 +231,40 @@ public class JavaReader { return ((AbstractTypeDeclaration)node).resolveBinding(); } - 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, - List<StatementNode> staticConstructor, ConstructorNode constructor, - List<MethodNode> methods) - { - this.fields = fields; - this.staticConstructor = staticConstructor; - this.constructor = constructor; - this.methods = methods; - } - - public List<FieldDeclarationNode> getFields() { - return fields; - } + private TypeDeclarationBody readTypeDeclarationBody(Scope scope, TypeName type, List<Object> bodyDeclarations) { + TypeDeclarationBody.Builder body = TypeDeclarationBody.builder(); - public List<StatementNode> getStaticConstructor() { - return staticConstructor; - } + for (Object declaration : bodyDeclarations) { + Casts.tryCast(MethodDeclaration.class, declaration) + .ifPresent(method -> readMethod(body, scope, method)); - public ConstructorNode getConstructor() { - return constructor; - } + Casts.tryCast(Initializer.class, declaration) + // TODO: handle instance initializer + .ifPresent(initializer -> body.addStaticInitializer(readStatement(scope, initializer.getBody()))); - public List<MethodNode> getMethods() { - return methods; + Casts.tryCast(FieldDeclaration.class, declaration) + .ifPresent(field -> readField(body, scope, type, field)); } + return body.build(); } - private TypeDeclarationBody readTypeDeclarationBody(Scope scope, TypeName type, List<Object> bodyDeclarations) { - ImmutableList.Builder<MethodNode> methods = ImmutableList.builder(); - ConstructorNode constructor = ConstructorNode.DEFAULT; - - for (CallableNode callable : readMethods(scope, ofType(bodyDeclarations, MethodDeclaration.class))) { - if (callable instanceof ConstructorNode) { - constructor = (ConstructorNode) callable; - } else { - methods.add((MethodNode) callable); - } - } - // TODO: handle instance initializers - List<StatementNode> staticConstructor = readStaticConstructor(scope, type, bodyDeclarations); - return new TypeDeclarationBody( - readFields(ofType(bodyDeclarations, FieldDeclaration.class)), - staticConstructor, - constructor, - 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); - } - - private List<FieldDeclarationNode> readField(FieldDeclaration field) { + private void readField(TypeDeclarationBody.Builder builder, Scope scope, TypeName declaringType, FieldDeclaration field) { @SuppressWarnings("unchecked") List<VariableDeclarationFragment> fragments = field.fragments(); TypeName type = typeOf(field.getType()); - return eagerMap(fragments, fragment -> - field(Modifier.isStatic(field.getModifiers()), fragment.getName().getIdentifier(), type)); - } + fragments.forEach(fragment -> { + builder.field(field(Modifier.isStatic(field.getModifiers()), fragment.getName().getIdentifier(), type)); + // TODO: handle instance initializer + if (fragment.getInitializer() != null) { + ExpressionNode value = readExpression(scope, type, fragment.getInitializer()); + String name = fragment.getName().getIdentifier(); + builder.addStaticInitializer(assignStatement(fieldAccess(declaringType, name, type), value)); + } + }); - private List<CallableNode> readMethods(Scope scope, List<MethodDeclaration> methods) { - return eagerMap(methods, method -> readMethod(scope, method)); } - private CallableNode readMethod(Scope outerScope, MethodDeclaration method) { + private void readMethod(TypeDeclarationBody.Builder builder, Scope outerScope, MethodDeclaration method) { Scope scope = outerScope.enterMethod(method.getName().getIdentifier()); List<FormalArgumentNode> formalArguments = readFormalArguments(scope, method); @@ -342,17 +274,17 @@ public class JavaReader { List<StatementNode> body = readBody(scope, method, returnType); if (method.isConstructor()) { - return constructor( + builder.constructor(constructor( formalArguments, - body); + body)); } else { - return MethodNode.method( + builder.addMethod(MethodNode.method( annotations, Modifier.isStatic(method.getModifiers()), method.getName().getIdentifier(), formalArguments, returnType.get(), - body); + body)); } } |
