Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrganor2010-02-17 08:42:17 +0000
committerrganor2010-02-17 08:42:17 +0000
commite5dca6b547cd74f16ca9284181c7878656814c85 (patch)
tree4d95ab374eb86e26d0c07d1f727f11723f276094
parente8c64d8c0effdaaba981d884084e6e5d24e3269a (diff)
downloadorg.eclipse.pdt-e5dca6b547cd74f16ca9284181c7878656814c85.tar.gz
org.eclipse.pdt-e5dca6b547cd74f16ca9284181c7878656814c85.tar.xz
org.eclipse.pdt-e5dca6b547cd74f16ca9284181c7878656814c85.zip
Bug 222530 - Classes other than exceptions are suggested by the code completion after throw new
fixed
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/AbstractCompletionContext.java35
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/ClassInstantiationContext.java61
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/CompletionContextResolver.java125
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/ExceptionClassInstantiationContext.java28
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/AbstractClassInstantiationStrategy.java180
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/ClassInstantiationStrategy.java90
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/CompletionStrategyFactory.java199
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/ExceptionClassInstantiationStrategy.java90
8 files changed, 724 insertions, 84 deletions
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/AbstractCompletionContext.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/AbstractCompletionContext.java
index 8662a4de2..dc5625429 100644
--- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/AbstractCompletionContext.java
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/AbstractCompletionContext.java
@@ -447,6 +447,41 @@ public abstract class AbstractCompletionContext implements ICompletionContext {
}
/**
+ * Returns previous word before the cursor position
+ * @throws BadLocationException
+ */
+ public String getPreviousWord(int times) throws BadLocationException {
+ TextSequence statementText = getStatementText();
+
+ int statementLength = statementText.length();
+ int wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(statementText, statementLength); // read whitespace
+ int wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(phpVersion, statementText, wordEnd, true);
+
+ for (int i = 0; i < times - 1; i++) {
+ statementLength = wordStart;
+ wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(statementText, statementLength); // read whitespace
+ wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(phpVersion, statementText, wordEnd, true);
+
+ }
+ if (wordStart < 0 || wordEnd < 0 || wordStart > wordEnd) {
+ return "";
+ }
+ String previousWord = statementText.subSequence(wordStart, wordEnd).toString();
+
+ if (hasWhitespaceBeforeCursor()) {
+ return previousWord;
+ }
+
+ wordEnd = PHPTextSequenceUtilities.readBackwardSpaces(statementText, wordStart - 1); // read whitespace
+ wordStart = PHPTextSequenceUtilities.readIdentifierStartIndex(phpVersion, statementText, wordEnd, true);
+ if (wordStart < 0 || wordEnd < 0 || wordStart > wordEnd) {
+ return "";
+ }
+ previousWord = statementText.subSequence(wordStart, wordEnd).toString();
+
+ return previousWord;
+ }
+ /**
* Returns PHP token under offset
*
* @return PHP token
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/ClassInstantiationContext.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/ClassInstantiationContext.java
new file mode 100644
index 000000000..a9480c21e
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/ClassInstantiationContext.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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.codeassist.contexts;
+
+import org.eclipse.dltk.core.CompletionRequestor;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.php.internal.core.PHPCorePlugin;
+import org.eclipse.php.internal.core.compiler.ast.nodes.NamespaceReference;
+
+/**
+ * This context represents state when staying in a class instantiation
+ * statement. <br/>
+ * Examples:
+ *
+ * <pre>
+ * 1. new |
+ * 2. new A|
+ * </pre>
+ *
+ * @author michael
+ */
+public class ClassInstantiationContext extends StatementContext {
+
+ public boolean isValid(ISourceModule sourceModule, int offset,
+ CompletionRequestor requestor) {
+ if (!super.isValid(sourceModule, offset, requestor)) {
+ return false;
+ }
+
+ try {
+ String previousWord = getPreviousWord();
+ String previous2Word = getPreviousWord(2);
+ if ("new".equalsIgnoreCase(previousWord) && !"throw".equalsIgnoreCase(previous2Word)) {
+ return true;
+ }
+ } catch (BadLocationException e) {
+ PHPCorePlugin.log(e);
+ }
+
+ return false;
+ }
+
+ public String getPrefix() throws BadLocationException {
+ String prefix = super.getPrefix();
+ if (prefix.length() > 0
+ && prefix.charAt(0) == NamespaceReference.NAMESPACE_SEPARATOR) {
+ return prefix.substring(1);
+ }
+ return prefix;
+ }
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/CompletionContextResolver.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/CompletionContextResolver.java
new file mode 100644
index 000000000..dee2c4779
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/CompletionContextResolver.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * 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.codeassist.contexts;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.dltk.core.CompletionRequestor;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.php.core.codeassist.ICompletionContext;
+import org.eclipse.php.core.codeassist.ICompletionContextResolver;
+import org.eclipse.php.internal.core.PHPCorePlugin;
+import org.eclipse.php.internal.core.codeassist.CompletionCompanion;
+
+/**
+ * Default implementation of the {@link ICompletionContextResolver}
+ *
+ * @author michael
+ */
+public class CompletionContextResolver implements ICompletionContextResolver {
+
+ private static ICompletionContextResolver[] instances;
+
+ /**
+ * Constructs default completion context resolver
+ */
+ public CompletionContextResolver() {
+ }
+
+ /**
+ * Returns active completion context resolver. By default returns this class
+ * instance, but may be overriden using extension point.
+ *
+ * @return array of active {@link ICompletionContextResolver}'s
+ */
+ public static ICompletionContextResolver[] getActive() {
+ if (instances == null) { // not synchronized since we don't care about
+ // creating multiple instances of resolvers
+ // in worst case
+
+ List<ICompletionContextResolver> resolvers = new LinkedList<ICompletionContextResolver>();
+ IConfigurationElement[] elements = Platform.getExtensionRegistry()
+ .getConfigurationElementsFor(
+ "org.eclipse.php.core.completionContextResolvers");
+ for (IConfigurationElement element : elements) {
+ if (element.getName().equals("resolver")) {
+ try {
+ resolvers.add((ICompletionContextResolver) element
+ .createExecutableExtension("class"));
+ } catch (CoreException e) {
+ PHPCorePlugin.log(e);
+ }
+ }
+ }
+ resolvers.add(new CompletionContextResolver()); // add default
+ instances = (ICompletionContextResolver[]) resolvers
+ .toArray(new ICompletionContextResolver[resolvers.size()]);
+ }
+ return instances;
+ }
+
+ public ICompletionContext[] createContexts() {
+ return new ICompletionContext[] { new PHPDocTagStartContext(),
+ new PHPDocParamTagContext(), new PHPDocReturnTagContext(),
+ new ArrayKeyContext(), new CatchTypeContext(),
+ new CatchVariableContext(),
+ new ClassDeclarationKeywordContext(),
+ new ClassExtendsContext(), new ClassImplementsContext(),
+ new ClassInstantiationContext(), new ClassObjMemberContext(),
+ new ClassStatementContext(), new ClassStaticMemberContext(),
+ new FunctionParameterTypeContext(),
+ new FunctionParameterValueContext(),
+ new FunctionParameterVariableContext(),
+ new MethodNameContext(), new GlobalStatementContext(),
+ new GlobalMethodStatementContext(), new InstanceOfContext(),
+ new InterfaceExtendsContext(),
+ new InterfaceDeclarationKeywordContext(),
+ new UseAliasContext(), new UseNameContext(),
+ new NamespaceMemberContext(), new NamespaceNameContext(),
+ new NamespaceDeclContext(), new IncludeStatementContext(),
+ new ExceptionClassInstantiationContext(),};
+ }
+
+ public ICompletionContext[] resolve(ISourceModule sourceModule, int offset,
+ CompletionRequestor requestor, CompletionCompanion companion) {
+ List<ICompletionContext> result = new LinkedList<ICompletionContext>();
+ // find correct completion contexts according to known information:
+ for (ICompletionContext context : createContexts()) {
+ context.init(companion);
+
+ try {
+ if (context.isValid(sourceModule, offset, requestor)) {
+ result.add(context);
+ }
+ } catch (Exception e) {
+ PHPCorePlugin.log(e);
+ }
+ }
+
+ // remove exclusive contexts:
+ if (result.size() > 1) {
+ List<ICompletionContext> filteredResult = new LinkedList<ICompletionContext>();
+ for (ICompletionContext context : result) {
+ if (!context.isExclusive()) {
+ filteredResult.add(context);
+ }
+ }
+ result = filteredResult;
+ }
+
+ return result.toArray(new ICompletionContext[result.size()]);
+ }
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/ExceptionClassInstantiationContext.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/ExceptionClassInstantiationContext.java
new file mode 100644
index 000000000..5c6a5aa9f
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/contexts/ExceptionClassInstantiationContext.java
@@ -0,0 +1,28 @@
+package org.eclipse.php.internal.core.codeassist.contexts;
+
+import org.eclipse.dltk.core.CompletionRequestor;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.jface.text.BadLocationException;
+
+public class ExceptionClassInstantiationContext extends StatementContext {
+ public boolean isValid(ISourceModule sourceModule, int offset, CompletionRequestor requestor) {
+ if (!super.isValid(sourceModule, offset, requestor)) {
+ return false;
+ }
+
+ try {
+ String previousWord = getPreviousWord();
+ String previous2Word = getPreviousWord(2);
+ if ("new".equalsIgnoreCase(previousWord) && "throw".equalsIgnoreCase(previous2Word)) {
+ return true;
+ }
+ } catch (BadLocationException e) {
+ if (DLTKCore.DEBUG_COMPLETION) {
+ e.printStackTrace();
+ }
+ }
+
+ return false;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/AbstractClassInstantiationStrategy.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/AbstractClassInstantiationStrategy.java
new file mode 100644
index 000000000..c460d99c3
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/AbstractClassInstantiationStrategy.java
@@ -0,0 +1,180 @@
+/**
+ *
+ */
+package org.eclipse.php.internal.core.codeassist.strategies;
+
+import org.eclipse.dltk.core.*;
+import org.eclipse.dltk.internal.core.ModelElement;
+import org.eclipse.dltk.internal.core.SourceRange;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.php.core.codeassist.ICompletionContext;
+import org.eclipse.php.core.compiler.PHPFlags;
+import org.eclipse.php.internal.core.PHPCorePlugin;
+import org.eclipse.php.internal.core.codeassist.ICompletionReporter;
+import org.eclipse.php.internal.core.codeassist.contexts.AbstractCompletionContext;
+import org.eclipse.php.internal.core.typeinference.FakeMethod;
+
+/**
+ * This is a basic strategy that completes global classes after 'new' statement,
+ * without any additional add-ons in final result
+ *
+ * @author vadim.p
+ *
+ */
+public abstract class AbstractClassInstantiationStrategy extends GlobalTypesStrategy {
+
+ public AbstractClassInstantiationStrategy(ICompletionContext context,
+ int trueFlag, int falseFlag) {
+ super(context, trueFlag, falseFlag);
+ }
+
+ public AbstractClassInstantiationStrategy(ICompletionContext context) {
+ this(context, 0, 0);
+ }
+
+ public void apply(ICompletionReporter reporter) throws BadLocationException {
+
+ ICompletionContext context = getContext();
+ AbstractCompletionContext concreteContext = (AbstractCompletionContext) context;
+
+ IType enclosingClass = null;
+ try {
+ IModelElement enclosingElement = concreteContext.getSourceModule()
+ .getElementAt(concreteContext.getOffset());
+ while (enclosingElement instanceof IField) {
+ enclosingElement = enclosingElement.getParent();
+ }
+ if (enclosingElement instanceof IMethod) {
+ IModelElement parent = ((IMethod) enclosingElement).getParent();
+ if (parent instanceof IType) {
+ enclosingClass = (IType) parent;
+ }
+ }
+ } catch (ModelException e) {
+ PHPCorePlugin.log(e);
+ }
+
+ SourceRange replaceRange = getReplacementRange(context);
+ String suffix = getSuffix(concreteContext);
+
+ IType[] types = getTypes(concreteContext);
+ for (IType type : types) {
+
+ IMethod ctor = null;
+ try {
+ IMethod[] methods = type.getMethods();
+ if (methods != null && methods.length > 0) {
+ for (IMethod method : methods) {
+ if (method.isConstructor()
+ && method.getParameters() != null
+ && method.getParameters().length > 0) {
+ ctor = method;
+ if (!PHPFlags.isPrivate(ctor.getFlags())
+ || type.equals(enclosingClass)) {
+ IMethod ctorMethod = createFakeMethod(ctor,
+ type);
+ reporter.reportMethod(ctorMethod, suffix,
+ replaceRange);
+ break;
+ }
+ }
+ }
+ }
+
+ // try to find constructor in super classes
+ if (ctor == null) {
+ ITypeHierarchy newSupertypeHierarchy = type
+ .newSupertypeHierarchy(null);
+ IType[] allSuperclasses = newSupertypeHierarchy
+ .getAllSuperclasses(type);
+ if (allSuperclasses != null && allSuperclasses.length > 0) {
+ for (IType superClass : allSuperclasses) {
+ methods = superClass.getMethods();
+ // find first constructor and exit
+ if (methods != null && methods.length > 0) {
+ for (IMethod method : methods) {
+ if (method.isConstructor()
+ && method.getParameters() != null
+ && method.getParameters().length > 0) {
+ ctor = method;
+ if (!PHPFlags
+ .isPrivate(ctor.getFlags())
+ || type.equals(enclosingClass)) {
+ IMethod ctorMethod = createFakeMethod(
+ ctor, type);
+ reporter.reportMethod(ctorMethod,
+ suffix, replaceRange);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ } catch (ModelException e) {
+ PHPCorePlugin.log(e);
+ }
+ if (ctor == null) {
+ reporter.reportType(type, suffix, replaceRange);
+ }
+ }
+
+ // addSelf(concreteContext, reporter);
+ }
+
+ public String getSuffix(AbstractCompletionContext abstractContext) {
+ String nextWord = null;
+ try {
+ nextWord = abstractContext.getNextWord();
+ } catch (BadLocationException e) {
+ PHPCorePlugin.log(e);
+ }
+ return "(".equals(nextWord) ? "" : "()"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ class FakeConstructor extends FakeMethod {
+ private IMethod ctor;
+
+ public FakeConstructor(ModelElement parent, String name, int offset,
+ int length, int nameOffset, int nameLength, IMethod ctor) {
+ super(parent, name, offset, length, nameOffset, nameLength);
+ this.ctor = ctor;
+ }
+
+ public boolean isConstructor() throws ModelException {
+ return true;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof FakeConstructor) {
+ FakeConstructor fakeConstructor = (FakeConstructor) o;
+ return this.ctor == fakeConstructor.ctor;
+ }
+ return false;
+ }
+ }
+
+ private FakeMethod createFakeMethod(IMethod ctor, IType type) {
+ ISourceRange sourceRange;
+ try {
+ sourceRange = type.getSourceRange();
+ FakeMethod ctorMethod = new FakeConstructor((ModelElement) type,
+ type.getElementName(), sourceRange.getOffset(), sourceRange
+ .getLength(), sourceRange.getOffset(), sourceRange
+ .getLength(), ctor) {
+
+ };
+ ctorMethod.setParameters(ctor.getParameters());
+ ctorMethod
+ .setParameterInitializers(ctor.getParameterInitializers());
+ return ctorMethod;
+ } catch (ModelException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/ClassInstantiationStrategy.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/ClassInstantiationStrategy.java
index 85ffca809..14c12905c 100644
--- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/ClassInstantiationStrategy.java
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/ClassInstantiationStrategy.java
@@ -12,109 +12,31 @@
package org.eclipse.php.internal.core.codeassist.strategies;
import org.eclipse.dltk.ast.Modifiers;
-import org.eclipse.dltk.core.*;
-import org.eclipse.dltk.internal.core.ModelElement;
-import org.eclipse.dltk.internal.core.SourceRange;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.php.core.codeassist.ICompletionContext;
-import org.eclipse.php.core.compiler.PHPFlags;
-import org.eclipse.php.internal.core.PHPCorePlugin;
import org.eclipse.php.internal.core.codeassist.ICompletionReporter;
import org.eclipse.php.internal.core.codeassist.contexts.AbstractCompletionContext;
-import org.eclipse.php.internal.core.typeinference.FakeMethod;
/**
- * This strategy completes global classes after 'new' statement
+ * This strategy completes global classes after 'new' statement. It adds "self"
+ * class to the final result
*
* @author michael
*/
-public class ClassInstantiationStrategy extends GlobalTypesStrategy {
+public class ClassInstantiationStrategy extends
+ AbstractClassInstantiationStrategy {
public ClassInstantiationStrategy(ICompletionContext context) {
super(context, 0, Modifiers.AccInterface | Modifiers.AccNameSpace
| Modifiers.AccAbstract);
}
+ @Override
public void apply(ICompletionReporter reporter) throws BadLocationException {
-
+ super.apply(reporter);
ICompletionContext context = getContext();
AbstractCompletionContext concreteContext = (AbstractCompletionContext) context;
- CompletionRequestor requestor = concreteContext
- .getCompletionRequestor();
-
- IType enclosingClass = null;
- try {
- IModelElement enclosingElement = concreteContext.getSourceModule()
- .getElementAt(concreteContext.getOffset());
- while (enclosingElement instanceof IField) {
- enclosingElement = enclosingElement.getParent();
- }
- if (enclosingElement instanceof IMethod) {
- IModelElement parent = ((IMethod) enclosingElement).getParent();
- if (parent instanceof IType) {
- enclosingClass = (IType) parent;
- }
- }
- } catch (ModelException e) {
- PHPCorePlugin.log(e);
- }
-
- SourceRange replaceRange = getReplacementRange(context);
- String suffix = getSuffix(concreteContext);
-
- IType[] types = getTypes(concreteContext);
- for (IType type : types) {
-
- IMethod ctor = null;
- if (requestor.isContextInformationMode()) {
- try {
- for (IMethod method : type.getMethods()) {
- if (method.isConstructor()) {
- ctor = method;
- break;
- }
- }
- } catch (ModelException e) {
- PHPCorePlugin.log(e);
- }
- }
-
- try {
- if (ctor != null) {
- if (!PHPFlags.isPrivate(ctor.getFlags())
- || type.equals(enclosingClass)) {
- ISourceRange sourceRange = type.getSourceRange();
- FakeMethod ctorMethod = new FakeMethod(
- (ModelElement) type, type.getElementName(),
- sourceRange.getOffset(), sourceRange
- .getLength(), sourceRange.getOffset(),
- sourceRange.getLength()) {
- public boolean isConstructor()
- throws ModelException {
- return true;
- }
- };
- ctorMethod.setParameters(ctor.getParameters());
- reporter.reportMethod(ctorMethod, suffix, replaceRange);
- }
- } else {
- reporter.reportType(type, suffix, replaceRange);
- }
- } catch (ModelException e) {
- PHPCorePlugin.log(e);
- }
- }
-
addSelf(concreteContext, reporter);
}
- public String getSuffix(AbstractCompletionContext abstractContext) {
- String nextWord = null;
- try {
- nextWord = abstractContext.getNextWord();
- } catch (BadLocationException e) {
- PHPCorePlugin.log(e);
- }
- return "(".equals(nextWord) ? "" : "()"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/CompletionStrategyFactory.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/CompletionStrategyFactory.java
new file mode 100644
index 000000000..036923700
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/CompletionStrategyFactory.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * 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.codeassist.strategies;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.php.core.codeassist.ICompletionContext;
+import org.eclipse.php.core.codeassist.ICompletionContextResolver;
+import org.eclipse.php.core.codeassist.ICompletionStrategy;
+import org.eclipse.php.core.codeassist.ICompletionStrategyFactory;
+import org.eclipse.php.internal.core.PHPCorePlugin;
+import org.eclipse.php.internal.core.codeassist.contexts.*;
+
+/**
+ * Default implementation of the {@link ICompletionStrategyFactory}
+ *
+ * @author michael
+ */
+public class CompletionStrategyFactory implements ICompletionStrategyFactory {
+
+ private static ICompletionStrategyFactory[] instances;
+
+ /**
+ * Returns active completion strategy factory. By default returns this class
+ * instance, but may be overriden using extension point.
+ *
+ * @return array of active {@link ICompletionContextResolver}'s
+ */
+ public static ICompletionStrategyFactory[] getActive() {
+ if (instances == null) { // not synchronized since we don't care about
+ // creating multiple instances of factories
+ // in worst case
+
+ List<ICompletionStrategyFactory> factories = new LinkedList<ICompletionStrategyFactory>();
+ IConfigurationElement[] elements = Platform.getExtensionRegistry()
+ .getConfigurationElementsFor(
+ "org.eclipse.php.core.completionStrategyFactories");
+ for (IConfigurationElement element : elements) {
+ if (element.getName().equals("factory")) {
+ try {
+ factories.add((ICompletionStrategyFactory) element
+ .createExecutableExtension("class"));
+ } catch (CoreException e) {
+ PHPCorePlugin.log(e);
+ }
+ }
+ }
+ factories.add(new CompletionStrategyFactory());
+ instances = (ICompletionStrategyFactory[]) factories
+ .toArray(new ICompletionStrategyFactory[factories.size()]);
+ }
+ return instances;
+ }
+
+ public ICompletionStrategy[] create(ICompletionContext[] contexts) {
+ // don't allow creation of strategies of the same class:
+ Set<Class<? super ICompletionStrategy>> processed = new HashSet<Class<? super ICompletionStrategy>>();
+
+ List<ICompletionStrategy> result = new LinkedList<ICompletionStrategy>();
+
+ for (ICompletionContext context : contexts) {
+ ICompletionStrategy[] strategies = createStrategies(context,
+ contexts);
+
+ for (ICompletionStrategy strategy : strategies) {
+ if (!processed.contains(strategy.getClass())) {
+ result.add(strategy);
+ }
+ }
+ }
+ return (ICompletionStrategy[]) result
+ .toArray(new ICompletionStrategy[result.size()]);
+ }
+
+ protected ICompletionStrategy[] createStrategies(
+ ICompletionContext context, ICompletionContext[] allContexts) {
+
+ Class<? extends ICompletionContext> contextClass = context.getClass();
+
+ if (contextClass == PHPDocTagStartContext.class) {
+ return new ICompletionStrategy[] { new PHPDocTagStrategy(context) };
+ }
+ if (contextClass == PHPDocParamTagContext.class) {
+ return new ICompletionStrategy[] { new PHPDocParamVariableStrategy(
+ context) };
+ }
+ if (contextClass == PHPDocReturnTagContext.class) {
+ return new ICompletionStrategy[] { new PHPDocReturnTypeStrategy(
+ context) };
+ }
+ if (contextClass == ArrayKeyContext.class) {
+ // If array has quotes or double-quotes around the key - show only
+ // builtin keys:
+ if (((ArrayKeyContext) context).hasQuotes()) {
+ return new ICompletionStrategy[] { new BuiltinArrayKeysStrategy(
+ context) };
+ }
+ // Otherwise - show all global elements also:
+ // Example: $array[foo()], $array[$otherVar]
+ return new ICompletionStrategy[] {
+ new BuiltinArrayKeysStrategy(context),
+ new GlobalElementsCompositeStrategy(context, false) };
+ }
+ if (contextClass == FunctionParameterTypeContext.class) {
+ return new ICompletionStrategy[] { new FunctionParameterTypeStrategy(
+ context) };
+ }
+ if (contextClass == FunctionParameterValueContext.class) {
+ return new ICompletionStrategy[] { new GlobalConstantsStrategy(
+ context) };
+ }
+ if (contextClass == MethodNameContext.class) {
+ return new ICompletionStrategy[] { new MethodNameStrategy(context) };
+ }
+ if (contextClass == ClassStatementContext.class) {
+ return new ICompletionStrategy[] { new ClassKeywordsStrategy(
+ context) };
+ }
+ if (contextClass == GlobalStatementContext.class) {
+ return new ICompletionStrategy[] { new GlobalElementsCompositeStrategy(
+ context, true) };
+ }
+ if (contextClass == GlobalMethodStatementContext.class) {
+ return new ICompletionStrategy[] { new LocalMethodElementsCompositeStrategy(
+ context) };
+ }
+ if (contextClass == CatchTypeContext.class) {
+ return new ICompletionStrategy[] { new CatchTypeStrategy(context) };
+ }
+ if (contextClass == ClassInstantiationContext.class) {
+ return new ICompletionStrategy[] {
+ new ClassInstantiationStrategy(context),
+ new GlobalVariablesStrategy(context, false) };
+ }
+ if (contextClass == InstanceOfContext.class) {
+ return new ICompletionStrategy[] { new InstanceOfStrategy(context) };
+ }
+ if (contextClass == ExceptionClassInstantiationContext.class) {
+ return new ICompletionStrategy[] { new ExceptionClassInstantiationStrategy(context) };
+ }
+ if (contextClass == ClassStaticMemberContext.class
+ || contextClass == ClassObjMemberContext.class) {
+ return new ICompletionStrategy[] {
+ new ClassFieldsStrategy(context),
+ new ClassMethodsStrategy(context) };
+ }
+ if (contextClass == ClassDeclarationKeywordContext.class) {
+ return new ICompletionStrategy[] { new ClassDeclarationKeywordsStrategy(
+ context) };
+ }
+ if (contextClass == InterfaceDeclarationKeywordContext.class) {
+ return new ICompletionStrategy[] { new InterfaceDeclarationKeywordsStrategy(
+ context) };
+ }
+ if (contextClass == ClassExtendsContext.class) {
+ return new ICompletionStrategy[] { new NonFinalClassesStrategy(
+ context) };
+ }
+ if (contextClass == ClassImplementsContext.class
+ || contextClass == InterfaceExtendsContext.class) {
+ return new ICompletionStrategy[] { new GlobalInterfacesStrategy(
+ context) };
+ }
+ if (contextClass == NamespaceMemberContext.class) {
+ return new ICompletionStrategy[] { new NamespaceElementsCompositeStrategy(
+ context, allContexts, ((NamespaceMemberContext) context)
+ .isGlobal()) };
+ }
+ if (contextClass == NamespaceNameContext.class
+ || contextClass == NamespaceDeclContext.class) {
+ return new ICompletionStrategy[] { new NamespacesStrategy(context) };
+ }
+ if (contextClass == UseNameContext.class) {
+ return new ICompletionStrategy[] { new UseNameStrategy(context) };
+ }
+ if (contextClass == IncludeStatementContext.class) {
+ return new ICompletionStrategy[] { new IncludeStatementStrategy(
+ context) };
+ }
+
+ return new ICompletionStrategy[] {};
+ }
+
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/ExceptionClassInstantiationStrategy.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/ExceptionClassInstantiationStrategy.java
new file mode 100644
index 000000000..51085f774
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/codeassist/strategies/ExceptionClassInstantiationStrategy.java
@@ -0,0 +1,90 @@
+package org.eclipse.php.internal.core.codeassist.strategies;
+
+import java.util.*;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.dltk.core.*;
+import org.eclipse.dltk.core.index2.search.ISearchEngine.MatchRule;
+import org.eclipse.dltk.core.search.IDLTKSearchScope;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.php.core.codeassist.ICompletionContext;
+import org.eclipse.php.internal.core.codeassist.contexts.AbstractCompletionContext;
+import org.eclipse.php.internal.core.model.PhpModelAccess;
+
+public class ExceptionClassInstantiationStrategy extends
+ AbstractClassInstantiationStrategy {
+ private static final String CORE_PHP = "Core.php";
+ private static final String BASIC_PHP = "basic.php";
+ private static final String EXCEPTION = "Exception";
+
+ private IType exceptionType;
+
+ public ExceptionClassInstantiationStrategy(ICompletionContext context) {
+ super(context);
+ }
+
+ protected IType[] getTypes(AbstractCompletionContext context)
+ throws BadLocationException {
+ IType exceptionType = getExceptionType();
+ if (exceptionType == null)
+ return super.getTypes(context);
+ List<IType> result = new LinkedList<IType>();
+ ITypeHierarchy typeHierarchy;
+ ISourceModule sourceModule = context.getSourceModule();
+ IScriptProject scriptProject = sourceModule.getScriptProject();
+ try {
+ if (scriptProject != null) {
+ typeHierarchy = exceptionType.newTypeHierarchy(scriptProject,
+ new NullProgressMonitor());
+ } else {
+ typeHierarchy = exceptionType
+ .newTypeHierarchy(new NullProgressMonitor());
+ }
+
+ IType[] classes = typeHierarchy.getAllSubtypes(exceptionType);
+ Set<IType> set = new HashSet<IType>();
+ set.add(exceptionType);
+ set.addAll(Arrays.asList(classes));
+ String prefix = context.getPrefix();
+ if (prefix.trim().length() != 0) {
+ IType[] types = super.getTypes(context);
+ for (int i = 0; i < types.length; i++) {
+ IType type = types[i];
+ if (set.contains(type)) {
+ result.add(type);
+ }
+ }
+ } else {
+ result.addAll(set);
+ }
+
+ } catch (ModelException e) {
+ return super.getTypes(context);
+ }
+
+ return (IType[]) result.toArray(new IType[result.size()]);
+ }
+
+ protected IType getExceptionType() {
+ if (exceptionType != null)
+ return exceptionType;
+ IDLTKSearchScope scope = createSearchScope();
+ IType[] exceptionTypes = PhpModelAccess.getDefault().findTypes(
+ EXCEPTION, MatchRule.EXACT, trueFlag, falseFlag, scope, null);
+ for (int i = 0; i < exceptionTypes.length; i++) {
+ if (isExctptionType(exceptionTypes[i])) {
+ exceptionType = exceptionTypes[i];
+ break;
+ }
+ }
+ return exceptionType;
+ }
+
+ private boolean isExctptionType(IType iType) {
+ if (EXCEPTION.equals(iType.getElementName())
+ && (CORE_PHP.equals(iType.getParent().getElementName()) || BASIC_PHP
+ .equals(iType.getParent().getElementName())))
+ return true;
+ return false;
+ }
+}

Back to the top