Я делаю плагин IntelliJ, чтобы добавить некоторые проверки в язык PHP. В plugin.xml я объявил свою проверку:
<extensions defaultExtensionNs = "com.intellij">
<localInspection
language = "PHP"
groupPath = "PHP,Php Inspections (MTA)"
shortName = "UnsafeCallToHeaderInspection"
displayName = "Unsafe call to 'header()' function"
groupName = "Security"
enabledByDefault = "true"
level = "ERROR"
implementationClass = "com.ge.sdc.intellij.mtaplugin.security.php.UnsafeCallToHeaderInspection"/>
</extensions>
<application-components>
<component>
<implementation-class>com.ge.sdc.intellij.mtaplugin.MtaApplicationComponent</implementation-class>
</component>
</application-components>
В своем классе инспекции я расширил PhpInspection и создаю PhpElementVisitor.
package com.ge.sdc.intellij.mtaplugin.security.php;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.jetbrains.php.lang.inspections.PhpInspection;
import com.jetbrains.php.lang.psi.elements.FunctionReference;
import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class UnsafeCallToHeaderInspection extends PhpInspection {
private Logger log = Logger.getInstance(UnsafeCallToHeaderInspection.class);
@Nullable
@Override
public String getStaticDescription() {
return "Calls to 'header()' function must only use constant strings or safe-known patterns." +
" Otherwise, this could allow arbitrary data to be passed in HTTP headers, and would then alter the behavior of the browser (or client)." +
"Ie: Inserting a custom Content-Security-Policy or a custom Content-Type can break several securities and be a breach.";
}
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder problemsHolder, final boolean isOnTheFly) {
return new PhpElementVisitor() {
@Override
public void visitPhpFunctionCall(FunctionReference reference) {
log.debug("visitPhpFunctionCall called");
super.visitPhpFunctionCall(reference);
}
@Override
public void visitElement(PsiElement element) {
log.debug("visitElement called");
super.visitElement(element);
}
};
}
}
Но когда я отлаживаю или запускаю плагин и открываю файл PHP, подобный этому:
<?php
header($headerName);
Я вижу только "visitElement", вызываемый в окне отладки, и не вижу вызова "visitPhpFunctionCall".
Как заставить IntelliJ выполнять вызов метода правильного посетителя, чтобы я мог управлять FunctionReference в этом методе посетителя вместо абстрактного PsiElement?
Что я пробовал до сих пор:
Я просмотрел библиотеку php.jar и взял в качестве примера PhpSillyAssignmentInspection, но здесь я не вижу разницы с моим кодом. Я также пытался имитировать https://github.com/kalessil/phpinspectionsea/ и все еще не нашел способа вызвать visitPhpFunctionCall. Наконец, я попытался загрузить этот плагин https://github.com/kalessil/phpinspectionsea/ и запустить его, но я тоже не увидел никакой проверки ...
Несмотря на это, плагин кажется правильно загруженным, и проверка, похоже, тоже распознается, потому что, когда я поднимаюсь в «Настройки / Проверки», я вижу недавно добавленную проверку под «PHP». Но кажется, что я не могу заставить IntelliJ вызывать visitPhpFunctionCall вместо visitElement (который слишком общий IMO, чтобы его можно было использовать на самом деле).






После повторения подсказок в https://intellij-support.jetbrains.com/hc/en-us/community/posts/206752935-com-jetbrains-php-classes-availability я увидел, что добавил неправильный php.jar в неправильное место.
Я должен использовать php.jar из в песочнице IntelliJ (C:\Users\212636336\.IntelliJIdea2018.1\system\plugins-sandbox), а не из IntelliJ, который я использую для разработки плагина. И этот jar должен быть в пути к классам этого изолированного IntelliJ SDK, а не добавлен как «внешняя библиотека», как это сделал я.