blob: 68746ed3046fb0a7e1d7627f3ed0d231c86bdf8c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2016 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.ruby.typeinference.evaluators;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.core.mixin.IMixinElement;
import org.eclipse.dltk.core.mixin.IMixinRequestor;
import org.eclipse.dltk.ruby.ast.RubyColonExpression;
import org.eclipse.dltk.ruby.internal.parser.mixin.RubyMixinElementInfo;
import org.eclipse.dltk.ruby.typeinference.DefaultRubyEvaluatorFactory;
import org.eclipse.dltk.ruby.typeinference.RubyClassType;
import org.eclipse.dltk.ruby.typeinference.goals.ColonExpressionGoal;
import org.eclipse.dltk.ruby.typeinference.goals.NonTypeConstantTypeGoal;
import org.eclipse.dltk.ti.GoalState;
import org.eclipse.dltk.ti.goals.AbstractTypeGoal;
import org.eclipse.dltk.ti.goals.ExpressionTypeGoal;
import org.eclipse.dltk.ti.goals.IGoal;
import org.eclipse.dltk.ti.types.ClassType;
import org.eclipse.dltk.ti.types.IEvaluatedType;
public class ColonExpressionEvaluator extends RubyMixinGoalEvaluator {
private AbstractTypeGoal helperGoal = null;
private IEvaluatedType helperResult = null;
private IEvaluatedType answer = null;
public ColonExpressionEvaluator(IGoal goal) {
super(goal);
}
private ColonExpressionGoal getTypedGoal() {
return (ColonExpressionGoal) DefaultRubyEvaluatorFactory
.translateGoal(this.goal);
}
@Override
public Object produceResult() {
return answer;
}
@Override
public IGoal[] init() {
RubyColonExpression expr = getTypedGoal().getColonExpression();
ASTNode left = expr.getLeft();
if (left != null) {
helperGoal = new ExpressionTypeGoal(getGoal().getContext(), left);
return new IGoal[] { helperGoal };
} else {
IMixinElement mixinElement = mixinModel.getRawModel().get(
expr.getName());
if (mixinElement != null)
answer = new RubyClassType(mixinElement.getKey());
}
return IGoal.NO_GOALS;
}
@Override
public IGoal[] subGoalDone(IGoal subgoal, Object result, GoalState state) {
this.helperResult = (IEvaluatedType) result;
RubyColonExpression expr = getTypedGoal().getColonExpression();
ASTNode left = expr.getLeft();
if (left != null) {
if (helperResult instanceof ClassType) { // TODO: check existance
// of the new key
ClassType classType = (ClassType) helperResult;
String modelKey = classType.getModelKey();
modelKey += IMixinRequestor.MIXIN_NAME_SEPARATOR
+ expr.getName();
IMixinElement mixinElement = mixinModel.getRawModel().get(
modelKey);
if (mixinElement != null) {
Object[] objects = mixinElement.getAllObjects();
boolean found = false;
for (int i = 0; i < objects.length; i++) {
if (objects[i] instanceof RubyMixinElementInfo) {
RubyMixinElementInfo info = (RubyMixinElementInfo) objects[i];
if (info.getKind() == RubyMixinElementInfo.K_VARIABLE) {
found = true;
break;
}
}
}
if (found) { // non-type constant
NonTypeConstantTypeGoal g = new NonTypeConstantTypeGoal(
goal.getContext(), mixinElement);
return new IGoal[] { g };
}
answer = new RubyClassType(modelKey);
} else
answer = null;
}
} else {
IMixinElement mixinElement = mixinModel.getRawModel().get(
expr.getName());
if (mixinElement != null)
answer = new RubyClassType(mixinElement.getKey());
}
return IGoal.NO_GOALS;
}
}