aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java3
-rw-r--r--src/main/java/org/zwobble/couscous/ast/FormalTypeParameterNode.java30
-rw-r--r--src/main/java/org/zwobble/couscous/ast/MethodNode.java3
-rw-r--r--src/main/java/org/zwobble/couscous/ast/MethodSignature.java10
-rw-r--r--src/main/java/org/zwobble/couscous/ast/identifiers/ExtendedIdentifier.java50
-rw-r--r--src/main/java/org/zwobble/couscous/ast/identifiers/Identifier.java50
-rw-r--r--src/main/java/org/zwobble/couscous/ast/identifiers/IdentifierPart.java19
-rw-r--r--src/main/java/org/zwobble/couscous/ast/identifiers/IdentifierType.java8
-rw-r--r--src/main/java/org/zwobble/couscous/ast/identifiers/Identifiers.java29
-rw-r--r--src/main/java/org/zwobble/couscous/ast/identifiers/TopIdentifier.java12
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java6
-rw-r--r--src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java10
-rw-r--r--src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java6
-rw-r--r--src/main/java/org/zwobble/couscous/backends/naming/Names.java9
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java13
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java5
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/Scope.java25
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java4
-rw-r--r--src/main/java/org/zwobble/couscous/types/MethodTypeParameter.java45
-rw-r--r--src/main/java/org/zwobble/couscous/types/Type.java1
-rw-r--r--src/main/java/org/zwobble/couscous/types/Types.java15
-rw-r--r--src/main/java/org/zwobble/couscous/util/ExtraIterables.java4
-rw-r--r--src/test/java/org/zwobble/couscous/tests/BackendMethodTests.java8
-rw-r--r--src/test/java/org/zwobble/couscous/tests/TestIds.java7
-rw-r--r--src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java7
-rw-r--r--src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java4
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java12
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaTypesTests.java6
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java7
29 files changed, 212 insertions, 196 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java b/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java
index 734a6a2..4bd432f 100644
--- a/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java
+++ b/src/main/java/org/zwobble/couscous/ast/ClassNodeBuilder.java
@@ -3,6 +3,7 @@ package org.zwobble.couscous.ast;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.zwobble.couscous.ast.identifiers.Identifier;
+import org.zwobble.couscous.ast.identifiers.Identifiers;
import org.zwobble.couscous.types.ScalarType;
import org.zwobble.couscous.types.Type;
import org.zwobble.couscous.types.Types;
@@ -40,7 +41,7 @@ public class ClassNodeBuilder {
}
public ClassNodeBuilder addTypeParameter(String name) {
- this.typeParameters.add(formalTypeParameter(name));
+ this.typeParameters.add(formalTypeParameter(Identifiers.forType(this.name.getQualifiedName()), name));
return this;
}
diff --git a/src/main/java/org/zwobble/couscous/ast/FormalTypeParameterNode.java b/src/main/java/org/zwobble/couscous/ast/FormalTypeParameterNode.java
index 4582719..3147d1d 100644
--- a/src/main/java/org/zwobble/couscous/ast/FormalTypeParameterNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/FormalTypeParameterNode.java
@@ -1,25 +1,35 @@
package org.zwobble.couscous.ast;
+import org.zwobble.couscous.ast.identifiers.Identifier;
import org.zwobble.couscous.ast.visitors.NodeMapper;
import org.zwobble.couscous.ast.visitors.NodeTransformer;
+import org.zwobble.couscous.types.TypeParameter;
public class FormalTypeParameterNode implements Node {
- public static FormalTypeParameterNode formalTypeParameter(String name) {
- return new FormalTypeParameterNode(name);
+ public static FormalTypeParameterNode formalTypeParameter(Identifier declaringScope, String name) {
+ return new FormalTypeParameterNode(new TypeParameter(declaringScope, name));
}
- private final String name;
+ public static FormalTypeParameterNode formalTypeParameter(TypeParameter type) {
+ return new FormalTypeParameterNode(type);
+ }
+
+ private final TypeParameter type;
+
+ public FormalTypeParameterNode(TypeParameter type) {
+ this.type = type;
+ }
- public FormalTypeParameterNode(String name) {
- this.name = name;
+ public TypeParameter getType() {
+ return type;
}
public String getName() {
- return name;
+ return type.getName();
}
public FormalTypeParameterNode transform(NodeTransformer transformer) {
- return this;
+ return new FormalTypeParameterNode(transformer.transform(type));
}
@Override
@@ -30,7 +40,7 @@ public class FormalTypeParameterNode implements Node {
@Override
public String toString() {
return "FormalTypeParameterNode(" +
- "name=" + name +
+ "type=" + type +
')';
}
@@ -41,12 +51,12 @@ public class FormalTypeParameterNode implements Node {
FormalTypeParameterNode that = (FormalTypeParameterNode) o;
- return name.equals(that.name);
+ return type.equals(that.type);
}
@Override
public int hashCode() {
- return name.hashCode();
+ return type.hashCode();
}
}
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodNode.java b/src/main/java/org/zwobble/couscous/ast/MethodNode.java
index de86a15..0f91024 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodNode.java
@@ -10,7 +10,6 @@ import java.util.List;
import java.util.Optional;
import java.util.function.Function;
-import static org.zwobble.couscous.types.MethodTypeParameter.methodTypeParameter;
import static org.zwobble.couscous.util.ExtraLists.eagerMap;
import static org.zwobble.couscous.util.ExtraLists.list;
@@ -174,7 +173,7 @@ public class MethodNode implements Node {
public MethodSignature signature() {
return new MethodSignature(
name,
- eagerMap(typeParameters, parameter -> methodTypeParameter(parameter.getName())),
+ eagerMap(typeParameters, parameter -> parameter.getType()),
eagerMap(arguments, argument -> argument.getType()),
returnType);
}
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodSignature.java b/src/main/java/org/zwobble/couscous/ast/MethodSignature.java
index 8c907e3..d6c42ab 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodSignature.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodSignature.java
@@ -1,7 +1,7 @@
package org.zwobble.couscous.ast;
-import org.zwobble.couscous.types.MethodTypeParameter;
import org.zwobble.couscous.types.Type;
+import org.zwobble.couscous.types.TypeParameter;
import org.zwobble.couscous.types.Types;
import java.util.List;
@@ -14,16 +14,16 @@ public class MethodSignature {
return signature(name, list(), arguments, returnType);
}
- public static MethodSignature signature(String name, List<MethodTypeParameter> typeParameters, List<Type> arguments, Type returnType) {
+ public static MethodSignature signature(String name, List<TypeParameter> typeParameters, List<Type> arguments, Type returnType) {
return new MethodSignature(name, typeParameters, arguments, returnType);
}
private final String name;
- private final List<MethodTypeParameter> typeParameters;
+ private final List<TypeParameter> typeParameters;
private final List<Type> arguments;
private final Type returnType;
- public MethodSignature(String name, List<MethodTypeParameter> typeParameters, List<Type> arguments, Type returnType) {
+ public MethodSignature(String name, List<TypeParameter> typeParameters, List<Type> arguments, Type returnType) {
this.name = name;
this.typeParameters = typeParameters;
this.arguments = arguments;
@@ -34,7 +34,7 @@ public class MethodSignature {
return name;
}
- public List<MethodTypeParameter> getTypeParameters() {
+ public List<TypeParameter> getTypeParameters() {
return typeParameters;
}
diff --git a/src/main/java/org/zwobble/couscous/ast/identifiers/ExtendedIdentifier.java b/src/main/java/org/zwobble/couscous/ast/identifiers/ExtendedIdentifier.java
new file mode 100644
index 0000000..407c6da
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/ast/identifiers/ExtendedIdentifier.java
@@ -0,0 +1,50 @@
+package org.zwobble.couscous.ast.identifiers;
+
+import static org.zwobble.couscous.util.ExtraIterables.lazyAppend;
+
+public class ExtendedIdentifier implements Identifier {
+ private final Identifier parent;
+ private final String part;
+ private final IdentifierType type;
+
+ ExtendedIdentifier(Identifier parent, String part, IdentifierType type) {
+ this.parent = parent;
+ this.part = part;
+ this.type = type;
+ }
+
+ @Override
+ public Iterable<IdentifierPart> getParts() {
+ return lazyAppend(parent.getParts(), new IdentifierPart(part, type));
+ }
+
+ @Override
+ public String toString() {
+ return "ExtendedIdentifier(" +
+ "parent=" + parent +
+ ", part='" + part + '\'' +
+ ", type=" + type +
+ ')';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ExtendedIdentifier that = (ExtendedIdentifier) o;
+
+ if (!parent.equals(that.parent)) return false;
+ if (!part.equals(that.part)) return false;
+ return type == that.type;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = parent.hashCode();
+ result = 31 * result + part.hashCode();
+ result = 31 * result + type.hashCode();
+ return result;
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/ast/identifiers/Identifier.java b/src/main/java/org/zwobble/couscous/ast/identifiers/Identifier.java
index c753034..777a0bb 100644
--- a/src/main/java/org/zwobble/couscous/ast/identifiers/Identifier.java
+++ b/src/main/java/org/zwobble/couscous/ast/identifiers/Identifier.java
@@ -1,51 +1,5 @@
package org.zwobble.couscous.ast.identifiers;
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-
-import static org.zwobble.couscous.util.ExtraLists.list;
-
-public class Identifier {
- // TODO: Should we have two Identifier classes, one for each namespace? (variables and types)
- public static final Identifier TOP = new Identifier(list());
-
- private final List<String> parts;
-
- private Identifier(List<String> parts) {
- this.parts = parts;
- }
-
- public List<String> getParts() {
- return parts;
- }
-
- public Identifier extend(String name) {
- ImmutableList.Builder<String> parts = ImmutableList.builder();
- parts.addAll(this.parts);
- parts.add(name);
- return new Identifier(parts.build());
- }
-
- @Override
- public String toString() {
- return "Identifier(" +
- "parts=" + parts +
- ')';
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- Identifier that = (Identifier) o;
-
- return parts.equals(that.parts);
- }
-
- @Override
- public int hashCode() {
- return parts.hashCode();
- }
+public interface Identifier {
+ Iterable<IdentifierPart> getParts();
}
diff --git a/src/main/java/org/zwobble/couscous/ast/identifiers/IdentifierPart.java b/src/main/java/org/zwobble/couscous/ast/identifiers/IdentifierPart.java
new file mode 100644
index 0000000..5aedcf0
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/ast/identifiers/IdentifierPart.java
@@ -0,0 +1,19 @@
+package org.zwobble.couscous.ast.identifiers;
+
+public class IdentifierPart {
+ private final String name;
+ private final IdentifierType type;
+
+ public IdentifierPart(String name, IdentifierType type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public IdentifierType getType() {
+ return type;
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/ast/identifiers/IdentifierType.java b/src/main/java/org/zwobble/couscous/ast/identifiers/IdentifierType.java
new file mode 100644
index 0000000..f18334f
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/ast/identifiers/IdentifierType.java
@@ -0,0 +1,8 @@
+package org.zwobble.couscous.ast.identifiers;
+
+public enum IdentifierType {
+ TYPE,
+ METHOD,
+ CONSTRUCTOR,
+ VARIABLE
+}
diff --git a/src/main/java/org/zwobble/couscous/ast/identifiers/Identifiers.java b/src/main/java/org/zwobble/couscous/ast/identifiers/Identifiers.java
new file mode 100644
index 0000000..9beac27
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/ast/identifiers/Identifiers.java
@@ -0,0 +1,29 @@
+package org.zwobble.couscous.ast.identifiers;
+
+public class Identifiers {
+ public static final Identifier TOP = new TopIdentifier();
+
+ public static Identifier type(Identifier identifier, String name) {
+ return extend(identifier, name, IdentifierType.TYPE);
+ }
+
+ public static Identifier method(Identifier identifier, String name) {
+ return extend(identifier, name, IdentifierType.METHOD);
+ }
+
+ public static Identifier constructor(Identifier identifier) {
+ return extend(identifier, "", IdentifierType.CONSTRUCTOR);
+ }
+
+ public static Identifier variable(Identifier identifier, String name) {
+ return extend(identifier, name, IdentifierType.VARIABLE);
+ }
+
+ private static Identifier extend(Identifier identifier, String name, IdentifierType type) {
+ return new ExtendedIdentifier(identifier, name, type);
+ }
+
+ public static Identifier forType(String name) {
+ return type(TOP, name);
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/ast/identifiers/TopIdentifier.java b/src/main/java/org/zwobble/couscous/ast/identifiers/TopIdentifier.java
new file mode 100644
index 0000000..4776dc1
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/ast/identifiers/TopIdentifier.java
@@ -0,0 +1,12 @@
+package org.zwobble.couscous.ast.identifiers;
+
+import static org.zwobble.couscous.util.ExtraLists.list;
+
+public class TopIdentifier implements Identifier {
+ static final Identifier INSTANCE = new TopIdentifier();
+
+ @Override
+ public Iterable<IdentifierPart> getParts() {
+ return list();
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java
index afa1681..6e63059 100644
--- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java
+++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeTransformer.java
@@ -5,9 +5,9 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import org.zwobble.couscous.ast.*;
-import org.zwobble.couscous.types.MethodTypeParameter;
import org.zwobble.couscous.types.ScalarType;
import org.zwobble.couscous.types.Type;
+import org.zwobble.couscous.types.TypeParameter;
import java.util.List;
import java.util.Map;
@@ -221,8 +221,8 @@ public class NodeTransformer {
return (ScalarType)transformType.apply(type);
}
- public MethodTypeParameter transform(MethodTypeParameter type) {
- return (MethodTypeParameter)transformType.apply(type);
+ public TypeParameter transform(TypeParameter type) {
+ return (TypeParameter)transformType.apply(type);
}
public String transformMethodName(MethodSignature signature) {
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 86afe8e..00de205 100644
--- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java
@@ -59,11 +59,6 @@ public class CsharpCodeGenerator {
}
@Override
- public Type visit(MethodTypeParameter parameter) {
- return parameter;
- }
-
- @Override
public TypeParameter visit(TypeParameter parameter) {
return parameter;
}
@@ -119,11 +114,6 @@ public class CsharpCodeGenerator {
}
@Override
- public Type visit(MethodTypeParameter parameter) {
- return parameter;
- }
-
- @Override
public TypeParameter visit(TypeParameter parameter) {
return parameter;
}
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 f5f75ec..13c3756 100644
--- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java
+++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java
@@ -537,12 +537,6 @@ public class CsharpSerializer implements NodeVisitor {
}
@Override
- public Void visit(MethodTypeParameter parameter) {
- writer.writeIdentifier(parameter.getName());
- return null;
- }
-
- @Override
public Void visit(TypeParameter parameter) {
writer.writeIdentifier(parameter.getName());
return null;
diff --git a/src/main/java/org/zwobble/couscous/backends/naming/Names.java b/src/main/java/org/zwobble/couscous/backends/naming/Names.java
index 537633b..ff671cd 100644
--- a/src/main/java/org/zwobble/couscous/backends/naming/Names.java
+++ b/src/main/java/org/zwobble/couscous/backends/naming/Names.java
@@ -25,14 +25,9 @@ public class Names {
}
@Override
- public String visit(MethodTypeParameter parameter) {
- return parameter.getName();
- }
-
- @Override
public String visit(TypeParameter parameter) {
- // TODO
- Iterable<String> parts = lazyMap(parameter.getDeclaringScope().getParts(), part -> part.replace(".", "_"));
+ // TODO: should we care about the type?
+ Iterable<String> parts = lazyMap(parameter.getDeclaringScope().getParts(), part -> part.getName().replace(".", "_"));
return String.join("_", parts) + "_" + parameter.getName();
}
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 063ffc6..44cbfab 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -6,6 +6,7 @@ import com.google.common.collect.Maps;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.*;
import org.zwobble.couscous.ast.*;
+import org.zwobble.couscous.ast.identifiers.Identifier;
import org.zwobble.couscous.ast.sugar.AnonymousClass;
import org.zwobble.couscous.ast.sugar.Lambda;
import org.zwobble.couscous.ast.sugar.TypeDeclarationBody;
@@ -98,7 +99,7 @@ public class JavaReader {
private TypeNode readTypeDeclaration(TypeDeclaration type) {
ScalarType name = erasure(typeOf(type.resolveBinding()));
Scope scope = topScope.enterClass(name);
- List<FormalTypeParameterNode> typeParameters = readTypeParameters(type);
+ List<FormalTypeParameterNode> typeParameters = readTypeParameters(scope.getIdentifier(), type);
TypeDeclarationBody body = readTypeDeclarationBody(scope, name, type.bodyDeclarations());
Set<Type> superTypes = superTypes(type);
if (type.isInterface()) {
@@ -116,14 +117,14 @@ public class JavaReader {
}
}
- private List<FormalTypeParameterNode> readTypeParameters(TypeDeclaration typeDeclaration) {
- return readTypeParameters(typeDeclaration.resolveBinding().getTypeParameters());
+ private List<FormalTypeParameterNode> readTypeParameters(Identifier declaringScope, TypeDeclaration typeDeclaration) {
+ return readTypeParameters(declaringScope, typeDeclaration.resolveBinding().getTypeParameters());
}
- private List<FormalTypeParameterNode> readTypeParameters(ITypeBinding[] typeParameters) {
+ private List<FormalTypeParameterNode> readTypeParameters(Identifier declaringScope, ITypeBinding[] typeParameters) {
return eagerMap(
asList(typeParameters),
- parameter -> formalTypeParameter(parameter.getName()));
+ parameter -> formalTypeParameter(declaringScope, parameter.getName()));
}
GeneratedClosure readExpressionMethodReference(Scope outerScope, ExpressionMethodReference expression) {
@@ -420,7 +421,7 @@ public class JavaReader {
annotations,
isStatic,
methodName,
- readTypeParameters(method.resolveBinding().getTypeParameters()),
+ readTypeParameters(scope.getIdentifier(), method.resolveBinding().getTypeParameters()),
formalArguments,
returnType.get(),
body,
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 4b3c5ea..1e373d8 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaTypes.java
@@ -3,6 +3,7 @@ package org.zwobble.couscous.frontends.java;
import com.google.common.collect.ImmutableSet;
import org.eclipse.jdt.core.dom.*;
import org.zwobble.couscous.ast.identifiers.Identifier;
+import org.zwobble.couscous.ast.identifiers.Identifiers;
import org.zwobble.couscous.types.*;
import org.zwobble.couscous.types.ParameterizedType;
import org.zwobble.couscous.types.Type;
@@ -64,14 +65,14 @@ public class JavaTypes {
if (typeParameter.getDeclaringClass() == null) {
IMethodBinding method = typeParameter.getDeclaringMethod();
// TODO: disambiguate overloads
- return identifierForType(method.getDeclaringClass()).extend(method.getName());
+ return Identifiers.method(identifierForType(method.getDeclaringClass()), method.getName());
} else {
return identifierForType(typeParameter.getDeclaringClass());
}
}
private static Identifier identifierForType(ITypeBinding type) {
- return Identifier.TOP.extend(erasure(typeOf(type)).getQualifiedName());
+ return Identifiers.forType(erasure(typeOf(type)).getQualifiedName());
}
static Set<Type> superTypes(TypeDeclaration declaration) {
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/Scope.java b/src/main/java/org/zwobble/couscous/frontends/java/Scope.java
index 98dd30b..0cc369b 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/Scope.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/Scope.java
@@ -2,6 +2,7 @@ package org.zwobble.couscous.frontends.java;
import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.ast.identifiers.Identifier;
+import org.zwobble.couscous.ast.identifiers.Identifiers;
import org.zwobble.couscous.types.ScalarType;
import org.zwobble.couscous.types.Type;
import org.zwobble.couscous.util.NaturalNumbers;
@@ -10,7 +11,7 @@ import java.util.*;
public class Scope {
public static Scope create() {
- return new Scope(new HashMap<>(), new HashSet<>(), Identifier.TOP, NaturalNumbers.INSTANCE.iterator());
+ return new Scope(new HashMap<>(), new HashSet<>(), Identifiers.TOP, NaturalNumbers.INSTANCE.iterator());
}
private final Map<String, VariableDeclaration> variablesByKey;
@@ -30,21 +31,25 @@ public class Scope {
this.temporaryCounter = temporaryCounter;
}
+ public Identifier getIdentifier() {
+ return identifier;
+ }
+
public Scope enterClass(ScalarType className) {
- return enter("class#" + className.getQualifiedName());
+ return enter(Identifiers.type(identifier, className.getQualifiedName()));
}
public Scope enterConstructor() {
- return enter("constructor");
+ return enter(Identifiers.constructor(identifier));
}
public Scope enterMethod(String name) {
// TODO: distinguish overloads
- return enter("method#" + name);
+ return enter(Identifiers.method(identifier, name));
}
- private Scope enter(String name) {
- return new Scope(variablesByKey, identifiers, identifier.extend(name), temporaryCounter);
+ private Scope enter(Identifier newIdentifier) {
+ return new Scope(variablesByKey, identifiers, newIdentifier, temporaryCounter);
}
public FormalArgumentNode formalArgument(String name, Type type) {
@@ -102,15 +107,15 @@ public class Scope {
}
public VariableDeclaration generateVariable(String name, Type type) {
- Identifier identifier = generateIdentifier(name);
+ Identifier identifier = generateVariableIdentifier(name);
return VariableDeclaration.var(identifier, name, type);
}
- private Identifier generateIdentifier(String name) {
- Identifier identifier = this.identifier.extend(name);
+ private Identifier generateVariableIdentifier(String name) {
+ Identifier identifier = Identifiers.variable(this.identifier, name);
int index = 0;
while (identifiers.contains(identifier)) {
- identifier = this.identifier.extend(name + "_" + index);
+ identifier = Identifiers.variable(this.identifier, name + "_" + index);
index++;
}
identifiers.add(identifier);
diff --git a/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java b/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java
index c296d01..07199bb 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java
@@ -1,7 +1,6 @@
package org.zwobble.couscous.interpreter.types;
import org.zwobble.couscous.ast.*;
-import org.zwobble.couscous.ast.identifiers.Identifier;
import org.zwobble.couscous.interpreter.Arguments;
import org.zwobble.couscous.interpreter.Environment;
import org.zwobble.couscous.interpreter.Executor;
@@ -10,7 +9,6 @@ import org.zwobble.couscous.interpreter.errors.NoSuchMethod;
import org.zwobble.couscous.interpreter.errors.WrongNumberOfArguments;
import org.zwobble.couscous.interpreter.values.InterpreterValue;
import org.zwobble.couscous.types.Type;
-import org.zwobble.couscous.types.TypeParameter;
import java.util.List;
import java.util.Map;
@@ -49,7 +47,7 @@ public class UserDefinedInterpreterType implements InterpreterType {
public Type getType() {
List<Type> parameters = eagerMap(
type.getTypeParameters(),
- parameter -> new TypeParameter(Identifier.TOP.extend(type.getName().getQualifiedName()), parameter.getName()));
+ parameter -> parameter.getType());
return parameters.isEmpty()
? type.getName()
: parameterizedType(type.getName(), parameters);
diff --git a/src/main/java/org/zwobble/couscous/types/MethodTypeParameter.java b/src/main/java/org/zwobble/couscous/types/MethodTypeParameter.java
deleted file mode 100644
index 323ec17..0000000
--- a/src/main/java/org/zwobble/couscous/types/MethodTypeParameter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.zwobble.couscous.types;
-
-public class MethodTypeParameter implements Type {
- public static MethodTypeParameter methodTypeParameter(String name) {
- return new MethodTypeParameter(name);
- }
-
- private final String name;
-
- public MethodTypeParameter(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- @Override
- public <T> T accept(Visitor<T> visitor) {
- return visitor.visit(this);
- }
-
- @Override
- public String toString() {
- return "MethodTypeParameter(" +
- "name=" + name +
- ')';
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- MethodTypeParameter that = (MethodTypeParameter) o;
-
- return name.equals(that.name);
-
- }
-
- @Override
- public int hashCode() {
- return name.hashCode();
- }
-}
diff --git a/src/main/java/org/zwobble/couscous/types/Type.java b/src/main/java/org/zwobble/couscous/types/Type.java
index 5261aa2..ad0f6fc 100644
--- a/src/main/java/org/zwobble/couscous/types/Type.java
+++ b/src/main/java/org/zwobble/couscous/types/Type.java
@@ -5,7 +5,6 @@ public interface Type {
interface Visitor<T> {
T visit(ScalarType type);
- T visit(MethodTypeParameter parameter);
T visit(TypeParameter parameter);
T visit(ParameterizedType type);
T visit(BoundTypeParameter type);
diff --git a/src/main/java/org/zwobble/couscous/types/Types.java b/src/main/java/org/zwobble/couscous/types/Types.java
index 1dfc202..89e88a6 100644
--- a/src/main/java/org/zwobble/couscous/types/Types.java
+++ b/src/main/java/org/zwobble/couscous/types/Types.java
@@ -28,11 +28,6 @@ public class Types {
}
@Override
- public ScalarType visit(MethodTypeParameter parameter) {
- return OBJECT;
- }
-
- @Override
public ScalarType visit(TypeParameter parameter) {
return OBJECT;
}
@@ -57,11 +52,6 @@ public class Types {
}
@Override
- public Type visit(MethodTypeParameter parameter) {
- return parameter;
- }
-
- @Override
public Type visit(TypeParameter type) {
return replacements.getOrDefault(type, type);
}
@@ -88,11 +78,6 @@ public class Types {
}
@Override
- public Type visit(MethodTypeParameter parameter) {
- return parameter;
- }
-
- @Override
public Type visit(TypeParameter parameter) {
return parameter;
}
diff --git a/src/main/java/org/zwobble/couscous/util/ExtraIterables.java b/src/main/java/org/zwobble/couscous/util/ExtraIterables.java
index a77869d..0fcc9af 100644
--- a/src/main/java/org/zwobble/couscous/util/ExtraIterables.java
+++ b/src/main/java/org/zwobble/couscous/util/ExtraIterables.java
@@ -78,6 +78,10 @@ public class ExtraIterables {
};
}
+ public static <T> Iterable<T> lazyAppend(Iterable<T> head, T tail) {
+ return Iterables.concat(head, list(tail));
+ }
+
public static <T> Iterable<T> lazyCons(T head, Iterable<T> tails) {
return Iterables.concat(list(head), tails);
}
diff --git a/src/test/java/org/zwobble/couscous/tests/BackendMethodTests.java b/src/test/java/org/zwobble/couscous/tests/BackendMethodTests.java
index 635dae8..dcb7d9e 100644
--- a/src/test/java/org/zwobble/couscous/tests/BackendMethodTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/BackendMethodTests.java
@@ -117,8 +117,8 @@ public abstract class BackendMethodTests {
@Test
public void whileLoopIsExecutedWhileConditionIsTrue() {
- LocalVariableDeclarationNode x = localVariableDeclaration(TestIds.id("x"), "x", Types.INT, literal(0));
- LocalVariableDeclarationNode y = localVariableDeclaration(TestIds.id("y"), "y", Types.INT, literal(2));
+ LocalVariableDeclarationNode x = localVariableDeclaration(TestIds.variable("x"), "x", Types.INT, literal(0));
+ LocalVariableDeclarationNode y = localVariableDeclaration(TestIds.variable("y"), "y", Types.INT, literal(2));
MethodNode.Builder method = staticMethod("hello")
.returns(Types.INT)
.statement(x)
@@ -132,8 +132,8 @@ public abstract class BackendMethodTests {
@Test
public void returnWillExitWhileLoopEarly() {
- LocalVariableDeclarationNode x = localVariableDeclaration(TestIds.id("x"), "x", Types.INT, literal(0));
- LocalVariableDeclarationNode y = localVariableDeclaration(TestIds.id("y"), "y", Types.INT, literal(2));
+ LocalVariableDeclarationNode x = localVariableDeclaration(TestIds.variable("x"), "x", Types.INT, literal(0));
+ LocalVariableDeclarationNode y = localVariableDeclaration(TestIds.variable("y"), "y", Types.INT, literal(2));
MethodNode.Builder method = staticMethod("hello")
.returns(Types.INT)
.statement(x)
diff --git a/src/test/java/org/zwobble/couscous/tests/TestIds.java b/src/test/java/org/zwobble/couscous/tests/TestIds.java
index b32cf84..da3cd09 100644
--- a/src/test/java/org/zwobble/couscous/tests/TestIds.java
+++ b/src/test/java/org/zwobble/couscous/tests/TestIds.java
@@ -1,11 +1,12 @@
package org.zwobble.couscous.tests;
import org.zwobble.couscous.ast.identifiers.Identifier;
+import org.zwobble.couscous.ast.identifiers.Identifiers;
public class TestIds {
- public static final Identifier ANY_ID = Identifier.TOP.extend("[any id]");
+ public static final Identifier ANY_ID = Identifiers.variable(Identifiers.TOP, "[any id]");
- public static Identifier id(String name) {
- return ANY_ID.extend(name);
+ public static Identifier variable(String name) {
+ return Identifiers.variable(ANY_ID, name);
}
}
diff --git a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java
index 0e96500..06906ca 100644
--- a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java
@@ -61,7 +61,6 @@ public class ValueObjectTests {
{LocalVariableDeclarationNode.class},
{MethodCallNode.class},
{MethodNode.class},
- {MethodTypeParameter.class},
{OperationNode.class},
{ParameterizedType.class},
{ReturnNode.class},
@@ -151,7 +150,7 @@ public class ValueObjectTests {
} else if (type.equals(Operator.class)) {
return Operator.DIVIDE;
} else if (type.equals(Identifier.class)) {
- return TestIds.id((String)generateFirstInstance(String.class));
+ return TestIds.variable((String)generateFirstInstance(String.class));
} else if (type.equals(PrimitiveValue.class)) {
return generateFirstInstance(StringValue.class);
} else if (type.equals(ExpressionNode.class)) {
@@ -181,7 +180,7 @@ public class ValueObjectTests {
} else if (type.equals(Operator.class)) {
return Operator.MULTIPLY;
} else if (type.equals(Identifier.class)) {
- return TestIds.id((String)generateSecondInstance(String.class));
+ return TestIds.variable((String)generateSecondInstance(String.class));
} else if (type.equals(PrimitiveValue.class)) {
return generateSecondInstance(StringValue.class);
} else if (type.equals(ExpressionNode.class)) {
@@ -211,7 +210,7 @@ public class ValueObjectTests {
} else if (type.equals(Operator.class)) {
return Operator.ADD;
} else if (type.equals(Identifier.class)) {
- return TestIds.id((String)generateInstance(String.class));
+ return TestIds.variable((String)generateInstance(String.class));
} else if (type.equals(PrimitiveValue.class)) {
return generateInstance(StringValue.class);
} else if (type.equals(ExpressionNode.class)) {
diff --git a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java
index a2f838f..52849dc 100644
--- a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java
@@ -304,8 +304,8 @@ public class CsharpSerializerTests {
@Test
public void methodWithArguments() {
MethodNode methodNode = MethodNode.staticMethod("nothing")
- .argument(formalArg(var(TestIds.id("x"), "x", ScalarType.of("X"))))
- .argument(formalArg(var(TestIds.id("y"), "y", ScalarType.of("Y"))))
+ .argument(formalArg(var(TestIds.variable("x"), "x", ScalarType.of("X"))))
+ .argument(formalArg(var(TestIds.variable("y"), "y", ScalarType.of("Y"))))
.returns(ScalarType.of("void"))
.build();
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 971ddd9..e9e75c4 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
@@ -3,6 +3,7 @@ package org.zwobble.couscous.tests.frontends.java;
import org.junit.Test;
import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.ast.identifiers.Identifier;
+import org.zwobble.couscous.ast.identifiers.Identifiers;
import org.zwobble.couscous.types.ScalarType;
import org.zwobble.couscous.types.Types;
@@ -92,10 +93,13 @@ public class JavaReaderTests {
"}");
MethodNode method = classNode.getMethods().get(0);
- assertThat(method.getTypeParameters(), contains(isFormalTypeParameter("T")));
+
+ Identifier classIdentifier = Identifiers.forType("com.example.Example");
+ Identifier expectedMethodIdentifier = Identifiers.method(classIdentifier, "identity");
+ assertThat(method.getTypeParameters(), contains(isFormalTypeParameter(expectedMethodIdentifier, "T")));
assertThat(
method.getArguments(),
- contains(isFormalArgument("value", typeParameter(Identifier.TOP.extend("com.example.Example").extend("identity"), "T"))));
+ contains(isFormalArgument("value", typeParameter(expectedMethodIdentifier, "T"))));
}
@Test
@@ -337,7 +341,7 @@ public class JavaReaderTests {
assertThat(classes, hasSize(1));
ClassNode classNode = (ClassNode) classes.get(0);
assertEquals(ScalarType.of("com.example.Example"), classNode.getName());
- assertEquals(list(formalTypeParameter("T")), classNode.getTypeParameters());
+ assertEquals(list(formalTypeParameter(Identifiers.forType("com.example.Example"), "T")), classNode.getTypeParameters());
}
@Test
@@ -348,7 +352,7 @@ public class JavaReaderTests {
assertThat(classes, hasSize(1));
InterfaceNode classNode = (InterfaceNode) classes.get(0);
assertEquals(ScalarType.of("com.example.Example"), classNode.getName());
- assertEquals(list(formalTypeParameter("T")), classNode.getTypeParameters());
+ assertEquals(list(formalTypeParameter(Identifiers.forType("com.example.Example"), "T")), classNode.getTypeParameters());
}
@Test
diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaTypesTests.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaTypesTests.java
index 329ccc7..75c3594 100644
--- a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaTypesTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaTypesTests.java
@@ -1,7 +1,7 @@
package org.zwobble.couscous.tests.frontends.java;
import org.junit.Test;
-import org.zwobble.couscous.ast.identifiers.Identifier;
+import org.zwobble.couscous.ast.identifiers.Identifiers;
import org.zwobble.couscous.frontends.java.JavaTypes;
import org.zwobble.couscous.types.ScalarType;
import org.zwobble.couscous.types.TypeParameter;
@@ -24,7 +24,7 @@ public class JavaTypesTests {
@Test
public void bindingTypeToGenericTypeParameterReturnsBoundTypeParameter() {
- TypeParameter typeParameter = typeParameter(Identifier.TOP.extend("List"), "T");
+ TypeParameter typeParameter = typeParameter(Identifiers.forType("List"), "T");
assertEquals(
boundTypeParameter(typeParameter, INT_TYPE),
JavaTypes.bind(typeParameter, INT_TYPE));
@@ -33,7 +33,7 @@ public class JavaTypesTests {
@Test
public void bindingTypeToParameterizedTypeBindsParameters() {
ScalarType rawList = ScalarType.of("List");
- TypeParameter typeParameter = typeParameter(Identifier.TOP.extend("List"), "T");
+ TypeParameter typeParameter = typeParameter(Identifiers.forType("List"), "T");
assertEquals(
parameterizedType(rawList, list(boundTypeParameter(typeParameter, INT_TYPE))),
JavaTypes.bind(
diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java
index 104cf8b..5ef5344 100644
--- a/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java
+++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/NodeMatchers.java
@@ -2,6 +2,7 @@ package org.zwobble.couscous.tests.frontends.java;
import org.hamcrest.Matcher;
import org.zwobble.couscous.ast.*;
+import org.zwobble.couscous.ast.identifiers.Identifier;
import org.zwobble.couscous.types.Type;
import static org.hamcrest.Matchers.allOf;
@@ -14,8 +15,10 @@ public class NodeMatchers {
return hasFeature("initial value", node -> node.getInitialValue(), matcher);
}
- public static Matcher<FormalTypeParameterNode> isFormalTypeParameter(String name) {
- return hasFeature("name", node -> node.getName(), equalTo(name));
+ public static Matcher<FormalTypeParameterNode> isFormalTypeParameter(Identifier declaringScope, String name) {
+ return allOf(
+ hasFeature("name", node -> node.getType().getName(), equalTo(name)),
+ hasFeature("declaringScope", node -> node.getType().getDeclaringScope(), equalTo(declaringScope)));
}
public static Matcher<FormalArgumentNode> isFormalArgument(String name, Type type) {