Haehnchen / idea-php-symfony2-plugin

IntelliJ IDEA / PhpStorm Symfony Plugin
https://plugins.jetbrains.com/plugin/7219
MIT License
913 stars 137 forks source link

Constants in methods argument of Route attribute cause plugin exception #1705

Closed andyexeter closed 2 years ago

andyexeter commented 3 years ago

PhpStorm Version: 2021.2.1 Plugin version: 0.23.212

When using a constant in the methods argument of a Route attribute, the following exception is thrown:

Click to expand
com.intellij.diagnostic.PluginException: Failed to build index 'fr.adrienbrault.idea.symfony2plugin.routes_object' for file file:///home/andy/projects/idea-symfony-plugin-routing-issue-demo/src/Controller/DefaultController.php (id = 563280) (file type = PHP) [Plugin: fr.adrienbrault.idea.symfony2plugin]
    at com.intellij.ide.plugins.PluginManagerCore.createPluginException(PluginManagerCore.java:274)
    at com.intellij.diagnostic.PluginProblemReporterImpl.createPluginExceptionByClass(PluginProblemReporterImpl.java:12)
    at com.intellij.diagnostic.PluginException.createByClass(PluginException.java:91)
    at com.intellij.util.indexing.diagnostic.BrokenIndexingDiagnostics$DefaultListener.onFileIndexMappingFailed(BrokenIndexingDiagnostics.kt:47)
    at com.intellij.util.indexing.FileBasedIndexImpl.updateSingleIndex(FileBasedIndexImpl.java:1530)
    at com.intellij.util.indexing.FileBasedIndexImpl.lambda$doIndexFileContent$23(FileBasedIndexImpl.java:1394)
    at com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl.freezeFileTypeTemporarilyIn(FileTypeManagerImpl.java:644)
    at com.intellij.util.indexing.FileBasedIndexImpl.doIndexFileContent(FileBasedIndexImpl.java:1361)
    at com.intellij.util.indexing.FileBasedIndexImpl.indexFileContent(FileBasedIndexImpl.java:1315)
    at com.intellij.util.indexing.contentQueue.IndexUpdateRunner.lambda$indexOneFileOfJob$5(IndexUpdateRunner.java:267)
    at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.insideReadAction(NonBlockingReadActionImpl.java:521)
    at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.lambda$attemptComputation$3(NonBlockingReadActionImpl.java:486)
    at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1078)
    at com.intellij.openapi.progress.util.ProgressIndicatorUtils.lambda$runInReadActionWithWriteActionPriority$0(ProgressIndicatorUtils.java:78)
    at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runActionAndCancelBeforeWrite(ProgressIndicatorUtils.java:161)
    at com.intellij.openapi.progress.util.ProgressIndicatorUtils.lambda$runWithWriteActionPriority$1(ProgressIndicatorUtils.java:118)
    at com.intellij.openapi.progress.ProgressManager.lambda$runProcess$0(ProgressManager.java:57)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:183)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:705)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:647)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:63)
    at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:170)
    at com.intellij.openapi.progress.ProgressManager.runProcess(ProgressManager.java:57)
    at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runWithWriteActionPriority(ProgressIndicatorUtils.java:115)
    at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runInReadActionWithWriteActionPriority(ProgressIndicatorUtils.java:78)
    at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.attemptComputation(NonBlockingReadActionImpl.java:486)
    at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.executeSynchronously(NonBlockingReadActionImpl.java:421)
    at com.intellij.openapi.application.impl.NonBlockingReadActionImpl.executeSynchronously(NonBlockingReadActionImpl.java:186)
    at com.intellij.util.indexing.contentQueue.IndexUpdateRunner.indexOneFileOfJob(IndexUpdateRunner.java:270)
    at com.intellij.util.indexing.contentQueue.IndexUpdateRunner.lambda$indexJobsFairly$4(IndexUpdateRunner.java:210)
    at com.intellij.openapi.progress.impl.ProgressSuspender.executeNonSuspendableSection(ProgressSuspender.java:83)
    at com.intellij.util.indexing.contentQueue.IndexUpdateRunner.indexJobsFairly(IndexUpdateRunner.java:213)
    at com.intellij.util.indexing.contentQueue.IndexUpdateRunner.lambda$doIndexFiles$3(IndexUpdateRunner.java:147)
    at com.intellij.util.concurrency.BoundedTaskExecutor.doRun(BoundedTaskExecutor.java:216)
    at com.intellij.util.concurrency.BoundedTaskExecutor.access$200(BoundedTaskExecutor.java:27)
    at com.intellij.util.concurrency.BoundedTaskExecutor$1.execute(BoundedTaskExecutor.java:195)
    at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:213)
    at com.intellij.util.concurrency.BoundedTaskExecutor$1.run(BoundedTaskExecutor.java:184)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:668)
    at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:665)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:665)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.intellij.util.indexing.impl.MapReduceIndexMappingException: com.intellij.openapi.project.IndexNotReadyException: Please change caller according to com.intellij.openapi.project.IndexNotReadyException documentation
    at com.intellij.util.indexing.impl.MapReduceIndex.mapInputAndPrepareUpdate(MapReduceIndex.java:272)
    at com.intellij.indexing.composite.CompositeInvertedIndexBase.updateBaseIndex(CompositeInvertedIndexBase.java:232)
    at com.intellij.indexing.composite.CompositeInvertedIndexBase.mapInputAndPrepareUpdate(CompositeInvertedIndexBase.java:55)
    at com.intellij.indexing.composite.CompositeInvertedIndexBase.mapInputAndPrepareUpdate(CompositeInvertedIndexBase.java:26)
    at com.intellij.util.indexing.FileBasedIndexImpl.updateSingleIndex(FileBasedIndexImpl.java:1520)
    ... 40 more
