package org.maziarz.yiiclipse; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.dltk.ast.ASTNode; import org.eclipse.dltk.ast.references.SimpleReference; import org.eclipse.dltk.ast.references.VariableReference; import org.eclipse.dltk.core.IType; import org.eclipse.dltk.ti.GoalState; import org.eclipse.dltk.ti.IGoalEvaluatorFactory; import org.eclipse.dltk.ti.goals.ExpressionTypeGoal; import org.eclipse.dltk.ti.goals.GoalEvaluator; import org.eclipse.dltk.ti.goals.IGoal; import org.eclipse.php.internal.core.compiler.ast.nodes.StaticMethodInvocation; import org.eclipse.php.internal.core.typeinference.PHPClassType; import org.eclipse.php.internal.core.typeinference.context.FileContext; import org.eclipse.php.internal.core.typeinference.context.MethodContext; import org.eclipse.php.internal.core.typeinference.goals.phpdoc.PHPDocMethodReturnTypeGoal; import org.maziarz.yiiclipse.hyperlinks.WorkspacePathHelper; import org.maziarz.yiiclipse.utils.YiiPathResolver; public class YiiGoalEvaluatorFactory implements IGoalEvaluatorFactory { private IPath viewPath; @Override public GoalEvaluator createEvaluator(IGoal goal) { if (goal.getClass() == ExpressionTypeGoal.class){ ExpressionTypeGoal exprGoal = ((ExpressionTypeGoal) goal); ASTNode expression = exprGoal.getExpression(); if (exprGoal.getContext() instanceof FileContext && expression instanceof VariableReference && "$this".equals(((VariableReference)expression).getName())){ FileContext ctx = (FileContext)exprGoal.getContext(); //retrieve view path if (viewPath == null) { YiiPathResolver resolver = new YiiPathResolver(new WorkspacePathHelper()); viewPath = resolver.resolveAliasPath("application.views", ctx.getSourceModule()); viewPath = viewPath.makeRelativeTo(ResourcesPlugin.getWorkspace().getRoot().getLocation()); } if (viewPath.isPrefixOf(ctx.getSourceModule().getPath())){ return new YiiAppGoalEvaluator(goal, "CController"); } } if (expression instanceof StaticMethodInvocation) { StaticMethodInvocation inv = (StaticMethodInvocation) expression; ASTNode reciever = inv.getReceiver(); if (reciever instanceof SimpleReference && "Yii".equals(((SimpleReference) reciever).getName())) { if ("app".equals(inv.getCallName().getName())) { return new YiiAppGoalEvaluator(goal, "CWebApplication"); } } } } else if (goal.getClass() == PHPDocMethodReturnTypeGoal.class){ PHPDocMethodReturnTypeGoal docGoal = ((PHPDocMethodReturnTypeGoal) goal); if (docGoal != null && docGoal.getTypes() != null) { if (docGoal.getTypes().length > 0){ IType type = docGoal.getTypes()[0]; if("Yii".equals(type.getElementName())){ if ("app".equals(docGoal.getMethodName())){ return new YiiAppGoalEvaluator(goal, "CWebApplication"); } } } } } return null; } class YiiAppGoalEvaluator extends GoalEvaluator { private String className; public YiiAppGoalEvaluator(IGoal goal, String className) { super(goal); this.className = className; } public Object produceResult() { return new PHPClassType(className); } public IGoal[] init() { return null; } public IGoal[] subGoalDone(IGoal subgoal, Object result, GoalState state) { return null; } } }