package fr.adrienbrault.idea.symfony2plugin.assistant.reference;
import com.intellij.psi.PsiElement;
import com.jetbrains.php.lang.parser.PhpElementTypes;
import com.jetbrains.php.lang.patterns.PhpPatterns;
import com.jetbrains.php.lang.psi.elements.*;
import fr.adrienbrault.idea.symfony2plugin.assistant.AssistantReferenceContributor;
/**
* @author Daniel Espendiller <daniel@espendiller.net>
*/
public class DefaultReferenceContributor {
// @TODO: dynamic adding
public static AssistantReferenceContributor[] DEFAULT_CONTRIBUTORS = new AssistantReferenceContributor[] {
new ParameterAssistantReferenceProvider(),
new AssistantReferenceProviderConfigArray(),
new AssistantReferenceProviderArrayKey()
};
public enum DEFAULT_CONTRIBUTORS_ENUM {
PARAMETER {
public String toString() {
return "parameter";
}
},
ARRAY_VALUE {
public String toString() {
return "array_value";
}
},
ARRAY_KEY {
public String toString() {
return "array_key";
}
}
}
private static class ParameterAssistantReferenceProvider implements AssistantReferenceContributor {
@Override
public boolean supportData() {
return false;
}
@Override
public String getAlias() {
return DEFAULT_CONTRIBUTORS_ENUM.PARAMETER.toString();
}
@Override
public boolean isContributedElement(PsiElement psiElement, MethodParameterSetting config) {
return psiElement.getContext() instanceof ParameterList;
}
}
public static class AssistantReferenceProviderConfigArray implements AssistantReferenceContributor {
@Override
public boolean supportData() {
return true;
}
@Override
public String getAlias() {
return DEFAULT_CONTRIBUTORS_ENUM.ARRAY_VALUE.toString();
}
public boolean isContributedElement(PsiElement psiElement, MethodParameterSetting config) {
// value inside array
// $menu->addChild(array(
// 'route' => 'foo',
// ));
if(PhpPatterns.psiElement(PhpElementTypes.ARRAY_VALUE).accepts(psiElement.getContext())) {
PsiElement arrayValue = psiElement.getContext();
if(arrayValue != null) {
PsiElement arrayHashElement = arrayValue.getContext();
if(arrayHashElement instanceof ArrayHashElement) {
PhpPsiElement arrayKey = ((ArrayHashElement) arrayHashElement).getKey();
if(arrayKey instanceof StringLiteralExpression && ((StringLiteralExpression) arrayKey).getContents().equals(config.getContributorData())) {
PsiElement arrayCreationExpression = arrayHashElement.getContext();
if(arrayCreationExpression instanceof ArrayCreationExpression) {
if(arrayCreationExpression.getParent() instanceof ParameterList) {
return true;
}
}
}
}
}
}
return false;
}
}
private static class AssistantReferenceProviderArrayKey implements AssistantReferenceContributor {
public boolean isContributedElement(PsiElement psiElement, MethodParameterSetting config) {
// value inside array
// $menu->addChild(array(
// 'foo' => '',
// ));
if(PhpPatterns.psiElement(PhpElementTypes.ARRAY_KEY).accepts(psiElement.getContext())) {
PsiElement arrayKey = psiElement.getContext();
if(arrayKey != null) {
PsiElement arrayHashElement = arrayKey.getContext();
if(arrayHashElement instanceof ArrayHashElement) {
PsiElement arrayCreationExpression = arrayHashElement.getContext();
if(arrayCreationExpression instanceof ArrayCreationExpression) {
if(arrayCreationExpression.getParent() instanceof ParameterList) {
return true;
}
}
}
}
}
// on array creation key dont have value, so provide completion here also
// array('foo' => 'bar', '<test>')
if(PhpPatterns.psiElement(PhpElementTypes.ARRAY_VALUE).accepts(psiElement.getContext())) {
PsiElement arrayKey = psiElement.getContext();
if(arrayKey != null) {
PsiElement arrayCreationExpression = arrayKey.getContext();
if(arrayCreationExpression instanceof ArrayCreationExpression) {
if(arrayCreationExpression.getParent() instanceof ParameterList) {
return true;
}
}
}
}
return false;
}
@Override
public boolean supportData() {
return false;
}
@Override
public String getAlias() {
return DEFAULT_CONTRIBUTORS_ENUM.ARRAY_KEY.toString();
}
}
}