diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-10-30 20:25:05 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-10-30 20:25:05 +0000 |
| commit | fee1878340fe2055f9d5b4c52eb2993c06c25f25 (patch) | |
| tree | fb827034b5a4a2174b08803120c295f5affd764f /src/main/java/org/zwobble | |
| parent | fd5dde9224680d46dd7081d051f1320194ff59ea (diff) | |
Store inner classes in ScalarType
Diffstat (limited to 'src/main/java/org/zwobble')
15 files changed, 80 insertions, 65 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java b/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java index ec17c9b..4d39b01 100644 --- a/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java +++ b/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java @@ -38,7 +38,7 @@ public class ClassNodeBuilder { } public ClassNodeBuilder(String name) { - this(ScalarType.of(name)); + this(ScalarType.topLevel(name)); } public ClassNodeBuilder addTypeParameter(String name) { @@ -47,7 +47,7 @@ public class ClassNodeBuilder { } public ClassNodeBuilder addSuperType(String type) { - this.superTypes.add(ScalarType.of(type)); + this.superTypes.add(ScalarType.topLevel(type)); return this; } diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java index 2a6f408..ece3175 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java @@ -19,7 +19,7 @@ public class MethodCallNode implements ExpressionNode { List<ExpressionNode> arguments, Type type) { - return staticMethodCall(ScalarType.of(className), methodName, arguments, type); + return staticMethodCall(ScalarType.topLevel(className), methodName, arguments, type); } public static ExpressionNode staticMethodCall( @@ -29,7 +29,7 @@ public class MethodCallNode implements ExpressionNode { Type returnType, MethodSignature signature) { - return staticMethodCall(ScalarType.of(className), methodName, arguments, returnType, signature); + return staticMethodCall(ScalarType.topLevel(className), methodName, arguments, returnType, signature); } public static ExpressionNode staticMethodCall( diff --git a/src/main/java/org/zwobble/couscous/ast/StaticReceiver.java b/src/main/java/org/zwobble/couscous/ast/StaticReceiver.java index 7ae7ec1..a61a685 100644 --- a/src/main/java/org/zwobble/couscous/ast/StaticReceiver.java +++ b/src/main/java/org/zwobble/couscous/ast/StaticReceiver.java @@ -6,7 +6,7 @@ import org.zwobble.couscous.util.ExtraIterables; public class StaticReceiver implements Receiver { public static Receiver staticReceiver(String type) { - return new StaticReceiver(ScalarType.of(type)); + return new StaticReceiver(ScalarType.topLevel(type)); } public static Receiver staticReceiver(ScalarType type) { diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java index 260d7ec..68eaa73 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java @@ -21,14 +21,14 @@ public class CsharpCodeGenerator { public static final Naming NAMING = Naming.noMangling(); private final static Map<ScalarType, ScalarType> PRIMITIVES = ImmutableMap.<ScalarType, ScalarType>builder() - .put(Types.INT, ScalarType.of("int")) - .put(Types.BOXED_INT, ScalarType.of("int")) - .put(Types.STRING, ScalarType.of("string")) - .put(Types.CHAR, ScalarType.of("char")) - .put(Types.BOOLEAN, ScalarType.of("bool")) - .put(Types.BOXED_BOOLEAN, ScalarType.of("bool")) - .put(Types.CLASS, ScalarType.of("System.Type")) - .put(Types.VOID, ScalarType.of("void")) + .put(Types.INT, ScalarType.topLevel("int")) + .put(Types.BOXED_INT, ScalarType.topLevel("int")) + .put(Types.STRING, ScalarType.topLevel("string")) + .put(Types.CHAR, ScalarType.topLevel("char")) + .put(Types.BOOLEAN, ScalarType.topLevel("bool")) + .put(Types.BOXED_BOOLEAN, ScalarType.topLevel("bool")) + .put(Types.CLASS, ScalarType.topLevel("System.Type")) + .put(Types.VOID, ScalarType.topLevel("void")) .put(Types.ARRAY, Types.ARRAY) .build(); @@ -81,7 +81,7 @@ public class CsharpCodeGenerator { @Override public Type visit(ParameterizedType type) { if (type.getRawType().equals(Types.CLASS)) { - return ScalarType.of("System.Type"); + return ScalarType.topLevel("System.Type"); } else { return new ParameterizedType( (ScalarType) transformType(type.getRawType()), @@ -102,7 +102,7 @@ public class CsharpCodeGenerator { return type.accept(new Type.Visitor<Type>() { @Override public ScalarType visit(ScalarType type) { - return ScalarType.of(namespace + "." + type.getQualifiedName()); + return ScalarType.topLevel(namespace + "." + type.getQualifiedName()); } @Override 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 c2fa029..4ddeb7c 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java @@ -596,7 +596,7 @@ public class CsharpSerializer { } private void writeInNamespace(TypeNode typeNode, Action writeBody) { - writeInNamespace(typeNode.getName().getQualifier().get(), writeBody); + writeInNamespace(typeNode.getName().getPackage().get(), writeBody); } private void writeInNamespace(String namespace, Action writeBody) { diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/primitives/CsharpPrimitiveMethods.java b/src/main/java/org/zwobble/couscous/backends/csharp/primitives/CsharpPrimitiveMethods.java index 6a5c084..3208e17 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/primitives/CsharpPrimitiveMethods.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/primitives/CsharpPrimitiveMethods.java @@ -135,10 +135,10 @@ public class CsharpPrimitiveMethods { .put("parseInt", new PrimitiveStaticMethod( arguments -> staticMethodCall( - ScalarType.of("int"), + ScalarType.topLevel("int"), "Parse", list(arguments.get(0)), - ScalarType.of("int") + ScalarType.topLevel("int") ), Types.INT )) @@ -155,7 +155,7 @@ public class CsharpPrimitiveMethods { .put("join", new PrimitiveStaticMethod( arguments -> staticMethodCall( - ScalarType.of("java.lang.String"), + ScalarType.topLevel("java.lang.String"), "join", arguments, Types.STRING 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 823310e..747bcac 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java @@ -230,7 +230,7 @@ public class JavaExpressionReader { private Receiver toReceiver(IBinding binding) { if (binding instanceof ITypeBinding) { - ScalarType receiver = ScalarType.of(((ITypeBinding) binding).getQualifiedName()); + ScalarType receiver = ScalarType.topLevel(((ITypeBinding) binding).getQualifiedName()); return staticReceiver(receiver); } else if (binding instanceof IVariableBinding) { return instanceReceiver(readVariableBinding((IVariableBinding) binding)); 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 a047e9e..b0d347b 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -239,7 +239,7 @@ public class JavaReader { while (type.isAnonymous()) { type = type.getDeclaringClass(); } - return ScalarType.of(erasure(typeOf(type)).getQualifiedName() + "_Anonymous_" + (anonymousClassCount++)); + return ScalarType.topLevel(erasure(typeOf(type)).getQualifiedName() + "_Anonymous_" + (anonymousClassCount++)); } private ITypeBinding findDeclaringClass(ASTNode node) { diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java index 5d9eddd..fbd2a3b 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java @@ -47,12 +47,10 @@ public class JavaTypes { Identifier declaringScope = getDeclaringScope(typeBinding); return new TypeParameter(declaringScope, typeBinding.getName()); } - // TODO: tidy-up -// ScalarType rawType = outerClass == null -// ? ScalarType.of(typeBinding.getErasure().getQualifiedName()) -// // TODO: test for erasure of inner type name -// : ScalarType.of(erasure(typeOf(outerClass)).getQualifiedName() + "__" + typeBinding.getErasure().getName()); - ScalarType rawType = ScalarType.of(typeBinding.getErasure().getQualifiedName()); + ScalarType rawType = outerClass == null + ? ScalarType.topLevel(typeBinding.getErasure().getQualifiedName()) + // TODO: test for erasure of inner type name + : ScalarType.innerType(erasure(typeOf(outerClass)), typeBinding.getErasure().getName()); if (typeBinding.isParameterizedType()) { List<Type> typeParameters = eagerMap( asList(typeBinding.getTypeArguments()), @@ -141,10 +139,10 @@ public class JavaTypes { } public static Type iterable(Type elementType) { - return parameterizedType(ScalarType.of("java.lang.Iterable"), list(elementType)); + return parameterizedType(ScalarType.topLevel("java.lang.Iterable"), list(elementType)); } - private static final ScalarType RAW_ITERATOR = ScalarType.of("java.util.Iterator"); + private static final ScalarType RAW_ITERATOR = ScalarType.topLevel("java.util.Iterator"); public static final TypeParameter ITERATOR_TYPE_PARAMETER = typeParameter(Identifier.TOP.type(RAW_ITERATOR.getQualifiedName()), "T"); public static Type iterator(Type elementType) { diff --git a/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java b/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java index b53b274..e687938 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java +++ b/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java @@ -28,7 +28,7 @@ public class IntrinsicInterpreterType implements InterpreterType { } public static <T> Builder<T> builder(Class<T> interpreterValueType, String name) { - return builder(interpreterValueType, ScalarType.of(name)); + return builder(interpreterValueType, ScalarType.topLevel(name)); } public static Builder<ObjectInterpreterValue> classBuilder(String name) { diff --git a/src/main/java/org/zwobble/couscous/transforms/HoistNestedTypes.java b/src/main/java/org/zwobble/couscous/transforms/HoistNestedTypes.java index ae4af14..6c40af9 100644 --- a/src/main/java/org/zwobble/couscous/transforms/HoistNestedTypes.java +++ b/src/main/java/org/zwobble/couscous/transforms/HoistNestedTypes.java @@ -12,7 +12,6 @@ import org.zwobble.couscous.util.ExtraSets; import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.regex.Pattern; import static org.zwobble.couscous.ast.MethodCallNode.methodCall; import static org.zwobble.couscous.ast.ReturnNode.returns; @@ -81,25 +80,22 @@ public class HoistNestedTypes { } } - private static final Pattern INNER_TYPE_QUALIFIER_REGEX = Pattern.compile(".*\\.[A-Z][^.]*$"); - private boolean isInnerType(Type type) { - // TODO: implement separate type classes for top-level and inner types rather than using this heuristic - return tryCast(ScalarType.class, type) - .flatMap(scalarType -> scalarType.getQualifier()) - .map(qualifier -> INNER_TYPE_QUALIFIER_REGEX.matcher(qualifier).matches()) + .map(scalarType -> scalarType.outerType().isPresent()) .orElse(false); } private Type outerType(ScalarType type) { - // TODO: implement separate type classes for top-level and inner types - - return ScalarType.of(type.getQualifier().get()); + return type.outerType().get(); } private static Type hoistedTypeName(ScalarType type) { - return ScalarType.of(type.getQualifier().get() + "__" + type.getSimpleName()); + List<String> typeNames = type.getTypeNames(); + return new ScalarType( + type.getPackage(), + cons(typeNames.get(0) + "__" + typeNames.get(1), typeNames.subList(2, typeNames.size())) + ); } private HoistResult hoistInnerTypes(TypeNode declaration) { diff --git a/src/main/java/org/zwobble/couscous/transforms/SplitStaticsFromInterface.java b/src/main/java/org/zwobble/couscous/transforms/SplitStaticsFromInterface.java index 3af4042..f8623fc 100644 --- a/src/main/java/org/zwobble/couscous/transforms/SplitStaticsFromInterface.java +++ b/src/main/java/org/zwobble/couscous/transforms/SplitStaticsFromInterface.java @@ -57,7 +57,7 @@ public class SplitStaticsFromInterface { } private static ScalarType staticTypeFor(ScalarType name) { - return ScalarType.of(name.getQualifiedName() + "_static"); + return ScalarType.topLevel(name.getQualifiedName() + "_static"); } private static boolean isSplittable(TypeNode typeNode) { diff --git a/src/main/java/org/zwobble/couscous/types/ScalarType.java b/src/main/java/org/zwobble/couscous/types/ScalarType.java index 4f77342..4a1bcc3 100644 --- a/src/main/java/org/zwobble/couscous/types/ScalarType.java +++ b/src/main/java/org/zwobble/couscous/types/ScalarType.java @@ -2,40 +2,61 @@ package org.zwobble.couscous.types; import com.google.common.base.Strings; +import java.util.List; import java.util.Optional; import java.util.function.Function; +import static org.zwobble.couscous.util.ExtraLists.*; + public class ScalarType implements Type { - public static ScalarType of(String qualifiedName) { + public static ScalarType topLevel(String qualifiedName) { if (Strings.isNullOrEmpty(qualifiedName)) { throw new IllegalArgumentException("qualifiedName cannot be blank"); } if (qualifiedName.contains("<")) { throw new IllegalArgumentException(qualifiedName + " contains <"); } - return new ScalarType(qualifiedName); + int lastDot = qualifiedName.lastIndexOf('.'); + String className = qualifiedName.substring(lastDot + 1); + Optional<String> packageName = lastDot == -1 ? Optional.empty() : Optional.of(qualifiedName.substring(0, lastDot)); + return new ScalarType(packageName, list(className)); } - + + public static ScalarType innerType(ScalarType outerType, String name) { + return new ScalarType(outerType.packageName, append(outerType.typeNames, name)); + } + + private final Optional<String> packageName; + private final List<String> typeNames; private final String qualifiedName; - - private ScalarType(String qualifiedName) { - this.qualifiedName = qualifiedName; + + public ScalarType(Optional<String> packageName, List<String> typeNames) { + this.packageName = packageName; + this.typeNames = typeNames; + this.qualifiedName = packageName.map(p -> p + ".").orElse("") + String.join(".", typeNames); + } + + public Optional<String> getPackage() { + return packageName; + } + + public List<String> getTypeNames() { + return typeNames; } public String getQualifiedName() { return qualifiedName; } - + public String getSimpleName() { - return qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1); + return getLast(typeNames); } - public Optional<String> getQualifier() { - int lastDot = qualifiedName.lastIndexOf("."); - if (lastDot == -1) { + public Optional<Type> outerType() { + if (typeNames.size() < 2) { return Optional.empty(); } else { - return Optional.of(qualifiedName.substring(0, lastDot)); + return Optional.of(new ScalarType(packageName, typeNames.subList(0, typeNames.size() - 1))); } } diff --git a/src/main/java/org/zwobble/couscous/types/Types.java b/src/main/java/org/zwobble/couscous/types/Types.java index d0ba3d6..6476828 100644 --- a/src/main/java/org/zwobble/couscous/types/Types.java +++ b/src/main/java/org/zwobble/couscous/types/Types.java @@ -8,16 +8,16 @@ import static org.zwobble.couscous.util.ExtraLists.eagerMap; import static org.zwobble.couscous.util.ExtraLists.list; public class Types { - public static final ScalarType VOID = ScalarType.of("void"); - public static final ScalarType BOOLEAN = ScalarType.of("boolean"); - public static final ScalarType INT = ScalarType.of("int"); - public static final ScalarType CHAR = ScalarType.of("char"); - public static final ScalarType STRING = ScalarType.of("java.lang.String"); - public static final ScalarType CLASS = ScalarType.of("java.lang.Class"); - public static final ScalarType OBJECT = ScalarType.of("java.lang.Object"); - public static final ScalarType BOXED_INT = ScalarType.of("java.lang.Integer"); - public static final ScalarType BOXED_BOOLEAN = ScalarType.of("java.lang.Boolean"); - public static final ScalarType ARRAY = ScalarType.of("array"); + public static final ScalarType VOID = ScalarType.topLevel("void"); + public static final ScalarType BOOLEAN = ScalarType.topLevel("boolean"); + public static final ScalarType INT = ScalarType.topLevel("int"); + public static final ScalarType CHAR = ScalarType.topLevel("char"); + public static final ScalarType STRING = ScalarType.topLevel("java.lang.String"); + public static final ScalarType CLASS = ScalarType.topLevel("java.lang.Class"); + public static final ScalarType OBJECT = ScalarType.topLevel("java.lang.Object"); + public static final ScalarType BOXED_INT = ScalarType.topLevel("java.lang.Integer"); + public static final ScalarType BOXED_BOOLEAN = ScalarType.topLevel("java.lang.Boolean"); + public static final ScalarType ARRAY = ScalarType.topLevel("array"); public static Type addTypeParameters(ScalarType rawType, List<Type> typeParameters) { if (typeParameters.isEmpty()) { diff --git a/src/main/java/org/zwobble/couscous/values/InternalCouscousValue.java b/src/main/java/org/zwobble/couscous/values/InternalCouscousValue.java index 0665063..f91f5b5 100644 --- a/src/main/java/org/zwobble/couscous/values/InternalCouscousValue.java +++ b/src/main/java/org/zwobble/couscous/values/InternalCouscousValue.java @@ -3,5 +3,5 @@ package org.zwobble.couscous.values; import org.zwobble.couscous.types.ScalarType; public class InternalCouscousValue { - public static final ScalarType REF = ScalarType.of("_couscous"); + public static final ScalarType REF = ScalarType.topLevel("_couscous"); } |
