All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.analysis.api.projectStructure.danglingFiles.kt Maven / Gradle / Ivy

/*
 * Copyright 2010-2024 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.analysis.api.projectStructure

import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.analysis.api.KaImplementationDetail
import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.kotlin.psi.analysisContext
import org.jetbrains.kotlin.psi.doNotAnalyze

/**
 * Specifies how references to non-local declarations in the dangling files should be resolved.
 */
public enum class KaDanglingFileResolutionMode {
    /** Resolve first to declarations in the dangling file, and delegate to the original file or module only when needed. */
    PREFER_SELF,

    /** * Resolve only to declarations in the original file or module. Ignore all non-local declarations in the dangling file copy. */
    IGNORE_SELF
}

@OptIn(KaImplementationDetail::class)
public val KtFile.isDangling: Boolean
    get() = when {
        this is KtCodeFragment -> true
        virtualFile?.analysisContextModule != null -> false
        !isPhysical -> true
        analysisContext != null -> true
        doNotAnalyze != null -> true
        else -> false
    }

/**
 * Returns the resolution mode that is explicitly set for this dangling file.
 * Returns `null` for files that are not dangling, or if the mode was not set.
 *
 * Use the `analyzeCopy {}` method for specifying the analysis mode. Note that the effect is thread-local; this is made on purpose, as
 * the file might potentially be resolved in parallel in different threads.
 *
 * Note that the resolution mode affects equality of [KaDanglingFileModule]. It means that for each resolution mode, a separate
 * resolution session will be created.
 */
public val KtFile.danglingFileResolutionMode: KaDanglingFileResolutionMode?
    get() = danglingFileResolutionModeState?.get()

/**
 * Runs the [action] with a resolution mode being explicitly set for the dangling [file].
 *
 * Avoid using this function in client-side code. Use `analyzeCopy {}` from Analysis API instead.
 */
@KaImplementationDetail
public fun  withDanglingFileResolutionMode(file: KtFile, mode: KaDanglingFileResolutionMode, action: () -> R): R {
    require(file.isDangling) { "'withDanglingFileResolutionMode()' is only available to dangling files" }
    require(file.originalFile != file) { "'withDanglingFileResolutionMode()' is only available to file copies" }

    val modeState = getOrCreateDanglingFileResolutionModeState(file)

    val oldValue = modeState.get()
    try {
        modeState.set(mode)
        return action()
    } finally {
        modeState.set(oldValue)
    }
}

private fun getOrCreateDanglingFileResolutionModeState(file: KtFile): ThreadLocal {
    synchronized(file) {
        val existingState = file.danglingFileResolutionModeState
        if (existingState != null) {
            return existingState
        }

        val newState = ThreadLocal()
        file.danglingFileResolutionModeState = newState
        return newState
    }
}

private var KtFile.danglingFileResolutionModeState: ThreadLocal?
        by UserDataProperty(Key.create("DANGLING_FILE_RESOLUTION_MODE"))




© 2015 - 2025 Weber Informatics LLC | Privacy Policy