apollographql / apollo-kotlin

:rocket:  A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
https://www.apollographql.com/docs/kotlin
MIT License
3.76k stars 653 forks source link

Android Studio Plugin - Navigate to Query Gutter Icon Missing #5035

Closed agrosner closed 1 year ago

agrosner commented 1 year ago

Version

3.8.1 (apollo), 4.0.0-alpha.2-SNAPSHOT.20 (plugin)

Summary

In the example provided in the announcement, you can navigate from a query to its corresponding GraphQL file operation via gutter icons that link you there.

Android Studio Hedgehog | 2023.1.1 Canary 7 Build #AI-231.9011.34.2311.10238683, built on June 1, 2023 Runtime version: 17.0.6+0-17.0.6b829.9-10027231 aarch64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. macOS 13.4 GC: G1 Young Generation, G1 Old Generation Memory: 16384M Cores: 10 Metal Rendering is ON Registry: external.system.auto.import.disabled=true debugger.watches.in.variables=false debugger.new.tool.window.layout=true ide.text.editor.with.preview.show.floating.toolbar=false ide.instant.shutdown=false ide.experimental.ui=true

Non-Bundled Plugins: detekt (2.0.0) com.intellij.lang.jsgraphql (4.0.1) com.apollographql.ijplugin (4.0.0-alpha.2-SNAPSHOT.20) com.nbadal.ktlint (0.12.0) com.jetbrains.kmm (0.6.0(231)-5) com.developerphil.adbidea (1.6.10) org.sonarlint.idea (8.3.0.71062)

In our project we return a query from an interface implementation like:

class SomeQueryMapper : QueryMapper<SomeQueryExperience, SomeQuery.Data, SomeQuery> {

    override fun map(exp: SomeQueryExperience): SomeQuery =
        SomeQuery()
}

The gutter icons do not show up for this instance. We will send this query off to a client outside of the file / not at the source call here. My guess is the plugin doesn't consider this case? In this situation we just go to the generated code.

Steps to reproduce the behavior

  1. Create a class or function that just returns a new query
  2. Observe no gutter icon

Logs

No response

BoD commented 1 year ago

Thanks for reporting!

It looks like a case where the corresponding GraphQL file is not found, but I'm not exactly sure of what you mean by "not at the source call here". Not sure if that's your case here, but FWIW it should also work when the referenced queries come from another module.

Could you describe the directory structure a bit?

If you wish you can also provide the plugin's debug logs:

  1. Help / Diagnostic Tools / Debug Log Settings / add Apollo
  2. Help / Show Log in Finder
agrosner commented 1 year ago

Sure! oh its so much simpler.

Quick verification: If I have a query with a lowercase letter or not matching exactly (minus Query) from the generated code:

query someQuery {

}

The error is:

2023-06-22 13:14:12,229 [84290303]   WARN - Apollo - Could not resolve REFERENCE_EXPRESSION
java.lang.Throwable: Control-flow exceptions (e.g. this class com.intellij.openapi.progress.ProcessCanceledException) should never be logged. Instead, these should have been rethrown if caught.
    at com.intellij.openapi.diagnostic.Logger.ensureNotControlFlow(Logger.java:302)
    at com.intellij.idea.IdeaLogger.warn(IdeaLogger.java:136)
    at com.apollographql.ijplugin.util.LoggingKt.logw(Logging.kt:50)
    at com.apollographql.ijplugin.util.PsiKt.resolveKtName(Psi.kt:50)
    at com.apollographql.ijplugin.navigation.GraphQLNavigationKt.isApolloOperationOrFragment(GraphQLNavigation.kt:88)
    at com.apollographql.ijplugin.navigation.GraphQLNavigationKt.isApolloOperationOrFragmentReference(GraphQLNavigation.kt:55)
    at com.apollographql.ijplugin.navigation.KotlinDefinitionMarkerProvider.collectNavigationMarkers(KotlinDefinitionMarkerProvider.kt:28)
    at com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider.collectNavigationMarkers(RelatedItemLineMarkerProvider.java:35)
    at com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider.collectSlowLineMarkers(RelatedItemLineMarkerProvider.java:27)
    at com.intellij.codeInsight.daemon.impl.LineMarkersPass.queryProviders(LineMarkersPass.java:223)
    at com.intellij.codeInsight.daemon.impl.LineMarkersPass.lambda$doCollectInformation$3(LineMarkersPass.java:104)
    at com.intellij.codeInsight.daemon.impl.Divider.divideInsideAndOutsideInOneRoot(Divider.java:95)
    at com.intellij.codeInsight.daemon.impl.LineMarkersPass.doCollectInformation(LineMarkersPass.java:99)
    at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:57)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$doRun$1(PassExecutorService.java:382)
    at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1102)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$doRun$2(PassExecutorService.java:374)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$13(CoreProgressManager.java:604)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:679)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:635)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:603)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:60)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.doRun(PassExecutorService.java:373)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$run$0(PassExecutorService.java:349)
    at com.intellij.openapi.application.impl.ReadMostlyRWLock.executeByImpatientReader(ReadMostlyRWLock.java:229)
    at com.intellij.openapi.application.impl.ApplicationImpl.executeByImpatientReader(ApplicationImpl.java:187)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:347)
    at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:181)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
