Skip to content

Commit

Permalink
Get rif of IDE plugin dependencies (#3073)
Browse files Browse the repository at this point in the history
* Get rif of IDE plugin dependencies

Everything in this commit has been copy-pasted from IDE plugin and marked as internal
  • Loading branch information
vmishenev authored Jul 17, 2023
1 parent e8d320a commit 298065f
Show file tree
Hide file tree
Showing 24 changed files with 1,239 additions and 77 deletions.
5 changes: 0 additions & 5 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,6 @@ gradlePlugin-shadow = { module = "gradle.plugin.com.github.johnrengelman:shadow"

#### Kotlin analysis ####
kotlin-compiler = { module = "org.jetbrains.kotlin:kotlin-compiler", version.ref = "kotlin-compiler" }
kotlin-idePlugin-common = { module = "org.jetbrains.kotlin:common", version.ref = "kotlin-ide-plugin" }
kotlin-idePlugin-idea = { module = "org.jetbrains.kotlin:idea", version.ref = "kotlin-ide-plugin" }
kotlin-idePlugin-core = { module = "org.jetbrains.kotlin:core", version.ref = "kotlin-ide-plugin" }
kotlin-idePlugin-native = { module = "org.jetbrains.kotlin:native", version.ref = "kotlin-ide-plugin" }
kotlin-jps-common = { module = "org.jetbrains.kotlin:jps-common", version.ref = "kotlin-jps-common" }

#### Java analysis ####
intellij-java-psi-api = { module = "com.jetbrains.intellij.java:java-psi", version.ref = "intellij-platform" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public abstract interface class org/jetbrains/dokka/analysis/kotlin/descriptors/
}

public final class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment : com/intellij/openapi/Disposable {
public fun <init> (Lorg/jetbrains/kotlin/cli/common/messages/MessageCollector;Lorg/jetbrains/dokka/Platform;Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider;Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack;Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService;)V
public fun <init> (Lorg/jetbrains/kotlin/cli/common/messages/MessageCollector;Lorg/jetbrains/dokka/Platform;Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack;Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService;)V
public fun dispose ()V
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ internal fun createAnalysisContext(
val analysisEnvironment = AnalysisEnvironment(
DokkaMessageCollector(context.logger),
sourceSet.analysisPlatform,
context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { compilerExtensionPointProvider },
context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { mockApplicationHack },
context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { klibService },
).apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ internal const val JAR_SEPARATOR = "!/"
class AnalysisEnvironment(
private val messageCollector: MessageCollector,
internal val analysisPlatform: Platform,
private val compilerExtensionPointProvider: CompilerExtensionPointProvider,
private val mockApplicationHack: MockApplicationHack,
private val kLibService: KLibService,
) : Disposable {
Expand Down Expand Up @@ -148,9 +147,6 @@ class AnalysisEnvironment(
CustomJavadocTagProvider { emptyList() }
)

compilerExtensionPointProvider.get().forEach { extension ->
registerExtensionPoint(extension.extensionDescriptor, extension.extensions, this)
}
return environment
}

Expand Down
8 changes: 0 additions & 8 deletions subprojects/analysis-kotlin-descriptors/ide/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ dependencies {

implementation(projects.subprojects.analysisKotlinDescriptors.compiler)

api(libs.kotlin.idePlugin.common)
api(libs.kotlin.idePlugin.idea)
api(libs.kotlin.idePlugin.core)
api(libs.kotlin.idePlugin.native)

// TODO [beresnev] needed for CommonIdePlatformKind, describe
implementation(libs.kotlin.jps.common)

// TODO [beresnev] get rid of it
compileOnly(libs.kotlinx.coroutines.core)
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ internal class DokkaResolutionFacade(
return resolverForModule.componentProvider.getService(serviceClass)
}

@Deprecated("DO NOT USE IT AS IT IS A ROOT CAUSE OF KTIJ-17649")
override fun <T : Any> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
return resolverForModule.componentProvider.getService(serviceClass)
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ class IdeDescriptorAnalysisPlugin : DokkaPlugin() {
plugin<CompilerDescriptorAnalysisPlugin>().klibService providing { IdeKLibService() }
}

internal val ideCompilerExtensionPointProvider by extending {
plugin<CompilerDescriptorAnalysisPlugin>().compilerExtensionPointProvider providing { IdeCompilerExtensionPointProvider() }
}

internal val ideApplicationHack by extending {
plugin<CompilerDescriptorAnalysisPlugin>().mockApplicationHack providing { IdeMockApplicationHack() }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ package org.jetbrains.dokka.analysis.kotlin.descriptors.ide

import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.DescriptorFinder
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.caches.resolve.resolveToParameterDescriptorIfAny
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode

internal class IdeDescriptorFinder : DescriptorFinder {
override fun KtDeclaration.findDescriptor(): DeclarationDescriptor? {
return this.descriptor
return if (this is KtParameter) this.resolveToParameterDescriptorIfAny(BodyResolveMode.FULL) else this.resolveToDescriptorIfAny(
BodyResolveMode.FULL
)
}

}


Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMo
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.idea.klib.createKlibPackageFragmentProvider
import org.jetbrains.kotlin.idea.klib.getCompatibilityInfo
import org.jetbrains.kotlin.idea.klib.CachingIdeKlibMetadataLoader
import org.jetbrains.kotlin.idea.klib.compatibilityInfo
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import org.jetbrains.kotlin.storage.StorageManager

internal class IdeKLibService : KLibService {
Expand All @@ -25,6 +26,29 @@ internal class IdeKLibService : KLibService {
}

override fun isAnalysisCompatible(kotlinLibrary: KotlinLibrary): Boolean {
return kotlinLibrary.getCompatibilityInfo().isCompatible
return kotlinLibrary.compatibilityInfo.isCompatible
}
}

internal fun KotlinLibrary.createKlibPackageFragmentProvider(
storageManager: StorageManager,
metadataModuleDescriptorFactory: KlibMetadataModuleDescriptorFactory,
languageVersionSettings: LanguageVersionSettings,
moduleDescriptor: ModuleDescriptor,
lookupTracker: LookupTracker
): PackageFragmentProvider? {
if (!compatibilityInfo.isCompatible) return null

val packageFragmentNames = CachingIdeKlibMetadataLoader.loadModuleHeader(this).packageFragmentNameList

return metadataModuleDescriptorFactory.createPackageFragmentProvider(
library = this,
packageAccessHandler = CachingIdeKlibMetadataLoader,
packageFragmentNames = packageFragmentNames,
storageManager = storageManager,
moduleDescriptor = moduleDescriptor,
configuration = CompilerDeserializationConfiguration(languageVersionSettings),
compositePackageFragmentAddend = null,
lookupTracker = lookupTracker
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.idea.kdoc.findKDoc
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.BindingContext
Expand All @@ -20,11 +21,11 @@ internal class IdePluginKDocFinder(
) : KDocFinder {

override fun KtElement.findKDoc(): KDocTag? {
return this.findKDoc { DescriptorToSourceUtils.descriptorToDeclaration(it) }
return this.findKDoc { DescriptorToSourceUtils.descriptorToDeclaration(it) }?.contentTag
}

override fun DeclarationDescriptor.find(descriptorToPsi: (DeclarationDescriptorWithSource) -> PsiElement?): KDocTag? {
return this.findKDoc(descriptorToPsi)
return this.findKDoc(descriptorToPsi)?.contentTag
}

override fun resolveKDocLink(
Expand All @@ -42,7 +43,8 @@ internal class IdePluginKDocFinder(
resolutionFacade = facadeAnalysisContext.facade,
fromDescriptor = fromDescriptor,
fromSubjectOfTag = null,
qualifiedName = qualifiedName.split('.')
qualifiedName = qualifiedName.split('.'),
contextElement = fromDescriptor.findPsi()
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.

package org.jetbrains.kotlin.caches.resolve

import com.intellij.openapi.components.ComponentManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache

internal interface KotlinCacheService {
companion object {
inline fun <reified T : Any> ComponentManager.service(): T {
val serviceClass = T::class.java
return getService(serviceClass)
?: error("Cannot find service ${serviceClass.name} in $this (classloader=${serviceClass.classLoader}")
}

fun getInstance(project: Project): KotlinCacheService = project.service()
}

/**
* Provides resolution facade for [elements], guaranteeing that the resolution will be seen from the [platform]-perspective.
*
* This allows to get resolution for common sources in MPP from the perspective of given platform (with expects substituted to actuals,
* declarations resolved from platform-specific artifacts, ModuleDescriptors will contain only platform dependencies, etc.)
*
* It is equivalent to usual [getResolutionFacade]-overloads if platform(s) of module(s) containing [elements] are equal to [platform]
*
* Doesn't support scripts or any other 'special' files.
*/
fun getResolutionFacadeWithForcedPlatform(elements: List<KtElement>, platform: TargetPlatform): ResolutionFacade

fun getResolutionFacade(element: KtElement): ResolutionFacade
fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade
fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade?

fun getSuppressionCache(): KotlinSuppressCache
fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, platform: TargetPlatform): ResolutionFacade?

fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, settings: PlatformAnalysisSettings): ResolutionFacade?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/

package org.jetbrains.kotlin.caches.resolve

/**
* Regulates which sources should be analyzed together.
*
* There are exactly two descendants, which are in strong one-to-one correspondence with [ResolutionModeComponent.Mode] (meaning
* that after checking value of ResolutionMode, it's safe to downcast settings instance to the respective type):
* - [PlatformAnalysisSettingsImpl] should be used iff we're working under [Mode.SEPARATE], and will create separate
* facade for each platforms, sdk, builtIns settings and other stuff.
* This is the old and stable mode, which should be used by default.
*
* - [CompositeAnalysisSettings] should be used iff we're working under [Mode.COMPOSITE], and will analyze all sources
* together, in one facade.
* This mode is new and experimental, and works only together with TypeRefinement facilities in the compiler's frontend.
* This mode is currently enabled only for HMPP projects
*/
internal interface PlatformAnalysisSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.

package org.jetbrains.kotlin.idea.caches.resolve

import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException


internal fun KtElement.getResolutionFacade(): ResolutionFacade = KotlinCacheService.getInstance(project).getResolutionFacade(this)

/**
* This function first uses declaration resolvers to resolve this declaration and/or additional declarations (e.g. its parent),
* and then takes the relevant descriptor from binding context.
* The exact set of declarations to resolve depends on bodyResolveMode
*/
internal fun KtDeclaration.resolveToDescriptorIfAny(
resolutionFacade: ResolutionFacade,
bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL
): DeclarationDescriptor? {
//TODO: BodyResolveMode.PARTIAL is not quite safe!
val context = safeAnalyze(resolutionFacade, bodyResolveMode)
return if (this is KtParameter && hasValOrVar()) {
context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, this)
// It is incorrect to have `val/var` parameters outside the primary constructor (e.g., `fun foo(val x: Int)`)
// but we still want to try to resolve in such cases.
?: context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
} else {
context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
}
}

internal fun KtParameter.resolveToParameterDescriptorIfAny(bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL) =
resolveToParameterDescriptorIfAny(getResolutionFacade(), bodyResolveMode)

internal fun KtParameter.resolveToParameterDescriptorIfAny(
resolutionFacade: ResolutionFacade,
bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL
): ValueParameterDescriptor? {
val context = safeAnalyze(resolutionFacade, bodyResolveMode)
return context.get(BindingContext.VALUE_PARAMETER, this) as? ValueParameterDescriptor
}

internal fun KtDeclaration.resolveToDescriptorIfAny(
bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL
): DeclarationDescriptor? =
resolveToDescriptorIfAny(getResolutionFacade(), bodyResolveMode)

internal fun KtElement.analyze(
resolutionFacade: ResolutionFacade,
bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL
): BindingContext = resolutionFacade.analyze(this, bodyResolveMode)

internal fun KtElement.safeAnalyze(
resolutionFacade: ResolutionFacade,
bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL
): BindingContext = try {
analyze(resolutionFacade, bodyResolveMode)
} catch (e: Exception) {
e.returnIfNoDescriptorForDeclarationException { BindingContext.EMPTY }
}

internal inline fun <T> Exception.returnIfNoDescriptorForDeclarationException(
crossinline condition: (Boolean) -> Boolean = { v -> v },
crossinline computable: () -> T
): T =
if (condition(this.isItNoDescriptorForDeclarationException)) {
computable()
} else {
throw this
}

internal val Exception.isItNoDescriptorForDeclarationException: Boolean
get() = this is NoDescriptorForDeclarationException || (cause as? Exception)?.isItNoDescriptorForDeclarationException == true
Loading

0 comments on commit 298065f

Please sign in to comment.