/*******************************************************************************
* Copyright (c) 2009, 2016 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.*;
import org.eclipse.php.internal.core.codeassist.templates.contexts.GlobalMethodStatementContextForTemplate;
import org.eclipse.php.internal.core.codeassist.templates.contexts.GlobalStatementContextForTemplate;
import org.eclipse.php.internal.core.codeassist.templates.strategies.LocalMethodVariablesStrategyForTemplate;
/**
* 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"); //$NON-NLS-1$
for (IConfigurationElement element : elements) {
if (element.getName().equals("factory")) { //$NON-NLS-1$
try {
factories.add((ICompletionStrategyFactory) element.createExecutableExtension("class")); //$NON-NLS-1$
} catch (CoreException e) {
PHPCorePlugin.log(e);
}
}
}
factories.add(new CompletionStrategyFactory());
instances = 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 == PHPDocVarStartContext.class) {
return new ICompletionStrategy[] { new PHPDocReturnTypeStrategy(context) };
}
if (contextClass == PHPDocThrowsStartContext.class) {
return new ICompletionStrategy[] { new ExceptionClassStrategy(context) };
}
if (contextClass == PHPDocParamTagContext.class) {
return new ICompletionStrategy[] { new PHPDocParamVariableStrategy(context) };
}
if (contextClass == PHPDocReturnTagContext.class || contextClass == PHPDocMagicTagsContext.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),
new ArrayStringKeysStrategy(context) };
}
// Otherwise - show all global elements also:
// Example: $array[foo()], $array[$otherVar]
return new ICompletionStrategy[] { new BuiltinArrayKeysStrategy(context),
new GlobalElementsCompositeStrategy(context, false),
new LocalMethodVariablesStrategyForArray(context), new BuiltinArrayKeysStrategy(context),
new ArrayStringKeysStrategy(context) };
}
if (contextClass == FunctionParameterTypeContext.class) {
return new ICompletionStrategy[] { new FunctionParameterTypeStrategy(context),
new FunctionParameterKeywordTypeStrategy(context) };
}
if (contextClass == FunctionReturnTypeContext.class) {
return new ICompletionStrategy[] { new FunctionReturnTypeStrategy(context) };
}
if (contextClass == FunctionParameterValueContext.class) {
return new ICompletionStrategy[] { new GlobalConstantsStrategy(context), new GlobalTypesStrategy(context),
new MethodParameterKeywordStrategy(context) };
}
if (contextClass == MethodNameContext.class) {
return new ICompletionStrategy[] { new MethodNameStrategy(context) };
}
if (contextClass == ClassStatementContext.class) {
if (((AbstractCompletionContext) context).isInUseTraitStatement()) {
int type = ((AbstractCompletionContext) context).getUseTraitStatementContext();
if (type == AbstractCompletionContext.TRAIT_NAME) {
return new ICompletionStrategy[] { new InUseTraitStrategy(context) };
} else if (type == AbstractCompletionContext.TRAIT_KEYWORD) {
return new ICompletionStrategy[] { new InUseTraitKeywordStrategy(context) };
} else {
return new ICompletionStrategy[] {};
}
} else if (((ClassStatementContext) context).isAssignment()) {
return new ICompletionStrategy[] { new ClassKeywordsStrategy(context),
new GlobalConstantsStrategy(context), new GlobalTypesStrategy(context) };
} else {
return new ICompletionStrategy[] { new ClassKeywordsStrategy(context),
// new GlobalConstantsStrategy(context),
// new GlobalTypesStrategy(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&&((ClassStaticMemberContext)context).isInUseTraitStatement())
// {
// return new ICompletionStrategy[] {
// new ClassFieldsStrategy(context),
// new ClassMethodsStrategy(context) };
// }
if (contextClass == ClassStaticMemberContext.class || contextClass == ClassObjMemberContext.class) {
if (((AbstractCompletionContext) context).isInUseTraitStatement()) {
int type = ((AbstractCompletionContext) context).getUseTraitStatementContext();
if (type == AbstractCompletionContext.TRAIT_NAME) {
return new ICompletionStrategy[] { new InUseTraitStrategy(context) };
} else if (type == AbstractCompletionContext.TRAIT_KEYWORD) {
return new ICompletionStrategy[] { new InUseTraitKeywordStrategy(context) };
} else {
return new ICompletionStrategy[] { new ClassFieldsStrategy(context),
new ClassMethodsStrategy(context) };
}
} else {
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),
new NamespaceNonFinalClassesStrategy(context) };
}
if (contextClass == ClassImplementsContext.class || contextClass == InterfaceExtendsContext.class) {
return new ICompletionStrategy[] { new NonFinalInterfacesStrategy(context) };
}
if (contextClass == NamespaceUseFunctionNameContext.class) {
return new ICompletionStrategy[] { new NamespaceUseFunctionNameStrategy(context) };
}
if (contextClass == NamespaceUseConstNameContext.class) {
return new ICompletionStrategy[] { new NamespaceUseConstNameStrategy(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 == QuotesContext.class) {
return new ICompletionStrategy[] { new TypeInStringStrategy(context) };
}
if (contextClass == GotoStatementContext.class) {
return new ICompletionStrategy[] { new GotoStatementStrategy(context) };
}
if (contextClass == TypeCastingContext.class) {
return new ICompletionStrategy[] { new TypeCastingStrategy(context) };
}
if (contextClass == UseNameContext.class) {
UseNameContext useNameContext = (UseNameContext) context;
if (useNameContext.isUseTrait()) {
return new ICompletionStrategy[] { new UseTraitNameStrategy(context) };
} else {
return new ICompletionStrategy[] { new UseNameStrategy(context) };
}
}
if (contextClass == UseConstNameContext.class) {
return new ICompletionStrategy[] { new GlobalConstantsStrategy(context) };
}
if (contextClass == UseFunctionNameContext.class) {
return new ICompletionStrategy[] { new GlobalFunctionsStrategy(context) };
}
if (contextClass == NamespaceUseNameContext.class) {
NamespaceUseNameContext useNameContext = (NamespaceUseNameContext) context;
if (useNameContext.isUseTrait()) {
return new ICompletionStrategy[] { new NamespaceUseTraitNameStrategy(context) };
} else {
return new ICompletionStrategy[] { new NamespaceUseNameStrategy(context) };
}
}
if (contextClass == IncludeStatementContext.class) {
return new ICompletionStrategy[] { new IncludeStatementStrategy(context) };
}
// Context for template
if (contextClass == GlobalStatementContextForTemplate.class) {
return new ICompletionStrategy[] { new GlobalVariablesStrategy(context, true) };
}
if (contextClass == GlobalMethodStatementContextForTemplate.class) {
return new ICompletionStrategy[] { new LocalMethodVariablesStrategyForTemplate(context) };
}
if (contextClass == NamespacePHPDocVarStartContext.class) {
return new ICompletionStrategy[] { new NamespaceDocTypesCompositeStrategy(context) };
}
return new ICompletionStrategy[] {};
}
}