Caused by: com.intellij.openapi.progress.ProcessCanceledException
    at com.intellij.openapi.progress.util.AbstractProgressIndicatorBase.throwIfCanceled(AbstractProgressIndicatorBase.java:158)
    at com.intellij.openapi.progress.util.AbstractProgressIndicatorBase.checkCanceled(AbstractProgressIndicatorBase.java:148)
    at com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator.checkCanceled(DaemonProgressIndicator.java:78)
    at com.intellij.openapi.progress.util.ProgressIndicatorUtils.checkCancelledEvenWithPCEDisabled(ProgressIndicatorUtils.java:386)
    at com.intellij.openapi.progress.util.ProgressIndicatorUtils.awaitWithCheckCanceled(ProgressIndicatorUtils.java:330)
    at com.intellij.openapi.progress.util.ProgressIndicatorUtils.awaitWithCheckCanceled(ProgressIndicatorUtils.java:325)
    at com.intellij.util.indexing.RegisteredIndexes.waitUntilIndicesAreInitialized(RegisteredIndexes.java:89)
    at com.intellij.util.indexing.FileBasedIndexImpl.waitUntilIndicesAreInitialized(FileBasedIndexImpl.java:435)
    at com.intellij.util.indexing.FileBasedIndexEx.processExceptions(FileBasedIndexEx.java:312)
    at com.intellij.util.indexing.FileBasedIndexEx.getContainingFilesIterator(FileBasedIndexEx.java:263)
    at org.jetbrains.kotlin.idea.vfilefinder.IdeVirtualFileFinder.findVirtualFileWithHeader(IdeVirtualFileFinder.kt:46)
    at org.jetbrains.kotlin.idea.vfilefinder.IdeVirtualFileFinder.findMetadata(IdeVirtualFileFinder.kt:18)
    at org.jetbrains.kotlin.serialization.deserialization.MetadataClassDataFinder.findClassData(MetadataUtil.kt:19)
    at org.jetbrains.kotlin.serialization.deserialization.DeserializedClassDataFinder.findClassData(DeserializedClassDataFinder.kt:29)
    at org.jetbrains.kotlin.serialization.deserialization.ClassDeserializer.createClass(ClassDeserializer.kt:44)
    at org.jetbrains.kotlin.serialization.deserialization.ClassDeserializer.access$createClass(ClassDeserializer.kt:27)
    at org.jetbrains.kotlin.serialization.deserialization.ClassDeserializer$classes$1.invoke(ClassDeserializer.kt:29)
    at org.jetbrains.kotlin.serialization.deserialization.ClassDeserializer$classes$1.invoke(ClassDeserializer.kt:29)
    at org.jetbrains.kotlin.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)
    at org.jetbrains.kotlin.serialization.deserialization.ClassDeserializer.deserializeClass(ClassDeserializer.kt:34)
    at org.jetbrains.kotlin.serialization.deserialization.ClassDeserializer.deserializeClass$default(ClassDeserializer.kt:33)
    at org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents.deserializeClass(context.kt:63)
    at org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberScope.deserializeClass(DeserializedMemberScope.kt:144)
    at org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberScope.getContributedClassifier(DeserializedMemberScope.kt:138)
    at org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope.getContributedClassifier(DeserializedPackageMemberScope.kt:64)
    at org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope.getContributedClassifier(ChainedMemberScope.kt:35)
    at org.jetbrains.kotlin.resolve.scopes.AbstractScopeAdapter.getContributedClassifier(AbstractScopeAdapter.kt:44)
    at org.jetbrains.kotlin.resolve.AllUnderImportScope.getContributedClassifier(AllUnderImportScope.kt:85)
    at org.jetbrains.kotlin.resolve.lazy.LazyImportScope$getClassifier$1.invoke(LazyImportScope.kt:279)
    at org.jetbrains.kotlin.resolve.lazy.LazyImportScope$getClassifier$1.invoke(LazyImportScope.kt:274)
    at org.jetbrains.kotlin.storage.LockBasedStorageManager.compute(LockBasedStorageManager.java:290)
    at org.jetbrains.kotlin.resolve.lazy.LazyImportScope.getClassifier(LazyImportScope.kt:274)
    at org.jetbrains.kotlin.resolve.lazy.LazyImportScope.getContributedClassifier(LazyImportScope.kt:270)
    at org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt.findClassifier(ScopeUtils.kt:89)
    at org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.resolveToPackageOrClassPrefix(QualifiedExpressionResolver.kt:517)
    at org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.resolveToPackageOrClassPrefix$default(QualifiedExpressionResolver.kt:481)
    at org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.resolveToPackageOrClass(QualifiedExpressionResolver.kt:469)
    at org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.resolveQualifierPartListForType(QualifiedExpressionResolver.kt:141)
    at org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.resolveDescriptorForType(QualifiedExpressionResolver.kt:129)
    at org.jetbrains.kotlin.resolve.TypeResolver.resolveDescriptorForType(TypeResolver.kt:1053)
    at org.jetbrains.kotlin.resolve.TypeResolver$resolveTypeElement$1.visitUserType(TypeResolver.kt:259)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitUserType(KtVisitorVoid.java:937)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitUserType(KtVisitorVoid.java:21)
    at org.jetbrains.kotlin.psi.KtUserType.accept(KtUserType.java:42)
    at org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:49)
    at org.jetbrains.kotlin.resolve.TypeResolver.resolveTypeElement(TypeResolver.kt:257)
    at org.jetbrains.kotlin.resolve.TypeResolver.resolvePossiblyBareType(TypeResolver.kt:136)
    at org.jetbrains.kotlin.resolve.TypeResolver.resolveType(TypeResolver.kt:126)
    at org.jetbrains.kotlin.resolve.TypeResolver.resolveType(TypeResolver.kt:97)
    at org.jetbrains.kotlin.resolve.DescriptorResolver.resolveSuperTypeListEntries(DescriptorResolver.java:219)
    at org.jetbrains.kotlin.resolve.DescriptorResolver.resolveSupertypes(DescriptorResolver.java:155)
    at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor.computeSupertypes(LazyClassDescriptor.java:888)
    at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor$LazyClassTypeConstructor.computeSupertypes(LazyClassDescriptor.java:785)
    at org.jetbrains.kotlin.types.AbstractTypeConstructor$supertypes$1.invoke(AbstractTypeConstructor.kt:78)
    at org.jetbrains.kotlin.types.AbstractTypeConstructor$supertypes$1.invoke(AbstractTypeConstructor.kt:77)
    at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
    at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:481)
    at org.jetbrains.kotlin.storage.LockBasedStorageManager$LockBasedNotNullLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:512)
    at org.jetbrains.kotlin.types.AbstractTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:27)
    at org.jetbrains.kotlin.types.AbstractTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:26)
    at org.jetbrains.kotlin.idea.project.ResolveElementCache.delegationSpecifierAdditionalResolve(ResolveElementCache.kt:627)
    at org.jetbrains.kotlin.idea.project.ResolveElementCache.performElementAdditionalResolve(ResolveElementCache.kt:469)
    at org.jetbrains.kotlin.idea.project.ResolveElementCache.getElementsAdditionalResolve(ResolveElementCache.kt:191)
    at org.jetbrains.kotlin.idea.project.ResolveElementCache.getElementsAdditionalResolve(ResolveElementCache.kt:198)
    at org.jetbrains.kotlin.idea.project.ResolveElementCache.resolveToElement(ResolveElementCache.kt:286)
    at org.jetbrains.kotlin.idea.caches.resolve.ModuleResolutionFacadeImpl$analyze$3.invoke(ModuleResolutionFacadeImpl.kt:53)
    at org.jetbrains.kotlin.idea.caches.resolve.ModuleResolutionFacadeImpl$analyze$3.invoke(ModuleResolutionFacadeImpl.kt:52)
    at com.intellij.openapi.progress.impl.CancellationCheck.withCancellationCheck(CancellationCheck.kt:59)
    at com.intellij.openapi.progress.impl.CancellationCheck$Companion.runWithCancellationCheck(CancellationCheck.kt:105)
    at org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt.runWithCancellationCheck(ApplicationUtils.kt:63)
    at org.jetbrains.kotlin.idea.caches.resolve.ModuleResolutionFacadeImpl.analyze(ModuleResolutionFacadeImpl.kt:52)
    at org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacadeWithDebugInfo.analyze(ResolutionFacadeWithDebugInfo.kt:43)
    at org.jetbrains.kotlin.idea.caches.resolve.ExtendedResolutionApiKt.analyze(ExtendedResolutionApi.kt:124)
    at org.jetbrains.kotlin.idea.caches.resolve.ExtendedResolutionApiKt.safeAnalyzeNonSourceRootCode(ExtendedResolutionApi.kt:158)
    at org.jetbrains.kotlin.idea.caches.resolve.ExtendedResolutionApiKt.safeAnalyzeNonSourceRootCode(ExtendedResolutionApi.kt:152)
    at org.jetbrains.kotlin.idea.references.KtFe10ReferenceResolutionHelperImpl.partialAnalyze(KtFe10ReferenceResolutionHelperImpl.kt:48)
    at org.jetbrains.kotlin.references.fe10.base.KtFe10PolyVariantResolver.resolveToPsiElements(KtFe10PolyVariantResolver.kt:27)
    at org.jetbrains.kotlin.references.fe10.base.KtFe10PolyVariantResolver.resolve(KtFe10PolyVariantResolver.kt:73)
    at org.jetbrains.kotlin.references.fe10.base.KtFe10PolyVariantResolver.resolve(KtFe10PolyVariantResolver.kt:22)
    at com.intellij.psi.impl.source.resolve.ResolveCache.lambda$resolveWithCaching$1(ResolveCache.java:161)
    at com.intellij.openapi.util.Computable.get(Computable.java:16)
    at com.intellij.psi.impl.source.resolve.ResolveCache.lambda$loggingResolver$4(ResolveCache.java:237)
    at com.intellij.openapi.util.Computable.get(Computable.java:16)
    at com.intellij.psi.impl.source.resolve.ResolveCache.resolve(ResolveCache.java:215)
    at com.intellij.psi.impl.source.resolve.ResolveCache.resolveWithCaching(ResolveCache.java:160)
    at com.intellij.psi.impl.source.resolve.ResolveCache.resolveWithCaching(ResolveCache.java:147)
    at org.jetbrains.kotlin.idea.references.AbstractKtReference.multiResolve(KtReference.kt:32)
    at com.intellij.psi.PsiPolyVariantReferenceBase.resolve(PsiPolyVariantReferenceBase.java:47)
    at com.apollographql.ijplugin.util.PsiKt.resolveKtName(Psi.kt:47)
    ... 29 more

This is all fixed if I make it match exact case:

query SomeQuery {

}
BoD commented 1 year ago

Oooh that makes sense - a bad assumption about the casing when searching for the corresponding operation. Good catch! 🙏 Fix coming soon to the snapshots channel.