[Test] Move java generation utils to :compiler:tests-compiler-utils module

This commit is contained in:
Dmitriy Novozhilov
2020-12-23 11:22:19 +03:00
committed by TeamCityServer
parent cb7b1652e7
commit 8689fc43cd
15 changed files with 78 additions and 97 deletions
@@ -22,6 +22,7 @@ dependencies {
testCompile(project(":compiler:cli"))
testCompile(project(":compiler:cli-js"))
testCompile(project(":compiler:serialization"))
testCompile(project(":compiler:fir:entrypoint"))
testCompile(projectTests(":compiler:test-infrastructure-utils"))
testCompile(project(":kotlin-preloader"))
testCompileOnly(intellijCoreDep()) { includeJars("intellij-core") }
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2020 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
import java.io.PrintStream
import java.io.PrintWriter
enum class TestsExceptionType(val postfix: String) {
COMPILER_ERROR("compiler"),
COMPILETIME_ERROR("compiletime"),
RUNTIME_ERROR("runtime"),
INFRASTRUCTURE_ERROR("infrastructure");
companion object {
private val map = values().associateBy(TestsExceptionType::postfix)
fun fromValue(type: String) = map[type]
}
}
sealed class TestsError(val original: Throwable, val type: TestsExceptionType) : Error() {
override fun toString(): String = original.toString()
override fun getStackTrace(): Array<out StackTraceElement> = original.stackTrace
override fun initCause(cause: Throwable?): Throwable = original.initCause(cause)
override val cause: Throwable? get() = original.cause
// This function is called in the constructor of Throwable, where original is not yet initialized
override fun fillInStackTrace(): Throwable? = @Suppress("UNNECESSARY_SAFE_CALL") original?.fillInStackTrace()
override fun setStackTrace(stackTrace: Array<out StackTraceElement>?) {
original.stackTrace = stackTrace
}
override fun printStackTrace() = original.printStackTrace()
override fun printStackTrace(s: PrintStream?) = original.printStackTrace(s)
override fun printStackTrace(s: PrintWriter?) = original.printStackTrace(s)
}
class TestsCompilerError(original: Throwable) : TestsError(original, TestsExceptionType.COMPILER_ERROR)
class TestsInfrastructureError(original: Throwable) : TestsError(original, TestsExceptionType.INFRASTRUCTURE_ERROR)
class TestsCompiletimeError(original: Throwable) : TestsError(original, TestsExceptionType.COMPILETIME_ERROR)
class TestsRuntimeError(original: Throwable) : TestsError(original, TestsExceptionType.RUNTIME_ERROR)
@@ -0,0 +1,138 @@
/*
* Copyright 2010-2017 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.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiErrorElement;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.AnalyzingUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CodegenTestFiles {
@NotNull
private final List<KtFile> psiFiles;
@NotNull
private final List<Pair<String, String>> expectedValues;
@NotNull
private final List<Object> scriptParameterValues;
private CodegenTestFiles(
@NotNull List<KtFile> psiFiles,
@NotNull List<Pair<String, String>> expectedValues,
@NotNull List<Object> scriptParameterValues
) {
this.psiFiles = psiFiles;
this.expectedValues = expectedValues;
this.scriptParameterValues = scriptParameterValues;
}
@NotNull
public KtFile getPsiFile() {
assert psiFiles.size() == 1;
return psiFiles.get(0);
}
@NotNull
public List<Pair<String, String>> getExpectedValues() {
return expectedValues;
}
@NotNull
public List<Object> getScriptParameterValues() {
return scriptParameterValues;
}
@NotNull
public List<KtFile> getPsiFiles() {
return psiFiles;
}
@NotNull
public static CodegenTestFiles create(@NotNull List<KtFile> ktFiles) {
assert !ktFiles.isEmpty() : "List should have at least one file";
return new CodegenTestFiles(ktFiles, Collections.emptyList(), Collections.emptyList());
}
public static CodegenTestFiles create(Project project, String[] names) {
return create(project, names, KtTestUtil.getTestDataPathBase());
}
public static CodegenTestFiles create(Project project, String[] names, String testDataPath) {
List<KtFile> files = new ArrayList<>(names.length);
for (String name : names) {
try {
String content = KtTestUtil.doLoadFile(testDataPath + "/codegen/", name);
KtFile file = KtTestUtil.createFile(name, content, project);
files.add(file);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
return create(files);
}
@NotNull
public static CodegenTestFiles create(@NotNull String fileName, @NotNull String contentWithDiagnosticMarkup, @NotNull Project project) {
// `rangesToDiagnosticNames` parameter is not-null only for diagnostic tests, it's using for lazy diagnostics
String content = CheckerTestUtil.INSTANCE.parseDiagnosedRanges(contentWithDiagnosticMarkup, new ArrayList<>(), null);
KtFile file = KtTestUtil.createFile(fileName, content, project);
List<PsiErrorElement> ranges = AnalyzingUtils.getSyntaxErrorRanges(file);
assert ranges.isEmpty() : "Syntax errors found in " + file + ": " + ranges;
List<Pair<String, String>> expectedValues = Lists.newArrayList();
Matcher matcher = Pattern.compile("// expected: (\\S+): (.*)").matcher(content);
while (matcher.find()) {
String fieldName = matcher.group(1);
String expectedValue = matcher.group(2);
expectedValues.add(Pair.create(fieldName, expectedValue));
}
List<Object> scriptParameterValues = Lists.newArrayList();
if (file.isScript()) {
Pattern scriptParametersPattern = Pattern.compile("param: (\\S.*)");
Matcher scriptParametersMatcher = scriptParametersPattern.matcher(file.getText());
if (scriptParametersMatcher.find()) {
String valueString = scriptParametersMatcher.group(1);
String[] values = valueString.split(" ");
scriptParameterValues.add(values);
}
else {
scriptParameterValues.add(ArrayUtil.EMPTY_STRING_ARRAY);
}
}
return new CodegenTestFiles(Collections.singletonList(file), expectedValues, scriptParameterValues);
}
}
@@ -0,0 +1,168 @@
/*
* Copyright 2010-2020 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.codegen;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.util.io.FileUtil;
import kotlin.collections.CollectionsKt;
import kotlin.io.FilesKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
import org.jetbrains.kotlin.test.Assertions;
import org.jetbrains.kotlin.test.JvmCompilationUtils;
import org.jetbrains.kotlin.test.KtAssert;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
import org.jetbrains.kotlin.utils.StringsKt;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CodegenTestUtil {
private CodegenTestUtil() {
}
@NotNull
public static ClassFileFactory generateFiles(@NotNull KotlinCoreEnvironment environment, @NotNull CodegenTestFiles files) {
return GenerationUtils.compileFiles(files.getPsiFiles(), environment).getFactory();
}
public static void assertThrows(
@NotNull Method foo, @NotNull Class<? extends Throwable> exceptionClass, @Nullable Object instance, @NotNull Object... args
) throws IllegalAccessException {
boolean caught = false;
try {
foo.invoke(instance, args);
}
catch (InvocationTargetException ex) {
caught = exceptionClass.isInstance(ex.getTargetException());
}
KtAssert.assertTrue(String.format("Exception of class %s must be thrown", exceptionClass.getName()), caught);
}
@NotNull
public static Method findDeclaredMethodByName(@NotNull Class<?> aClass, @NotNull String name) {
Method result = findDeclaredMethodByNameOrNull(aClass, name);
if (result == null) {
throw new AssertionError("Method " + name + " is not found in " + aClass);
}
return result;
}
public static Method findDeclaredMethodByNameOrNull(@NotNull Class<?> aClass, @NotNull String name) {
for (Method method : aClass.getDeclaredMethods()) {
if (method.getName().equals(name)) {
return method;
}
}
return null;
}
@NotNull
public static File compileJava(
@NotNull List<String> fileNames,
@NotNull List<String> additionalClasspath,
@NotNull List<String> additionalOptions,
@NotNull Assertions assertions
) {
try {
File directory = KtTestUtil.tmpDir("java-classes");
compileJava(fileNames, additionalClasspath, additionalOptions, directory, assertions);
return directory;
}
catch (IOException e) {
throw ExceptionUtilsKt.rethrow(e);
}
}
public static void compileJava(
@NotNull List<String> fileNames,
@NotNull List<String> additionalClasspath,
@NotNull List<String> additionalOptions,
@NotNull File outDirectory,
@NotNull Assertions assertions
) {
try {
List<String> options = prepareJavacOptions(additionalClasspath, additionalOptions, outDirectory);
JvmCompilationUtils.compileJavaFiles(CollectionsKt.map(fileNames, File::new), options, assertions);
}
catch (IOException e) {
throw ExceptionUtilsKt.rethrow(e);
}
}
@NotNull
public static List<String> prepareJavacOptions(
@NotNull List<String> additionalClasspath,
@NotNull List<String> additionalOptions,
@NotNull File outDirectory
) {
List<String> classpath = new ArrayList<>();
classpath.add(ForTestCompileRuntime.runtimeJarForTests().getPath());
classpath.add(ForTestCompileRuntime.reflectJarForTests().getPath());
classpath.add(KtTestUtil.getAnnotationsJar().getPath());
classpath.addAll(additionalClasspath);
List<String> options = new ArrayList<>(Arrays.asList(
"-classpath", StringsKt.join(classpath, File.pathSeparator),
"-d", outDirectory.getPath()
));
options.addAll(additionalOptions);
return options;
}
@NotNull
public static Method findTheOnlyMethod(@NotNull Class<?> aClass) {
Method r = null;
for (Method method : aClass.getMethods()) {
if (method.getDeclaringClass().equals(Object.class)) {
continue;
}
if (r != null) {
throw new AssertionError("More than one public method in class " + aClass);
}
r = method;
}
if (r == null) {
throw new AssertionError("No public methods in class " + aClass);
}
return r;
}
@Nullable
public static Object getAnnotationAttribute(@NotNull Object annotation, @NotNull String name) {
try {
return annotation.getClass().getMethod(name).invoke(annotation);
}
catch (Exception e) {
throw ExceptionUtilsKt.rethrow(e);
}
}
@NotNull
public static List<String> findJavaSourcesInDirectory(@NotNull File directory) {
List<String> javaFilePaths = new ArrayList<>(1);
FileUtil.processFilesRecursively(directory, file -> {
if (file.isFile() && FilesKt.getExtension(file).equals(JavaFileType.DEFAULT_EXTENSION)) {
javaFilePaths.add(file.getPath());
}
return true;
});
return javaFilePaths;
}
}
@@ -0,0 +1,189 @@
/*
* Copyright 2010-2020 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.codegen
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectScope
import org.jetbrains.kotlin.TestsCompiletimeError
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.backend.jvm.jvmPhases
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.output.writeAllTo
import org.jetbrains.kotlin.cli.js.messageCollectorLogger
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.createSession
import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import org.jetbrains.kotlin.util.DummyLogger
import java.io.File
object GenerationUtils {
@JvmStatic
fun compileFileTo(ktFile: KtFile, environment: KotlinCoreEnvironment, output: File): ClassFileFactory =
compileFilesTo(listOf(ktFile), environment, output)
@JvmStatic
fun compileFilesTo(files: List<KtFile>, environment: KotlinCoreEnvironment, output: File): ClassFileFactory =
compileFiles(files, environment).factory.apply {
writeAllTo(output)
}
@JvmStatic
@JvmOverloads
fun compileFiles(
files: List<KtFile>,
environment: KotlinCoreEnvironment,
classBuilderFactory: ClassBuilderFactory = ClassBuilderFactories.TEST,
trace: BindingTrace = NoScopeRecordCliBindingTrace()
): GenerationState =
compileFiles(files, environment.configuration, classBuilderFactory, environment::createPackagePartProvider, trace)
@JvmStatic
@JvmOverloads
fun compileFiles(
files: List<KtFile>,
configuration: CompilerConfiguration,
classBuilderFactory: ClassBuilderFactory,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
trace: BindingTrace = NoScopeRecordCliBindingTrace()
): GenerationState {
val project = files.first().project
val state = if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR)) {
compileFilesUsingFrontendIR(project, files, configuration, classBuilderFactory, packagePartProvider, trace)
} else {
compileFilesUsingStandardMode(project, files, configuration, classBuilderFactory, packagePartProvider, trace)
}
// For JVM-specific errors
try {
AnalyzingUtils.throwExceptionOnErrors(state.collectedExtraJvmDiagnostics)
} catch (e: Throwable) {
throw TestsCompiletimeError(e)
}
return state
}
private fun compileFilesUsingFrontendIR(
project: Project,
files: List<KtFile>,
configuration: CompilerConfiguration,
classBuilderFactory: ClassBuilderFactory,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
trace: BindingTrace
): GenerationState {
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
val scope = GlobalSearchScope.filesScope(project, files.map { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
val librariesScope = ProjectScope.getLibrariesScope(project)
val session = createSession(project, scope, librariesScope, "main", packagePartProvider)
// TODO: add running checkers and check that it's safe to compile
val firAnalyzerFacade = FirAnalyzerFacade(session, configuration.languageVersionSettings, files)
val extensions = JvmGeneratorExtensions()
val (moduleFragment, symbolTable, sourceManager, components) = firAnalyzerFacade.convertToIr(extensions)
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val codegenFactory = JvmIrCodegenFactory(configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
// Create and initialize the test module and its dependencies
val container = TopDownAnalyzerFacadeForJVM.createContainer(
project, files, trace, configuration, packagePartProvider, ::FileBasedDeclarationProviderFactory, CompilerEnvironment,
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, files), emptyList()
)
val generationState = GenerationState.Builder(
project, classBuilderFactory, container.get<ModuleDescriptor>(), dummyBindingContext, files, configuration
).codegenFactory(
codegenFactory
).isIrBackend(
true
).jvmBackendClassResolver(
FirJvmBackendClassResolver(components)
).build()
generationState.beforeCompile()
codegenFactory.generateModuleInFrontendIRMode(
generationState, moduleFragment, symbolTable, sourceManager, extensions, FirJvmBackendExtension(session, components),
)
generationState.factory.done()
return generationState
}
private fun compileFilesUsingStandardMode(
project: Project,
files: List<KtFile>,
configuration: CompilerConfiguration,
classBuilderFactory: ClassBuilderFactory,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
trace: BindingTrace
): GenerationState {
val logger = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)?.let { messageCollectorLogger(it) }
?: DummyLogger
val resolvedKlibs = configuration.get(JVMConfigurationKeys.KLIB_PATHS)?.let { klibPaths ->
jvmResolveLibraries(klibPaths, logger)
}
val analysisResult =
JvmResolveUtil.analyzeAndCheckForErrors(
project, files, configuration, packagePartProvider, trace,
klibList = resolvedKlibs?.getFullList() ?: emptyList()
)
analysisResult.throwIfError()
return generateFiles(project, files, configuration, classBuilderFactory, analysisResult)
}
fun generateFiles(
project: Project,
files: List<KtFile>,
configuration: CompilerConfiguration,
classBuilderFactory: ClassBuilderFactory,
analysisResult: AnalysisResult,
configureGenerationState: GenerationState.Builder.() -> Unit = {},
): GenerationState {
/* Currently Kapt3 only works with the old JVM backend, so disable IR for everything except actual bytecode generation. */
val isIrBackend =
classBuilderFactory.classBuilderMode == ClassBuilderMode.FULL && configuration.getBoolean(JVMConfigurationKeys.IR)
val generationState = GenerationState.Builder(
project, classBuilderFactory, analysisResult.moduleDescriptor, analysisResult.bindingContext,
files, configuration
).codegenFactory(
if (isIrBackend)
JvmIrCodegenFactory(configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
else DefaultCodegenFactory
).isIrBackend(isIrBackend).apply(configureGenerationState).build()
if (analysisResult.shouldGenerateCode) {
KotlinCodegenFacade.compileCorrectFiles(generationState)
}
return generationState
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2018 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.fir
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
class FirTestModuleInfo(
override val name: Name = Name.identifier("TestModule"),
val dependencies: MutableList<ModuleInfo> = mutableListOf(),
override val platform: TargetPlatform = JvmPlatforms.unspecifiedJvmPlatform,
override val analyzerServices: PlatformDependentAnalyzerServices = JvmPlatformAnalyzerServices
) : ModuleInfo {
override fun dependencies(): List<ModuleInfo> = dependencies
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2019 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.fir
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.name.Name
fun createSession(
environment: KotlinCoreEnvironment,
sourceScope: GlobalSearchScope,
librariesScope: GlobalSearchScope = GlobalSearchScope.notScope(sourceScope),
moduleName: String = "TestModule"
): FirSession = createSession(environment.project, sourceScope, librariesScope, moduleName, environment::createPackagePartProvider)
fun createSession(
project: Project,
sourceScope: GlobalSearchScope,
librariesScope: GlobalSearchScope,
moduleName: String = "TestModule",
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider
): FirSession {
val moduleInfo = FirTestModuleInfo(name = Name.identifier(moduleName))
val provider = FirProjectSessionProvider()
return FirSessionFactory.createJavaModuleBasedSession(moduleInfo, provider, sourceScope, project).also {
createSessionForDependencies(project, provider, moduleInfo, librariesScope, packagePartProvider)
}
}
private fun createSessionForDependencies(
project: Project,
provider: FirProjectSessionProvider,
moduleInfo: FirTestModuleInfo,
librariesScope: GlobalSearchScope,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider
) {
val dependenciesInfo = FirTestModuleInfo(name = Name.identifier(moduleInfo.name.identifier + ".dependencies"))
moduleInfo.dependencies.add(dependenciesInfo)
FirSessionFactory.createLibrarySession(
dependenciesInfo, provider, librariesScope, project, packagePartProvider(librariesScope)
)
}
@@ -0,0 +1,104 @@
/*
* Copyright 2010-2020 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.resolve.lazy
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.TestsCompiletimeError
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.cli.jvm.compiler.CliBindingTrace
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.container.ComponentProvider
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
object JvmResolveUtil {
@JvmStatic
@JvmOverloads
fun createContainer(
environment: KotlinCoreEnvironment,
files: Collection<KtFile> = emptyList(),
targetEnvironment: TargetEnvironment = CompilerEnvironment
): ComponentProvider =
TopDownAnalyzerFacadeForJVM.createContainer(
environment.project, files, NoScopeRecordCliBindingTrace(),
environment.configuration, { PackagePartProvider.Empty }, ::FileBasedDeclarationProviderFactory,
targetEnvironment
)
@JvmStatic
fun analyzeAndCheckForErrors(file: KtFile, environment: KotlinCoreEnvironment): AnalysisResult =
analyzeAndCheckForErrors(setOf(file), environment)
@JvmStatic
fun analyzeAndCheckForErrors(files: Collection<KtFile>, environment: KotlinCoreEnvironment): AnalysisResult =
analyzeAndCheckForErrors(environment.project, files, environment.configuration, environment::createPackagePartProvider)
@JvmStatic
fun analyzeAndCheckForErrors(
project: Project,
files: Collection<KtFile>,
configuration: CompilerConfiguration,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
trace: BindingTrace = CliBindingTrace(),
klibList: List<KotlinLibrary> = emptyList()
): AnalysisResult {
for (file in files) {
try {
AnalyzingUtils.checkForSyntacticErrors(file)
} catch (e: Exception) {
throw TestsCompiletimeError(e)
}
}
return analyze(project, files, configuration, packagePartProvider, trace, klibList).apply {
try {
AnalyzingUtils.throwExceptionOnErrors(bindingContext)
} catch (e: Exception) {
throw TestsCompiletimeError(e)
}
}
}
@JvmStatic
fun analyze(environment: KotlinCoreEnvironment): AnalysisResult =
analyze(emptySet(), environment)
@JvmStatic
fun analyze(file: KtFile, environment: KotlinCoreEnvironment): AnalysisResult =
analyze(setOf(file), environment)
@JvmStatic
fun analyze(files: Collection<KtFile>, environment: KotlinCoreEnvironment): AnalysisResult =
analyze(files, environment, environment.configuration)
@JvmStatic
fun analyze(files: Collection<KtFile>, environment: KotlinCoreEnvironment, configuration: CompilerConfiguration): AnalysisResult =
analyze(environment.project, files, configuration, environment::createPackagePartProvider)
private fun analyze(
project: Project,
files: Collection<KtFile>,
configuration: CompilerConfiguration,
packagePartProviderFactory: (GlobalSearchScope) -> PackagePartProvider,
trace: BindingTrace = CliBindingTrace(),
klibList: List<KotlinLibrary> = emptyList()
): AnalysisResult {
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
project, files, trace, configuration, packagePartProviderFactory,
klibList = klibList
)
}
}