999e4cda1d
Previously we traversed all notLoadedRoots on each request for package parts with the given package FQ name. Since notLoadedRoots might contain a lot of roots (which never transition into "loadedModules" because e.g. they are not Kotlin libraries, but just Java libraries or SDK roots with the META-INF directory), this was potentially hurting performance. It seems it's more optimal to compute everything eagerly once JvmPackagePartProvider is constructed. Another problem with the previous version of JvmPackagePartProvider was that it did not support "updateable classpath" which is used by REPL and kapt2, it only used the initial roots provided in the CompilerConfiguration. In REPL specifically, we would thus fail to resolve top-level callables from libraries which were dynamically added to the execution classpath (via some kind of a @DependsOn annotation). In the new code, JvmPackagePartProvider no longer depends on CompilerConfiguration to avoid this sort of confusion, but rather relies on the object that constructed it (KotlinCoreEnvironment in this case) to provide the correct roots. This is also beneficial because the computation of actual VirtualFile-based roots from the ones in the CompilerConfiguration might get trickier with modular Java 9 roots
76 lines
3.1 KiB
Kotlin
76 lines
3.1 KiB
Kotlin
/*
|
|
* Copyright 2010-2015 JetBrains s.r.o.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package org.jetbrains.kotlin.codegen
|
|
|
|
import com.intellij.psi.search.GlobalSearchScope
|
|
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
|
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAllTo
|
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
|
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
|
import org.jetbrains.kotlin.psi.KtFile
|
|
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
|
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
|
import java.io.File
|
|
|
|
object GenerationUtils {
|
|
@JvmStatic
|
|
fun compileFileTo(ktFile: KtFile, environment: KotlinCoreEnvironment, output: File): ClassFileFactory =
|
|
compileFile(ktFile, environment).apply {
|
|
writeAllTo(output)
|
|
}
|
|
|
|
@JvmStatic
|
|
fun compileFile(ktFile: KtFile, environment: KotlinCoreEnvironment): ClassFileFactory =
|
|
compileFiles(listOf(ktFile), environment).factory
|
|
|
|
@JvmStatic
|
|
@JvmOverloads
|
|
fun compileFiles(
|
|
files: List<KtFile>,
|
|
environment: KotlinCoreEnvironment,
|
|
classBuilderFactory: ClassBuilderFactory = ClassBuilderFactories.TEST
|
|
): GenerationState =
|
|
compileFiles(files, environment.configuration, classBuilderFactory, environment::createPackagePartProvider)
|
|
|
|
@JvmStatic
|
|
fun compileFiles(
|
|
files: List<KtFile>,
|
|
configuration: CompilerConfiguration,
|
|
classBuilderFactory: ClassBuilderFactory,
|
|
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider
|
|
): GenerationState {
|
|
val analysisResult = JvmResolveUtil.analyzeAndCheckForErrors(files.first().project, files, configuration, packagePartProvider)
|
|
analysisResult.throwIfError()
|
|
|
|
val state = GenerationState(
|
|
files.first().project, classBuilderFactory, analysisResult.moduleDescriptor, analysisResult.bindingContext,
|
|
files, configuration,
|
|
codegenFactory = if (configuration.getBoolean(JVMConfigurationKeys.IR)) JvmIrCodegenFactory else DefaultCodegenFactory
|
|
)
|
|
if (analysisResult.shouldGenerateCode) {
|
|
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION)
|
|
}
|
|
|
|
// For JVM-specific errors
|
|
AnalyzingUtils.throwExceptionOnErrors(state.collectedExtraJvmDiagnostics)
|
|
return state
|
|
}
|
|
}
|