Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvpunski2010-02-17 11:11:45 +0000
committervpunski2010-02-17 11:11:45 +0000
commit0588f65ca23317776ab48e901248906dd97e4d6d (patch)
treecaa798521880d25e5b4a12c3df486b9619f6e7df
parent84c7928904d35b28799bf28ca291630929e02683 (diff)
downloadorg.eclipse.pdt-0588f65ca23317776ab48e901248906dd97e4d6d.tar.gz
org.eclipse.pdt-0588f65ca23317776ab48e901248906dd97e4d6d.tar.xz
org.eclipse.pdt-0588f65ca23317776ab48e901248906dd97e4d6d.zip
selection fails on parent::foo when the current class extends class from global namespace
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/TypeReferenceEvaluator.java146
1 files changed, 142 insertions, 4 deletions
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/TypeReferenceEvaluator.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/TypeReferenceEvaluator.java
index ad279431a..f9e3341e7 100644
--- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/TypeReferenceEvaluator.java
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/typeinference/evaluators/TypeReferenceEvaluator.java
@@ -1,13 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Zend Technologies
+ *******************************************************************************/
package org.eclipse.php.internal.core.typeinference.evaluators;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.dltk.ast.ASTListNode;
+import org.eclipse.dltk.ast.ASTNode;
+import org.eclipse.dltk.ast.ASTVisitor;
+import org.eclipse.dltk.ast.declarations.MethodDeclaration;
+import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
+import org.eclipse.dltk.ast.declarations.TypeDeclaration;
+import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.ast.references.TypeReference;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.evaluation.types.AmbiguousType;
import org.eclipse.dltk.ti.GoalState;
import org.eclipse.dltk.ti.IContext;
+import org.eclipse.dltk.ti.ISourceModuleContext;
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.MethodContext;
+import org.eclipse.php.internal.core.compiler.ast.nodes.ClassDeclaration;
+import org.eclipse.php.internal.core.compiler.ast.nodes.FullyQualifiedReference;
+import org.eclipse.php.internal.core.compiler.ast.nodes.NamespaceReference;
import org.eclipse.php.internal.core.typeinference.PHPClassType;
+import org.eclipse.php.internal.core.typeinference.PHPModelUtils;
+import org.eclipse.php.internal.core.typeinference.context.INamespaceContext;
+import org.eclipse.php.internal.core.typeinference.context.MethodContext;
public class TypeReferenceEvaluator extends GoalEvaluator {
@@ -20,7 +51,7 @@ public class TypeReferenceEvaluator extends GoalEvaluator {
}
public IGoal[] init() {
- IContext context = goal.getContext();
+ final IContext context = goal.getContext();
String className = typeReference.getName();
if ("self".equals(className)) { //$NON-NLS-1$
@@ -28,11 +59,118 @@ public class TypeReferenceEvaluator extends GoalEvaluator {
MethodContext methodContext = (MethodContext) context;
IEvaluatedType instanceType = methodContext.getInstanceType();
if (instanceType instanceof PHPClassType) {
- className = instanceType.getTypeName();
+ result = instanceType;
+ }
+ }
+ } else if ("parent".equals(className)) { //$NON-NLS-1$
+ if (context instanceof MethodContext) {
+ final MethodContext methodContext = (MethodContext) context;
+ ModuleDeclaration rootNode = methodContext.getRootNode();
+ final MethodDeclaration methodDecl = methodContext
+ .getMethodNode();
+
+ // Look for parent class types:
+ final List<IEvaluatedType> types = new LinkedList<IEvaluatedType>();
+ try {
+ rootNode.traverse(new ASTVisitor() {
+ private TypeDeclaration currentType;
+ private boolean found;
+
+ public boolean visit(MethodDeclaration s)
+ throws Exception {
+ if (s == methodDecl
+ && currentType instanceof ClassDeclaration) {
+ ClassDeclaration classDecl = (ClassDeclaration) currentType;
+
+ ASTListNode superClasses = classDecl
+ .getSuperClasses();
+ List childs = superClasses.getChilds();
+ for (Iterator iterator = childs.iterator(); iterator
+ .hasNext();) {
+ ASTNode node = (ASTNode) iterator.next();
+ NamespaceReference namespace = null;
+ SimpleReference reference = null;
+ if (node instanceof SimpleReference) {
+ reference = (SimpleReference) node;
+ if (reference instanceof FullyQualifiedReference) {
+ FullyQualifiedReference ref = (FullyQualifiedReference) node;
+ namespace = ref.getNamespace();
+ }
+ }
+ if (namespace == null
+ || namespace.getName().equals("")) {
+ types.add(new PHPClassType(reference
+ .getName()));
+ } else {
+ types
+ .add(new PHPClassType(namespace
+ .getName(), reference
+ .getName()));
+ }
+
+ }
+ found = true;
+ }
+ return !found;
+ }
+
+ public boolean visit(TypeDeclaration s)
+ throws Exception {
+ this.currentType = s;
+ return !found;
+ }
+
+ public boolean endvisit(TypeDeclaration s)
+ throws Exception {
+ this.currentType = null;
+ return super.endvisit(s);
+ }
+
+ public boolean visit(ASTNode n) throws Exception {
+ return !found;
+ }
+ });
+ } catch (Exception e) {
+ if (DLTKCore.DEBUG) {
+ e.printStackTrace();
+ }
+ }
+
+ if (types.size() == 1) {
+ result = types.get(0);
+ } else if (types.size() > 1) {
+ result = new AmbiguousType(types
+ .toArray(new IEvaluatedType[types.size()]));
+ }
+ }
+ } else {
+ String parentNamespace = null;
+
+ // Check current context - if we are under some namespace:
+ if (context instanceof INamespaceContext) {
+ parentNamespace = ((INamespaceContext) context).getNamespace();
+ }
+
+ // If the namespace was prefixed explicitly - use it:
+ if (typeReference instanceof FullyQualifiedReference) {
+ String fullyQualifiedName = ((FullyQualifiedReference) typeReference)
+ .getFullyQualifiedName();
+ ISourceModule sourceModule = ((ISourceModuleContext) context)
+ .getSourceModule();
+ int offset = typeReference.sourceStart();
+ String extractedNamespace = PHPModelUtils.extractNamespaceName(
+ fullyQualifiedName, sourceModule, offset);
+ if (extractedNamespace != null) {
+ parentNamespace = extractedNamespace;
}
}
+
+ if (parentNamespace != null) {
+ result = new PHPClassType(parentNamespace, className);
+ } else {
+ result = new PHPClassType(className);
+ }
}
- result = new PHPClassType(className);
return IGoal.NO_GOALS;
}

Back to the top