package com.aopphp.go.injector;

import com.aopphp.go.PointcutQueryLanguage;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.InjectedLanguagePlaces;
import com.intellij.psi.LanguageInjector;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import de.espend.idea.php.annotation.dict.PhpDocTagAnnotation;
import de.espend.idea.php.annotation.pattern.AnnotationPattern;
import de.espend.idea.php.annotation.util.AnnotationUtil;
import org.jetbrains.annotations.NotNull;

public class PointcutQueryLanguageInjector implements LanguageInjector {

    private static final String GO_AOP_ANNOTATION = "\\Go\\Lang\\Annotation";

    @Override
    public void getLanguagesToInject(
            @NotNull PsiLanguageInjectionHost host,
            @NotNull InjectedLanguagePlaces injectionPlacesRegistrar)
    {
        // we accept only PHP literal expressions, such as docBlocks and string for PointcutBuilder->method('<expr>')
        if (!(host instanceof StringLiteralExpression)) {
            return;
        }

        boolean enableInjection = false;

        PhpDocTag phpDocTag = PsiTreeUtil.getParentOfType(host, PhpDocTag.class);
        if (phpDocTag == null || !AnnotationPattern.getDocBlockTag().accepts(phpDocTag)) {
            return;
        }

        PhpDocTagAnnotation phpDocAnnotationContainer = AnnotationUtil.getPhpDocAnnotationContainer(phpDocTag);
        PhpClass phpClass = null;
        if (phpDocAnnotationContainer != null) {
            phpClass = phpDocAnnotationContainer.getPhpClass();
        }

        if (phpClass == null || phpClass.getFQN() == null) {
            return;
        }

        if (phpClass.getFQN().startsWith(GO_AOP_ANNOTATION)) {
            enableInjection = true;
        }

        if (enableInjection) {
            TextRange rangeInsideHost = new TextRange(1, host.getTextLength() - 1);
            injectionPlacesRegistrar.addPlace(PointcutQueryLanguage.INSTANCE, rangeInsideHost, "", "");
        }
    }
}

@@ -204,16 +204,52 @@
 jector;%0A
+import com.intellij.psi.PsiElement;%0A
 import c
@@ -290,16 +290,16 @@
 onHost;%0A
-
 import c
@@ -403,16 +403,134 @@
 DocTag;%0A
+import com.jetbrains.php.lang.psi.elements.MethodReference;%0Aimport com.jetbrains.php.lang.psi.elements.ParameterList;%0A
 import c
@@ -638,24 +638,84 @@
 Expression;%0A
+import com.jetbrains.php.lang.psi.elements.impl.MethodImpl;%0A
 import de.es
@@ -1462,32 +1462,1516 @@
 urn;%0A        %7D%0A%0A
+        boolean enableInjection = isInjectionIntoAnnotation(host);%0A        enableInjection %7C= isInjectionIntoPointcutBuilder(host);%0A%0A        if (enableInjection) %7B%0A            TextRange rangeInsideHost = new TextRange(1, host.getTextLength() - 1);%0A            injectionPlacesRegistrar.addPlace(PointcutQueryLanguage.INSTANCE, rangeInsideHost, %22%22, %22%22);%0A        %7D%0A    %7D%0A%0A    /**%0A     * Checks if injection is performed into PointcutBuilder-%3Emethod('%3CpointcutExpression%3E', function () %7B...%7D)%0A     * @param host Host element is typically PHP string%0A     *%0A     * @return boolean%0A     */%0A    private boolean isInjectionIntoPointcutBuilder(PsiLanguageInjectionHost host)%0A    %7B%0A        PsiElement element = host.getParent();%0A        if (!(element instanceof ParameterList)) %7B%0A            return false;%0A        %7D%0A        element = element.getParent();%0A        if (!(element instanceof MethodReference)) %7B%0A            return false;%0A        %7D%0A%0A        MethodImpl methodImpl = (MethodImpl) ((MethodReference) element).resolve();%0A        if (methodImpl == null %7C%7C methodImpl.getFQN() == null) %7B%0A            return false;%0A        %7D%0A%0A        return methodImpl.getFQN().startsWith(%22%5C%5CGo%5C%5CAop%5C%5CSupport%5C%5CPointcutBuilder%22);%0A    %7D%0A%0A    /**%0A     * Checks if injection is performed into annotation%0A     *%0A     * @param host Host element, typically string literal expression%0A     *%0A     * @return boolean%0A     */%0A    private boolean isInjectionIntoAnnotation (@NotNull PsiLanguageInjectionHost host)%0A    %7B%0A
         boolean 
@@ -3179,32 +3179,38 @@
           return
+ false
 ;%0A        %7D%0A%0A   
@@ -3547,32 +3547,38 @@
           return
+ false
 ;%0A        %7D%0A%0A   
@@ -3696,228 +3696,31 @@
     
-if (enableInjection) %7B%0A            TextRange rangeInsideHost = new TextRange(1, host.getTextLength() - 1);%0A            injectionPlacesRegistrar.addPlace(PointcutQueryLanguage.INSTANCE, rangeInsideHost, %22%22, %22%22);%0A        %7D
+return enableInjection;
 %0A   

Add automatic language injection for PointcutBuilder class methods