Jump to: navigation, search

API Document for Extension Points PDT

PHP Core

PHP Evaluator Factory

Extension Description

This extension point allows providing additional goal evaluator factories (IGoalEvaluatorFactory) thus overriding default PHP goal evaluator factory. Goal evaluator factory is a part of DLTK type inference engine, and it is used for creating evaluators that correspond to goals (see DDP algorithm for more information).

Extension Registry Algorithm

PHP Goal evaluators registry goes over all contributed extensions sorted by priority, and tries to resolve goal evaluator using current factory. The first that returns non-null goal evaluator is working - the rest are discarded.

Extension Example

Lets add a new goal and goal evaluator for resolving special Aspect PHP variable "$thisJoinPoint":

  • Create a new goal factory extension:
<extension point="org.eclipse.php.core.goalEvaluatorFactories">
  <factory
       class="org.eclipse.apdt.core.AspectPHPEvaluatorFactory"
       priority="100">
  </factory>
</extension>
  • Write the factory class:
public class AspectPHPEvaluatorFactory implements IGoalEvaluatorFactory {
	public GoalEvaluator createEvaluator(IGoal goal) {
		if (goal instanceof ExpressionTypeGoal) {
			ExpressionTypeGoal typedGoal = (ExpressionTypeGoal) goal;
			Expression expression = typedGoal.getExpression();
			if (expression instanceof VariableReference) {
				VariableReference varReference = (VariableReference) expression;
				if (varReference.getName().equals("$thisJoinPoint")) {
					return new ThisJoinPointEvaluator(typedGoal);
				}
			}
		}
		return null; // let other factories proceeed
	}
}
  • Implement the evaluator class:
public class ThisJoinPointEvaluator extends GoalEvaluator {
	private IEvaluatedType result;

	public IGoal[] init() {
		ExpressionTypeGoal typedGoal = (ExpressionTypeGoal) getGoal();
		VariableReference varReference = (VariableReference)typedGoal.getExpression();
		BasicContext context = (BasicContext)typedGoal.getContext();

		// Find the relevant JoinPoint model element:
		ISourceModule sourceModule = context.getSourceModule();
		
		IModelElement element = sourceModule.getElementAt(varReference.sourceStart());
		while (element != null && !(element instanceof IType)) { // search for relevant JoinPoint type
			element = element.getParent();
		}

		if (element instanceof IType) { // this is a JoinPoint type
			// Set result to the special builtin 'JoinPoint' type that extends ModelClassType
			result = new JoinPointType((IType)element);
		}
		return IGoal.NO_GOALS;
	}
	public Object produceResult() {
		return result;
	}
	public IGoal[] subGoalDone(IGoal subgoal, Object result, GoalState state) {
		return IGoal.NO_GOALS;
	}
}

PHP Mixin Build Visitor

Extension Description

This extension point allows providing additional visitors for Mixin Parser Build Visitor. Mixin model represents global workspace-scope database for model elements that are stored in a special index, and can be easily accessed using special key (for more details refer to DLTK Core Architecture).

Extension Registry Algorithm

PHP Mixin Parser first calls to the PHP Mixin Build Visitor, which builds Mixin model for most of PHP elements. Then it calls to all other extensions, thus allowing them to complete Mixin index with other potential model elements.

Extension Example

Lets create a special Aspect type element for the PHPAspect.

  • Create new PHP Mixin Build Visitor extension:
<extension point="org.eclipse.php.core.phpMixinBuildVisitors">
      <visitor
            class="org.eclipse.apdt.core.AspectMixinBuildVisitor">
      </visitor>
</extension>
  • Implement visitor class AspectMixinBuildVisitor (it must extend PHPMixinBuildVisitorExtension class by extension point definition):
public class AspectMixinBuildVisitor extends PHPMixinBuildVisitorExtension {

	public static final String ASPECT_TYPE_SUFFIX = "__ASPECT";

	public boolean visit(Expression expression) throws Exception {
		if (expression instanceof AspectASTNode) {
			AspectASTNode aspectNode = (AspectASTNode) expression;

			// report model element info:
			ElementInfo info = new IMixinRequestor.ElementInfo();

			// build mixin model key:
			info.key = aspectNode.getName() + ASPECT_KEY_SUFFIX;

			// find mixin element info object:
			info.object = findModelElementFor(aspectNode);

			if (getRequestor() != null) {
				getRequestor().reportElement(info);
			}
		}
		return true;
	}

	protected IModelElement findModelElementFor(ASTNode decl) throws ModelException {
		return getSourceModule().getElementAt(decl.sourceStart() + 1);
	}
}
  • Now we can search for Aspect type named 'Singleton' in Mixin model:
Object[] aspectTypes = PHPMixinModel.getRawInstance().find("Singleton" + AspectMixinBuildVisitor.ASPECT_TYPE_SUFFIX);
// aspectTypes should contain now all aspect declarations in the workspace

PHP Source Element Requestor

Extension Description

This extension point allows intervention into structured model build process for contribution additional model elements. Structured model (IModuleElement hierarchy) is used to present elements structure in script explorer, outline, search, code completion, code selection, etc... This model consists only from top level elements, like: IType, IMethod, IField. If additional element type is considered to be added - it must derive from one of those basic types.

Extension Registry Algorithm

Default PHP Soruce Element Requestor delegates from its visit() and endvisit() methods to all extensions, before it does its work, like in example:

public boolean visit(Expression node) throws Exception {
	for (PHPSourceElementRequestorExtension visitor : extensions) {
		visitor.visit(node);
	}
	// process expression node:
	// .....
}

Extension Example

Lets create a PHP Source Element Requestor extension that creates special AspectType model element.

  • Create an extension:
<extension point="org.eclipse.php.core.phpSourceElementRequestors">
      <requestor
            class="org.eclipse.apdt.core.AspectSourceElementRequestor">
      </requestor>
</extension>
  • Implement extension class:
public class AspectSourceElementRequestor extends PHPSourceElementRequestorExtension {
	public boolean visit(Expression expression) throws Exception {
		if (expression instanceof AspectASTNode) {
			AspectASTNode aspectNode = (AspectASTNode) expression;

			// notify about new type element start (it will be of type IType):
			int start = aspectNode.sourceStart();
			int end = aspectNode.sourceEnd();
			ISourceElementRequestor.TypeInfo typeInfo = new ISourceElementRequestor.TypeInfo();
			typeInfo.modifiers = IPHPModifiers.NonPhp;
			typeInfo.name = aspectNode.getName();
			typeInfo.nameSourceStart = start;
			typeInfo.nameSourceEnd = end - 1;
			typeInfo.declarationStart = start;
			fRequestor.enterType(typeInfo);
		}
		return true;
	}

	public boolean endvisit(Expression expression) throws Exception {
		if (expression instanceof AspectASTNode) {
			AspectASTNode aspectNode = (AspectASTNode) expression;
			int end = aspectNode.sourceEnd();
			// notify about element end:
			fRequestor.exitType(end);
		}
		return true;
	}
}