[Analysis API] Add IGNORE_SELF dangling file resolution mode
In the 'IGNORE_SELF' mode, dangling files don't have their own declarations in providers. As a result, all references there resolve to declarations of the original file. It is conceptually similar to that we had in on-air resolve, however, now it's possible to work with the whole content of the in-memory 'FirFile'. As it can be seen in 'ProjectStructureProvider.kt' (KtFile.danglingFileResolutionMode), the 'IGNORE_SELF' mode is automatically applied for non-physical files with an original file being set. For other scenarios, now there is a new 'analyzeCopy()' function that allows to pass the analysis mode explicitly.
This commit is contained in:
@@ -106,6 +106,7 @@ public abstract class KtAnalysisSession(final override val token: KtLifetimeToke
|
||||
*
|
||||
* @see analyzeInDependedAnalysisSession
|
||||
*/
|
||||
@Deprecated("On-air analysis is obsolete. Use 'analyzeCopy()' instead")
|
||||
public abstract fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession
|
||||
|
||||
internal val smartCastProvider: KtSmartCastProvider get() = smartCastProviderImpl
|
||||
|
||||
@@ -7,9 +7,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenFactory
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleStructureInternals
|
||||
import org.jetbrains.kotlin.analysis.project.structure.withDanglingFileResolutionMode
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
@@ -51,10 +54,41 @@ public inline fun <R> analyze(
|
||||
*
|
||||
* @see KtAnalysisSession.createContextDependentCopy
|
||||
*/
|
||||
@Deprecated(
|
||||
"On-air analysis is obsolete. Use 'analyzeCopy()' instead",
|
||||
ReplaceWith(
|
||||
"analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE.SELF)",
|
||||
imports = [
|
||||
"org.jetbrains.kotlin.analysis.api.analyzeCopy",
|
||||
"org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode"
|
||||
]
|
||||
)
|
||||
)
|
||||
public inline fun <R> analyzeInDependedAnalysisSession(
|
||||
originalFile: KtFile,
|
||||
@Suppress("unused", "UNUSED_PARAMETER") originalFile: KtFile,
|
||||
elementToReanalyze: KtElement,
|
||||
action: KtAnalysisSession.() -> R
|
||||
): R =
|
||||
KtAnalysisSessionProvider.getInstance(originalFile.project)
|
||||
.analyseInDependedAnalysisSession(originalFile, elementToReanalyze, action)
|
||||
crossinline action: KtAnalysisSession.() -> R
|
||||
): R {
|
||||
return analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE_SELF, action)
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given [action] in a [KtAnalysisSession] context.
|
||||
* Depending on the passed [resolutionMode], declarations inside a file copy will be treated in a specific way.
|
||||
*
|
||||
* Note that the [useSiteKtElement] must be inside a dangling file copy.
|
||||
* Specifically, [PsiFile.getOriginalFile] must point to the copy source.
|
||||
*
|
||||
* The project will be analyzed from the perspective of [useSiteKtElement]'s module, also called the use-site module.
|
||||
*/
|
||||
@OptIn(KtModuleStructureInternals::class)
|
||||
public inline fun <R> analyzeCopy(
|
||||
useSiteKtElement: KtElement,
|
||||
resolutionMode: DanglingFileResolutionMode,
|
||||
crossinline action: KtAnalysisSession.() -> R,
|
||||
): R {
|
||||
val containingFile = useSiteKtElement.containingKtFile
|
||||
return withDanglingFileResolutionMode(containingFile, resolutionMode) {
|
||||
analyze(containingFile, action)
|
||||
}
|
||||
}
|
||||
+17
-8
@@ -10,9 +10,11 @@ import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
||||
import org.jetbrains.kotlin.analysis.api.analyzeCopy
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.impl.NoWriteActionInAnalyseCallChecker
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenFactory
|
||||
import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -20,8 +22,8 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
/**
|
||||
* Provides [KtAnalysisSession]s by use-site [KtElement]s or [KtModule]s.
|
||||
*
|
||||
* This provider should not be used directly. Please use [analyze][org.jetbrains.kotlin.analysis.api.analyze] or
|
||||
* [analyzeInDependedAnalysisSession][org.jetbrains.kotlin.analysis.api.analyzeInDependedAnalysisSession] instead.
|
||||
* This provider should not be used directly.
|
||||
* Please use [analyze][org.jetbrains.kotlin.analysis.api.analyze] or [analyzeCopy][org.jetbrains.kotlin.analysis.api.analyzeCopy] instead.
|
||||
*/
|
||||
@OptIn(KtAnalysisApiInternals::class)
|
||||
public abstract class KtAnalysisSessionProvider(public val project: Project) : Disposable {
|
||||
@@ -37,15 +39,22 @@ public abstract class KtAnalysisSessionProvider(public val project: Project) : D
|
||||
|
||||
public abstract fun getAnalysisSessionByUseSiteKtModule(useSiteKtModule: KtModule): KtAnalysisSession
|
||||
|
||||
@Deprecated(
|
||||
"On-air analysis is obsolete. Use 'analyzeCopy()' instead",
|
||||
replaceWith = ReplaceWith(
|
||||
"analyzeCopy(elementToReanalyze, DanglingFileAnalysisMode.IGNORE_SELF, action)",
|
||||
imports = [
|
||||
"org.jetbrains.kotlin.analysis.api.analyzeCopy",
|
||||
"org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode"
|
||||
]
|
||||
)
|
||||
)
|
||||
public inline fun <R> analyseInDependedAnalysisSession(
|
||||
originalFile: KtFile,
|
||||
@Suppress("unused", "UNUSED_PARAMETER") originalFile: KtFile,
|
||||
elementToReanalyze: KtElement,
|
||||
action: KtAnalysisSession.() -> R,
|
||||
crossinline action: KtAnalysisSession.() -> R,
|
||||
): R {
|
||||
val originalAnalysisSession = getAnalysisSession(originalFile)
|
||||
val dependedAnalysisSession = originalAnalysisSession
|
||||
.createContextDependentCopy(originalFile, elementToReanalyze)
|
||||
return analyse(dependedAnalysisSession, action)
|
||||
return analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE_SELF, action)
|
||||
}
|
||||
|
||||
public inline fun <R> analyse(
|
||||
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
class Foo<Value> {
|
||||
fun foo() {
|
||||
call<V<caret>alue>()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> call(): T? {
|
||||
return null
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: Value [classTypeParameter.kt]
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
companion object
|
||||
}
|
||||
|
||||
fun test() {
|
||||
consume(F<caret>oo)
|
||||
}
|
||||
|
||||
private fun consume(obj: Any) {}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) companion object [companionObject.kt]
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
fun <Value> foo() {
|
||||
call<V<caret>alue>()
|
||||
}
|
||||
|
||||
fun <T> call(): T? {
|
||||
return null
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: Value [fake.kt]
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
private fun foo() {
|
||||
class Local {
|
||||
fun call() {}
|
||||
}
|
||||
|
||||
Lo<caret>cal().call()
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in <local>: Foo.foo.Local) constructor() [fake.kt]
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class Foo {
|
||||
private fun foo() {
|
||||
val name = "Foo"
|
||||
nam<caret>e.length
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in <local>: Foo.foo) val name: kotlin.String [fake.kt]
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
class Outer {
|
||||
val foo: String = "foo"
|
||||
|
||||
inner class Inner {
|
||||
fun test() {
|
||||
f<caret>oo
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Outer) val foo: kotlin.String [outerClassProperty.kt]
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Foo(name: String) {
|
||||
private val userName: String
|
||||
|
||||
init {
|
||||
userName = n<caret>ame
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: name: kotlin.String [primaryConstructorParameter.kt]
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
private class Bar {
|
||||
fun call() {}
|
||||
}
|
||||
|
||||
private fun foo() {
|
||||
B<caret>ar().call()
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo.Bar) constructor() [privateClass.kt]
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Foo() {
|
||||
private fun call() {}
|
||||
|
||||
private fun foo() {
|
||||
c<caret>all()
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) private fun call() [privateFunction.kt]
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Foo(private val name: String) {
|
||||
private fun foo() {
|
||||
nam<caret>e.length
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) private val name: kotlin.String [privateProperty.kt]
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Foo() {
|
||||
fun call() {}
|
||||
|
||||
private fun foo() {
|
||||
c<caret>all()
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) fun call() [publicFunction.kt]
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Foo(val name: String) {
|
||||
private fun foo() {
|
||||
nam<caret>e.length
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) val name: kotlin.String [publicProperty.kt]
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
var x: Int = 0
|
||||
get() = f<caret>ield + 1
|
||||
set(value) { field = value - 1 }
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in <local>: x) field
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
fun foo() {
|
||||
c<caret>all()
|
||||
}
|
||||
|
||||
fun call() {}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in ROOT) fun call() [topLevelFunction.kt]
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(abc: Int) {
|
||||
a<caret>bc
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: abc: kotlin.Int [fake.kt]
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
class Foo<Value> {
|
||||
fun foo() {
|
||||
call<V<caret>alue>()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> call(): T? {
|
||||
return null
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: Value [fake.kt]
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
companion object
|
||||
}
|
||||
|
||||
fun test() {
|
||||
consume(F<caret>oo)
|
||||
}
|
||||
|
||||
private fun consume(obj: Any) {}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) companion object [fake.kt]
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
fun <Value> foo() {
|
||||
call<V<caret>alue>()
|
||||
}
|
||||
|
||||
fun <T> call(): T? {
|
||||
return null
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: Value [fake.kt]
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
private fun foo() {
|
||||
class Local {
|
||||
fun call() {}
|
||||
}
|
||||
|
||||
Lo<caret>cal().call()
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in <local>: Foo.foo.Local) constructor() [fake.kt]
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class Foo {
|
||||
private fun foo() {
|
||||
val name = "Foo"
|
||||
nam<caret>e.length
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in <local>: Foo.foo) val name: kotlin.String [fake.kt]
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
class Outer {
|
||||
val foo: String = "foo"
|
||||
|
||||
inner class Inner {
|
||||
fun test() {
|
||||
f<caret>oo
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Outer) val foo: kotlin.String [fake.kt]
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Foo(name: String) {
|
||||
private val userName: String
|
||||
|
||||
init {
|
||||
userName = n<caret>ame
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: name: kotlin.String [fake.kt]
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
private class Bar {
|
||||
fun call() {}
|
||||
}
|
||||
|
||||
private fun foo() {
|
||||
B<caret>ar().call()
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo.Bar) constructor() [fake.kt]
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Foo() {
|
||||
private fun call() {}
|
||||
|
||||
private fun foo() {
|
||||
c<caret>all()
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) private fun call() [fake.kt]
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Foo(private val name: String) {
|
||||
private fun foo() {
|
||||
nam<caret>e.length
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) private val name: kotlin.String [fake.kt]
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Foo() {
|
||||
fun call() {}
|
||||
|
||||
private fun foo() {
|
||||
c<caret>all()
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) fun call() [fake.kt]
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Foo(val name: String) {
|
||||
private fun foo() {
|
||||
nam<caret>e.length
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in Foo) val name: kotlin.String [fake.kt]
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
var x: Int = 0
|
||||
get() = f<caret>ield + 1
|
||||
set(value) { field = value - 1 }
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in <local>: x) field
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
fun foo() {
|
||||
c<caret>all()
|
||||
}
|
||||
|
||||
fun call() {}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: (in ROOT) fun call() [fake.kt]
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(abc: Int) {
|
||||
a<caret>bc
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
0: abc: kotlin.Int [fake.kt]
|
||||
Reference in New Issue
Block a user