Caused by: com.intellij.openapi.project.IndexNotReadyException: Please change caller according to com.intellij.openapi.project.IndexNotReadyException documentation
    at com.intellij.openapi.project.IndexNotReadyException.create(IndexNotReadyException.java:67)
    at com.intellij.util.indexing.FileBasedIndexImpl.handleDumbMode(FileBasedIndexImpl.java:821)
    at com.intellij.util.indexing.FileBasedIndexImpl.ensureUpToDate(FileBasedIndexImpl.java:773)
    at com.intellij.psi.stubs.StubIndexImpl.getContainingIds(StubIndexImpl.java:501)
    at com.intellij.psi.stubs.StubIndexImpl.processElements(StubIndexImpl.java:305)
    at com.intellij.psi.stubs.StubIndex.getElements(StubIndex.java:100)
    at com.intellij.psi.stubs.StubIndex.getElements(StubIndex.java:88)
    at com.jetbrains.php.PhpIndexImpl.getElements(PhpIndexImpl.java:574)
    at com.jetbrains.php.PhpIndexImpl.getByName(PhpIndexImpl.java:992)
    at com.jetbrains.php.PhpIndexImpl.getByFQN(PhpIndexImpl.java:967)
    at com.jetbrains.php.PhpIndexImpl.getClassesByFQNInternal(PhpIndexImpl.java:1042)
    at com.jetbrains.php.PhpIndexImpl.getAnyByFQN(PhpIndexImpl.java:1079)
    at com.jetbrains.php.lang.psi.elements.impl.MemberReferenceImpl.findClasses(MemberReferenceImpl.java:326)
    at com.jetbrains.php.lang.psi.elements.impl.MemberReferenceImpl.resolveInHierarchyInner(MemberReferenceImpl.java:270)
    at com.jetbrains.php.lang.psi.elements.impl.MemberReferenceImpl.resolveInHierarchyInner(MemberReferenceImpl.java:243)
    at com.jetbrains.php.lang.psi.elements.impl.MemberReferenceImpl.lambda$resolveInHierarchy$0(MemberReferenceImpl.java:229)
    at com.intellij.psi.util.CachedValuesManager$1.compute(CachedValuesManager.java:158)
    at com.intellij.psi.impl.PsiCachedValueImpl.doCompute(PsiCachedValueImpl.java:39)
    at com.intellij.util.CachedValueBase.lambda$getValueWithLock$3(CachedValueBase.java:227)
    at com.intellij.util.CachedValueBase.computeData(CachedValueBase.java:42)
    at com.intellij.util.CachedValueBase.lambda$getValueWithLock$4(CachedValueBase.java:227)
    at com.intellij.openapi.util.RecursionManager$1.computePreventingRecursion(RecursionManager.java:111)
    at com.intellij.openapi.util.RecursionGuard.doPreventingRecursion(RecursionGuard.java:43)
    at com.intellij.openapi.util.RecursionManager.doPreventingRecursion(RecursionManager.java:68)
    at com.intellij.util.CachedValueBase.getValueWithLock(CachedValueBase.java:228)
    at com.intellij.psi.impl.PsiCachedValueImpl.getValue(PsiCachedValueImpl.java:28)
    at com.intellij.util.CachedValuesManagerImpl.getCachedValue(CachedValuesManagerImpl.java:72)
    at com.intellij.psi.util.CachedValuesManager.getCachedValue(CachedValuesManager.java:155)
    at com.intellij.psi.util.CachedValuesManager.getCachedValue(CachedValuesManager.java:121)
    at com.jetbrains.php.lang.psi.elements.impl.MemberReferenceImpl.resolveInHierarchy(MemberReferenceImpl.java:228)
    at com.jetbrains.php.lang.psi.elements.impl.MemberReferenceImpl.resolveGlobal(MemberReferenceImpl.java:199)
    at com.jetbrains.php.lang.psi.elements.impl.MemberReferenceImpl.resolveGlobal(MemberReferenceImpl.java:185)
    at com.jetbrains.php.lang.psi.elements.impl.PhpReferenceImpl.lambda$static$0(PhpReferenceImpl.java:159)
    at com.intellij.psi.impl.source.resolve.ResolveCache$PolyVariantResolver.resolve(ResolveCache.java:69)
    at com.intellij.psi.impl.source.resolve.ResolveCache.lambda$resolve$1(ResolveCache.java:154)
    at com.intellij.openapi.util.Computable.get(Computable.java:18)
    at com.intellij.psi.impl.source.resolve.ResolveCache.lambda$loggingResolver$4(ResolveCache.java:260)
    at com.intellij.openapi.util.RecursionManager$1.computePreventingRecursion(RecursionManager.java:111)
    at com.intellij.openapi.util.RecursionGuard.doPreventingRecursion(RecursionGuard.java:43)
    at com.intellij.openapi.util.RecursionManager.doPreventingRecursion(RecursionManager.java:68)
    at com.intellij.psi.impl.source.resolve.ResolveCache.resolve(ResolveCache.java:237)
    at com.intellij.psi.impl.source.resolve.ResolveCache.resolve(ResolveCache.java:154)
    at com.intellij.psi.impl.source.resolve.ResolveCache.resolveWithCaching(ResolveCache.java:169)
    at com.intellij.psi.impl.source.resolve.ResolveCache.resolveWithCaching(ResolveCache.java:162)
    at com.jetbrains.php.lang.psi.elements.impl.PhpReferenceImpl.multiResolve(PhpReferenceImpl.java:153)
    at com.jetbrains.php.lang.psi.elements.impl.PhpReferenceImpl.resolve(PhpReferenceImpl.java:139)
    at fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil.getStringValue(PhpElementsUtil.java:643)
    at fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil.getStringValue(PhpElementsUtil.java:616)
    at fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil.getArrayValuesAsMap(PhpElementsUtil.java:123)
    at fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil.getArrayValuesAsString(PhpElementsUtil.java:107)
    at fr.adrienbrault.idea.symfony2plugin.util.PhpPsiAttributesUtil.getAttributeValueByNameAsArray(PhpPsiAttributesUtil.java:46)
    at fr.adrienbrault.idea.symfony2plugin.stubs.indexes.visitor.AnnotationRouteElementWalkingVisitor.visitPhpAttributesList(AnnotationRouteElementWalkingVisitor.java:197)
    at fr.adrienbrault.idea.symfony2plugin.stubs.indexes.visitor.AnnotationRouteElementWalkingVisitor.visitElement(AnnotationRouteElementWalkingVisitor.java:53)
    at com.intellij.psi.impl.PsiElementBase.accept(PsiElementBase.java:273)
    at com.jetbrains.php.lang.psi.elements.impl.PhpPsiElementImpl.accept(PhpPsiElementImpl.java:76)
    at com.intellij.psi.PsiWalkingState.visit(PsiWalkingState.java:67)
    at com.intellij.psi.PsiWalkingState.visit(PsiWalkingState.java:24)
    at com.intellij.util.WalkingState.walkChildren(WalkingState.java:62)
    at com.intellij.util.WalkingState.elementStarted(WalkingState.java:49)
    at com.intellij.psi.PsiWalkingState.elementStarted(PsiWalkingState.java:76)
    at com.intellij.psi.PsiRecursiveElementWalkingVisitor.visitElement(PsiRecursiveElementWalkingVisitor.java:48)
    at fr.adrienbrault.idea.symfony2plugin.stubs.indexes.visitor.AnnotationRouteElementWalkingVisitor.visitElement(AnnotationRouteElementWalkingVisitor.java:56)
    at com.intellij.psi.PsiElementVisitor.visitFile(PsiElementVisitor.java:35)
    at com.intellij.psi.PsiRecursiveElementWalkingVisitor.visitFile(PsiRecursiveElementWalkingVisitor.java:70)
    at com.intellij.extapi.psi.PsiFileBase.accept(PsiFileBase.java:60)
    at com.jetbrains.php.lang.psi.PhpFileImpl.accept(PhpFileImpl.java:200)
    at fr.adrienbrault.idea.symfony2plugin.stubs.indexes.RoutesStubIndex.lambda$getIndexer$0(RoutesStubIndex.java:81)
    at com.intellij.util.indexing.impl.MapReduceIndex.mapByIndexer(MapReduceIndex.java:328)
    at com.intellij.util.indexing.impl.MapReduceIndex.mapInput(MapReduceIndex.java:318)
    at com.intellij.util.indexing.impl.storage.VfsAwareMapReduceIndex.mapInput(VfsAwareMapReduceIndex.java:182)
    at com.intellij.util.indexing.impl.storage.VfsAwareMapReduceIndex.mapInput(VfsAwareMapReduceIndex.java:47)
    at com.intellij.util.indexing.impl.MapReduceIndex.mapInputAndPrepareUpdate(MapReduceIndex.java:263)
    ... 44 more

