Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Extending PDT"

m (Type inference hinting)
m (Type inference hinting)
Line 4: Line 4:
 
== Extending ==
 
== Extending ==
 
=== Code Assist ===
 
=== Code Assist ===
==== Type inference hinting ====
+
==== Type inference hinting ====
 
Suppose your framework uses the following language structure for object instantiation:
 
Suppose your framework uses the following language structure for object instantiation:
  
Line 13: Line 13:
 
org.eclipse.php.core.goalEvaluatorFactories extension point allows to provide additional rules to the PHP type inference engine. For our example what we'll need to contribute is:
 
org.eclipse.php.core.goalEvaluatorFactories extension point allows to provide additional rules to the PHP type inference engine. For our example what we'll need to contribute is:
  
   <extension point="org.eclipse.php.core.goalEvaluatorFactories">
+
   &lt;extension point="org.eclipse.php.core.goalEvaluatorFactories"&gt;
      <factory
+
    &lt;factory
            class="com.xyz.php.fmwrk.XYZGoalEvaluatorFactory"
+
          class="com.xyz.php.fmwrk.XYZGoalEvaluatorFactory"
            priority="100">
+
          priority="100"&gt;
      </factory>
+
    &lt;/factory&gt;
  </extension>
+
  &lt;/extension&gt;
  
 
Please note the priority is set to 100 in order to override the default PHP goal evaluator (its priority is 10).
 
Please note the priority is set to 100 in order to override the default PHP goal evaluator (its priority is 10).
Line 25: Line 25:
 
public class XYZGoalEvaluatorFactory implements IGoalEvaluatorFactory {
 
public class XYZGoalEvaluatorFactory implements IGoalEvaluatorFactory {
  
public GoalEvaluator createEvaluator(IGoal goal) {
+
  public GoalEvaluator createEvaluator(IGoal goal) {
Class<?> goalClass = goal.getClass();
+
    Class<?> goalClass = goal.getClass();
  
// We're overriding only the expression type goal:
+
    // We're overriding only the expression type goal:
if (goalClass == ExpressionTypeGoal.class) {
+
    if (goalClass == ExpressionTypeGoal.class) {
ASTNode expression = ((ExpressionTypeGoal) goal).getExpression();
+
      ASTNode expression = ((ExpressionTypeGoal) goal).getExpression();
  
// Check the expression AST node type
+
      // Check the expression AST node type
if (expression instanceof StaticMethodInvocation) {
+
      if (expression instanceof StaticMethodInvocation) {
StaticMethodInvocation inv = (StaticMethodInvocation) expression;
+
        StaticMethodInvocation inv = (StaticMethodInvocation) expression;
ASTNode reciever = inv.getReceiver();
+
        ASTNode reciever = inv.getReceiver();
  
// Check that the class name is 'CallRegistry':
+
        // Check that the class name is 'CallRegistry':
if (reciever instanceof SimpleReference
+
        if (reciever instanceof SimpleReference
&& "ClassRegistry".equals(((SimpleReference) reciever)
+
            && "ClassRegistry".equals(((SimpleReference) reciever)
.getName())) {
+
                .getName())) {
  
// Check that the method name is 'init'
+
          // Check that the method name is 'init'
if ("init".equals(inv.getCallName().getName())) {
+
          if ("init".equals(inv.getCallName().getName())) {
  
// Take the first call argument:
+
            // Take the first call argument:
List arguments = inv.getArgs().getChilds();
+
            List arguments = inv.getArgs().getChilds();
if (arguments.size() == 1) {
+
            if (arguments.size() == 1) {
Object first = arguments.get(0);
+
              Object first = arguments.get(0);
if (first instanceof Scalar
+
              if (first instanceof Scalar
&& ((Scalar) first).getScalarType() == Scalar.TYPE_STRING) {
+
                  && ((Scalar) first).getScalarType() == Scalar.TYPE_STRING) {
  
String className = ((Scalar) first).getValue();
+
                String className = ((Scalar) first).getValue();
  
// Return the evaluated type through dummy
+
                // Return the evaluated type through dummy
// evaluator
+
                // evaluator
return new DummyGoalEvaluator(goal, className);
+
                return new DummyGoalEvaluator(goal, className);
}
+
              }
}
+
            }
}
+
          }
}
+
        }
}
+
      }
}
+
    }
  
// Give the control to the default PHP goal evaluator
+
    // Give the control to the default PHP goal evaluator
return null;
+
    return null;
}
+
  }
 
}
 
}
 
</pre>
 
</pre>

Revision as of 05:23, 30 November 2009

Purpose

There are different purposes for extending PDT. One of them is adding support for specific PHP framework to the IDE features like: Code Assist, Navigation (CTRL + click), Presentation (Outline, PHP Explorer). In this document we'll describe how to achieve these goals using PDT extension points.

Extending

Code Assist

Type inference hinting

Suppose your framework uses the following language structure for object instantiation:

 $myObject = ClassRegistry::init('MyObject');

In this case PDT type inference engine is unable to detect the type of $myObject variable, so we'll have to add a specific rule that helps him.

org.eclipse.php.core.goalEvaluatorFactories extension point allows to provide additional rules to the PHP type inference engine. For our example what we'll need to contribute is:

 <extension point="org.eclipse.php.core.goalEvaluatorFactories">
    <factory
          class="com.xyz.php.fmwrk.XYZGoalEvaluatorFactory"
          priority="100">
    </factory>
 </extension>

Please note the priority is set to 100 in order to override the default PHP goal evaluator (its priority is 10).

public class XYZGoalEvaluatorFactory implements IGoalEvaluatorFactory {

  public GoalEvaluator createEvaluator(IGoal goal) {
    Class<?> goalClass = goal.getClass();

    // We're overriding only the expression type goal:
    if (goalClass == ExpressionTypeGoal.class) {
      ASTNode expression = ((ExpressionTypeGoal) goal).getExpression();

      // Check the expression AST node type
      if (expression instanceof StaticMethodInvocation) {
        StaticMethodInvocation inv = (StaticMethodInvocation) expression;
        ASTNode reciever = inv.getReceiver();

        // Check that the class name is 'CallRegistry':
        if (reciever instanceof SimpleReference
            && "ClassRegistry".equals(((SimpleReference) reciever)
                .getName())) {

          // Check that the method name is 'init'
          if ("init".equals(inv.getCallName().getName())) {

            // Take the first call argument:
            List arguments = inv.getArgs().getChilds();
            if (arguments.size() == 1) {
              Object first = arguments.get(0);
              if (first instanceof Scalar
                  && ((Scalar) first).getScalarType() == Scalar.TYPE_STRING) {

                String className = ((Scalar) first).getValue();

                // Return the evaluated type through dummy
                // evaluator
                return new DummyGoalEvaluator(goal, className);
              }
            }
          }
        }
      }
    }

    // Give the control to the default PHP goal evaluator
    return null;
  }
}

CTRL + click

Outline and PHP Explorer

Back to the top