Skip to content

Commit

Permalink
Fix generics
Browse files Browse the repository at this point in the history
  • Loading branch information
= committed Aug 19, 2018
1 parent 6c77abb commit 4707702
Show file tree
Hide file tree
Showing 33 changed files with 146 additions and 265 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public class IteratorExtensionTest extends ScriptTestCase {
private static final String SOURCE =
"let x = [1,2,3,4,5,6,7,8];\n"+
"let y = [];\n"+
"x.iterator().filter(x -> x % 2 == 0).reverse().forEachRemaining(x -> y.add(x));\n"+
"x.iterator().filter(e -> e % 2 == 0).reverse().forEachRemaining(e -> y.add(e));\n"+
"assert y[0] == 8;\n"+
"assert y[1] == 6;\n"+
"assert y[2] == 4;\n"+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public List<Annotation> getAnnotations() {
}

@Override
public List<Constraint> getConstraints() {
public List<Constraint> getGenerics() {
return constraints;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ArrayToStreamTest extends CompileTestCase {
"\n"+
"var x: String[] = ['x', 'y', 'z'];\n"+
"var v = x.stream()\n"+
" .map(x -> x.toUpperCase())\n"+
" .map(e -> e.toUpperCase())\n"+
" .collect(Collectors.toList())\n"+
" .stream()\n"+
" .findFirst()\n"+
Expand All @@ -33,11 +33,11 @@ public class ArrayToStreamTest extends CompileTestCase {

private static final String SUCCESS_4 =
"var x: Integer[] = [1,2,3];\n"+
"x.forEach(x -> println(x));\n";
"x.forEach(e -> println(e));\n";

private static final String SUCCESS_5 =
"var x: Integer[] = [1,2,3];\n"+
"x.iterator().forEachRemaining(x -> println(x));\n";
"x.iterator().forEachRemaining(e -> println(e));\n";

private static final String SUCCESS_6 =
"var x: Integer[] = [1,2,3];\n"+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
public class GenericFunctionTest extends CompileTestCase {

private static final String SUCCESS_1 =
"func fun<T: Integer>(a: T): T {\n"+
"func fun<T: Number>(a: T): T {\n"+
" return a;\n"+
"}\n"+
"fun<Double>(1.0).intValue();\n";
Expand All @@ -28,8 +28,15 @@ public class GenericFunctionTest extends CompileTestCase {
"}\n"+
"fun(1.0).intValue();\n"; // no qualification at all

private static final String SUCCESS_5 =
"func fun<F, B>(b: B): List<F> {\n"+
" return [['a','b']];\n"+
"}\n"+
"let u = fun<List<String>, Number>(11).get(0).get(0).toUpperCase();\n"+
"println(u);\n";

private static final String FAILURE_1 =
"func fun<T: Integer>(a: T): T {\n"+
"func fun<T: Number>(a: T): T {\n"+
" return a;\n"+
"}\n"+
"fun<Double>(1.0).substring(1);\n";
Expand All @@ -48,14 +55,22 @@ public class GenericFunctionTest extends CompileTestCase {
"}\n"+
"fun(1.0).substring(1);\n"; // no qualifier so default


private static final String FAILURE_4 =
"func fun<F, B>(b: B): List<F> {\n"+
" return [['a','b']];\n"+
"}\n"+
"let u = fun<List<String>, Number>(11).get(0).get(0).intValue();\n";

public void testGenericFunction() throws Exception {
assertCompileAndExecuteSuccess(SUCCESS_1);
assertCompileAndExecuteSuccess(SUCCESS_2);
assertCompileAndExecuteSuccess(SUCCESS_3);
assertCompileAndExecuteSuccess(SUCCESS_4);
assertCompileAndExecuteSuccess(SUCCESS_4);
assertCompileAndExecuteSuccess(SUCCESS_5);
assertCompileError(FAILURE_1, "Function 'substring(lang.Integer)' not found for 'lang.Double' in /default.snap at line 4");
assertCompileError(FAILURE_2, "Function 'substring(lang.Integer)' not found for 'lang.Integer' in /default.snap at line 6");
assertCompileError(FAILURE_3, "Function 'substring(lang.Integer)' not found for 'lang.Integer' in /default.snap at line 4");
assertCompileError(FAILURE_4, "Function 'intValue()' not found for 'lang.String' in /default.snap at line 4");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void testGenericParametersForScript() throws Exception {
assertNotNull(type);
assertNotNull(string);

List<Constraint> constraints = type.getConstraints();
List<Constraint> constraints = type.getGenerics();
Scope scope = type.getScope();

assertFalse(constraints.isEmpty());
Expand Down Expand Up @@ -127,7 +127,7 @@ public void testGenericParameters() throws Exception {
assertNotNull(type);
assertNotNull(string);

List<Constraint> constraints = type.getConstraints();
List<Constraint> constraints = type.getGenerics();
Scope scope = type.getScope();

assertFalse(constraints.isEmpty());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public static boolean isTrait(int modifier){
public static boolean isEnum(int modifier){
return modifier >= 0 && (ENUM.mask & modifier) != 0;
}

public static boolean isProxy(int modifier){
return modifier >= 0 && (PROXY.mask & modifier) != 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void verify(Scope scope, Constraint constraint) {
Type type = constraint.getType(scope);

if(type != null) {
List<Constraint> generics = type.getConstraints();
List<Constraint> generics = type.getGenerics();
List<Constraint> constraints = constraint.getGenerics(scope);
int constraintCount = constraints.size();
int genericCount = generics.size();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.snapscript.core.constraint.transform;

import java.util.List;

import org.snapscript.core.Bug;
import org.snapscript.core.attribute.Attribute;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.convert.InstanceOfChecker;
import org.snapscript.core.error.InternalStateException;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.scope.State;
import org.snapscript.core.scope.index.Table;
import org.snapscript.core.type.Type;

public class AttributeRule implements ConstraintRule {

private final InstanceOfChecker checker;
private final Attribute attribute;
private final ConstraintRule rule;

public AttributeRule(ConstraintRule rule, Attribute attribute) {
this.checker = new InstanceOfChecker();
this.attribute = attribute;
this.rule = rule;
}

@Bug
@Override
public Constraint getResult(Scope scope, Constraint returns) {
List<Constraint> defaults = attribute.getGenerics();
int count = defaults.size();

if(count > 0) {
Table table = scope.getTable();
State state = scope.getState();
Constraint first = table.getConstraint(0);

for(int i = 0; i < count; i++) {
Constraint parameter = table.getConstraint(i);
Constraint constraint = defaults.get(i);
String name = constraint.getName(scope);

if(parameter != null) {
Type require = constraint.getType(scope);
Type actual = parameter.getType(scope);

if(!checker.isInstanceOf(scope, actual, require)) {
throw new InternalStateException("Generic parameter '" + name +"' is does not match '" + constraint + "'");
}
state.addConstraint(name, parameter);
} else {
if(first != null) {
throw new InternalStateException("Generic parameter '" + name +"' not specified");
}
state.addConstraint(name, constraint);
}
}
}
return rule.getResult(scope, returns);
}

@Override
public Constraint getSource() {
return rule.getSource();
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
package org.snapscript.core.constraint.transform;

import java.util.List;

import org.snapscript.core.Bug;
import org.snapscript.core.attribute.Attribute;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.error.InternalStateException;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.scope.State;
import org.snapscript.core.scope.index.Table;

public class AttributeTransform implements ConstraintTransform {

Expand All @@ -25,49 +18,4 @@ public ConstraintRule apply(Constraint left) {
ConstraintRule rule = transform.apply(left);
return new AttributeRule(rule, attribute);
}

private static class AttributeRule implements ConstraintRule {

private final Attribute attribute;
private final ConstraintRule rule;

public AttributeRule(ConstraintRule rule, Attribute attribute) {
this.attribute = attribute;
this.rule = rule;
}

@Bug
@Override
public Constraint getResult(Scope scope, Constraint returns) {
List<Constraint> defaults = attribute.getGenerics();
int count = defaults.size();

if(count > 0) {
Table table = scope.getTable();
State state = scope.getState();
Constraint first = table.getConstraint(0);

for(int i = 0; i < count; i++) {
Constraint parameter = table.getConstraint(i);
Constraint constraint = defaults.get(i);
String name = constraint.getName(scope);

if(parameter != null) {
state.addConstraint(name, parameter);
} else {
if(first != null) {
throw new InternalStateException("Generic parameter '" + name +"' not specified");
}
state.addConstraint(name, constraint);
}
}
}
return rule.getResult(scope, returns);
}

@Override
public Constraint getSource() {
return rule.getSource();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ConstraintIndex index(Type type){ // give me the named parameters

private ConstraintIndex create(Type type) {
Scope scope = type.getScope();
List<Constraint> generics = type.getConstraints();
List<Constraint> generics = type.getGenerics();
int count = generics.size();

if(count > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private ConstraintTransform resolveArray(Type constraint, Type require) { // Str

private ConstraintTransform resolveArray(Constraint constraint, Type require) { // String[] -> List
ConstraintIndex index = indexer.index(require);
List<Constraint> constraints = require.getConstraints();
List<Constraint> constraints = require.getGenerics();

if(!constraints.isEmpty()) {
List<Constraint> generics = new ArrayList<Constraint>();
Expand All @@ -97,7 +97,7 @@ private ConstraintTransform resolveArray(Constraint constraint, Type require) {
}

private ConstraintTransform resolveType(Type constraint, Type require) {
List<Constraint> constraints = require.getConstraints();
List<Constraint> constraints = require.getGenerics();

if(!constraints.isEmpty()) {
List<Constraint> path = extractor.getTypes(constraint, require);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,9 @@

import static java.util.Collections.EMPTY_MAP;

import java.util.List;

import org.snapscript.core.attribute.Attribute;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.error.InternalStateException;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.scope.State;
import org.snapscript.core.scope.index.Table;

public class LocalTransform implements ConstraintTransform {

Expand All @@ -25,46 +20,22 @@ public LocalTransform(Attribute attribute){

@Override
public ConstraintRule apply(Constraint left){
return new LocalRule(index, attribute, left);
ConstraintRule rule = new LocalRule(index, attribute, left);
return new AttributeRule(rule, attribute);
}

private static class LocalRule implements ConstraintRule {

private final ConstraintIndex index;
private final Attribute attribute;
private final Constraint left;

public LocalRule(ConstraintIndex index, Attribute attribute, Constraint left) {
this.attribute = attribute;
this.index = index;
this.left = left;
}

@Override
public Constraint getResult(Scope scope, Constraint returns) {
List<Constraint> defaults = attribute.getGenerics();
int count = defaults.size();

if(count > 0) {
Table table = scope.getTable();
State state = scope.getState();
Constraint first = table.getConstraint(0);

for(int i = 0; i < count; i++) {
Constraint parameter = table.getConstraint(i);
Constraint constraint = defaults.get(i);
String name = constraint.getName(scope);

if(parameter != null) {
state.addConstraint(name, parameter);
} else {
if(first != null) {
throw new InternalStateException("Generic parameter '" + name +"' not specified");
}
state.addConstraint(name, constraint);
}
}
}
return index.update(scope, left, returns);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public TypeSource(Type type) {
public List<Constraint> getConstraints(Constraint constraint) {
Scope scope = type.getScope();
List<Constraint> generics = constraint.getGenerics(scope);
List<Constraint> constraints = type.getConstraints();
List<Constraint> constraints = type.getGenerics();
int require = constraints.size();
int actual = generics.size();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ public boolean isInstanceOf(Scope scope, Type instance, Type constraint) {
return false;
}
}
return false;
return constraint == null;
}

public boolean isInstanceOf(Scope scope, Object instance, Object constraint) {
if (constraint != null && instance != null) {
try {
Expand Down Expand Up @@ -75,5 +75,5 @@ private boolean isInstanceOf(Scope scope, Class instance, Class constraint) {
}
}
return constraint == Object.class;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class ErrorHandler {
private final CompileErrorHandler compile;

public ErrorHandler(TypeExtractor extractor, ThreadStack stack) {
this(extractor, stack, false);
this(extractor, stack, true);
}

public ErrorHandler(TypeExtractor extractor, ThreadStack stack, boolean replace) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public List<Annotation> getAnnotations() {
}

@Override
public List<Constraint> getConstraints() {
public List<Constraint> getGenerics() {
return Collections.emptyList();
}

Expand Down
Loading

0 comments on commit 4707702

Please sign in to comment.