This leads to a "Missing Route" warning on all route names in Twig templates and in arguments to the router.

Reproducible example code:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class DefaultController extends AbstractController
{
    #[Route('/', name: 'home', methods: [Request::METHOD_GET])]
    public function index()
    {

    }
}

Using the fully-qualified class name instead of a use statement doesn't seem to help.

Replacing the constant with string literals e.g GET resolves the issue, but I'd like to use constants if possible.

I've set up a small reproducer here, if it helps: https://github.com/andyexeter/idea-symfony-plugin-routing-issue-demo

adamwojs commented 3 years ago

Hi @andyexeter. Thank you for great bug report. I was able to reproduce your issue.

My first idea here is to wrap https://github.com/Haehnchen/idea-php-symfony2-plugin/blob/master/src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java#L632-L651 with dumb mode check but I'm not sure if it's right direction.

```diff Index: src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java (date 1632149790480) @@ -1,7 +1,6 @@ package fr.adrienbrault.idea.symfony2plugin.util; import com.intellij.codeInsight.completion.CompletionResultSet; -import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.patterns.ElementPattern; import com.intellij.patterns.PatternCondition; @@ -630,27 +629,24 @@ } return resolvedString; - } - else if (!DumbService.getInstance(psiElement.getProject()).isDumb()) { - if(psiElement instanceof Field) { - return getStringValue(((Field) psiElement).getDefaultValue(), depth); - } else if(psiElement instanceof ClassConstantReference && "class".equals(((ClassConstantReference) psiElement).getName())) { - // Foobar::class - return getClassConstantPhpFqn((ClassConstantReference) psiElement); - } else if(psiElement instanceof PhpReference) { - PsiReference psiReference = psiElement.getReference(); - if(psiReference == null) { - return null; - } + } else if(psiElement instanceof Field) { + return getStringValue(((Field) psiElement).getDefaultValue(), depth); + } else if(psiElement instanceof ClassConstantReference && "class".equals(((ClassConstantReference) psiElement).getName())) { + // Foobar::class + return getClassConstantPhpFqn((ClassConstantReference) psiElement); + } else if(psiElement instanceof PhpReference) { + PsiReference psiReference = psiElement.getReference(); + if(psiReference == null) { + return null; + } - PsiElement ref = psiReference.resolve(); - if(ref instanceof PhpReference) { - return getStringValue(psiElement, depth); - } + PsiElement ref = psiReference.resolve(); + if(ref instanceof PhpReference) { + return getStringValue(psiElement, depth); + } - if(ref instanceof Field) { - return getStringValue(((Field) ref).getDefaultValue()); - } + if(ref instanceof Field) { + return getStringValue(((Field) ref).getDefaultValue()); } } ```
Haehnchen commented 2 years ago

fixed