Skip to content

WIP: move Drupal bridge plugin inside #1794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/main/java/de/espend/idea/php/drupal/DrupalIcons.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package de.espend.idea.php.drupal;

import com.intellij.openapi.util.IconLoader;

import javax.swing.*;

/**
* @author Daniel Espendiller <[email protected]>
*/
public class DrupalIcons {
public static final Icon DRUPAL = IconLoader.getIcon("icons/drupal.png");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package de.espend.idea.php.drupal;


import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
import org.jetbrains.annotations.Nullable;

/**
* @author Daniel Espendiller <[email protected]>
*/
public class DrupalProjectComponent {

public static boolean isEnabled(Project project) {
return Symfony2ProjectComponent.isEnabled(project);
}

public static boolean isEnabled(@Nullable PsiElement psiElement) {
return psiElement != null && isEnabled(psiElement.getProject());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package de.espend.idea.php.drupal.annotation;

import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.jetbrains.php.lang.PhpLangUtil;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import de.espend.idea.php.annotation.extension.PhpAnnotationCompletionProvider;
import de.espend.idea.php.annotation.extension.PhpAnnotationReferenceProvider;
import de.espend.idea.php.annotation.extension.parameter.AnnotationCompletionProviderParameter;
import de.espend.idea.php.annotation.extension.parameter.AnnotationPropertyParameter;
import de.espend.idea.php.annotation.extension.parameter.PhpAnnotationReferenceProviderParameter;
import de.espend.idea.php.drupal.index.PermissionIndex;
import de.espend.idea.php.drupal.utils.IndexUtil;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* @author Daniel Espendiller <[email protected]>
*
* "@ContentEntityTypeAnnotation"
*/
public class ConfigEntityTypeAnnotation implements PhpAnnotationCompletionProvider, PhpAnnotationReferenceProvider {
@Override
public void getPropertyValueCompletions(AnnotationPropertyParameter parameter, AnnotationCompletionProviderParameter completionProviderParameter) {
if(!isSupported(parameter)) {
return;
}

if("admin_permission".equalsIgnoreCase(parameter.getPropertyName())) {
completionProviderParameter.getResult().addAllElements(IndexUtil.getIndexedKeyLookup(parameter.getProject(), PermissionIndex.KEY));
}
}

private boolean isSupported(@NotNull AnnotationPropertyParameter parameter) {
return parameter.getType() != AnnotationPropertyParameter.Type.DEFAULT &&
PhpLangUtil.equalsClassNames(StringUtils.stripStart(parameter.getPhpClass().getFQN(), "\\"), "Drupal\\Core\\Entity\\Annotation\\ConfigEntityType");
}

@Nullable
@Override
public PsiReference[] getPropertyReferences(AnnotationPropertyParameter parameter, PhpAnnotationReferenceProviderParameter phpAnnotationReferenceProviderParameter) {
if(!isSupported(parameter)) {
return new PsiReference[0];
}

String propertyName = parameter.getPropertyName();

if("admin_permission".equalsIgnoreCase(propertyName)) {
String contents = getContents(parameter.getElement());
if(StringUtils.isBlank(contents)) {
return new PsiReference[0];
}

return new PsiReference[] {new ContentEntityTypeAnnotation.MyPermissionPsiPolyVariantReferenceBase(parameter.getElement(), contents)};
}

return new PsiReference[0];
}

@Nullable
private String getContents(@NotNull PsiElement element) {
if(!(element instanceof StringLiteralExpression)) {
return null;
}

String contents = ((StringLiteralExpression) element).getContents();
if(StringUtils.isBlank(contents)) {
return null;
}

return contents;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package de.espend.idea.php.drupal.annotation;

import com.intellij.psi.*;
import com.jetbrains.php.lang.PhpLangUtil;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import de.espend.idea.php.annotation.extension.PhpAnnotationCompletionProvider;
import de.espend.idea.php.annotation.extension.PhpAnnotationReferenceProvider;
import de.espend.idea.php.annotation.extension.parameter.AnnotationCompletionProviderParameter;
import de.espend.idea.php.annotation.extension.parameter.AnnotationPropertyParameter;
import de.espend.idea.php.annotation.extension.parameter.PhpAnnotationReferenceProviderParameter;
import de.espend.idea.php.drupal.index.PermissionIndex;
import de.espend.idea.php.drupal.registrar.YamlPermissionGotoCompletion;
import de.espend.idea.php.drupal.utils.IndexUtil;
import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* @author Daniel Espendiller <[email protected]>
*
* "@ContentEntityTypeAnnotation"
*/
public class ContentEntityTypeAnnotation implements PhpAnnotationCompletionProvider, PhpAnnotationReferenceProvider {
@Override
public void getPropertyValueCompletions(AnnotationPropertyParameter parameter, AnnotationCompletionProviderParameter completionProviderParameter) {
if(!isSupported(parameter)) {
return;
}

if("field_ui_base_route".equalsIgnoreCase(parameter.getPropertyName())) {
completionProviderParameter.getResult().addAllElements(RouteHelper.getRoutesLookupElements(parameter.getProject()));
}

if("admin_permission".equalsIgnoreCase(parameter.getPropertyName())) {
completionProviderParameter.getResult().addAllElements(IndexUtil.getIndexedKeyLookup(parameter.getProject(), PermissionIndex.KEY));
}
}

private boolean isSupported(@NotNull AnnotationPropertyParameter parameter) {
return parameter.getType() != AnnotationPropertyParameter.Type.DEFAULT &&
PhpLangUtil.equalsClassNames(StringUtils.stripStart(parameter.getPhpClass().getFQN(), "\\"), "Drupal\\Core\\Entity\\Annotation\\ContentEntityType");
}

@Nullable
@Override
public PsiReference[] getPropertyReferences(AnnotationPropertyParameter parameter, PhpAnnotationReferenceProviderParameter phpAnnotationReferenceProviderParameter) {
if(!isSupported(parameter)) {
return new PsiReference[0];
}

String propertyName = parameter.getPropertyName();

if("field_ui_base_route".equalsIgnoreCase(propertyName)) {
String contents = getContents(parameter.getElement());
if(StringUtils.isBlank(contents)) {
return new PsiReference[0];
}

return new PsiReference[] {new MyRoutePsiPolyVariantReferenceBase(parameter.getElement(), contents)};
} else if("admin_permission".equalsIgnoreCase(propertyName)) {
String contents = getContents(parameter.getElement());
if(StringUtils.isBlank(contents)) {
return new PsiReference[0];
}

return new PsiReference[] {new MyPermissionPsiPolyVariantReferenceBase(parameter.getElement(), contents)};
}

return new PsiReference[0];
}

@Nullable
private String getContents(@NotNull PsiElement element) {
if(!(element instanceof StringLiteralExpression)) {
return null;
}

String contents = ((StringLiteralExpression) element).getContents();
if(StringUtils.isBlank(contents)) {
return null;
}

return contents;
}

private static class MyRoutePsiPolyVariantReferenceBase extends PsiPolyVariantReferenceBase<PsiElement> {
@NotNull
private final PsiElement element;

@NotNull
private final String contents;

MyRoutePsiPolyVariantReferenceBase(@NotNull PsiElement element, @NotNull String contents) {
super(element);
this.element = element;
this.contents = contents;
}

@NotNull
@Override
public Object[] getVariants() {
return new Object[0];
}

@NotNull
@Override
public ResolveResult[] multiResolve(boolean b) {
PsiElement routeNameTarget = RouteHelper.getRouteNameTarget(element.getProject(), contents);
if(routeNameTarget == null) {
return new ResolveResult[0];
}

return PsiElementResolveResult.createResults(routeNameTarget);
}
}

public static class MyPermissionPsiPolyVariantReferenceBase extends PsiPolyVariantReferenceBase<PsiElement> {
@NotNull
private final PsiElement element;

@NotNull
private final String contents;

MyPermissionPsiPolyVariantReferenceBase(@NotNull PsiElement element, @NotNull String contents) {
super(element);
this.element = element;
this.contents = contents;
}

@NotNull
@Override
public Object[] getVariants() {
return new Object[0];
}

@NotNull
@Override
public ResolveResult[] multiResolve(boolean b) {
return PsiElementResolveResult.createResults(YamlPermissionGotoCompletion.getPermissionPsiElements(element.getProject(), contents));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package de.espend.idea.php.drupal.annotation;

import de.espend.idea.php.annotation.dict.AnnotationPropertyEnum;
import de.espend.idea.php.annotation.extension.PhpAnnotationVirtualProperties;
import de.espend.idea.php.annotation.extension.parameter.AnnotationCompletionProviderParameter;
import de.espend.idea.php.annotation.extension.parameter.AnnotationVirtualPropertyCompletionParameter;
import de.espend.idea.php.annotation.extension.parameter.AnnotationVirtualPropertyTargetsParameter;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
* @author Daniel Espendiller <[email protected]>
*/
public class DrupalVirtualProperties implements PhpAnnotationVirtualProperties {
final private static Map<String, Map<String, AnnotationPropertyEnum>> ITEMS = Collections.unmodifiableMap(new HashMap<String, Map<String, AnnotationPropertyEnum>>() {{
put("Drupal\\Core\\Entity\\Annotation\\ContentEntityType", Collections.unmodifiableMap(new HashMap<String, AnnotationPropertyEnum>() {{
put("id", AnnotationPropertyEnum.STRING);
put("label", AnnotationPropertyEnum.STRING);
put("handlers", AnnotationPropertyEnum.ARRAY);
put("admin_permission", AnnotationPropertyEnum.STRING);
put("base_table", AnnotationPropertyEnum.STRING);
put("data_table", AnnotationPropertyEnum.STRING);
put("label_callback", AnnotationPropertyEnum.STRING);
put("translatable", AnnotationPropertyEnum.BOOLEAN);
put("entity_keys", AnnotationPropertyEnum.ARRAY);
put("links", AnnotationPropertyEnum.ARRAY);
put("field_ui_base_route", AnnotationPropertyEnum.STRING);
put("common_reference_target", AnnotationPropertyEnum.STRING);
}}));

put("Drupal\\Core\\Entity\\Annotation\\ConfigEntityType", Collections.unmodifiableMap(new HashMap<String, AnnotationPropertyEnum>() {{
put("id", AnnotationPropertyEnum.STRING);
put("label", AnnotationPropertyEnum.STRING);
put("handlers", AnnotationPropertyEnum.STRING);
put("entity_keys", AnnotationPropertyEnum.ARRAY);
put("admin_permission", AnnotationPropertyEnum.STRING);
put("list_cache_tags", AnnotationPropertyEnum.ARRAY);
put("config_export", AnnotationPropertyEnum.ARRAY);
}}));

put("Drupal\\Component\\Annotation\\Plugin", Collections.unmodifiableMap(new HashMap<String, AnnotationPropertyEnum>() {{
put("id", AnnotationPropertyEnum.STRING);
put("title", AnnotationPropertyEnum.STRING);
put("description", AnnotationPropertyEnum.STRING);
}}));
}});

@Override
public void addCompletions(@NotNull AnnotationVirtualPropertyCompletionParameter virtualPropertyParameter, @NotNull AnnotationCompletionProviderParameter parameter) {
String fqn = StringUtils.stripStart(virtualPropertyParameter.getPhpClass().getFQN(), "\\");
if(!ITEMS.containsKey(fqn)) {
return;
}

for (Map.Entry<String, AnnotationPropertyEnum> item : ITEMS.get(fqn).entrySet()) {
virtualPropertyParameter.addLookupElement(item.getKey(), item.getValue());
}
}

@Override
public void getTargets(@NotNull AnnotationVirtualPropertyTargetsParameter parameter) {
String fqn = StringUtils.stripStart(parameter.getPhpClass().getFQN(), "\\");
if(!ITEMS.containsKey(fqn)) {
return;
}

if(ITEMS.containsKey(fqn) && ITEMS.get(fqn).containsKey(parameter.getProperty())) {
parameter.addTarget(parameter.getPhpClass());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package de.espend.idea.php.drupal.annotation;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.jetbrains.php.PhpIndex;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import de.espend.idea.php.annotation.extension.PhpAnnotationGlobalNamespacesLoader;
import de.espend.idea.php.annotation.extension.parameter.AnnotationGlobalNamespacesLoaderParameter;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.HashSet;

/**
* @author Daniel Espendiller <[email protected]>
*/
public class GlobalNamespaceLoader implements PhpAnnotationGlobalNamespacesLoader {

private static final Key<CachedValue<Collection<String>>> CACHE = new Key<>("DRUPAL_GLOBAL_NAMESPACE");

@Override
@NotNull
public Collection<String> getGlobalNamespaces(@NotNull AnnotationGlobalNamespacesLoaderParameter parameter) {
Project project = parameter.getProject();

CachedValue<Collection<String>> cache = project.getUserData(CACHE);

if(cache == null) {
cache = CachedValuesManager.getManager(project).createCachedValue(() ->
CachedValueProvider.Result.create(getGlobalNamespacesInner(project), PsiModificationTracker.MODIFICATION_COUNT), false
);

project.putUserData(CACHE, cache);
}

return cache.getValue();
}

@NotNull
private static Collection<String> getGlobalNamespacesInner(@NotNull Project project) {
Collection<String> namespaces = new HashSet<>();

for (PhpClass phpClass : PhpIndex.getInstance(project).getAllSubclasses("Drupal\\Component\\Annotation\\AnnotationInterface")) {
String namespaceName = StringUtils.strip(phpClass.getNamespaceName(), "\\");
if(namespaceName.endsWith("Annotation")) {
namespaces.add(namespaceName);
}
}

return namespaces;
}
}
Loading