aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzzhongwei2012-09-09 04:46:46 (EDT)
committerzzhongwei2012-09-09 04:46:46 (EDT)
commit07bef3e011524140669ab954b75229284d8b87dc (patch)
treef35c99b31bce4f9c6c88160314f834fba132cee0
parentcf2cc95b8b6a20493b07f02029ee618a0e2272d2 (diff)
downloadorg.eclipse.pdt-07bef3e011524140669ab954b75229284d8b87dc.zip
org.eclipse.pdt-07bef3e011524140669ab954b75229284d8b87dc.tar.gz
org.eclipse.pdt-07bef3e011524140669ab954b75229284d8b87dc.tar.bz2
Bug 201108 - [TypeInferencer] Code assist in foreach for classes
implementing Iterator
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/DefaultPHPGoalEvaluatorFactory.java3
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/ForeachStatementEvaluator.java11
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/IteratorTypeGoalEvaluator.java92
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/goals/IteratorTypeGoal.java44
-rw-r--r--tests/org.eclipse.php.core.tests/workspace/codeassist/php5/testClassMembers27-nonstrict.pdtt60
-rw-r--r--tests/org.eclipse.php.core.tests/workspace/codeassist/php5/testClassMembers27-strict.pdtt60
-rw-r--r--tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference1.pdtt26
-rw-r--r--tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference2.pdtt35
-rw-r--r--tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference3.pdtt36
9 files changed, 363 insertions, 4 deletions
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/DefaultPHPGoalEvaluatorFactory.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/DefaultPHPGoalEvaluatorFactory.java
index 19ad560..518820f 100644
--- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/DefaultPHPGoalEvaluatorFactory.java
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/DefaultPHPGoalEvaluatorFactory.java
@@ -62,6 +62,9 @@ public class DefaultPHPGoalEvaluatorFactory implements IGoalEvaluatorFactory {
if (goalClass == ArrayDeclarationGoal.class) {
return new ArrayDeclarationGoalEvaluator(goal);
}
+ if (goalClass == IteratorTypeGoal.class) {
+ return new IteratorTypeGoalEvaluator(goal);
+ }
return null;
}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/ForeachStatementEvaluator.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/ForeachStatementEvaluator.java
index 0d84b84..8943ac8 100644
--- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/ForeachStatementEvaluator.java
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/ForeachStatementEvaluator.java
@@ -16,11 +16,11 @@ import java.util.List;
import org.eclipse.dltk.evaluation.types.AmbiguousType;
import org.eclipse.dltk.evaluation.types.MultiTypeType;
import org.eclipse.dltk.ti.GoalState;
-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 org.eclipse.php.internal.core.typeinference.goals.ForeachStatementGoal;
+import org.eclipse.php.internal.core.typeinference.goals.IteratorTypeGoal;
/**
* This evaluator determines types that array expression in foreach statement
@@ -36,7 +36,7 @@ public class ForeachStatementEvaluator extends GoalEvaluator {
public IGoal[] init() {
ForeachStatementGoal typedGoal = (ForeachStatementGoal) goal;
- return new IGoal[] { new ExpressionTypeGoal(goal.getContext(),
+ return new IGoal[] { new IteratorTypeGoal(goal.getContext(),
typedGoal.getExpression()) };
}
@@ -44,8 +44,11 @@ public class ForeachStatementEvaluator extends GoalEvaluator {
public IGoal[] subGoalDone(IGoal subgoal, Object result, GoalState state) {
if (result instanceof MultiTypeType) {
List types = ((MultiTypeType) result).getTypes();
- this.result = new AmbiguousType((IEvaluatedType[]) types
- .toArray(new IEvaluatedType[types.size()]));
+ this.result = new AmbiguousType(
+ (IEvaluatedType[]) types.toArray(new IEvaluatedType[types
+ .size()]));
+ } else if (result instanceof AmbiguousType) {
+ this.result = (AmbiguousType) result;
}
return IGoal.NO_GOALS;
}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/IteratorTypeGoalEvaluator.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/IteratorTypeGoalEvaluator.java
new file mode 100644
index 0000000..9819367
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/IteratorTypeGoalEvaluator.java
@@ -0,0 +1,92 @@
+package org.eclipse.php.internal.core.typeinference.evaluators;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.core.IType;
+import org.eclipse.dltk.core.ModelException;
+import org.eclipse.dltk.evaluation.types.MultiTypeType;
+import org.eclipse.dltk.ti.GoalState;
+import org.eclipse.dltk.ti.ISourceModuleContext;
+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 org.eclipse.php.internal.core.typeinference.PHPClassType;
+import org.eclipse.php.internal.core.typeinference.PHPModelUtils;
+import org.eclipse.php.internal.core.typeinference.goals.IteratorTypeGoal;
+import org.eclipse.php.internal.core.typeinference.goals.MethodElementReturnTypeGoal;
+import org.eclipse.php.internal.core.typeinference.goals.phpdoc.PHPDocMethodReturnTypeGoal;
+
+public class IteratorTypeGoalEvaluator extends GoalEvaluator {
+
+ private IEvaluatedType result;
+
+ public IteratorTypeGoalEvaluator(IGoal goal) {
+ super(goal);
+ }
+
+ public IGoal[] init() {
+ IteratorTypeGoal typedGoal = (IteratorTypeGoal) goal;
+ return new IGoal[] { new ExpressionTypeGoal(goal.getContext(),
+ typedGoal.getExpression()) };
+ }
+
+ public Object produceResult() {
+ return result;
+ }
+
+ public IGoal[] subGoalDone(IGoal subgoal, Object result, GoalState state) {
+ if (state != GoalState.RECURSIVE) {
+ if (result instanceof PHPClassType) {
+ if (subgoal instanceof ExpressionTypeGoal) {
+ ISourceModule sourceModule = ((ISourceModuleContext) subgoal
+ .getContext()).getSourceModule();
+ PHPClassType classType = (PHPClassType) result;
+ List<IGoal> subGoals = new LinkedList<IGoal>();
+ try {
+ IType[] types = PHPModelUtils.getTypes(
+ classType.getTypeName(), sourceModule, 0, null);
+ for (IType type : types) {
+ IType[] superTypes = PHPModelUtils.getSuperClasses(
+ type, null);
+ if (isImplementedIterator(superTypes)) {
+ subGoals.add(new MethodElementReturnTypeGoal(
+ subgoal.getContext(),
+ new IType[] { type }, "current"));
+ subGoals.add(new PHPDocMethodReturnTypeGoal(
+ subgoal.getContext(),
+ new IType[] { type }, "current"));
+ }
+ }
+ return subGoals.toArray(new IGoal[subGoals.size()]);
+ } catch (ModelException e) {
+ if (DLTKCore.DEBUG) {
+ e.printStackTrace();
+ }
+ }
+ }
+ MultiTypeType type = new MultiTypeType();
+ type.addType((IEvaluatedType) result);
+ this.result = type;
+ return IGoal.NO_GOALS;
+ }
+ this.result = (IEvaluatedType) result;
+ }
+ return IGoal.NO_GOALS;
+ }
+
+ private boolean isImplementedIterator(IType[] superClasses) {
+ if (superClasses == null)
+ return false;
+ for (IType superClass : superClasses) {
+ if (superClass.getFullyQualifiedName().equalsIgnoreCase("Iterator")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/goals/IteratorTypeGoal.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/goals/IteratorTypeGoal.java
new file mode 100644
index 0000000..7fdc6d7
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/goals/IteratorTypeGoal.java
@@ -0,0 +1,44 @@
+package org.eclipse.php.internal.core.typeinference.goals;
+
+import org.eclipse.dltk.ast.ASTNode;
+import org.eclipse.dltk.ti.IContext;
+import org.eclipse.dltk.ti.goals.AbstractGoal;
+
+public class IteratorTypeGoal extends AbstractGoal {
+
+ private ASTNode expression;
+
+ public IteratorTypeGoal(IContext context, ASTNode expression) {
+ super(context);
+ this.expression = expression;
+ }
+
+ public ASTNode getExpression() {
+ return expression;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result
+ + ((expression == null) ? 0 : expression.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ IteratorTypeGoal other = (IteratorTypeGoal) obj;
+ if (expression == null) {
+ if (other.expression != null)
+ return false;
+ } else if (!expression.equals(other.expression))
+ return false;
+ return true;
+ }
+
+} \ No newline at end of file
diff --git a/tests/org.eclipse.php.core.tests/workspace/codeassist/php5/testClassMembers27-nonstrict.pdtt b/tests/org.eclipse.php.core.tests/workspace/codeassist/php5/testClassMembers27-nonstrict.pdtt
new file mode 100644
index 0000000..f11ff2c
--- /dev/null
+++ b/tests/org.eclipse.php.core.tests/workspace/codeassist/php5/testClassMembers27-nonstrict.pdtt
@@ -0,0 +1,60 @@
+--TEST--
+Test class constructor
+--PREFERENCES--
+org.eclipse.php.core/contentAssistShowStrictOptions=false
+--FILE--
+<?
+class Model {
+ private $a;
+ function test() {
+ ;
+ }
+}
+class ListOfModels implements Iterator {
+ /**
+ * @return Model
+ */
+ public function current(){
+ }
+ /**
+ * @return Model
+ * @see Iterator::next()
+ */
+ public function next() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-PHPdoc)
+ * @see Iterator::key()
+ */
+ public function key() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-PHPdoc)
+ * @see Iterator::valid()
+ */
+ public function valid() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-PHPdoc)
+ * @see Iterator::rewind()
+ */
+ public function rewind() {
+ // TODO Auto-generated method stub
+
+ }
+
+}
+
+$list=new ListOfModels();
+foreach($list as $model) {
+ $model->|
+}
+?>
+--EXPECT--
+method(test) \ No newline at end of file
diff --git a/tests/org.eclipse.php.core.tests/workspace/codeassist/php5/testClassMembers27-strict.pdtt b/tests/org.eclipse.php.core.tests/workspace/codeassist/php5/testClassMembers27-strict.pdtt
new file mode 100644
index 0000000..81ca8b5
--- /dev/null
+++ b/tests/org.eclipse.php.core.tests/workspace/codeassist/php5/testClassMembers27-strict.pdtt
@@ -0,0 +1,60 @@
+--TEST--
+Test class constructor
+--PREFERENCES--
+org.eclipse.php.core/contentAssistShowStrictOptions=true
+--FILE--
+<?
+class Model {
+ private $a;
+ function test() {
+ ;
+ }
+}
+class ListOfModels implements Iterator {
+ /**
+ * @return Model
+ */
+ public function current(){
+ }
+ /**
+ * @return Model
+ * @see Iterator::next()
+ */
+ public function next() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-PHPdoc)
+ * @see Iterator::key()
+ */
+ public function key() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-PHPdoc)
+ * @see Iterator::valid()
+ */
+ public function valid() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-PHPdoc)
+ * @see Iterator::rewind()
+ */
+ public function rewind() {
+ // TODO Auto-generated method stub
+
+ }
+
+}
+
+$list=new ListOfModels();
+foreach($list as $model) {
+ $model->|
+}
+?>
+--EXPECT--
+method(test) \ No newline at end of file
diff --git a/tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference1.pdtt b/tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference1.pdtt
new file mode 100644
index 0000000..d390058
--- /dev/null
+++ b/tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference1.pdtt
@@ -0,0 +1,26 @@
+--TEST--
+Test Type Inference for class implementing Iterator
+--FILE--
+<?php
+class Model {
+
+ public function get() {
+
+ }
+
+}
+class ListOfModels implements Iterator {
+
+ public function current(){
+ return new Model();
+ }
+
+
+}
+$list = new ListOfModels();
+foreach($list as $model) {
+ testIteratorTypeInference1($model);
+}
+?>
+--EXPECT--
+Model \ No newline at end of file
diff --git a/tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference2.pdtt b/tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference2.pdtt
new file mode 100644
index 0000000..0b2d327
--- /dev/null
+++ b/tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference2.pdtt
@@ -0,0 +1,35 @@
+--TEST--
+Test Type Inference for class implementing Iterator
+--FILE--
+<?php
+class Model {
+
+ public function get() {
+
+ }
+
+}
+class Model1 {
+
+ public function get() {
+
+ }
+
+}
+class ListOfModels implements Iterator {
+
+ /**
+ * @return Model|Model1
+ */
+ public function current(){
+ }
+
+
+}
+$list = new ListOfModels();
+foreach($list as $model) {
+ testIteratorTypeInference2($model);
+}
+?>
+--EXPECT--
+Ambigous <Model, Model1> \ No newline at end of file
diff --git a/tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference3.pdtt b/tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference3.pdtt
new file mode 100644
index 0000000..f3d96c6
--- /dev/null
+++ b/tests/org.eclipse.php.core.tests/workspace/typeinference/php5/testIteratorTypeInference3.pdtt
@@ -0,0 +1,36 @@
+--TEST--
+Test Type Inference for class implementing Iterator
+--FILE--
+<?php
+class Model extends ArrayIterator {
+
+ public function current(){
+ return new SubModel();
+ }
+
+}
+
+class SubModel {
+
+ public function get() {
+
+ }
+
+}
+class ListOfModels implements Iterator {
+
+ public function current(){
+ return new Model();
+ }
+
+
+}
+$list = new ListOfModels();
+foreach($list as $model) {
+ foreach ($model as $submodel) {
+ testIteratorTypeInference3($submodel);
+ }
+}
+?>
+--EXPECT--
+SubModel \ No newline at end of file