From 0102779512e4475a32c95f0d84d704bcef7d38fe Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 13 Feb 2016 14:27:28 +0000 Subject: Tidy up reading of class bodies --- .../couscous/ast/sugar/TypeDeclarationBody.java | 82 ++++++++++++++ .../couscous/frontends/java/JavaReader.java | 124 +++++---------------- 2 files changed, 110 insertions(+), 96 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/ast/sugar/TypeDeclarationBody.java (limited to 'src') 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 fields = ImmutableList.builder(); + private final ImmutableList.Builder staticConstructor = ImmutableList.builder(); + private ConstructorNode constructor = ConstructorNode.DEFAULT; + private final ImmutableList.Builder methods = ImmutableList.builder(); + + private Builder() { + } + + public void field(FieldDeclarationNode field) { + fields.add(field); + } + + public void addStaticInitializer(List 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 fields; + private final List staticConstructor; + private final ConstructorNode constructor; + private final List methods; + + public TypeDeclarationBody( + List fields, + List staticConstructor, ConstructorNode constructor, + List methods) + { + this.fields = fields; + this.staticConstructor = staticConstructor; + this.constructor = constructor; + this.methods = methods; + } + + public List getFields() { + return fields; + } + + public List getStaticConstructor() { + return staticConstructor; + } + + public ConstructorNode getConstructor() { + return constructor; + } + + public List 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 fields; - private final List staticConstructor; - private final ConstructorNode constructor; - private final List methods; - - public TypeDeclarationBody( - List fields, - List staticConstructor, ConstructorNode constructor, - List methods) - { - this.fields = fields; - this.staticConstructor = staticConstructor; - this.constructor = constructor; - this.methods = methods; - } - - public List getFields() { - return fields; - } + private TypeDeclarationBody readTypeDeclarationBody(Scope scope, TypeName type, List bodyDeclarations) { + TypeDeclarationBody.Builder body = TypeDeclarationBody.builder(); - public List 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 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 bodyDeclarations) { - ImmutableList.Builder 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 staticConstructor = readStaticConstructor(scope, type, bodyDeclarations); - return new TypeDeclarationBody( - readFields(ofType(bodyDeclarations, FieldDeclaration.class)), - staticConstructor, - constructor, - methods.build()); - } - - private List readStaticConstructor(Scope scope, TypeName type, List bodyDeclarations) { - return eagerFlatMap( - bodyDeclarations, - declaration -> readStaticConstructorStatements(scope, type, declaration)); - } - - private Iterable 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 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 readFields(List fields) { - return eagerFlatMap(fields, this::readField); - } - - private List readField(FieldDeclaration field) { + private void readField(TypeDeclarationBody.Builder builder, Scope scope, TypeName declaringType, FieldDeclaration field) { @SuppressWarnings("unchecked") List 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 readMethods(Scope scope, List 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 formalArguments = readFormalArguments(scope, method); @@ -342,17 +274,17 @@ public class JavaReader { List 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)); } } -- cgit v1.2.3