jdemeulenaere
11/08/2019, 9:37 PMimport com.intellij.openapi.Disposable
import com.intellij.psi.PsiFileFactory
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.jvm.compiler.CliBindingTrace
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer
import org.jetbrains.kotlin.resolve.TopDownAnalysisMode
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import kotlin.reflect.jvm.internal.impl.storage.StorageManager
class Analyzer {
private val compilerConfiguration = CompilerConfiguration().apply {
put(CommonConfigurationKeys.MODULE_NAME, JvmProtoBufUtil.DEFAULT_MODULE_NAME)
put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, StdOutMessageCollector)
put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_1_8)
}
private val kotlinEnvironment = KotlinCoreEnvironment.createForProduction(
parentDisposable = Disposable { },
configuration = compilerConfiguration,
configFiles = EnvironmentConfigFiles.JVM_CONFIG_FILES
)
private val project = kotlinEnvironment.project
private val psiFactory = PsiFileFactory.getInstance(project)
fun analyzeCode(code: String): Pair<KtFile, BindingContext> {
val file = createKotlinFile(code)
return file to analyze(file)
}
private fun createKotlinFile(code: String): KtFile {
val file = psiFactory.createFileFromText("Dumb.kt", KotlinLanguage.INSTANCE, code, true, false)
return file as KtFile
}
private fun analyze(psiFile: KtFile): BindingContext {
val files = arrayListOf(psiFile)
val trace = CliBindingTrace()
val container = TopDownAnalyzerFacadeForJVM.createContainer(
project,
emptyList(),
trace,
kotlinEnvironment.configuration,
kotlinEnvironment::createPackagePartProvider,
{ storageManager, _ -> FileBasedDeclarationProviderFactory(storageManager, files) }
)
val analyzer = container.get<LazyTopDownAnalyzer>()
analyzer.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files)
return trace.bindingContext
}
}
tschuchort
11/09/2019, 12:34 AM