blob: 65628cedf4400f9435e70cb73c25e92ca10e5289 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.dltk.core.tests.ddp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.expressions.NumericLiteral;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.core.tests.model.SuiteOfTestCases;
import org.eclipse.dltk.ti.DefaultTypeInferencer;
import org.eclipse.dltk.ti.GoalState;
import org.eclipse.dltk.ti.IGoalEvaluatorFactory;
import org.eclipse.dltk.ti.ITypeInferencer;
import org.eclipse.dltk.ti.goals.ExpressionTypeGoal;
import org.eclipse.dltk.ti.goals.GoalEvaluator;
import org.eclipse.dltk.ti.goals.IGoal;
import org.eclipse.dltk.ti.types.IEvaluatedType;
import junit.framework.Test;
public class CoreDDPTests extends SuiteOfTestCases {
public CoreDDPTests(String name) {
super(name);
}
public static Test suite() {
return new Suite(CoreDDPTests.class);
}
private static final class FixedAnswerGoalEvaluator extends GoalEvaluator {
private final IEvaluatedType answer;
private FixedAnswerGoalEvaluator(IGoal goal, IEvaluatedType answer) {
super(goal);
this.answer = answer;
}
@Override
public Object produceResult() {
return answer;
}
@Override
public IGoal[] init() {
return IGoal.NO_GOALS;
}
@Override
public IGoal[] subGoalDone(IGoal goal2, Object result,
GoalState state) {
return IGoal.NO_GOALS;
}
}
private static final class SingleDependentGoalEvaluator
extends GoalEvaluator {
private final IEvaluatedType answer;
private final IGoal[] dependents;
// private int state = 0;
private int produceCalls = 0;
private int produceTypeCalls = 0;
private SingleDependentGoalEvaluator(IGoal goal, IGoal dependent,
IEvaluatedType answer) {
super(goal);
this.dependents = new IGoal[] { dependent };
this.answer = answer;
}
private SingleDependentGoalEvaluator(IGoal goal, IGoal[] dependents,
Object answer) {
super(goal);
this.dependents = dependents;
this.answer = (IEvaluatedType) answer;
}
@Override
public IGoal[] init() {
++produceCalls;
return dependents;
}
@Override
public IGoal[] subGoalDone(IGoal goal2, Object result,
GoalState _state) {
++produceCalls;
assertTrue(
result instanceof MyNum || _state == GoalState.RECURSIVE);
return IGoal.NO_GOALS;
}
@Override
public Object produceResult() {
++produceTypeCalls;
return answer;
}
public void assertState() {
assertEquals(1, produceTypeCalls);
assertEquals(1 + dependents.length, produceCalls);
}
}
class MyNum implements IEvaluatedType {
@Override
public String toString() {
return "MyNum";
}
@Override
public String getTypeName() {
return "MyNum";
}
@Override
public boolean subtypeOf(IEvaluatedType type) {
// TODO Auto-generated method stub
return false;
}
}
public void testSimple() throws Exception {
// y = 2; x = y; x?
final Expression x = new SimpleReference(0, 0, "x");
final Expression y = new SimpleReference(0, 0, "y");
final Expression num = new NumericLiteral(0, 0, 0);
IGoalEvaluatorFactory factory = goal -> {
if (goal instanceof ExpressionTypeGoal) {
ExpressionTypeGoal egoal = (ExpressionTypeGoal) goal;
ASTNode expr = egoal.getExpression();
if (expr == x)
return new SingleDependentGoalEvaluator(goal,
new ExpressionTypeGoal(null, y), new MyNum());
if (expr == y)
return new SingleDependentGoalEvaluator(goal,
new ExpressionTypeGoal(null, num), new MyNum());
if (expr == num)
return new FixedAnswerGoalEvaluator(goal, new MyNum());
}
return null;
};
final ITypeInferencer man = new DefaultTypeInferencer(factory);
ExpressionTypeGoal rootGoal = new ExpressionTypeGoal(null, x);
IEvaluatedType answer = man.evaluateType(rootGoal, -1);
assertTrue(answer instanceof MyNum);
}
public void testCycles() throws Exception {
final Expression x = new SimpleReference(0, 0, "x");
final Expression y = new SimpleReference(0, 0, "y");
final Expression z = new SimpleReference(0, 0, "z");
final Expression num = new NumericLiteral(0, 0, 0);
final Collection<GoalEvaluator> evaluators = new ArrayList<>();
IGoalEvaluatorFactory factory = new IGoalEvaluatorFactory() {
public GoalEvaluator createEvaluator2(IGoal goal) {
if (goal instanceof ExpressionTypeGoal) {
ExpressionTypeGoal egoal = (ExpressionTypeGoal) goal;
ASTNode expr = egoal.getExpression();
if (expr == x)
return new SingleDependentGoalEvaluator(goal,
new IGoal[] { new ExpressionTypeGoal(null, y),
new ExpressionTypeGoal(null, z) },
new MyNum());
if (expr == y)
return new SingleDependentGoalEvaluator(goal,
new IGoal[] { new ExpressionTypeGoal(null, z) },
new MyNum());
if (expr == z)
return new SingleDependentGoalEvaluator(goal,
new IGoal[] { new ExpressionTypeGoal(null, num),
new ExpressionTypeGoal(null, y) },
new MyNum());
if (expr == num)
return new FixedAnswerGoalEvaluator(goal, new MyNum());
}
return null;
}
@Override
public GoalEvaluator createEvaluator(IGoal goal) {
GoalEvaluator result = createEvaluator2(goal);
if (result != null)
evaluators.add(result);
return result;
}
};
final ITypeInferencer man = new DefaultTypeInferencer(factory);
ExpressionTypeGoal rootGoal = new ExpressionTypeGoal(null, x);
IEvaluatedType answer = man.evaluateType(rootGoal, -1);
assertTrue(answer instanceof MyNum);
for (Iterator<GoalEvaluator> iter = evaluators.iterator(); iter
.hasNext();) {
GoalEvaluator ev = iter.next();
if (ev instanceof SingleDependentGoalEvaluator) {
SingleDependentGoalEvaluator sdge = (SingleDependentGoalEvaluator) ev;
sdge.assertState();
}
}
}
}