Reformat module 'cli', fix warnings/inspections
This commit is contained in:
@@ -17,15 +17,17 @@
|
|||||||
package org.jetbrains.kotlin.cli.common
|
package org.jetbrains.kotlin.cli.common
|
||||||
|
|
||||||
import org.fusesource.jansi.AnsiConsole
|
import org.fusesource.jansi.AnsiConsole
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.*
|
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.ManualLanguageFeatureSetting
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.validateArguments
|
||||||
import org.jetbrains.kotlin.cli.common.messages.*
|
import org.jetbrains.kotlin.cli.common.messages.*
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentException
|
import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentException
|
||||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature.Kind.BUG_FIX
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature.Kind.*
|
import org.jetbrains.kotlin.config.LanguageFeature.State.ENABLED
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature.State.*
|
|
||||||
import org.jetbrains.kotlin.config.Services
|
import org.jetbrains.kotlin.config.Services
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
@@ -196,13 +198,11 @@ abstract class CLITool<A : CommonToolArguments> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun doMainNoExit(compiler: CLITool<*>, args: Array<String>): ExitCode {
|
fun doMainNoExit(compiler: CLITool<*>, args: Array<String>): ExitCode = try {
|
||||||
try {
|
compiler.exec(System.err, *args)
|
||||||
return compiler.exec(System.err, *args)
|
} catch (e: CompileEnvironmentException) {
|
||||||
} catch (e: CompileEnvironmentException) {
|
System.err.println(e.message)
|
||||||
System.err.println(e.message)
|
ExitCode.INTERNAL_ERROR
|
||||||
return ExitCode.INTERNAL_ERROR
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import java.lang.management.ManagementFactory
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
abstract class CommonCompilerPerformanceManager(private val presentableName: String) {
|
abstract class CommonCompilerPerformanceManager(private val presentableName: String) {
|
||||||
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
protected val measurements: MutableList<PerformanceMeasurement> = mutableListOf()
|
protected val measurements: MutableList<PerformanceMeasurement> = mutableListOf()
|
||||||
protected var isEnabled: Boolean = false
|
protected var isEnabled: Boolean = false
|
||||||
private var initStartNanos = PerformanceCounter.currentTime()
|
private var initStartNanos = PerformanceCounter.currentTime()
|
||||||
|
|||||||
+34
-25
@@ -50,13 +50,19 @@ class AnalyzerWithCompilerReport(
|
|||||||
val bindingContext = analysisResult.bindingContext
|
val bindingContext = analysisResult.bindingContext
|
||||||
val classes = bindingContext.getKeys(TraceBasedErrorReporter.INCOMPLETE_HIERARCHY)
|
val classes = bindingContext.getKeys(TraceBasedErrorReporter.INCOMPLETE_HIERARCHY)
|
||||||
if (!classes.isEmpty()) {
|
if (!classes.isEmpty()) {
|
||||||
val message = StringBuilder("Supertypes of the following classes cannot be resolved. " +
|
val message = StringBuilder(
|
||||||
"Please make sure you have the required dependencies in the classpath:\n")
|
"Supertypes of the following classes cannot be resolved. " +
|
||||||
|
"Please make sure you have the required dependencies in the classpath:\n"
|
||||||
|
)
|
||||||
for (descriptor in classes) {
|
for (descriptor in classes) {
|
||||||
val fqName = DescriptorUtils.getFqName(descriptor).asString()
|
val fqName = DescriptorUtils.getFqName(descriptor).asString()
|
||||||
val unresolved = bindingContext.get(TraceBasedErrorReporter.INCOMPLETE_HIERARCHY, descriptor)
|
val unresolved = bindingContext.get(TraceBasedErrorReporter.INCOMPLETE_HIERARCHY, descriptor)
|
||||||
assert(unresolved != null && !unresolved.isEmpty()) { "Incomplete hierarchy should be reported with names of unresolved superclasses: " + fqName }
|
assert(unresolved != null && !unresolved.isEmpty()) {
|
||||||
message.append(" class ").append(fqName).append(", unresolved supertypes: ").append(unresolved!!.joinToString()).append("\n")
|
"Incomplete hierarchy should be reported with names of unresolved superclasses: $fqName"
|
||||||
|
}
|
||||||
|
message.append(" class ").append(fqName)
|
||||||
|
.append(", unresolved supertypes: ").append(unresolved!!.joinToString())
|
||||||
|
.append("\n")
|
||||||
}
|
}
|
||||||
messageCollector.report(ERROR, message.toString())
|
messageCollector.report(ERROR, message.toString())
|
||||||
}
|
}
|
||||||
@@ -110,8 +116,9 @@ class AnalyzerWithCompilerReport(
|
|||||||
reportAlternativeSignatureErrors()
|
reportAlternativeSignatureErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MyDiagnostic<E : PsiElement>(psiElement: E, factory: DiagnosticFactory0<E>,
|
private class MyDiagnostic<E : PsiElement>(
|
||||||
val message: String) : SimpleDiagnostic<E>(psiElement, factory, Severity.ERROR) {
|
psiElement: E, factory: DiagnosticFactory0<E>, val message: String
|
||||||
|
) : SimpleDiagnostic<E>(psiElement, factory, Severity.ERROR) {
|
||||||
|
|
||||||
override fun isValid(): Boolean = true
|
override fun isValid(): Boolean = true
|
||||||
}
|
}
|
||||||
@@ -122,7 +129,7 @@ class AnalyzerWithCompilerReport(
|
|||||||
Severity.INFO -> INFO
|
Severity.INFO -> INFO
|
||||||
Severity.ERROR -> ERROR
|
Severity.ERROR -> ERROR
|
||||||
Severity.WARNING -> WARNING
|
Severity.WARNING -> WARNING
|
||||||
else -> throw IllegalStateException("Unknown severity: " + severity)
|
else -> throw IllegalStateException("Unknown severity: $severity")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val SYNTAX_ERROR_FACTORY = DiagnosticFactory0.create<PsiErrorElement>(Severity.ERROR)
|
private val SYNTAX_ERROR_FACTORY = DiagnosticFactory0.create<PsiErrorElement>(Severity.ERROR)
|
||||||
@@ -131,9 +138,9 @@ class AnalyzerWithCompilerReport(
|
|||||||
if (!diagnostic.isValid) return false
|
if (!diagnostic.isValid) return false
|
||||||
|
|
||||||
reporter.report(
|
reporter.report(
|
||||||
diagnostic,
|
diagnostic,
|
||||||
diagnostic.psiFile,
|
diagnostic.psiFile,
|
||||||
(diagnostic as? MyDiagnostic<*>)?.message ?: DefaultErrorMessages.render(diagnostic)
|
(diagnostic as? MyDiagnostic<*>)?.message ?: DefaultErrorMessages.render(diagnostic)
|
||||||
)
|
)
|
||||||
|
|
||||||
return diagnostic.severity == Severity.ERROR
|
return diagnostic.severity == Severity.ERROR
|
||||||
@@ -159,9 +166,9 @@ class AnalyzerWithCompilerReport(
|
|||||||
|
|
||||||
if (hasIncompatibleClassErrors) {
|
if (hasIncompatibleClassErrors) {
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
ERROR,
|
ERROR,
|
||||||
"Incompatible classes were found in dependencies. " +
|
"Incompatible classes were found in dependencies. " +
|
||||||
"Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors"
|
"Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,8 +199,10 @@ class AnalyzerWithCompilerReport(
|
|||||||
|
|
||||||
override fun visitErrorElement(element: PsiErrorElement) {
|
override fun visitErrorElement(element: PsiErrorElement) {
|
||||||
val description = element.errorDescription
|
val description = element.errorDescription
|
||||||
reportDiagnostic(element, SYNTAX_ERROR_FACTORY,
|
reportDiagnostic(
|
||||||
if (StringUtil.isEmpty(description)) "Syntax error" else description)
|
element, SYNTAX_ERROR_FACTORY,
|
||||||
|
if (StringUtil.isEmpty(description)) "Syntax error" else description
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,29 +219,29 @@ class AnalyzerWithCompilerReport(
|
|||||||
|
|
||||||
fun reportBytecodeVersionErrors(bindingContext: BindingContext, messageCollector: MessageCollector) {
|
fun reportBytecodeVersionErrors(bindingContext: BindingContext, messageCollector: MessageCollector) {
|
||||||
val severity =
|
val severity =
|
||||||
if (System.getProperty("kotlin.jvm.disable.bytecode.version.error") == "true") STRONG_WARNING
|
if (System.getProperty("kotlin.jvm.disable.bytecode.version.error") == "true") STRONG_WARNING
|
||||||
else ERROR
|
else ERROR
|
||||||
|
|
||||||
val locations = bindingContext.getKeys(IncompatibleClassTrackerImpl.BYTECODE_VERSION_ERRORS)
|
val locations = bindingContext.getKeys(IncompatibleClassTrackerImpl.BYTECODE_VERSION_ERRORS)
|
||||||
if (locations.isEmpty()) return
|
if (locations.isEmpty()) return
|
||||||
|
|
||||||
for (location in locations) {
|
for (location in locations) {
|
||||||
val data = bindingContext.get(IncompatibleClassTrackerImpl.BYTECODE_VERSION_ERRORS, location)
|
val data = bindingContext.get(IncompatibleClassTrackerImpl.BYTECODE_VERSION_ERRORS, location)
|
||||||
?: error("Value is missing for key in binding context: " + location)
|
?: error("Value is missing for key in binding context: $location")
|
||||||
reportIncompatibleBinaryVersion(messageCollector, data, severity)
|
reportIncompatibleBinaryVersion(messageCollector, data, severity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportIncompatibleBinaryVersion(
|
private fun reportIncompatibleBinaryVersion(
|
||||||
messageCollector: MessageCollector,
|
messageCollector: MessageCollector,
|
||||||
data: IncompatibleVersionErrorData<JvmBytecodeBinaryVersion>,
|
data: IncompatibleVersionErrorData<JvmBytecodeBinaryVersion>,
|
||||||
severity: CompilerMessageSeverity
|
severity: CompilerMessageSeverity
|
||||||
) {
|
) {
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
severity,
|
severity,
|
||||||
"Class '" + JvmClassName.byClassId(data.classId) + "' was compiled with an incompatible version of Kotlin. " +
|
"Class '" + JvmClassName.byClassId(data.classId) + "' was compiled with an incompatible version of Kotlin. " +
|
||||||
"The binary version of its bytecode is " + data.actualVersion + ", expected version is " + data.expectedVersion,
|
"The binary version of its bytecode is " + data.actualVersion + ", expected version is " + data.expectedVersion,
|
||||||
CompilerMessageLocation.create(toSystemDependentName(data.filePath))
|
CompilerMessageLocation.create(toSystemDependentName(data.filePath))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -26,12 +26,11 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
|||||||
class DefaultDiagnosticReporter(override val messageCollector: MessageCollector) : MessageCollectorBasedReporter
|
class DefaultDiagnosticReporter(override val messageCollector: MessageCollector) : MessageCollectorBasedReporter
|
||||||
|
|
||||||
interface MessageCollectorBasedReporter : DiagnosticMessageReporter {
|
interface MessageCollectorBasedReporter : DiagnosticMessageReporter {
|
||||||
|
|
||||||
val messageCollector: MessageCollector
|
val messageCollector: MessageCollector
|
||||||
|
|
||||||
override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) = messageCollector.report(
|
override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) = messageCollector.report(
|
||||||
AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity),
|
AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity),
|
||||||
render,
|
render,
|
||||||
MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumn(diagnostic))
|
MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumn(diagnostic))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -29,15 +29,13 @@ import org.jetbrains.kotlin.util.ModuleVisibilityHelper
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class ModuleVisibilityHelperImpl : ModuleVisibilityHelper {
|
class ModuleVisibilityHelperImpl : ModuleVisibilityHelper {
|
||||||
|
|
||||||
override fun isInFriendModule(what: DeclarationDescriptor, from: DeclarationDescriptor): Boolean {
|
override fun isInFriendModule(what: DeclarationDescriptor, from: DeclarationDescriptor): Boolean {
|
||||||
val fromSource = getSourceElement(from)
|
val fromSource = getSourceElement(from)
|
||||||
// We should check accessibility of 'from' in current module (some set of source files, which are compiled together),
|
// We should check accessibility of 'from' in current module (some set of source files, which are compiled together),
|
||||||
// so we can assume that 'from' should have sources or is a LazyPackageDescriptor with some package files.
|
// so we can assume that 'from' should have sources or is a LazyPackageDescriptor with some package files.
|
||||||
val project: Project = if (fromSource is KotlinSourceElement) {
|
val project: Project = if (fromSource is KotlinSourceElement) {
|
||||||
fromSource.psi.project
|
fromSource.psi.project
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
(from as? LazyPackageDescriptor)?.declarationProvider?.getPackageFiles()?.firstOrNull()?.project ?: return true
|
(from as? LazyPackageDescriptor)?.declarationProvider?.getPackageFiles()?.firstOrNull()?.project ?: return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,11 +68,10 @@ class ModuleVisibilityHelperImpl : ModuleVisibilityHelper {
|
|||||||
val sourceElement = getSourceElement(descriptor)
|
val sourceElement = getSourceElement(descriptor)
|
||||||
return if (sourceElement is KotlinSourceElement) {
|
return if (sourceElement is KotlinSourceElement) {
|
||||||
modules.singleOrNull() ?: modules.firstOrNull { sourceElement.psi.containingKtFile.virtualFile.path in it.getSourceFiles() }
|
modules.singleOrNull() ?: modules.firstOrNull { sourceElement.psi.containingKtFile.virtualFile.path in it.getSourceFiles() }
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
modules.firstOrNull { module ->
|
modules.firstOrNull { module ->
|
||||||
isContainedByCompiledPartOfOurModule(descriptor, File(module.getOutputDirectory())) ||
|
isContainedByCompiledPartOfOurModule(descriptor, File(module.getOutputDirectory())) ||
|
||||||
module.getFriendPaths().any { isContainedByCompiledPartOfOurModule(descriptor, File(it)) }
|
module.getFriendPaths().any { isContainedByCompiledPartOfOurModule(descriptor, File(it)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +83,7 @@ class ModuleVisibilityHelperImpl : ModuleVisibilityHelper {
|
|||||||
*/
|
*/
|
||||||
class CliModuleVisibilityManagerImpl(override val enabled: Boolean) : ModuleVisibilityManager, Disposable {
|
class CliModuleVisibilityManagerImpl(override val enabled: Boolean) : ModuleVisibilityManager, Disposable {
|
||||||
override val chunk: MutableList<Module> = arrayListOf()
|
override val chunk: MutableList<Module> = arrayListOf()
|
||||||
override val friendPaths: MutableList <String> = arrayListOf()
|
override val friendPaths: MutableList<String> = arrayListOf()
|
||||||
|
|
||||||
override fun addModule(module: Module) {
|
override fun addModule(module: Module) {
|
||||||
chunk.add(module)
|
chunk.add(module)
|
||||||
|
|||||||
+2
-6
@@ -27,10 +27,7 @@ import kotlin.concurrent.read
|
|||||||
import kotlin.concurrent.write
|
import kotlin.concurrent.write
|
||||||
import kotlin.script.experimental.dependencies.ScriptDependencies
|
import kotlin.script.experimental.dependencies.ScriptDependencies
|
||||||
|
|
||||||
class CliScriptDependenciesProvider(
|
class CliScriptDependenciesProvider(private val project: Project) : ScriptDependenciesProvider {
|
||||||
private val project: Project
|
|
||||||
) : ScriptDependenciesProvider {
|
|
||||||
|
|
||||||
private val cacheLock = ReentrantReadWriteLock()
|
private val cacheLock = ReentrantReadWriteLock()
|
||||||
private val cache = hashMapOf<String, ScriptDependencies?>()
|
private val cache = hashMapOf<String, ScriptDependencies?>()
|
||||||
private val scriptContentLoader = ScriptContentLoader(project)
|
private val scriptContentLoader = ScriptContentLoader(project)
|
||||||
@@ -59,8 +56,7 @@ class CliScriptDependenciesProvider(
|
|||||||
cache.put(path, deps)
|
cache.put(path, deps)
|
||||||
}
|
}
|
||||||
deps
|
deps
|
||||||
}
|
} else null
|
||||||
else null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class CliScriptReportSink(private val messageCollector: MessageCollector) : Scri
|
|||||||
return CompilerMessageLocation.create(scriptFile.path, position.startLine, position.startColumn, null)
|
return CompilerMessageLocation.create(scriptFile.path, position.startLine, position.startColumn, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ScriptReport.Severity.convertSeverity(): CompilerMessageSeverity = when(this) {
|
private fun ScriptReport.Severity.convertSeverity(): CompilerMessageSeverity = when (this) {
|
||||||
ScriptReport.Severity.FATAL -> CompilerMessageSeverity.ERROR
|
ScriptReport.Severity.FATAL -> CompilerMessageSeverity.ERROR
|
||||||
ScriptReport.Severity.ERROR -> CompilerMessageSeverity.ERROR
|
ScriptReport.Severity.ERROR -> CompilerMessageSeverity.ERROR
|
||||||
ScriptReport.Severity.WARNING -> CompilerMessageSeverity.WARNING
|
ScriptReport.Severity.WARNING -> CompilerMessageSeverity.WARNING
|
||||||
@@ -44,4 +44,3 @@ class CliScriptReportSink(private val messageCollector: MessageCollector) : Scri
|
|||||||
ScriptReport.Severity.DEBUG -> CompilerMessageSeverity.LOGGING
|
ScriptReport.Severity.DEBUG -> CompilerMessageSeverity.LOGGING
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
|||||||
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
|
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.name.isSubpackageOf
|
import org.jetbrains.kotlin.name.isSubpackageOf
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
@@ -30,15 +29,16 @@ fun checkKotlinPackageUsage(environment: KotlinCoreEnvironment, files: Collectio
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
val messageCollector = environment.configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
|
val messageCollector = environment.configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
|
||||||
val kotlinPackage = FqName.topLevel(Name.identifier("kotlin"))
|
val kotlinPackage = FqName("kotlin")
|
||||||
files.forEach {
|
for (file in files) {
|
||||||
if (it.packageFqName.isSubpackageOf(kotlinPackage)) {
|
if (file.packageFqName.isSubpackageOf(kotlinPackage)) {
|
||||||
messageCollector.report(CompilerMessageSeverity.ERROR,
|
messageCollector.report(
|
||||||
"Only the Kotlin standard library is allowed to use the 'kotlin' package",
|
CompilerMessageSeverity.ERROR,
|
||||||
MessageUtil.psiElementToMessageLocation(it.packageDirective!!))
|
"Only the Kotlin standard library is allowed to use the 'kotlin' package",
|
||||||
|
MessageUtil.psiElementToMessageLocation(file.packageDirective!!)
|
||||||
|
)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import com.intellij.openapi.vfs.VfsUtilCore;
|
|||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.util.ExceptionUtil;
|
import com.intellij.util.ExceptionUtil;
|
||||||
import com.intellij.util.SmartList;
|
import com.intellij.util.SmartList;
|
||||||
import com.intellij.util.containers.HashMap;
|
|
||||||
import kotlin.collections.ArraysKt;
|
import kotlin.collections.ArraysKt;
|
||||||
import kotlin.collections.CollectionsKt;
|
import kotlin.collections.CollectionsKt;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -106,7 +105,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected TranslationResult translate(
|
private static TranslationResult translate(
|
||||||
@NotNull JsConfig.Reporter reporter,
|
@NotNull JsConfig.Reporter reporter,
|
||||||
@NotNull List<KtFile> allKotlinFiles,
|
@NotNull List<KtFile> allKotlinFiles,
|
||||||
@NotNull JsAnalysisResult jsAnalysisResult,
|
@NotNull JsAnalysisResult jsAnalysisResult,
|
||||||
@@ -116,7 +115,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
K2JSTranslator translator = new K2JSTranslator(config);
|
K2JSTranslator translator = new K2JSTranslator(config);
|
||||||
IncrementalDataProvider incrementalDataProvider = config.getConfiguration().get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER);
|
IncrementalDataProvider incrementalDataProvider = config.getConfiguration().get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER);
|
||||||
if (incrementalDataProvider != null) {
|
if (incrementalDataProvider != null) {
|
||||||
Map<File, KtFile> nonCompiledSources = new HashMap<File, KtFile>(allKotlinFiles.size());
|
Map<File, KtFile> nonCompiledSources = new HashMap<>(allKotlinFiles.size());
|
||||||
for (KtFile ktFile : allKotlinFiles) {
|
for (KtFile ktFile : allKotlinFiles) {
|
||||||
nonCompiledSources.put(VfsUtilCore.virtualToIoFile(ktFile.getVirtualFile()), ktFile);
|
nonCompiledSources.put(VfsUtilCore.virtualToIoFile(ktFile.getVirtualFile()), ktFile);
|
||||||
}
|
}
|
||||||
@@ -169,7 +168,8 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
return COMPILATION_ERROR;
|
return COMPILATION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExitCode pluginLoadResult = PluginCliParser.loadPluginsSafe(arguments.getPluginClasspaths(), arguments.getPluginOptions(), configuration);
|
ExitCode pluginLoadResult =
|
||||||
|
PluginCliParser.loadPluginsSafe(arguments.getPluginClasspaths(), arguments.getPluginOptions(), configuration);
|
||||||
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult;
|
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult;
|
||||||
|
|
||||||
configuration.put(JSConfigurationKeys.LIBRARIES, configureLibraries(arguments, paths, messageCollector));
|
configuration.put(JSConfigurationKeys.LIBRARIES, configureLibraries(arguments, paths, messageCollector));
|
||||||
|
|||||||
@@ -20,11 +20,9 @@ import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
|
|||||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||||
|
|
||||||
object BundledCompilerPlugins {
|
object BundledCompilerPlugins {
|
||||||
|
|
||||||
val componentRegistrars: List<ComponentRegistrar>
|
val componentRegistrars: List<ComponentRegistrar>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
|
|
||||||
val commandLineProcessors: List<CommandLineProcessor>
|
val commandLineProcessors: List<CommandLineProcessor>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
|
|
||||||
}
|
}
|
||||||
+62
-62
@@ -32,10 +32,10 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
private val LOG = Logger.getInstance(JvmRuntimeVersionsConsistencyChecker::class.java)
|
private val LOG = Logger.getInstance(JvmRuntimeVersionsConsistencyChecker::class.java)
|
||||||
|
|
||||||
private fun <T> T?.assertNotNull(lazyMessage: () -> String): T =
|
private fun <T> T?.assertNotNull(lazyMessage: () -> String): T =
|
||||||
this ?: lazyMessage().let { message ->
|
this ?: lazyMessage().let { message ->
|
||||||
LOG.error(message)
|
LOG.error(message)
|
||||||
throw AssertionError(message)
|
throw AssertionError(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val META_INF = "META-INF"
|
private const val META_INF = "META-INF"
|
||||||
private const val MANIFEST_MF = "$META_INF/MANIFEST.MF"
|
private const val MANIFEST_MF = "$META_INF/MANIFEST.MF"
|
||||||
@@ -51,7 +51,7 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
private const val KOTLIN_REFLECT_MODULE = "$META_INF/kotlin-reflection.kotlin_module"
|
private const val KOTLIN_REFLECT_MODULE = "$META_INF/kotlin-reflection.kotlin_module"
|
||||||
|
|
||||||
private val RUNTIME_IMPLEMENTATION_TITLES = setOf(
|
private val RUNTIME_IMPLEMENTATION_TITLES = setOf(
|
||||||
"kotlin-runtime", "kotlin-stdlib", "kotlin-reflect", "Kotlin Runtime", "Kotlin Standard Library", "Kotlin Reflect"
|
"kotlin-runtime", "kotlin-stdlib", "kotlin-reflect", "Kotlin Runtime", "Kotlin Standard Library", "Kotlin Reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val KOTLIN_VERSION_ATTRIBUTE: String
|
private val KOTLIN_VERSION_ATTRIBUTE: String
|
||||||
@@ -62,44 +62,43 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
init {
|
init {
|
||||||
val manifestProperties: Properties = try {
|
val manifestProperties: Properties = try {
|
||||||
JvmRuntimeVersionsConsistencyChecker::class.java
|
JvmRuntimeVersionsConsistencyChecker::class.java
|
||||||
.getResourceAsStream("/kotlinManifest.properties")
|
.getResourceAsStream("/kotlinManifest.properties")
|
||||||
.let { input -> Properties().apply { load(input) } }
|
.let { input -> Properties().apply { load(input) } }
|
||||||
}
|
} catch (e: Exception) {
|
||||||
catch (e: Exception) {
|
|
||||||
LOG.error(e)
|
LOG.error(e)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
|
|
||||||
KOTLIN_VERSION_ATTRIBUTE = manifestProperties.getProperty(MANIFEST_KOTLIN_VERSION_ATTRIBUTE)
|
KOTLIN_VERSION_ATTRIBUTE = manifestProperties.getProperty(MANIFEST_KOTLIN_VERSION_ATTRIBUTE)
|
||||||
.assertNotNull { "$MANIFEST_KOTLIN_VERSION_ATTRIBUTE not found in kotlinManifest.properties" }
|
.assertNotNull { "$MANIFEST_KOTLIN_VERSION_ATTRIBUTE not found in kotlinManifest.properties" }
|
||||||
KOTLIN_RUNTIME_COMPONENT_ATTRIBUTE = manifestProperties.getProperty(MANIFEST_KOTLIN_RUNTIME_COMPONENT)
|
KOTLIN_RUNTIME_COMPONENT_ATTRIBUTE = manifestProperties.getProperty(MANIFEST_KOTLIN_RUNTIME_COMPONENT)
|
||||||
.assertNotNull { "$MANIFEST_KOTLIN_RUNTIME_COMPONENT not found in kotlinManifest.properties" }
|
.assertNotNull { "$MANIFEST_KOTLIN_RUNTIME_COMPONENT not found in kotlinManifest.properties" }
|
||||||
KOTLIN_RUNTIME_COMPONENT_CORE = manifestProperties.getProperty(MANIFEST_KOTLIN_RUNTIME_COMPONENT_CORE)
|
KOTLIN_RUNTIME_COMPONENT_CORE = manifestProperties.getProperty(MANIFEST_KOTLIN_RUNTIME_COMPONENT_CORE)
|
||||||
.assertNotNull { "$MANIFEST_KOTLIN_RUNTIME_COMPONENT_CORE not found in kotlinManifest.properties" }
|
.assertNotNull { "$MANIFEST_KOTLIN_RUNTIME_COMPONENT_CORE not found in kotlinManifest.properties" }
|
||||||
KOTLIN_RUNTIME_COMPONENT_MAIN = manifestProperties.getProperty(MANIFEST_KOTLIN_RUNTIME_COMPONENT_MAIN)
|
KOTLIN_RUNTIME_COMPONENT_MAIN = manifestProperties.getProperty(MANIFEST_KOTLIN_RUNTIME_COMPONENT_MAIN)
|
||||||
.assertNotNull { "$MANIFEST_KOTLIN_RUNTIME_COMPONENT_MAIN not found in kotlinManifest.properties" }
|
.assertNotNull { "$MANIFEST_KOTLIN_RUNTIME_COMPONENT_MAIN not found in kotlinManifest.properties" }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class KotlinLibraryFile(val file: VirtualFile, val version: MavenComparableVersion) {
|
private class KotlinLibraryFile(val file: VirtualFile, val version: MavenComparableVersion) {
|
||||||
override fun toString(): String =
|
override fun toString(): String =
|
||||||
"${file.name}:$version"
|
"${file.name}:$version"
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RuntimeJarsInfo(
|
private class RuntimeJarsInfo(
|
||||||
// Runtime jars with components "Main" and "Core"
|
// Runtime jars with components "Main" and "Core"
|
||||||
val jars: List<KotlinLibraryFile>,
|
val jars: List<KotlinLibraryFile>,
|
||||||
// Runtime jars with components "Core" only (a subset of [jars])
|
// Runtime jars with components "Core" only (a subset of [jars])
|
||||||
val coreJars: List<KotlinLibraryFile>,
|
val coreJars: List<KotlinLibraryFile>,
|
||||||
// Library jars which have some Kotlin Runtime library bundled into them
|
// Library jars which have some Kotlin Runtime library bundled into them
|
||||||
val otherLibrariesWithBundledRuntime: List<VirtualFile>,
|
val otherLibrariesWithBundledRuntime: List<VirtualFile>,
|
||||||
val stdlibJre7: List<KotlinLibraryFile>,
|
val stdlibJre7: List<KotlinLibraryFile>,
|
||||||
val stdlibJre8: List<KotlinLibraryFile>
|
val stdlibJre8: List<KotlinLibraryFile>
|
||||||
)
|
)
|
||||||
|
|
||||||
fun checkCompilerClasspathConsistency(
|
fun checkCompilerClasspathConsistency(
|
||||||
messageCollector: MessageCollector,
|
messageCollector: MessageCollector,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
classpathJarRoots: List<VirtualFile>
|
classpathJarRoots: List<VirtualFile>
|
||||||
) {
|
) {
|
||||||
val runtimeJarsInfo = collectRuntimeJarsInfo(classpathJarRoots)
|
val runtimeJarsInfo = collectRuntimeJarsInfo(classpathJarRoots)
|
||||||
if (runtimeJarsInfo.jars.isEmpty()) return
|
if (runtimeJarsInfo.jars.isEmpty()) return
|
||||||
@@ -114,11 +113,11 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
messageCollector.issue(
|
messageCollector.issue(
|
||||||
null,
|
null,
|
||||||
"Runtime JAR files in the classpath have the version $actualRuntimeVersion, " +
|
"Runtime JAR files in the classpath have the version $actualRuntimeVersion, " +
|
||||||
"which is older than the API version ${currentApi.version}. " +
|
"which is older than the API version ${currentApi.version}. " +
|
||||||
"Consider using the runtime of version ${currentApi.version}, or pass '-api-version $actualRuntimeVersion' " +
|
"Consider using the runtime of version ${currentApi.version}, or pass '-api-version $actualRuntimeVersion' " +
|
||||||
"explicitly to restrict the available APIs to the runtime of version $actualRuntimeVersion. " +
|
"explicitly to restrict the available APIs to the runtime of version $actualRuntimeVersion. " +
|
||||||
"You can also pass '-language-version $actualRuntimeVersion' instead, which will restrict " +
|
"You can also pass '-language-version $actualRuntimeVersion' instead, which will restrict " +
|
||||||
"not only the APIs to the specified version, but also the language features"
|
"not only the APIs to the specified version, but also the language features"
|
||||||
)
|
)
|
||||||
|
|
||||||
for (jar in consistency.incompatibleJars) {
|
for (jar in consistency.incompatibleJars) {
|
||||||
@@ -141,17 +140,18 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
override val apiVersion: ApiVersion get() = actualApi
|
override val apiVersion: ApiVersion get() = actualApi
|
||||||
}
|
}
|
||||||
|
|
||||||
messageCollector.issue(null, "Old runtime has been found in the classpath. " +
|
messageCollector.issue(
|
||||||
"Initial language version settings: $languageVersionSettings. " +
|
null, "Old runtime has been found in the classpath. " +
|
||||||
"Updated language version settings: $newSettings", CompilerMessageSeverity.LOGGING)
|
"Initial language version settings: $languageVersionSettings. " +
|
||||||
|
"Updated language version settings: $newSettings", CompilerMessageSeverity.LOGGING
|
||||||
|
)
|
||||||
|
|
||||||
configuration.languageVersionSettings = newSettings
|
configuration.languageVersionSettings = newSettings
|
||||||
}
|
}
|
||||||
}
|
} else if (consistency != ClasspathConsistency.Consistent) {
|
||||||
else if (consistency != ClasspathConsistency.Consistent) {
|
|
||||||
messageCollector.issue(
|
messageCollector.issue(
|
||||||
null,
|
null,
|
||||||
"Some runtime JAR files in the classpath have an incompatible version. Consider removing them from the classpath"
|
"Some runtime JAR files in the classpath have an incompatible version. Consider removing them from the classpath"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,10 +167,10 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
val librariesWithBundled = runtimeJarsInfo.otherLibrariesWithBundledRuntime
|
val librariesWithBundled = runtimeJarsInfo.otherLibrariesWithBundledRuntime
|
||||||
if (librariesWithBundled.isNotEmpty()) {
|
if (librariesWithBundled.isNotEmpty()) {
|
||||||
messageCollector.issue(
|
messageCollector.issue(
|
||||||
null,
|
null,
|
||||||
"Some JAR files in the classpath have the Kotlin Runtime library bundled into them. " +
|
"Some JAR files in the classpath have the Kotlin Runtime library bundled into them. " +
|
||||||
"This may cause difficult to debug problems if there's a different version of the Kotlin Runtime library in the classpath. " +
|
"This may cause difficult to debug problems if there's a different version of the Kotlin Runtime library in the classpath. " +
|
||||||
"Consider removing these libraries from the classpath"
|
"Consider removing these libraries from the classpath"
|
||||||
)
|
)
|
||||||
|
|
||||||
for (library in librariesWithBundled) {
|
for (library in librariesWithBundled) {
|
||||||
@@ -185,14 +185,15 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
val actualRuntimeVersion: MavenComparableVersion,
|
val actualRuntimeVersion: MavenComparableVersion,
|
||||||
val incompatibleJars: List<KotlinLibraryFile>
|
val incompatibleJars: List<KotlinLibraryFile>
|
||||||
) : ClasspathConsistency()
|
) : ClasspathConsistency()
|
||||||
|
|
||||||
object InconsistentWithCompilerVersion : ClasspathConsistency()
|
object InconsistentWithCompilerVersion : ClasspathConsistency()
|
||||||
object InconsistentBecauseOfRuntimesWithDifferentVersions : ClasspathConsistency()
|
object InconsistentBecauseOfRuntimesWithDifferentVersions : ClasspathConsistency()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkCompilerClasspathConsistency(
|
private fun checkCompilerClasspathConsistency(
|
||||||
messageCollector: MessageCollector,
|
messageCollector: MessageCollector,
|
||||||
apiVersion: MavenComparableVersion,
|
apiVersion: MavenComparableVersion,
|
||||||
runtimeJarsInfo: RuntimeJarsInfo
|
runtimeJarsInfo: RuntimeJarsInfo
|
||||||
): ClasspathConsistency {
|
): ClasspathConsistency {
|
||||||
// The "Core" jar files should not be newer than the compiler. This behavior is reserved for the future if we realise that we're
|
// The "Core" jar files should not be newer than the compiler. This behavior is reserved for the future if we realise that we're
|
||||||
// going to break language/library compatibility in such a way that it's easier to make the old compiler just report an error
|
// going to break language/library compatibility in such a way that it's easier to make the old compiler just report an error
|
||||||
@@ -206,7 +207,7 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
if (jars.isEmpty()) return ClasspathConsistency.Consistent
|
if (jars.isEmpty()) return ClasspathConsistency.Consistent
|
||||||
|
|
||||||
val runtimeVersion = checkMatchingVersionsAndGetRuntimeVersion(messageCollector, jars)
|
val runtimeVersion = checkMatchingVersionsAndGetRuntimeVersion(messageCollector, jars)
|
||||||
?: return ClasspathConsistency.InconsistentBecauseOfRuntimesWithDifferentVersions
|
?: return ClasspathConsistency.InconsistentBecauseOfRuntimesWithDifferentVersions
|
||||||
|
|
||||||
val jarsIncompatibleWithApiVersion = jars.filter { it.version < apiVersion }
|
val jarsIncompatibleWithApiVersion = jars.filter { it.version < apiVersion }
|
||||||
if (jarsIncompatibleWithApiVersion.isNotEmpty()) {
|
if (jarsIncompatibleWithApiVersion.isNotEmpty()) {
|
||||||
@@ -219,9 +220,9 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
private fun checkNotNewerThanCompiler(messageCollector: MessageCollector, jar: KotlinLibraryFile): Boolean {
|
private fun checkNotNewerThanCompiler(messageCollector: MessageCollector, jar: KotlinLibraryFile): Boolean {
|
||||||
if (jar.version > ApiVersion.LATEST_STABLE.version) {
|
if (jar.version > ApiVersion.LATEST_STABLE.version) {
|
||||||
messageCollector.issue(
|
messageCollector.issue(
|
||||||
jar.file,
|
jar.file,
|
||||||
"Runtime JAR file has version ${jar.version} which is newer than compiler version ${ApiVersion.LATEST_STABLE.version}",
|
"Runtime JAR file has version ${jar.version} which is newer than compiler version ${ApiVersion.LATEST_STABLE.version}",
|
||||||
CompilerMessageSeverity.ERROR
|
CompilerMessageSeverity.ERROR
|
||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -230,8 +231,8 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
|
|
||||||
// Returns the version if it's the same across all jars, or null if versions of some jars differ.
|
// Returns the version if it's the same across all jars, or null if versions of some jars differ.
|
||||||
private fun checkMatchingVersionsAndGetRuntimeVersion(
|
private fun checkMatchingVersionsAndGetRuntimeVersion(
|
||||||
messageCollector: MessageCollector,
|
messageCollector: MessageCollector,
|
||||||
jars: List<KotlinLibraryFile>
|
jars: List<KotlinLibraryFile>
|
||||||
): MavenComparableVersion? {
|
): MavenComparableVersion? {
|
||||||
assert(jars.isNotEmpty()) { "'jars' must not be empty" }
|
assert(jars.isNotEmpty()) { "'jars' must not be empty" }
|
||||||
val oldestVersion = jars.minBy { it.version }!!.version
|
val oldestVersion = jars.minBy { it.version }!!.version
|
||||||
@@ -251,13 +252,13 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
// we suggest to provide an explicit dependency on version X.
|
// we suggest to provide an explicit dependency on version X.
|
||||||
// TODO: report this depending on the content of the jars instead
|
// TODO: report this depending on the content of the jars instead
|
||||||
val minReflectJar =
|
val minReflectJar =
|
||||||
jars.filter { it.file.name.startsWith("kotlin-reflect") }.minBy { it.version }
|
jars.filter { it.file.name.startsWith("kotlin-reflect") }.minBy { it.version }
|
||||||
val maxStdlibJar =
|
val maxStdlibJar =
|
||||||
jars.filter { it.file.name.startsWith("kotlin-runtime") || it.file.name.startsWith("kotlin-stdlib") }.maxBy { it.version }
|
jars.filter { it.file.name.startsWith("kotlin-runtime") || it.file.name.startsWith("kotlin-stdlib") }.maxBy { it.version }
|
||||||
if (minReflectJar != null && maxStdlibJar != null && minReflectJar.version < maxStdlibJar.version) {
|
if (minReflectJar != null && maxStdlibJar != null && minReflectJar.version < maxStdlibJar.version) {
|
||||||
messageCollector.issue(
|
messageCollector.issue(
|
||||||
null,
|
null,
|
||||||
"Consider providing an explicit dependency on kotlin-reflect ${maxStdlibJar.version} to prevent strange errors"
|
"Consider providing an explicit dependency on kotlin-reflect ${maxStdlibJar.version} to prevent strange errors"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,9 +266,9 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageCollector.issue(
|
private fun MessageCollector.issue(
|
||||||
file: VirtualFile?,
|
file: VirtualFile?,
|
||||||
message: String,
|
message: String,
|
||||||
severity: CompilerMessageSeverity = CompilerMessageSeverity.STRONG_WARNING
|
severity: CompilerMessageSeverity = CompilerMessageSeverity.STRONG_WARNING
|
||||||
) {
|
) {
|
||||||
report(severity, message, CompilerMessageLocation.create(file?.let(VfsUtilCore::virtualToIoFile)?.path))
|
report(severity, message, CompilerMessageLocation.create(file?.let(VfsUtilCore::virtualToIoFile)?.path))
|
||||||
}
|
}
|
||||||
@@ -330,8 +331,7 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
val manifestFile = jarRoot.findFileByRelativePath(MANIFEST_MF)
|
val manifestFile = jarRoot.findFileByRelativePath(MANIFEST_MF)
|
||||||
val manifest = try {
|
val manifest = try {
|
||||||
manifestFile?.let { Manifest(it.inputStream) }
|
manifestFile?.let { Manifest(it.inputStream) }
|
||||||
}
|
} catch (e: IOException) {
|
||||||
catch (e: IOException) {
|
|
||||||
return FileKind.Irrelevant
|
return FileKind.Irrelevant
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
FileKind.Runtime(manifest.getKotlinLanguageVersion(), isStdlibJre7, isStdlibJre8, isCoreComponent = true)
|
FileKind.Runtime(manifest.getKotlinLanguageVersion(), isStdlibJre7, isStdlibJre8, isCoreComponent = true)
|
||||||
null -> when {
|
null -> when {
|
||||||
jarRoot.findFileByRelativePath(KOTLIN_STDLIB_MODULE) == null &&
|
jarRoot.findFileByRelativePath(KOTLIN_STDLIB_MODULE) == null &&
|
||||||
jarRoot.findFileByRelativePath(KOTLIN_REFLECT_MODULE) == null -> FileKind.Irrelevant
|
jarRoot.findFileByRelativePath(KOTLIN_REFLECT_MODULE) == null -> FileKind.Irrelevant
|
||||||
isGenuineKotlinRuntime(manifest) -> FileKind.OldRuntime
|
isGenuineKotlinRuntime(manifest) -> FileKind.OldRuntime
|
||||||
else -> FileKind.LibraryWithBundledRuntime
|
else -> FileKind.LibraryWithBundledRuntime
|
||||||
}
|
}
|
||||||
@@ -356,9 +356,9 @@ object JvmRuntimeVersionsConsistencyChecker {
|
|||||||
// Returns true if the manifest is from the original Kotlin Runtime jar, false if it's from a library with a bundled runtime
|
// Returns true if the manifest is from the original Kotlin Runtime jar, false if it's from a library with a bundled runtime
|
||||||
private fun isGenuineKotlinRuntime(manifest: Manifest?): Boolean {
|
private fun isGenuineKotlinRuntime(manifest: Manifest?): Boolean {
|
||||||
return manifest != null &&
|
return manifest != null &&
|
||||||
manifest.mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE) in RUNTIME_IMPLEMENTATION_TITLES
|
manifest.mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE) in RUNTIME_IMPLEMENTATION_TITLES
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Manifest.getKotlinLanguageVersion(): MavenComparableVersion =
|
private fun Manifest.getKotlinLanguageVersion(): MavenComparableVersion =
|
||||||
(mainAttributes.getValue(KOTLIN_VERSION_ATTRIBUTE)?.let((ApiVersion)::parse) ?: ApiVersion.KOTLIN_1_0).version
|
(mainAttributes.getValue(KOTLIN_VERSION_ATTRIBUTE)?.let((ApiVersion)::parse) ?: ApiVersion.KOTLIN_1_0).version
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
KotlinToJVMBytecodeCompiler.configureSourceRoots(configuration, moduleChunk.modules, buildFile)
|
KotlinToJVMBytecodeCompiler.configureSourceRoots(configuration, moduleChunk.modules, buildFile)
|
||||||
|
|
||||||
val environment = createCoreEnvironment(rootDisposable, configuration, messageCollector)
|
val environment = createCoreEnvironment(rootDisposable, configuration, messageCollector)
|
||||||
?: return COMPILATION_ERROR
|
?: return COMPILATION_ERROR
|
||||||
|
|
||||||
registerJavacIfNeeded(environment, arguments).let {
|
registerJavacIfNeeded(environment, arguments).let {
|
||||||
if (!it) return COMPILATION_ERROR
|
if (!it) return COMPILATION_ERROR
|
||||||
@@ -164,7 +164,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
configuration.put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
|
configuration.put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
|
||||||
|
|
||||||
val environment = createCoreEnvironment(rootDisposable, configuration, messageCollector)
|
val environment = createCoreEnvironment(rootDisposable, configuration, messageCollector)
|
||||||
?: return COMPILATION_ERROR
|
?: return COMPILATION_ERROR
|
||||||
|
|
||||||
val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(environment.project)
|
val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(environment.project)
|
||||||
val scriptFile = File(sourcePath)
|
val scriptFile = File(sourcePath)
|
||||||
@@ -188,7 +188,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val environment = createCoreEnvironment(rootDisposable, configuration, messageCollector)
|
val environment = createCoreEnvironment(rootDisposable, configuration, messageCollector)
|
||||||
?: return COMPILATION_ERROR
|
?: return COMPILATION_ERROR
|
||||||
|
|
||||||
registerJavacIfNeeded(environment, arguments).let {
|
registerJavacIfNeeded(environment, arguments).let {
|
||||||
if (!it) return COMPILATION_ERROR
|
if (!it) return COMPILATION_ERROR
|
||||||
@@ -243,7 +243,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
val jars = arrayOf(
|
val jars = arrayOf(
|
||||||
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
|
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
|
||||||
KOTLIN_SCRIPTING_JVM_JAR, KOTLIN_SCRIPTING_MISC_JAR
|
KOTLIN_SCRIPTING_JVM_JAR, KOTLIN_SCRIPTING_MISC_JAR
|
||||||
).mapNotNull { File(libPath, it).takeIf { it.exists() }?.canonicalPath }
|
).mapNotNull { File(libPath, it).takeIf(File::exists)?.canonicalPath }
|
||||||
if (jars.size == 4) {
|
if (jars.size == 4) {
|
||||||
pluginClasspaths = jars + pluginClasspaths
|
pluginClasspaths = jars + pluginClasspaths
|
||||||
}
|
}
|
||||||
@@ -308,19 +308,19 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
configuration: CompilerConfiguration, arguments: K2JVMCompilerArguments, services: Services
|
configuration: CompilerConfiguration, arguments: K2JVMCompilerArguments, services: Services
|
||||||
) {
|
) {
|
||||||
if (IncrementalCompilation.isEnabledForJvm()) {
|
if (IncrementalCompilation.isEnabledForJvm()) {
|
||||||
services.get(LookupTracker::class.java)?.let {
|
services[LookupTracker::class.java]?.let {
|
||||||
configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, it)
|
configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
services.get(ExpectActualTracker::class.java)?.let {
|
services[ExpectActualTracker::class.java]?.let {
|
||||||
configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, it)
|
configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
services.get(IncrementalCompilationComponents::class.java)?.let {
|
services[IncrementalCompilationComponents::class.java]?.let {
|
||||||
configuration.put(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, it)
|
configuration.put(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
services.get(JavaClassesTracker::class.java)?.let {
|
services[JavaClassesTracker::class.java]?.let {
|
||||||
configuration.put(JVMConfigurationKeys.JAVA_CLASSES_TRACKER, it)
|
configuration.put(JVMConfigurationKeys.JAVA_CLASSES_TRACKER, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,13 +46,13 @@ import java.util.jar.Manifest
|
|||||||
import kotlin.LazyThreadSafetyMode.NONE
|
import kotlin.LazyThreadSafetyMode.NONE
|
||||||
|
|
||||||
class ClasspathRootsResolver(
|
class ClasspathRootsResolver(
|
||||||
private val psiManager: PsiManager,
|
private val psiManager: PsiManager,
|
||||||
private val messageCollector: MessageCollector?,
|
private val messageCollector: MessageCollector?,
|
||||||
private val additionalModules: List<String>,
|
private val additionalModules: List<String>,
|
||||||
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
|
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
|
||||||
private val javaModuleFinder: CliJavaModuleFinder,
|
private val javaModuleFinder: CliJavaModuleFinder,
|
||||||
private val requireStdlibModule: Boolean,
|
private val requireStdlibModule: Boolean,
|
||||||
private val outputDirectory: VirtualFile?
|
private val outputDirectory: VirtualFile?
|
||||||
) {
|
) {
|
||||||
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
||||||
|
|
||||||
@@ -80,9 +80,9 @@ class ClasspathRootsResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun computeRoots(
|
private fun computeRoots(
|
||||||
javaSourceRoots: List<RootWithPrefix>,
|
javaSourceRoots: List<RootWithPrefix>,
|
||||||
jvmClasspathRoots: List<VirtualFile>,
|
jvmClasspathRoots: List<VirtualFile>,
|
||||||
jvmModulePathRoots: List<VirtualFile>
|
jvmModulePathRoots: List<VirtualFile>
|
||||||
): RootsAndModules {
|
): RootsAndModules {
|
||||||
val result = mutableListOf<JavaRoot>()
|
val result = mutableListOf<JavaRoot>()
|
||||||
val modules = mutableListOf<JavaModule>()
|
val modules = mutableListOf<JavaModule>()
|
||||||
@@ -93,8 +93,7 @@ class ClasspathRootsResolver(
|
|||||||
val modularRoot = modularSourceRoot(root, hasOutputDirectoryInClasspath)
|
val modularRoot = modularSourceRoot(root, hasOutputDirectoryInClasspath)
|
||||||
if (modularRoot != null) {
|
if (modularRoot != null) {
|
||||||
modules += modularRoot
|
modules += modularRoot
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result += JavaRoot(root, JavaRoot.RootType.SOURCE, packagePrefix?.let { prefix ->
|
result += JavaRoot(root, JavaRoot.RootType.SOURCE, packagePrefix?.let { prefix ->
|
||||||
if (isValidJavaFqName(prefix)) FqName(prefix)
|
if (isValidJavaFqName(prefix)) FqName(prefix)
|
||||||
else null.also {
|
else null.also {
|
||||||
@@ -128,11 +127,11 @@ class ClasspathRootsResolver(
|
|||||||
|
|
||||||
private fun findSourceModuleInfo(root: VirtualFile): Pair<VirtualFile, PsiJavaModule>? {
|
private fun findSourceModuleInfo(root: VirtualFile): Pair<VirtualFile, PsiJavaModule>? {
|
||||||
val moduleInfoFile =
|
val moduleInfoFile =
|
||||||
when {
|
when {
|
||||||
root.isDirectory -> root.findChild(PsiJavaModule.MODULE_INFO_FILE)
|
root.isDirectory -> root.findChild(PsiJavaModule.MODULE_INFO_FILE)
|
||||||
root.name == PsiJavaModule.MODULE_INFO_FILE -> root
|
root.name == PsiJavaModule.MODULE_INFO_FILE -> root
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return null
|
} ?: return null
|
||||||
|
|
||||||
val psiFile = psiManager.findFile(moduleInfoFile) ?: return null
|
val psiFile = psiManager.findFile(moduleInfoFile) ?: return null
|
||||||
val psiJavaModule = psiFile.children.singleOrNull { it is PsiJavaModule } as? PsiJavaModule ?: return null
|
val psiJavaModule = psiFile.children.singleOrNull { it is PsiJavaModule } as? PsiJavaModule ?: return null
|
||||||
@@ -144,9 +143,9 @@ class ClasspathRootsResolver(
|
|||||||
val (moduleInfoFile, psiJavaModule) = findSourceModuleInfo(root) ?: return null
|
val (moduleInfoFile, psiJavaModule) = findSourceModuleInfo(root) ?: return null
|
||||||
val sourceRoot = JavaModule.Root(root, isBinary = false)
|
val sourceRoot = JavaModule.Root(root, isBinary = false)
|
||||||
val roots =
|
val roots =
|
||||||
if (hasOutputDirectoryInClasspath)
|
if (hasOutputDirectoryInClasspath)
|
||||||
listOf(sourceRoot, JavaModule.Root(outputDirectory!!, isBinary = true))
|
listOf(sourceRoot, JavaModule.Root(outputDirectory!!, isBinary = true))
|
||||||
else listOf(sourceRoot)
|
else listOf(sourceRoot)
|
||||||
return JavaModule.Explicit(JavaModuleInfo.create(psiJavaModule), roots, moduleInfoFile)
|
return JavaModule.Explicit(JavaModuleInfo.create(psiJavaModule), roots, moduleInfoFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +154,7 @@ class ClasspathRootsResolver(
|
|||||||
val manifest: Attributes? by lazy(NONE) { readManifestAttributes(root) }
|
val manifest: Attributes? by lazy(NONE) { readManifestAttributes(root) }
|
||||||
|
|
||||||
val moduleInfoFile =
|
val moduleInfoFile =
|
||||||
root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE)
|
root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE)
|
||||||
?: root.takeIf { isJar }?.findFileByRelativePath(MULTI_RELEASE_MODULE_INFO_CLS_FILE)?.takeIf {
|
?: root.takeIf { isJar }?.findFileByRelativePath(MULTI_RELEASE_MODULE_INFO_CLS_FILE)?.takeIf {
|
||||||
manifest?.getValue(IS_MULTI_RELEASE)?.equals("true", ignoreCase = true) == true
|
manifest?.getValue(IS_MULTI_RELEASE)?.equals("true", ignoreCase = true) == true
|
||||||
}
|
}
|
||||||
@@ -190,8 +189,7 @@ class ClasspathRootsResolver(
|
|||||||
val manifestFile = jarRoot.findChild("META-INF")?.findChild("MANIFEST.MF")
|
val manifestFile = jarRoot.findChild("META-INF")?.findChild("MANIFEST.MF")
|
||||||
return try {
|
return try {
|
||||||
manifestFile?.inputStream?.let(::Manifest)?.mainAttributes
|
manifestFile?.inputStream?.let(::Manifest)?.mainAttributes
|
||||||
}
|
} catch (e: IOException) {
|
||||||
catch (e: IOException) {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,16 +209,17 @@ class ClasspathRootsResolver(
|
|||||||
val existing = javaModuleFinder.findModule(module.name)
|
val existing = javaModuleFinder.findModule(module.name)
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
javaModuleFinder.addUserModule(module)
|
javaModuleFinder.addUserModule(module)
|
||||||
}
|
} else if (module.moduleRoots != existing.moduleRoots) {
|
||||||
else if (module.moduleRoots != existing.moduleRoots) {
|
|
||||||
fun JavaModule.getRootFile() =
|
fun JavaModule.getRootFile() =
|
||||||
moduleRoots.firstOrNull()?.file?.let { VfsUtilCore.getVirtualFileForJar(it) ?: it }
|
moduleRoots.firstOrNull()?.file?.let { VfsUtilCore.getVirtualFileForJar(it) ?: it }
|
||||||
|
|
||||||
val thisFile = module.getRootFile()
|
val thisFile = module.getRootFile()
|
||||||
val existingFile = existing.getRootFile()
|
val existingFile = existing.getRootFile()
|
||||||
val atExistingPath = if (existingFile == null) "" else " at: ${existingFile.path}"
|
val atExistingPath = if (existingFile == null) "" else " at: ${existingFile.path}"
|
||||||
report(STRONG_WARNING, "The root is ignored because a module with the same name '${module.name}' " +
|
report(
|
||||||
"has been found earlier on the module path$atExistingPath", thisFile)
|
STRONG_WARNING, "The root is ignored because a module with the same name '${module.name}' " +
|
||||||
|
"has been found earlier on the module path$atExistingPath", thisFile
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,8 +256,7 @@ class ClasspathRootsResolver(
|
|||||||
val module = javaModuleFinder.findModule(moduleName)
|
val module = javaModuleFinder.findModule(moduleName)
|
||||||
if (module == null) {
|
if (module == null) {
|
||||||
report(ERROR, "Module $moduleName cannot be found in the module graph")
|
report(ERROR, "Module $moduleName cannot be found in the module graph")
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for ((root, isBinary) in module.moduleRoots) {
|
for ((root, isBinary) in module.moduleRoots) {
|
||||||
result.add(JavaRoot(root, if (isBinary) JavaRoot.RootType.BINARY else JavaRoot.RootType.SOURCE))
|
result.add(JavaRoot(root, if (isBinary) JavaRoot.RootType.BINARY else JavaRoot.RootType.SOURCE))
|
||||||
}
|
}
|
||||||
@@ -267,10 +265,10 @@ class ClasspathRootsResolver(
|
|||||||
|
|
||||||
if (requireStdlibModule && sourceModule != null && !javaModuleGraph.reads(sourceModule.name, KOTLIN_STDLIB_MODULE_NAME)) {
|
if (requireStdlibModule && sourceModule != null && !javaModuleGraph.reads(sourceModule.name, KOTLIN_STDLIB_MODULE_NAME)) {
|
||||||
report(
|
report(
|
||||||
ERROR,
|
ERROR,
|
||||||
"The Kotlin standard library is not found in the module graph. " +
|
"The Kotlin standard library is not found in the module graph. " +
|
||||||
"Please ensure you have the 'requires $KOTLIN_STDLIB_MODULE_NAME' clause in your module definition",
|
"Please ensure you have the 'requires $KOTLIN_STDLIB_MODULE_NAME' clause in your module definition",
|
||||||
sourceModule.moduleInfoFile
|
sourceModule.moduleInfoFile
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,8 +312,8 @@ class ClasspathRootsResolver(
|
|||||||
throw IllegalStateException("${if (file != null) file.path + ":" else ""}$severity: $message (no MessageCollector configured)")
|
throw IllegalStateException("${if (file != null) file.path + ":" else ""}$severity: $message (no MessageCollector configured)")
|
||||||
}
|
}
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
severity, message,
|
severity, message,
|
||||||
if (file == null) null else CompilerMessageLocation.create(MessageUtil.virtualFileToPath(file))
|
if (file == null) null else CompilerMessageLocation.create(MessageUtil.virtualFileToPath(file))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+49
-52
@@ -20,7 +20,6 @@ import com.intellij.openapi.vfs.StandardFileSystems
|
|||||||
import com.intellij.openapi.vfs.VfsUtilCore
|
import com.intellij.openapi.vfs.VfsUtilCore
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiJavaModule
|
import com.intellij.psi.PsiJavaModule
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.impl.light.LightJavaModule
|
import com.intellij.psi.impl.light.LightJavaModule
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||||
@@ -47,13 +46,13 @@ import java.util.jar.Manifest
|
|||||||
import kotlin.LazyThreadSafetyMode.NONE
|
import kotlin.LazyThreadSafetyMode.NONE
|
||||||
|
|
||||||
class ClasspathRootsResolver(
|
class ClasspathRootsResolver(
|
||||||
private val psiManager: PsiManager,
|
private val psiManager: PsiManager,
|
||||||
private val messageCollector: MessageCollector?,
|
private val messageCollector: MessageCollector?,
|
||||||
private val additionalModules: List<String>,
|
private val additionalModules: List<String>,
|
||||||
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
|
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
|
||||||
private val javaModuleFinder: CliJavaModuleFinder,
|
private val javaModuleFinder: CliJavaModuleFinder,
|
||||||
private val requireStdlibModule: Boolean,
|
private val requireStdlibModule: Boolean,
|
||||||
private val outputDirectory: VirtualFile?
|
private val outputDirectory: VirtualFile?
|
||||||
) {
|
) {
|
||||||
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
||||||
|
|
||||||
@@ -81,9 +80,9 @@ class ClasspathRootsResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun computeRoots(
|
private fun computeRoots(
|
||||||
javaSourceRoots: List<RootWithPrefix>,
|
javaSourceRoots: List<RootWithPrefix>,
|
||||||
jvmClasspathRoots: List<VirtualFile>,
|
jvmClasspathRoots: List<VirtualFile>,
|
||||||
jvmModulePathRoots: List<VirtualFile>
|
jvmModulePathRoots: List<VirtualFile>
|
||||||
): RootsAndModules {
|
): RootsAndModules {
|
||||||
val result = mutableListOf<JavaRoot>()
|
val result = mutableListOf<JavaRoot>()
|
||||||
val modules = mutableListOf<JavaModule>()
|
val modules = mutableListOf<JavaModule>()
|
||||||
@@ -92,22 +91,21 @@ class ClasspathRootsResolver(
|
|||||||
|
|
||||||
for ((root, packagePrefix) in javaSourceRoots) {
|
for ((root, packagePrefix) in javaSourceRoots) {
|
||||||
val modularRoot = modularSourceRoot(root, hasOutputDirectoryInClasspath)
|
val modularRoot = modularSourceRoot(root, hasOutputDirectoryInClasspath)
|
||||||
if (modularRoot != null) {
|
if (modularRoot != null) {
|
||||||
modules += modularRoot
|
modules += modularRoot
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result += JavaRoot(root, JavaRoot.RootType.SOURCE, packagePrefix?.let { prefix ->
|
result += JavaRoot(root, JavaRoot.RootType.SOURCE, packagePrefix?.let { prefix ->
|
||||||
if (isValidJavaFqName(prefix)) FqName(prefix)
|
if (isValidJavaFqName(prefix)) FqName(prefix)
|
||||||
else null.also {
|
else null.also {
|
||||||
report(STRONG_WARNING, "Invalid package prefix name is ignored: $prefix")
|
report(STRONG_WARNING, "Invalid package prefix name is ignored: $prefix")
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (root in jvmClasspathRoots) {
|
for (root in jvmClasspathRoots) {
|
||||||
result += JavaRoot(root, JavaRoot.RootType.BINARY)
|
result += JavaRoot(root, JavaRoot.RootType.BINARY)
|
||||||
}
|
}
|
||||||
|
|
||||||
val outputDirectoryAddedAsPartOfModule = modules.any { module -> module.moduleRoots.any { it.file == outputDirectory } }
|
val outputDirectoryAddedAsPartOfModule = modules.any { module -> module.moduleRoots.any { it.file == outputDirectory } }
|
||||||
|
|
||||||
@@ -117,24 +115,24 @@ class ClasspathRootsResolver(
|
|||||||
if (outputDirectoryAddedAsPartOfModule && root == outputDirectory) continue
|
if (outputDirectoryAddedAsPartOfModule && root == outputDirectory) continue
|
||||||
|
|
||||||
val module = modularBinaryRoot(root)
|
val module = modularBinaryRoot(root)
|
||||||
if (module != null) {
|
if (module != null) {
|
||||||
modules += module
|
modules += module
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addModularRoots(modules, result)
|
addModularRoots(modules, result)
|
||||||
|
|
||||||
return RootsAndModules(result, modules)
|
return RootsAndModules(result, modules)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
private fun findSourceModuleInfo(root: VirtualFile): Pair<VirtualFile, PsiJavaModule>? {
|
private fun findSourceModuleInfo(root: VirtualFile): Pair<VirtualFile, PsiJavaModule>? {
|
||||||
val moduleInfoFile =
|
val moduleInfoFile =
|
||||||
when {
|
when {
|
||||||
root.isDirectory -> root.findChild(PsiJavaModule.MODULE_INFO_FILE)
|
root.isDirectory -> root.findChild(PsiJavaModule.MODULE_INFO_FILE)
|
||||||
root.name == PsiJavaModule.MODULE_INFO_FILE -> root
|
root.name == PsiJavaModule.MODULE_INFO_FILE -> root
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return null
|
} ?: return null
|
||||||
|
|
||||||
val psiFile = psiManager.findFile(moduleInfoFile) ?: return null
|
val psiFile = psiManager.findFile(moduleInfoFile) ?: return null
|
||||||
val psiJavaModule = psiFile.children.singleOrNull { it is PsiJavaModule } as? PsiJavaModule ?: return null
|
val psiJavaModule = psiFile.children.singleOrNull { it is PsiJavaModule } as? PsiJavaModule ?: return null
|
||||||
@@ -148,9 +146,9 @@ class ClasspathRootsResolver(
|
|||||||
val (moduleInfoFile, psiJavaModule) = findSourceModuleInfo(root) ?: return null
|
val (moduleInfoFile, psiJavaModule) = findSourceModuleInfo(root) ?: return null
|
||||||
val sourceRoot = JavaModule.Root(root, isBinary = false)
|
val sourceRoot = JavaModule.Root(root, isBinary = false)
|
||||||
val roots =
|
val roots =
|
||||||
if (hasOutputDirectoryInClasspath)
|
if (hasOutputDirectoryInClasspath)
|
||||||
listOf(sourceRoot, JavaModule.Root(outputDirectory!!, isBinary = true))
|
listOf(sourceRoot, JavaModule.Root(outputDirectory!!, isBinary = true))
|
||||||
else listOf(sourceRoot)
|
else listOf(sourceRoot)
|
||||||
return JavaModule.Explicit(JavaModuleInfo.create(psiJavaModule), roots, moduleInfoFile)
|
return JavaModule.Explicit(JavaModuleInfo.create(psiJavaModule), roots, moduleInfoFile)
|
||||||
*/
|
*/
|
||||||
return null
|
return null
|
||||||
@@ -162,7 +160,7 @@ class ClasspathRootsResolver(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
val moduleInfoFile =
|
val moduleInfoFile =
|
||||||
root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE)
|
root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE)
|
||||||
?: root.takeIf { isJar }?.findFileByRelativePath(MULTI_RELEASE_MODULE_INFO_CLS_FILE)?.takeIf {
|
?: root.takeIf { isJar }?.findFileByRelativePath(MULTI_RELEASE_MODULE_INFO_CLS_FILE)?.takeIf {
|
||||||
manifest?.getValue(IS_MULTI_RELEASE)?.equals("true", ignoreCase = true) == true
|
manifest?.getValue(IS_MULTI_RELEASE)?.equals("true", ignoreCase = true) == true
|
||||||
}
|
}
|
||||||
@@ -198,8 +196,7 @@ class ClasspathRootsResolver(
|
|||||||
val manifestFile = jarRoot.findChild("META-INF")?.findChild("MANIFEST.MF")
|
val manifestFile = jarRoot.findChild("META-INF")?.findChild("MANIFEST.MF")
|
||||||
return try {
|
return try {
|
||||||
manifestFile?.inputStream?.let(::Manifest)?.mainAttributes
|
manifestFile?.inputStream?.let(::Manifest)?.mainAttributes
|
||||||
}
|
} catch (e: IOException) {
|
||||||
catch (e: IOException) {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,16 +216,17 @@ class ClasspathRootsResolver(
|
|||||||
val existing = javaModuleFinder.findModule(module.name)
|
val existing = javaModuleFinder.findModule(module.name)
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
javaModuleFinder.addUserModule(module)
|
javaModuleFinder.addUserModule(module)
|
||||||
}
|
} else if (module.moduleRoots != existing.moduleRoots) {
|
||||||
else if (module.moduleRoots != existing.moduleRoots) {
|
|
||||||
fun JavaModule.getRootFile() =
|
fun JavaModule.getRootFile() =
|
||||||
moduleRoots.firstOrNull()?.file?.let { VfsUtilCore.getVirtualFileForJar(it) ?: it }
|
moduleRoots.firstOrNull()?.file?.let { VfsUtilCore.getVirtualFileForJar(it) ?: it }
|
||||||
|
|
||||||
val thisFile = module.getRootFile()
|
val thisFile = module.getRootFile()
|
||||||
val existingFile = existing.getRootFile()
|
val existingFile = existing.getRootFile()
|
||||||
val atExistingPath = if (existingFile == null) "" else " at: ${existingFile.path}"
|
val atExistingPath = if (existingFile == null) "" else " at: ${existingFile.path}"
|
||||||
report(STRONG_WARNING, "The root is ignored because a module with the same name '${module.name}' " +
|
report(
|
||||||
"has been found earlier on the module path$atExistingPath", thisFile)
|
STRONG_WARNING, "The root is ignored because a module with the same name '${module.name}' " +
|
||||||
|
"has been found earlier on the module path$atExistingPath", thisFile
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,8 +263,7 @@ class ClasspathRootsResolver(
|
|||||||
val module = javaModuleFinder.findModule(moduleName)
|
val module = javaModuleFinder.findModule(moduleName)
|
||||||
if (module == null) {
|
if (module == null) {
|
||||||
report(ERROR, "Module $moduleName cannot be found in the module graph")
|
report(ERROR, "Module $moduleName cannot be found in the module graph")
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for ((root, isBinary) in module.moduleRoots) {
|
for ((root, isBinary) in module.moduleRoots) {
|
||||||
result.add(JavaRoot(root, if (isBinary) JavaRoot.RootType.BINARY else JavaRoot.RootType.SOURCE))
|
result.add(JavaRoot(root, if (isBinary) JavaRoot.RootType.BINARY else JavaRoot.RootType.SOURCE))
|
||||||
}
|
}
|
||||||
@@ -275,10 +272,10 @@ class ClasspathRootsResolver(
|
|||||||
|
|
||||||
if (requireStdlibModule && sourceModule != null && !javaModuleGraph.reads(sourceModule.name, KOTLIN_STDLIB_MODULE_NAME)) {
|
if (requireStdlibModule && sourceModule != null && !javaModuleGraph.reads(sourceModule.name, KOTLIN_STDLIB_MODULE_NAME)) {
|
||||||
report(
|
report(
|
||||||
ERROR,
|
ERROR,
|
||||||
"The Kotlin standard library is not found in the module graph. " +
|
"The Kotlin standard library is not found in the module graph. " +
|
||||||
"Please ensure you have the 'requires $KOTLIN_STDLIB_MODULE_NAME' clause in your module definition",
|
"Please ensure you have the 'requires $KOTLIN_STDLIB_MODULE_NAME' clause in your module definition",
|
||||||
sourceModule.moduleInfoFile
|
sourceModule.moduleInfoFile
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,8 +319,8 @@ class ClasspathRootsResolver(
|
|||||||
throw IllegalStateException("${if (file != null) file.path + ":" else ""}$severity: $message (no MessageCollector configured)")
|
throw IllegalStateException("${if (file != null) file.path + ":" else ""}$severity: $message (no MessageCollector configured)")
|
||||||
}
|
}
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
severity, message,
|
severity, message,
|
||||||
if (file == null) null else CompilerMessageLocation.create(MessageUtil.virtualFileToPath(file))
|
if (file == null) null else CompilerMessageLocation.create(MessageUtil.virtualFileToPath(file))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+49
-52
@@ -20,7 +20,6 @@ import com.intellij.openapi.vfs.StandardFileSystems
|
|||||||
import com.intellij.openapi.vfs.VfsUtilCore
|
import com.intellij.openapi.vfs.VfsUtilCore
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiJavaModule
|
import com.intellij.psi.PsiJavaModule
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.impl.light.LightJavaModule
|
import com.intellij.psi.impl.light.LightJavaModule
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||||
@@ -47,13 +46,13 @@ import java.util.jar.Manifest
|
|||||||
import kotlin.LazyThreadSafetyMode.NONE
|
import kotlin.LazyThreadSafetyMode.NONE
|
||||||
|
|
||||||
class ClasspathRootsResolver(
|
class ClasspathRootsResolver(
|
||||||
private val psiManager: PsiManager,
|
private val psiManager: PsiManager,
|
||||||
private val messageCollector: MessageCollector?,
|
private val messageCollector: MessageCollector?,
|
||||||
private val additionalModules: List<String>,
|
private val additionalModules: List<String>,
|
||||||
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
|
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
|
||||||
private val javaModuleFinder: CliJavaModuleFinder,
|
private val javaModuleFinder: CliJavaModuleFinder,
|
||||||
private val requireStdlibModule: Boolean,
|
private val requireStdlibModule: Boolean,
|
||||||
private val outputDirectory: VirtualFile?
|
private val outputDirectory: VirtualFile?
|
||||||
) {
|
) {
|
||||||
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
||||||
|
|
||||||
@@ -81,9 +80,9 @@ class ClasspathRootsResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun computeRoots(
|
private fun computeRoots(
|
||||||
javaSourceRoots: List<RootWithPrefix>,
|
javaSourceRoots: List<RootWithPrefix>,
|
||||||
jvmClasspathRoots: List<VirtualFile>,
|
jvmClasspathRoots: List<VirtualFile>,
|
||||||
jvmModulePathRoots: List<VirtualFile>
|
jvmModulePathRoots: List<VirtualFile>
|
||||||
): RootsAndModules {
|
): RootsAndModules {
|
||||||
val result = mutableListOf<JavaRoot>()
|
val result = mutableListOf<JavaRoot>()
|
||||||
val modules = mutableListOf<JavaModule>()
|
val modules = mutableListOf<JavaModule>()
|
||||||
@@ -92,22 +91,21 @@ class ClasspathRootsResolver(
|
|||||||
|
|
||||||
for ((root, packagePrefix) in javaSourceRoots) {
|
for ((root, packagePrefix) in javaSourceRoots) {
|
||||||
val modularRoot = modularSourceRoot(root, hasOutputDirectoryInClasspath)
|
val modularRoot = modularSourceRoot(root, hasOutputDirectoryInClasspath)
|
||||||
if (modularRoot != null) {
|
if (modularRoot != null) {
|
||||||
modules += modularRoot
|
modules += modularRoot
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result += JavaRoot(root, JavaRoot.RootType.SOURCE, packagePrefix?.let { prefix ->
|
result += JavaRoot(root, JavaRoot.RootType.SOURCE, packagePrefix?.let { prefix ->
|
||||||
if (isValidJavaFqName(prefix)) FqName(prefix)
|
if (isValidJavaFqName(prefix)) FqName(prefix)
|
||||||
else null.also {
|
else null.also {
|
||||||
report(STRONG_WARNING, "Invalid package prefix name is ignored: $prefix")
|
report(STRONG_WARNING, "Invalid package prefix name is ignored: $prefix")
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (root in jvmClasspathRoots) {
|
for (root in jvmClasspathRoots) {
|
||||||
result += JavaRoot(root, JavaRoot.RootType.BINARY)
|
result += JavaRoot(root, JavaRoot.RootType.BINARY)
|
||||||
}
|
}
|
||||||
|
|
||||||
val outputDirectoryAddedAsPartOfModule = modules.any { module -> module.moduleRoots.any { it.file == outputDirectory } }
|
val outputDirectoryAddedAsPartOfModule = modules.any { module -> module.moduleRoots.any { it.file == outputDirectory } }
|
||||||
|
|
||||||
@@ -117,24 +115,24 @@ class ClasspathRootsResolver(
|
|||||||
if (outputDirectoryAddedAsPartOfModule && root == outputDirectory) continue
|
if (outputDirectoryAddedAsPartOfModule && root == outputDirectory) continue
|
||||||
|
|
||||||
val module = modularBinaryRoot(root)
|
val module = modularBinaryRoot(root)
|
||||||
if (module != null) {
|
if (module != null) {
|
||||||
modules += module
|
modules += module
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addModularRoots(modules, result)
|
addModularRoots(modules, result)
|
||||||
|
|
||||||
return RootsAndModules(result, modules)
|
return RootsAndModules(result, modules)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
private fun findSourceModuleInfo(root: VirtualFile): Pair<VirtualFile, PsiJavaModule>? {
|
private fun findSourceModuleInfo(root: VirtualFile): Pair<VirtualFile, PsiJavaModule>? {
|
||||||
val moduleInfoFile =
|
val moduleInfoFile =
|
||||||
when {
|
when {
|
||||||
root.isDirectory -> root.findChild(PsiJavaModule.MODULE_INFO_FILE)
|
root.isDirectory -> root.findChild(PsiJavaModule.MODULE_INFO_FILE)
|
||||||
root.name == PsiJavaModule.MODULE_INFO_FILE -> root
|
root.name == PsiJavaModule.MODULE_INFO_FILE -> root
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return null
|
} ?: return null
|
||||||
|
|
||||||
val psiFile = psiManager.findFile(moduleInfoFile) ?: return null
|
val psiFile = psiManager.findFile(moduleInfoFile) ?: return null
|
||||||
val psiJavaModule = psiFile.children.singleOrNull { it is PsiJavaModule } as? PsiJavaModule ?: return null
|
val psiJavaModule = psiFile.children.singleOrNull { it is PsiJavaModule } as? PsiJavaModule ?: return null
|
||||||
@@ -148,9 +146,9 @@ class ClasspathRootsResolver(
|
|||||||
val (moduleInfoFile, psiJavaModule) = findSourceModuleInfo(root) ?: return null
|
val (moduleInfoFile, psiJavaModule) = findSourceModuleInfo(root) ?: return null
|
||||||
val sourceRoot = JavaModule.Root(root, isBinary = false)
|
val sourceRoot = JavaModule.Root(root, isBinary = false)
|
||||||
val roots =
|
val roots =
|
||||||
if (hasOutputDirectoryInClasspath)
|
if (hasOutputDirectoryInClasspath)
|
||||||
listOf(sourceRoot, JavaModule.Root(outputDirectory!!, isBinary = true))
|
listOf(sourceRoot, JavaModule.Root(outputDirectory!!, isBinary = true))
|
||||||
else listOf(sourceRoot)
|
else listOf(sourceRoot)
|
||||||
return JavaModule.Explicit(JavaModuleInfo.create(psiJavaModule), roots, moduleInfoFile)
|
return JavaModule.Explicit(JavaModuleInfo.create(psiJavaModule), roots, moduleInfoFile)
|
||||||
*/
|
*/
|
||||||
return null
|
return null
|
||||||
@@ -162,7 +160,7 @@ class ClasspathRootsResolver(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
val moduleInfoFile =
|
val moduleInfoFile =
|
||||||
root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE)
|
root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE)
|
||||||
?: root.takeIf { isJar }?.findFileByRelativePath(MULTI_RELEASE_MODULE_INFO_CLS_FILE)?.takeIf {
|
?: root.takeIf { isJar }?.findFileByRelativePath(MULTI_RELEASE_MODULE_INFO_CLS_FILE)?.takeIf {
|
||||||
manifest?.getValue(IS_MULTI_RELEASE)?.equals("true", ignoreCase = true) == true
|
manifest?.getValue(IS_MULTI_RELEASE)?.equals("true", ignoreCase = true) == true
|
||||||
}
|
}
|
||||||
@@ -198,8 +196,7 @@ class ClasspathRootsResolver(
|
|||||||
val manifestFile = jarRoot.findChild("META-INF")?.findChild("MANIFEST.MF")
|
val manifestFile = jarRoot.findChild("META-INF")?.findChild("MANIFEST.MF")
|
||||||
return try {
|
return try {
|
||||||
manifestFile?.inputStream?.let(::Manifest)?.mainAttributes
|
manifestFile?.inputStream?.let(::Manifest)?.mainAttributes
|
||||||
}
|
} catch (e: IOException) {
|
||||||
catch (e: IOException) {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,16 +216,17 @@ class ClasspathRootsResolver(
|
|||||||
val existing = javaModuleFinder.findModule(module.name)
|
val existing = javaModuleFinder.findModule(module.name)
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
javaModuleFinder.addUserModule(module)
|
javaModuleFinder.addUserModule(module)
|
||||||
}
|
} else if (module.moduleRoots != existing.moduleRoots) {
|
||||||
else if (module.moduleRoots != existing.moduleRoots) {
|
|
||||||
fun JavaModule.getRootFile() =
|
fun JavaModule.getRootFile() =
|
||||||
moduleRoots.firstOrNull()?.file?.let { VfsUtilCore.getVirtualFileForJar(it) ?: it }
|
moduleRoots.firstOrNull()?.file?.let { VfsUtilCore.getVirtualFileForJar(it) ?: it }
|
||||||
|
|
||||||
val thisFile = module.getRootFile()
|
val thisFile = module.getRootFile()
|
||||||
val existingFile = existing.getRootFile()
|
val existingFile = existing.getRootFile()
|
||||||
val atExistingPath = if (existingFile == null) "" else " at: ${existingFile.path}"
|
val atExistingPath = if (existingFile == null) "" else " at: ${existingFile.path}"
|
||||||
report(STRONG_WARNING, "The root is ignored because a module with the same name '${module.name}' " +
|
report(
|
||||||
"has been found earlier on the module path$atExistingPath", thisFile)
|
STRONG_WARNING, "The root is ignored because a module with the same name '${module.name}' " +
|
||||||
|
"has been found earlier on the module path$atExistingPath", thisFile
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,8 +263,7 @@ class ClasspathRootsResolver(
|
|||||||
val module = javaModuleFinder.findModule(moduleName)
|
val module = javaModuleFinder.findModule(moduleName)
|
||||||
if (module == null) {
|
if (module == null) {
|
||||||
report(ERROR, "Module $moduleName cannot be found in the module graph")
|
report(ERROR, "Module $moduleName cannot be found in the module graph")
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for ((root, isBinary) in module.moduleRoots) {
|
for ((root, isBinary) in module.moduleRoots) {
|
||||||
result.add(JavaRoot(root, if (isBinary) JavaRoot.RootType.BINARY else JavaRoot.RootType.SOURCE))
|
result.add(JavaRoot(root, if (isBinary) JavaRoot.RootType.BINARY else JavaRoot.RootType.SOURCE))
|
||||||
}
|
}
|
||||||
@@ -275,10 +272,10 @@ class ClasspathRootsResolver(
|
|||||||
|
|
||||||
if (requireStdlibModule && sourceModule != null && !javaModuleGraph.reads(sourceModule.name, KOTLIN_STDLIB_MODULE_NAME)) {
|
if (requireStdlibModule && sourceModule != null && !javaModuleGraph.reads(sourceModule.name, KOTLIN_STDLIB_MODULE_NAME)) {
|
||||||
report(
|
report(
|
||||||
ERROR,
|
ERROR,
|
||||||
"The Kotlin standard library is not found in the module graph. " +
|
"The Kotlin standard library is not found in the module graph. " +
|
||||||
"Please ensure you have the 'requires $KOTLIN_STDLIB_MODULE_NAME' clause in your module definition",
|
"Please ensure you have the 'requires $KOTLIN_STDLIB_MODULE_NAME' clause in your module definition",
|
||||||
sourceModule.moduleInfoFile
|
sourceModule.moduleInfoFile
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,8 +319,8 @@ class ClasspathRootsResolver(
|
|||||||
throw IllegalStateException("${if (file != null) file.path + ":" else ""}$severity: $message (no MessageCollector configured)")
|
throw IllegalStateException("${if (file != null) file.path + ":" else ""}$severity: $message (no MessageCollector configured)")
|
||||||
}
|
}
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
severity, message,
|
severity, message,
|
||||||
if (file == null) null else CompilerMessageLocation.create(MessageUtil.virtualFileToPath(file))
|
if (file == null) null else CompilerMessageLocation.create(MessageUtil.virtualFileToPath(file))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,15 +10,12 @@ import com.intellij.psi.PsiClass
|
|||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.search.PsiSearchScopeUtil
|
import com.intellij.psi.search.PsiSearchScopeUtil
|
||||||
import com.intellij.util.Function
|
|
||||||
import com.intellij.util.SmartList
|
import com.intellij.util.SmartList
|
||||||
import com.intellij.util.containers.ContainerUtil
|
|
||||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||||
import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer
|
import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer
|
||||||
@@ -35,19 +32,14 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|||||||
class CliKotlinAsJavaSupport(
|
class CliKotlinAsJavaSupport(
|
||||||
project: Project,
|
project: Project,
|
||||||
private val traceHolder: CliTraceHolder
|
private val traceHolder: CliTraceHolder
|
||||||
): KotlinAsJavaSupport() {
|
) : KotlinAsJavaSupport() {
|
||||||
private val psiManager = PsiManager.getInstance(project)
|
private val psiManager = PsiManager.getInstance(project)
|
||||||
|
|
||||||
override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||||
return findFacadeFilesInPackage(packageFqName, scope)
|
return findFacadeFilesInPackage(packageFqName, scope)
|
||||||
.groupBy { it.javaFileFacadeFqName }
|
.groupBy { it.javaFileFacadeFqName }
|
||||||
.mapNotNull {
|
.mapNotNull { (facadeClassFqName, files) ->
|
||||||
KtLightClassForFacade.createForFacade(
|
KtLightClassForFacade.createForFacade(psiManager, facadeClassFqName, scope, files)
|
||||||
psiManager,
|
|
||||||
it.key,
|
|
||||||
scope,
|
|
||||||
it.value
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,13 +59,8 @@ class CliKotlinAsJavaSupport(
|
|||||||
val filesForFacade = findFilesForFacade(facadeFqName, scope)
|
val filesForFacade = findFilesForFacade(facadeFqName, scope)
|
||||||
if (filesForFacade.isEmpty()) return emptyList()
|
if (filesForFacade.isEmpty()) return emptyList()
|
||||||
|
|
||||||
return listOfNotNull<PsiClass>(
|
return listOfNotNull(
|
||||||
KtLightClassForFacade.createForFacade(
|
KtLightClassForFacade.createForFacade(psiManager, facadeFqName, scope, filesForFacade)
|
||||||
psiManager,
|
|
||||||
facadeFqName,
|
|
||||||
scope,
|
|
||||||
filesForFacade
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +75,6 @@ class CliKotlinAsJavaSupport(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||||
//
|
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +83,7 @@ class CliKotlinAsJavaSupport(
|
|||||||
|
|
||||||
return traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_FQ_NAME, facadeFqName)?.filter {
|
return traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_FQ_NAME, facadeFqName)?.filter {
|
||||||
PsiSearchScopeUtil.isInScope(scope, it)
|
PsiSearchScopeUtil.isInScope(scope, it)
|
||||||
} ?: emptyList()
|
}.orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -122,20 +108,10 @@ class CliKotlinAsJavaSupport(
|
|||||||
|
|
||||||
override fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection<FqName> {
|
override fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection<FqName> {
|
||||||
val packageView = traceHolder.module.getPackage(fqn)
|
val packageView = traceHolder.module.getPackage(fqn)
|
||||||
val members = packageView.memberScope.getContributedDescriptors(
|
return packageView.memberScope.getContributedDescriptors(
|
||||||
DescriptorKindFilter.PACKAGES,
|
DescriptorKindFilter.PACKAGES,
|
||||||
MemberScope.ALL_NAME_FILTER
|
MemberScope.ALL_NAME_FILTER
|
||||||
)
|
).mapNotNull { member -> (member as? PackageViewDescriptor)?.fqName }
|
||||||
return ContainerUtil.mapNotNull(
|
|
||||||
members,
|
|
||||||
object : Function<DeclarationDescriptor, FqName> {
|
|
||||||
override fun `fun`(member: DeclarationDescriptor): FqName? {
|
|
||||||
if (member is PackageViewDescriptor) {
|
|
||||||
return member.fqName
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? =
|
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? =
|
||||||
@@ -144,24 +120,18 @@ class CliKotlinAsJavaSupport(
|
|||||||
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? =
|
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? =
|
||||||
KtLightClassForScript.create(script)
|
KtLightClassForScript.create(script)
|
||||||
|
|
||||||
|
|
||||||
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||||
return ResolveSessionUtils.getClassDescriptorsByFqName(traceHolder.module, fqName).mapNotNull {
|
return ResolveSessionUtils.getClassDescriptorsByFqName(traceHolder.module, fqName).mapNotNull {
|
||||||
val element = DescriptorToSourceUtils.getSourceFromDescriptor(it)
|
val element = DescriptorToSourceUtils.getSourceFromDescriptor(it)
|
||||||
if (element is KtClassOrObject && PsiSearchScopeUtil.isInScope(
|
if (element is KtClassOrObject && PsiSearchScopeUtil.isInScope(searchScope, element)) {
|
||||||
searchScope,
|
|
||||||
element
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
element
|
element
|
||||||
}
|
} else null
|
||||||
else null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> {
|
override fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> {
|
||||||
return traceHolder.bindingContext.get(BindingContext.PACKAGE_TO_FILES, fqName)?.filter {
|
return traceHolder.bindingContext.get(BindingContext.PACKAGE_TO_FILES, fqName)?.filter {
|
||||||
PsiSearchScopeUtil.isInScope(searchScope, it)
|
PsiSearchScopeUtil.isInScope(searchScope, it)
|
||||||
} ?: emptyList()
|
}.orEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-9
@@ -39,9 +39,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
|||||||
* To mitigate this, CliLightClassGenerationSupport hold a trace that is shared between the analyzer and JetLightClasses
|
* To mitigate this, CliLightClassGenerationSupport hold a trace that is shared between the analyzer and JetLightClasses
|
||||||
*/
|
*/
|
||||||
class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) : LightClassGenerationSupport() {
|
class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) : LightClassGenerationSupport() {
|
||||||
override fun createDataHolderForClass(
|
override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {
|
||||||
classOrObject: KtClassOrObject, builder: LightClassBuilder
|
|
||||||
): LightClassDataHolder.ForClass {
|
|
||||||
//force resolve companion for light class generation
|
//force resolve companion for light class generation
|
||||||
traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
|
traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
|
||||||
|
|
||||||
@@ -49,10 +47,7 @@ class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) :
|
|||||||
|
|
||||||
bindingContext.get(BindingContext.CLASS, classOrObject) ?: return InvalidLightClassDataHolder
|
bindingContext.get(BindingContext.CLASS, classOrObject) ?: return InvalidLightClassDataHolder
|
||||||
|
|
||||||
return LightClassDataHolderImpl(
|
return LightClassDataHolderImpl(stub, diagnostics)
|
||||||
stub,
|
|
||||||
diagnostics
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade {
|
override fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade {
|
||||||
@@ -75,5 +70,3 @@ class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) :
|
|||||||
|
|
||||||
override fun analyzeWithContent(element: KtClassOrObject) = traceHolder.bindingContext
|
override fun analyzeWithContent(element: KtClassOrObject) = traceHolder.bindingContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class CliTraceHolder : CodeAnalyzerInitializer {
|
|||||||
// TODO: needs better name + list of keys to skip somewhere
|
// TODO: needs better name + list of keys to skip somewhere
|
||||||
class NoScopeRecordCliBindingTrace : CliBindingTrace() {
|
class NoScopeRecordCliBindingTrace : CliBindingTrace() {
|
||||||
override fun <K, V> record(slice: WritableSlice<K, V>, key: K, value: V) {
|
override fun <K, V> record(slice: WritableSlice<K, V>, key: K, value: V) {
|
||||||
if (slice === BindingContext.LEXICAL_SCOPE || slice == BindingContext.DATA_FLOW_INFO_BEFORE) {
|
if (slice == BindingContext.LEXICAL_SCOPE || slice == BindingContext.DATA_FLOW_INFO_BEFORE) {
|
||||||
// In the compiler there's no need to keep scopes
|
// In the compiler there's no need to keep scopes
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,16 +29,19 @@ import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerial
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
|
||||||
class CliVirtualFileFinder(
|
class CliVirtualFileFinder(
|
||||||
private val index: JvmDependenciesIndex,
|
private val index: JvmDependenciesIndex,
|
||||||
private val scope: GlobalSearchScope
|
private val scope: GlobalSearchScope
|
||||||
) : VirtualFileFinder() {
|
) : VirtualFileFinder() {
|
||||||
override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? =
|
override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? =
|
||||||
findBinaryClass(classId, classId.relativeClassName.asString().replace('.', '$') + ".class")
|
findBinaryClass(classId, classId.relativeClassName.asString().replace('.', '$') + ".class")
|
||||||
|
|
||||||
override fun findMetadata(classId: ClassId): InputStream? {
|
override fun findMetadata(classId: ClassId): InputStream? {
|
||||||
assert(!classId.isNestedClass) { "Nested classes are not supported here: $classId" }
|
assert(!classId.isNestedClass) { "Nested classes are not supported here: $classId" }
|
||||||
|
|
||||||
return findBinaryClass(classId, classId.shortClassName.asString() + MetadataPackageFragment.DOT_METADATA_FILE_EXTENSION)?.inputStream
|
return findBinaryClass(
|
||||||
|
classId,
|
||||||
|
classId.shortClassName.asString() + MetadataPackageFragment.DOT_METADATA_FILE_EXTENSION
|
||||||
|
)?.inputStream
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hasMetadataPackage(fqName: FqName): Boolean {
|
override fun hasMetadataPackage(fqName: FqName): Boolean {
|
||||||
@@ -59,7 +62,7 @@ class CliVirtualFileFinder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findBinaryClass(classId: ClassId, fileName: String): VirtualFile? =
|
private fun findBinaryClass(classId: ClassId, fileName: String): VirtualFile? =
|
||||||
index.findClass(classId, acceptedRootTypes = JavaRoot.OnlyBinary) { dir, _ ->
|
index.findClass(classId, acceptedRootTypes = JavaRoot.OnlyBinary) { dir, _ ->
|
||||||
dir.findChild(fileName)?.takeIf(VirtualFile::isValid)
|
dir.findChild(fileName)?.takeIf(VirtualFile::isValid)
|
||||||
}?.takeIf { it in scope }
|
}?.takeIf { it in scope }
|
||||||
}
|
}
|
||||||
|
|||||||
-4
@@ -21,10 +21,6 @@ public class CompileEnvironmentException extends RuntimeException {
|
|||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompileEnvironmentException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompileEnvironmentException(String message, Throwable cause) {
|
public CompileEnvironmentException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,9 @@ public class CompileEnvironmentUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: includeRuntime should be not a flag but a path to runtime
|
// TODO: includeRuntime should be not a flag but a path to runtime
|
||||||
private static void doWriteToJar(OutputFileCollection outputFiles, OutputStream fos, @Nullable FqName mainClass, boolean includeRuntime) {
|
private static void doWriteToJar(
|
||||||
|
OutputFileCollection outputFiles, OutputStream fos, @Nullable FqName mainClass, boolean includeRuntime
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
Manifest manifest = new Manifest();
|
Manifest manifest = new Manifest();
|
||||||
Attributes mainAttributes = manifest.getMainAttributes();
|
Attributes mainAttributes = manifest.getMainAttributes();
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider
|
|||||||
import java.io.EOFException
|
import java.io.EOFException
|
||||||
|
|
||||||
class JvmPackagePartProvider(
|
class JvmPackagePartProvider(
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
private val scope: GlobalSearchScope
|
private val scope: GlobalSearchScope
|
||||||
) : PackagePartProvider, MetadataPartProvider {
|
) : PackagePartProvider, MetadataPartProvider {
|
||||||
private data class ModuleMappingInfo(val root: VirtualFile, val mapping: ModuleMapping, val name: String)
|
private data class ModuleMappingInfo(val root: VirtualFile, val mapping: ModuleMapping, val name: String)
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ class JvmPackagePartProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun findMetadataPackageParts(packageFqName: String): List<String> =
|
override fun findMetadataPackageParts(packageFqName: String): List<String> =
|
||||||
getPackageParts(packageFqName).values.flatMap(PackageParts::metadataParts).distinct()
|
getPackageParts(packageFqName).values.flatMap(PackageParts::metadataParts).distinct()
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun getPackageParts(packageFqName: String): Map<VirtualFile, PackageParts> {
|
private fun getPackageParts(packageFqName: String): Map<VirtualFile, PackageParts> {
|
||||||
|
|||||||
+30
-41
@@ -53,10 +53,10 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
private var useFastClassFilesReading = false
|
private var useFastClassFilesReading = false
|
||||||
|
|
||||||
fun initialize(
|
fun initialize(
|
||||||
index: JvmDependenciesIndex,
|
index: JvmDependenciesIndex,
|
||||||
packagePartProviders: List<JvmPackagePartProvider>,
|
packagePartProviders: List<JvmPackagePartProvider>,
|
||||||
singleJavaFileRootsIndex: SingleJavaFileRootsIndex,
|
singleJavaFileRootsIndex: SingleJavaFileRootsIndex,
|
||||||
useFastClassFilesReading: Boolean
|
useFastClassFilesReading: Boolean
|
||||||
) {
|
) {
|
||||||
this.index = index
|
this.index = index
|
||||||
this.packagePartProviders = packagePartProviders
|
this.packagePartProviders = packagePartProviders
|
||||||
@@ -73,14 +73,12 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
return topLevelClassesCache.getOrPut(classId.packageFqName.child(classId.relativeClassName.pathSegments().first())) {
|
return topLevelClassesCache.getOrPut(classId.packageFqName.child(classId.relativeClassName.pathSegments().first())) {
|
||||||
index.findClass(classId) { dir, type ->
|
index.findClass(classId) { dir, type ->
|
||||||
findVirtualFileGivenPackage(dir, relativeClassName, type)
|
findVirtualFileGivenPackage(dir, relativeClassName, type)
|
||||||
}
|
} ?: singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||||
?: singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
|
||||||
}?.takeIf { it in searchScope }
|
}?.takeIf { it in searchScope }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
||||||
private val signatureParsingComponent =
|
private val signatureParsingComponent = BinaryClassSignatureParser()
|
||||||
BinaryClassSignatureParser()
|
|
||||||
|
|
||||||
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? {
|
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? {
|
||||||
val virtualFile = findVirtualFileForTopLevelClass(classId, searchScope) ?: return null
|
val virtualFile = findVirtualFileForTopLevelClass(classId, searchScope) ?: return null
|
||||||
@@ -103,12 +101,8 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
val resolver = ClassifierResolutionContext { findClass(it, allScope) }
|
val resolver = ClassifierResolutionContext { findClass(it, allScope) }
|
||||||
|
|
||||||
BinaryJavaClass(
|
BinaryJavaClass(
|
||||||
virtualFile,
|
virtualFile, classId.asSingleFqName(), resolver, signatureParsingComponent,
|
||||||
classId.asSingleFqName(),
|
outerClass = null, classContent = classContent
|
||||||
resolver,
|
|
||||||
signatureParsingComponent,
|
|
||||||
outerClass = null,
|
|
||||||
classContent = classContent
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,9 +136,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
if (packageFqName.isRoot) break
|
if (packageFqName.isRoot) break
|
||||||
|
|
||||||
classId = ClassId(
|
classId = ClassId(
|
||||||
packageFqName.parent(),
|
packageFqName.parent(),
|
||||||
FqName(packageFqName.shortName().asString() + "." + classId.relativeClassName.asString()),
|
FqName(packageFqName.shortName().asString() + "." + classId.relativeClassName.asString()),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,9 +149,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
val relativeClassName = classId.relativeClassName.asString()
|
val relativeClassName = classId.relativeClassName.asString()
|
||||||
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
|
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
|
||||||
val psiClass =
|
val psiClass =
|
||||||
findVirtualFileGivenPackage(dir, relativeClassName, rootType)
|
findVirtualFileGivenPackage(dir, relativeClassName, rootType)
|
||||||
?.takeIf { it in scope }
|
?.takeIf { it in scope }
|
||||||
?.findPsiClassInVirtualFile(relativeClassName)
|
?.findPsiClassInVirtualFile(relativeClassName)
|
||||||
if (psiClass != null) {
|
if (psiClass != null) {
|
||||||
result.add(psiClass)
|
result.add(psiClass)
|
||||||
}
|
}
|
||||||
@@ -166,9 +160,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.addIfNotNull(
|
result.addIfNotNull(
|
||||||
singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||||
?.takeIf { it in scope }
|
?.takeIf { it in scope }
|
||||||
?.findPsiClassInVirtualFile(relativeClassName)
|
?.findPsiClassInVirtualFile(relativeClassName)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (result.isNotEmpty()) {
|
if (result.isNotEmpty()) {
|
||||||
@@ -197,9 +191,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findVirtualFileGivenPackage(
|
private fun findVirtualFileGivenPackage(
|
||||||
packageDir: VirtualFile,
|
packageDir: VirtualFile,
|
||||||
classNameWithInnerClasses: String,
|
classNameWithInnerClasses: String,
|
||||||
rootType: JavaRoot.RootType
|
rootType: JavaRoot.RootType
|
||||||
): VirtualFile? {
|
): VirtualFile? {
|
||||||
val topLevelClassName = classNameWithInnerClasses.substringBefore('.')
|
val topLevelClassName = classNameWithInnerClasses.substringBefore('.')
|
||||||
|
|
||||||
@@ -216,18 +210,14 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
return vFile
|
return vFile
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun VirtualFile.findPsiClassInVirtualFile(
|
private fun VirtualFile.findPsiClassInVirtualFile(classNameWithInnerClasses: String): PsiClass? {
|
||||||
classNameWithInnerClasses: String
|
|
||||||
): PsiClass? {
|
|
||||||
val file = myPsiManager.findFile(this) as? PsiClassOwner ?: return null
|
val file = myPsiManager.findFile(this) as? PsiClassOwner ?: return null
|
||||||
return findClassInPsiFile(classNameWithInnerClasses, file)
|
return findClassInPsiFile(classNameWithInnerClasses, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String> {
|
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String> {
|
||||||
val result = hashSetOf<String>()
|
val result = hashSetOf<String>()
|
||||||
index.traverseDirectoriesInPackage(packageFqName, continueSearch = {
|
index.traverseDirectoriesInPackage(packageFqName, continueSearch = { dir, _ ->
|
||||||
dir, _ ->
|
|
||||||
|
|
||||||
for (child in dir.children) {
|
for (child in dir.children) {
|
||||||
if (child.extension == "class" || child.extension == "java") {
|
if (child.extension == "class" || child.extension == "java") {
|
||||||
result.add(child.nameWithoutExtension)
|
result.add(child.nameWithoutExtension)
|
||||||
@@ -286,15 +276,14 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// a sad workaround to avoid throwing exception when called from inside IDEA code
|
// a sad workaround to avoid throwing exception when called from inside IDEA code
|
||||||
private fun <T : Any> safely(compute: () -> T): T? = try {
|
private fun <T : Any> safely(compute: () -> T): T? =
|
||||||
compute()
|
try {
|
||||||
}
|
compute()
|
||||||
catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
null
|
null
|
||||||
}
|
} catch (e: AssertionError) {
|
||||||
catch (e: AssertionError) {
|
null
|
||||||
null
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun String.toSafeFqName(): FqName? = safely { FqName(this) }
|
private fun String.toSafeFqName(): FqName? = safely { FqName(this) }
|
||||||
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }
|
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }
|
||||||
|
|||||||
+30
-41
@@ -53,10 +53,10 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
private var useFastClassFilesReading = false
|
private var useFastClassFilesReading = false
|
||||||
|
|
||||||
fun initialize(
|
fun initialize(
|
||||||
index: JvmDependenciesIndex,
|
index: JvmDependenciesIndex,
|
||||||
packagePartProviders: List<JvmPackagePartProvider>,
|
packagePartProviders: List<JvmPackagePartProvider>,
|
||||||
singleJavaFileRootsIndex: SingleJavaFileRootsIndex,
|
singleJavaFileRootsIndex: SingleJavaFileRootsIndex,
|
||||||
useFastClassFilesReading: Boolean
|
useFastClassFilesReading: Boolean
|
||||||
) {
|
) {
|
||||||
this.index = index
|
this.index = index
|
||||||
this.packagePartProviders = packagePartProviders
|
this.packagePartProviders = packagePartProviders
|
||||||
@@ -73,14 +73,12 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
return topLevelClassesCache.getOrPut(classId.packageFqName.child(classId.relativeClassName.pathSegments().first())) {
|
return topLevelClassesCache.getOrPut(classId.packageFqName.child(classId.relativeClassName.pathSegments().first())) {
|
||||||
index.findClass(classId) { dir, type ->
|
index.findClass(classId) { dir, type ->
|
||||||
findVirtualFileGivenPackage(dir, relativeClassName, type)
|
findVirtualFileGivenPackage(dir, relativeClassName, type)
|
||||||
}
|
} ?: singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||||
?: singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
|
||||||
}?.takeIf { it in searchScope }
|
}?.takeIf { it in searchScope }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
||||||
private val signatureParsingComponent =
|
private val signatureParsingComponent = BinaryClassSignatureParser()
|
||||||
BinaryClassSignatureParser()
|
|
||||||
|
|
||||||
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? {
|
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? {
|
||||||
val virtualFile = findVirtualFileForTopLevelClass(classId, searchScope) ?: return null
|
val virtualFile = findVirtualFileForTopLevelClass(classId, searchScope) ?: return null
|
||||||
@@ -103,12 +101,8 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
val resolver = ClassifierResolutionContext { findClass(it, allScope) }
|
val resolver = ClassifierResolutionContext { findClass(it, allScope) }
|
||||||
|
|
||||||
BinaryJavaClass(
|
BinaryJavaClass(
|
||||||
virtualFile,
|
virtualFile, classId.asSingleFqName(), resolver, signatureParsingComponent,
|
||||||
classId.asSingleFqName(),
|
outerClass = null, classContent = classContent
|
||||||
resolver,
|
|
||||||
signatureParsingComponent,
|
|
||||||
outerClass = null,
|
|
||||||
classContent = classContent
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,9 +136,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
if (packageFqName.isRoot) break
|
if (packageFqName.isRoot) break
|
||||||
|
|
||||||
classId = ClassId(
|
classId = ClassId(
|
||||||
packageFqName.parent(),
|
packageFqName.parent(),
|
||||||
FqName(packageFqName.shortName().asString() + "." + classId.relativeClassName.asString()),
|
FqName(packageFqName.shortName().asString() + "." + classId.relativeClassName.asString()),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,9 +149,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
val relativeClassName = classId.relativeClassName.asString()
|
val relativeClassName = classId.relativeClassName.asString()
|
||||||
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
|
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
|
||||||
val psiClass =
|
val psiClass =
|
||||||
findVirtualFileGivenPackage(dir, relativeClassName, rootType)
|
findVirtualFileGivenPackage(dir, relativeClassName, rootType)
|
||||||
?.takeIf { it in scope }
|
?.takeIf { it in scope }
|
||||||
?.findPsiClassInVirtualFile(relativeClassName)
|
?.findPsiClassInVirtualFile(relativeClassName)
|
||||||
if (psiClass != null) {
|
if (psiClass != null) {
|
||||||
result.add(psiClass)
|
result.add(psiClass)
|
||||||
}
|
}
|
||||||
@@ -166,9 +160,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.addIfNotNull(
|
result.addIfNotNull(
|
||||||
singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||||
?.takeIf { it in scope }
|
?.takeIf { it in scope }
|
||||||
?.findPsiClassInVirtualFile(relativeClassName)
|
?.findPsiClassInVirtualFile(relativeClassName)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (result.isNotEmpty()) {
|
if (result.isNotEmpty()) {
|
||||||
@@ -197,9 +191,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findVirtualFileGivenPackage(
|
private fun findVirtualFileGivenPackage(
|
||||||
packageDir: VirtualFile,
|
packageDir: VirtualFile,
|
||||||
classNameWithInnerClasses: String,
|
classNameWithInnerClasses: String,
|
||||||
rootType: JavaRoot.RootType
|
rootType: JavaRoot.RootType
|
||||||
): VirtualFile? {
|
): VirtualFile? {
|
||||||
val topLevelClassName = classNameWithInnerClasses.substringBefore('.')
|
val topLevelClassName = classNameWithInnerClasses.substringBefore('.')
|
||||||
|
|
||||||
@@ -216,18 +210,14 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
return vFile
|
return vFile
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun VirtualFile.findPsiClassInVirtualFile(
|
private fun VirtualFile.findPsiClassInVirtualFile(classNameWithInnerClasses: String): PsiClass? {
|
||||||
classNameWithInnerClasses: String
|
|
||||||
): PsiClass? {
|
|
||||||
val file = myPsiManager.findFile(this) as? PsiClassOwner ?: return null
|
val file = myPsiManager.findFile(this) as? PsiClassOwner ?: return null
|
||||||
return findClassInPsiFile(classNameWithInnerClasses, file)
|
return findClassInPsiFile(classNameWithInnerClasses, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String> {
|
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String> {
|
||||||
val result = hashSetOf<String>()
|
val result = hashSetOf<String>()
|
||||||
index.traverseDirectoriesInPackage(packageFqName, continueSearch = {
|
index.traverseDirectoriesInPackage(packageFqName, continueSearch = { dir, _ ->
|
||||||
dir, _ ->
|
|
||||||
|
|
||||||
for (child in dir.children) {
|
for (child in dir.children) {
|
||||||
if (child.extension == "class" || child.extension == "java") {
|
if (child.extension == "class" || child.extension == "java") {
|
||||||
result.add(child.nameWithoutExtension)
|
result.add(child.nameWithoutExtension)
|
||||||
@@ -288,15 +278,14 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// a sad workaround to avoid throwing exception when called from inside IDEA code
|
// a sad workaround to avoid throwing exception when called from inside IDEA code
|
||||||
private fun <T : Any> safely(compute: () -> T): T? = try {
|
private fun <T : Any> safely(compute: () -> T): T? =
|
||||||
compute()
|
try {
|
||||||
}
|
compute()
|
||||||
catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
null
|
null
|
||||||
}
|
} catch (e: AssertionError) {
|
||||||
catch (e: AssertionError) {
|
null
|
||||||
null
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun String.toSafeFqName(): FqName? = safely { FqName(this) }
|
private fun String.toSafeFqName(): FqName? = safely { FqName(this) }
|
||||||
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }
|
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }
|
||||||
|
|||||||
+30
-41
@@ -53,10 +53,10 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
private var useFastClassFilesReading = false
|
private var useFastClassFilesReading = false
|
||||||
|
|
||||||
fun initialize(
|
fun initialize(
|
||||||
index: JvmDependenciesIndex,
|
index: JvmDependenciesIndex,
|
||||||
packagePartProviders: List<JvmPackagePartProvider>,
|
packagePartProviders: List<JvmPackagePartProvider>,
|
||||||
singleJavaFileRootsIndex: SingleJavaFileRootsIndex,
|
singleJavaFileRootsIndex: SingleJavaFileRootsIndex,
|
||||||
useFastClassFilesReading: Boolean
|
useFastClassFilesReading: Boolean
|
||||||
) {
|
) {
|
||||||
this.index = index
|
this.index = index
|
||||||
this.packagePartProviders = packagePartProviders
|
this.packagePartProviders = packagePartProviders
|
||||||
@@ -73,14 +73,12 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
return topLevelClassesCache.getOrPut(classId.packageFqName.child(classId.relativeClassName.pathSegments().first())) {
|
return topLevelClassesCache.getOrPut(classId.packageFqName.child(classId.relativeClassName.pathSegments().first())) {
|
||||||
index.findClass(classId) { dir, type ->
|
index.findClass(classId) { dir, type ->
|
||||||
findVirtualFileGivenPackage(dir, relativeClassName, type)
|
findVirtualFileGivenPackage(dir, relativeClassName, type)
|
||||||
}
|
} ?: singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||||
?: singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
|
||||||
}?.takeIf { it in searchScope }
|
}?.takeIf { it in searchScope }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
||||||
private val signatureParsingComponent =
|
private val signatureParsingComponent = BinaryClassSignatureParser()
|
||||||
BinaryClassSignatureParser()
|
|
||||||
|
|
||||||
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? {
|
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? {
|
||||||
val virtualFile = findVirtualFileForTopLevelClass(classId, searchScope) ?: return null
|
val virtualFile = findVirtualFileForTopLevelClass(classId, searchScope) ?: return null
|
||||||
@@ -103,12 +101,8 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
val resolver = ClassifierResolutionContext { findClass(it, allScope) }
|
val resolver = ClassifierResolutionContext { findClass(it, allScope) }
|
||||||
|
|
||||||
BinaryJavaClass(
|
BinaryJavaClass(
|
||||||
virtualFile,
|
virtualFile, classId.asSingleFqName(), resolver, signatureParsingComponent,
|
||||||
classId.asSingleFqName(),
|
outerClass = null, classContent = classContent
|
||||||
resolver,
|
|
||||||
signatureParsingComponent,
|
|
||||||
outerClass = null,
|
|
||||||
classContent = classContent
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,9 +136,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
if (packageFqName.isRoot) break
|
if (packageFqName.isRoot) break
|
||||||
|
|
||||||
classId = ClassId(
|
classId = ClassId(
|
||||||
packageFqName.parent(),
|
packageFqName.parent(),
|
||||||
FqName(packageFqName.shortName().asString() + "." + classId.relativeClassName.asString()),
|
FqName(packageFqName.shortName().asString() + "." + classId.relativeClassName.asString()),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,9 +149,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
val relativeClassName = classId.relativeClassName.asString()
|
val relativeClassName = classId.relativeClassName.asString()
|
||||||
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
|
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
|
||||||
val psiClass =
|
val psiClass =
|
||||||
findVirtualFileGivenPackage(dir, relativeClassName, rootType)
|
findVirtualFileGivenPackage(dir, relativeClassName, rootType)
|
||||||
?.takeIf { it in scope }
|
?.takeIf { it in scope }
|
||||||
?.findPsiClassInVirtualFile(relativeClassName)
|
?.findPsiClassInVirtualFile(relativeClassName)
|
||||||
if (psiClass != null) {
|
if (psiClass != null) {
|
||||||
result.add(psiClass)
|
result.add(psiClass)
|
||||||
}
|
}
|
||||||
@@ -166,9 +160,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.addIfNotNull(
|
result.addIfNotNull(
|
||||||
singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||||
?.takeIf { it in scope }
|
?.takeIf { it in scope }
|
||||||
?.findPsiClassInVirtualFile(relativeClassName)
|
?.findPsiClassInVirtualFile(relativeClassName)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (result.isNotEmpty()) {
|
if (result.isNotEmpty()) {
|
||||||
@@ -197,9 +191,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findVirtualFileGivenPackage(
|
private fun findVirtualFileGivenPackage(
|
||||||
packageDir: VirtualFile,
|
packageDir: VirtualFile,
|
||||||
classNameWithInnerClasses: String,
|
classNameWithInnerClasses: String,
|
||||||
rootType: JavaRoot.RootType
|
rootType: JavaRoot.RootType
|
||||||
): VirtualFile? {
|
): VirtualFile? {
|
||||||
val topLevelClassName = classNameWithInnerClasses.substringBefore('.')
|
val topLevelClassName = classNameWithInnerClasses.substringBefore('.')
|
||||||
|
|
||||||
@@ -216,18 +210,14 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
return vFile
|
return vFile
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun VirtualFile.findPsiClassInVirtualFile(
|
private fun VirtualFile.findPsiClassInVirtualFile(classNameWithInnerClasses: String): PsiClass? {
|
||||||
classNameWithInnerClasses: String
|
|
||||||
): PsiClass? {
|
|
||||||
val file = myPsiManager.findFile(this) as? PsiClassOwner ?: return null
|
val file = myPsiManager.findFile(this) as? PsiClassOwner ?: return null
|
||||||
return findClassInPsiFile(classNameWithInnerClasses, file)
|
return findClassInPsiFile(classNameWithInnerClasses, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String> {
|
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String> {
|
||||||
val result = hashSetOf<String>()
|
val result = hashSetOf<String>()
|
||||||
index.traverseDirectoriesInPackage(packageFqName, continueSearch = {
|
index.traverseDirectoriesInPackage(packageFqName, continueSearch = { dir, _ ->
|
||||||
dir, _ ->
|
|
||||||
|
|
||||||
for (child in dir.children) {
|
for (child in dir.children) {
|
||||||
if (child.extension == "class" || child.extension == "java") {
|
if (child.extension == "class" || child.extension == "java") {
|
||||||
result.add(child.nameWithoutExtension)
|
result.add(child.nameWithoutExtension)
|
||||||
@@ -288,15 +278,14 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// a sad workaround to avoid throwing exception when called from inside IDEA code
|
// a sad workaround to avoid throwing exception when called from inside IDEA code
|
||||||
private fun <T : Any> safely(compute: () -> T): T? = try {
|
private fun <T : Any> safely(compute: () -> T): T? =
|
||||||
compute()
|
try {
|
||||||
}
|
compute()
|
||||||
catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
null
|
null
|
||||||
}
|
} catch (e: AssertionError) {
|
||||||
catch (e: AssertionError) {
|
null
|
||||||
null
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun String.toSafeFqName(): FqName? = safely { FqName(this) }
|
private fun String.toSafeFqName(): FqName? = safely { FqName(this) }
|
||||||
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }
|
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
|
|
||||||
val outputDirectory =
|
val outputDirectory =
|
||||||
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
||||||
?: configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)?.absolutePath
|
?: configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)?.absolutePath
|
||||||
|
|
||||||
classpathRootsResolver = ClasspathRootsResolver(
|
classpathRootsResolver = ClasspathRootsResolver(
|
||||||
PsiManager.getInstance(project),
|
PsiManager.getInstance(project),
|
||||||
@@ -554,14 +554,14 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
|
|
||||||
val pluginRoot =
|
val pluginRoot =
|
||||||
configuration.get(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT)?.let(::File)
|
configuration.get(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT)?.let(::File)
|
||||||
?: configuration.get(CLIConfigurationKeys.COMPILER_JAR_LOCATOR)?.compilerJar
|
?: configuration.get(CLIConfigurationKeys.COMPILER_JAR_LOCATOR)?.compilerJar
|
||||||
?: PathUtil.getResourcePathForClass(this::class.java).takeIf { it.hasConfigFile(configFilePath) }
|
?: PathUtil.getResourcePathForClass(this::class.java).takeIf { it.hasConfigFile(configFilePath) }
|
||||||
// hack for load extensions when compiler run directly from project directory (e.g. in tests)
|
// hack for load extensions when compiler run directly from project directory (e.g. in tests)
|
||||||
?: File("idea/src").takeIf { it.hasConfigFile(configFilePath) }
|
?: File("idea/src").takeIf { it.hasConfigFile(configFilePath) }
|
||||||
?: throw IllegalStateException(
|
?: throw IllegalStateException(
|
||||||
"Unable to find extension point configuration $configFilePath " +
|
"Unable to find extension point configuration $configFilePath " +
|
||||||
"(cp:\n ${(Thread.currentThread().contextClassLoader as? UrlClassLoader)?.urls?.joinToString("\n ") { it.file }})"
|
"(cp:\n ${(Thread.currentThread().contextClassLoader as? UrlClassLoader)?.urls?.joinToString("\n ") { it.file }})"
|
||||||
)
|
)
|
||||||
|
|
||||||
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginRoot, configFilePath, Extensions.getRootArea())
|
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginRoot, configFilePath, Extensions.getRootArea())
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -20,11 +20,10 @@ import com.intellij.core.JavaCoreApplicationEnvironment
|
|||||||
import com.intellij.core.JavaCoreProjectEnvironment
|
import com.intellij.core.JavaCoreProjectEnvironment
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.controlFlow.ControlFlowFactory
|
|
||||||
|
|
||||||
open class KotlinCoreProjectEnvironment(
|
open class KotlinCoreProjectEnvironment(
|
||||||
disposable: Disposable,
|
disposable: Disposable,
|
||||||
applicationEnvironment: JavaCoreApplicationEnvironment
|
applicationEnvironment: JavaCoreApplicationEnvironment
|
||||||
) : JavaCoreProjectEnvironment(disposable, applicationEnvironment) {
|
) : JavaCoreProjectEnvironment(disposable, applicationEnvironment) {
|
||||||
override fun createCoreFileManager() = KotlinCliJavaFileManagerImpl(PsiManager.getInstance(project))
|
override fun createCoreFileManager() = KotlinCliJavaFileManagerImpl(PsiManager.getInstance(project))
|
||||||
}
|
}
|
||||||
+11
-12
@@ -29,7 +29,9 @@ import org.jetbrains.kotlin.asJava.FilteredJvmDiagnostics
|
|||||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
|
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
|
||||||
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
|
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||||
import org.jetbrains.kotlin.cli.common.*
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||||
|
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
|
||||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.OUTPUT
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.OUTPUT
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
|
||||||
@@ -51,12 +53,10 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.script.tryConstructClassFromStringArgs
|
import org.jetbrains.kotlin.script.tryConstructClassFromStringArgs
|
||||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
|
||||||
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.reflect.InvocationTargetException
|
import java.lang.reflect.InvocationTargetException
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
object KotlinToJVMBytecodeCompiler {
|
object KotlinToJVMBytecodeCompiler {
|
||||||
|
|
||||||
@@ -159,12 +159,11 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
it.compile(File(singleModule.getOutputDirectory()))
|
it.compile(File(singleModule.getOutputDirectory()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
projectConfiguration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).let {
|
projectConfiguration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(
|
||||||
it.report(
|
WARNING,
|
||||||
WARNING,
|
"A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). " +
|
||||||
"A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). -Xuse-javac option couldn't be used to compile java files"
|
"-Xuse-javac option couldn't be used to compile java files"
|
||||||
)
|
)
|
||||||
}
|
|
||||||
JavacWrapper.getInstance(environment.project).close()
|
JavacWrapper.getInstance(environment.project).close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +256,7 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
tryConstructClassFromStringArgs(scriptClass, scriptArgs)
|
tryConstructClassFromStringArgs(scriptClass, scriptArgs)
|
||||||
?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n")
|
?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n")
|
||||||
} finally {
|
} finally {
|
||||||
// NB: these lines are required (see KT-9546) but aren't covered by tests
|
// NB: these lines are required (see KT-9546) but aren't covered by tests
|
||||||
System.out.flush()
|
System.out.flush()
|
||||||
@@ -335,11 +334,11 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
val script = environment.getSourceFiles()[0].script ?: error("Script must be parsed")
|
val script = environment.getSourceFiles()[0].script ?: error("Script must be parsed")
|
||||||
return classLoader.loadClass(script.fqName.asString())
|
return classLoader.loadClass(script.fqName.asString())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw RuntimeException("Failed to evaluate script: " + e, e)
|
throw RuntimeException("Failed to evaluate script: $e", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun analyzeAndGenerate(environment: KotlinCoreEnvironment): GenerationState? {
|
private fun analyzeAndGenerate(environment: KotlinCoreEnvironment): GenerationState? {
|
||||||
val result = repeatAnalysisIfNeeded(analyze(environment, null), environment, null) ?: return null
|
val result = repeatAnalysisIfNeeded(analyze(environment, null), environment, null) ?: return null
|
||||||
|
|
||||||
if (!result.shouldGenerateCode) return null
|
if (!result.shouldGenerateCode) return null
|
||||||
|
|||||||
+10
-14
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
|
|||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
||||||
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll
|
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll
|
||||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.*
|
import org.jetbrains.kotlin.cli.jvm.config.*
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
@@ -53,12 +52,10 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.script.tryConstructClassFromStringArgs
|
import org.jetbrains.kotlin.script.tryConstructClassFromStringArgs
|
||||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
|
||||||
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.reflect.InvocationTargetException
|
import java.lang.reflect.InvocationTargetException
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
object KotlinToJVMBytecodeCompiler {
|
object KotlinToJVMBytecodeCompiler {
|
||||||
|
|
||||||
@@ -161,12 +158,11 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
it.compile(File(singleModule.getOutputDirectory()))
|
it.compile(File(singleModule.getOutputDirectory()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
projectConfiguration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).let {
|
projectConfiguration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(
|
||||||
it.report(
|
WARNING,
|
||||||
WARNING,
|
"A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). " +
|
||||||
"A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). -Xuse-javac option couldn't be used to compile java files"
|
"-Xuse-javac option couldn't be used to compile java files"
|
||||||
)
|
)
|
||||||
}
|
|
||||||
JavacWrapper.getInstance(environment.project).close()
|
JavacWrapper.getInstance(environment.project).close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,8 +188,8 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
module.getJavaSourceRoots().any { (path, packagePrefix) ->
|
module.getJavaSourceRoots().any { (path, packagePrefix) ->
|
||||||
val file = File(path)
|
val file = File(path)
|
||||||
packagePrefix == null &&
|
packagePrefix == null &&
|
||||||
(file.name == PsiJavaModule.MODULE_INFO_FILE ||
|
(file.name == PsiJavaModule.MODULE_INFO_FILE ||
|
||||||
(file.isDirectory && file.listFiles().any { it.name == PsiJavaModule.MODULE_INFO_FILE }))
|
(file.isDirectory && file.listFiles().any { it.name == PsiJavaModule.MODULE_INFO_FILE }))
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
@@ -259,7 +255,7 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
tryConstructClassFromStringArgs(scriptClass, scriptArgs)
|
tryConstructClassFromStringArgs(scriptClass, scriptArgs)
|
||||||
?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n")
|
?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n")
|
||||||
} finally {
|
} finally {
|
||||||
// NB: these lines are required (see KT-9546) but aren't covered by tests
|
// NB: these lines are required (see KT-9546) but aren't covered by tests
|
||||||
System.out.flush()
|
System.out.flush()
|
||||||
@@ -337,11 +333,11 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
val script = environment.getSourceFiles()[0].script ?: error("Script must be parsed")
|
val script = environment.getSourceFiles()[0].script ?: error("Script must be parsed")
|
||||||
return classLoader.loadClass(script.fqName.asString())
|
return classLoader.loadClass(script.fqName.asString())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw RuntimeException("Failed to evaluate script: " + e, e)
|
throw RuntimeException("Failed to evaluate script: $e", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun analyzeAndGenerate(environment: KotlinCoreEnvironment): GenerationState? {
|
private fun analyzeAndGenerate(environment: KotlinCoreEnvironment): GenerationState? {
|
||||||
val result = repeatAnalysisIfNeeded(analyze(environment, null), environment, null) ?: return null
|
val result = repeatAnalysisIfNeeded(analyze(environment, null), environment, null) ?: return null
|
||||||
|
|
||||||
if (!result.shouldGenerateCode) return null
|
if (!result.shouldGenerateCode) return null
|
||||||
|
|||||||
+10
-14
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
|
|||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
||||||
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll
|
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll
|
||||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.*
|
import org.jetbrains.kotlin.cli.jvm.config.*
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
@@ -53,12 +52,10 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.script.tryConstructClassFromStringArgs
|
import org.jetbrains.kotlin.script.tryConstructClassFromStringArgs
|
||||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
|
||||||
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.reflect.InvocationTargetException
|
import java.lang.reflect.InvocationTargetException
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
object KotlinToJVMBytecodeCompiler {
|
object KotlinToJVMBytecodeCompiler {
|
||||||
|
|
||||||
@@ -161,12 +158,11 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
it.compile(File(singleModule.getOutputDirectory()))
|
it.compile(File(singleModule.getOutputDirectory()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
projectConfiguration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).let {
|
projectConfiguration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(
|
||||||
it.report(
|
WARNING,
|
||||||
WARNING,
|
"A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). " +
|
||||||
"A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). -Xuse-javac option couldn't be used to compile java files"
|
"-Xuse-javac option couldn't be used to compile java files"
|
||||||
)
|
)
|
||||||
}
|
|
||||||
JavacWrapper.getInstance(environment.project).close()
|
JavacWrapper.getInstance(environment.project).close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,8 +188,8 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
module.getJavaSourceRoots().any { (path, packagePrefix) ->
|
module.getJavaSourceRoots().any { (path, packagePrefix) ->
|
||||||
val file = File(path)
|
val file = File(path)
|
||||||
packagePrefix == null &&
|
packagePrefix == null &&
|
||||||
(file.name == PsiJavaModule.MODULE_INFO_FILE ||
|
(file.name == PsiJavaModule.MODULE_INFO_FILE ||
|
||||||
(file.isDirectory && file.listFiles().any { it.name == PsiJavaModule.MODULE_INFO_FILE }))
|
(file.isDirectory && file.listFiles().any { it.name == PsiJavaModule.MODULE_INFO_FILE }))
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
@@ -259,7 +255,7 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
tryConstructClassFromStringArgs(scriptClass, scriptArgs)
|
tryConstructClassFromStringArgs(scriptClass, scriptArgs)
|
||||||
?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n")
|
?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n")
|
||||||
} finally {
|
} finally {
|
||||||
// NB: these lines are required (see KT-9546) but aren't covered by tests
|
// NB: these lines are required (see KT-9546) but aren't covered by tests
|
||||||
System.out.flush()
|
System.out.flush()
|
||||||
@@ -337,11 +333,11 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
val script = environment.getSourceFiles()[0].script ?: error("Script must be parsed")
|
val script = environment.getSourceFiles()[0].script ?: error("Script must be parsed")
|
||||||
return classLoader.loadClass(script.fqName.asString())
|
return classLoader.loadClass(script.fqName.asString())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw RuntimeException("Failed to evaluate script: " + e, e)
|
throw RuntimeException("Failed to evaluate script: $e", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun analyzeAndGenerate(environment: KotlinCoreEnvironment): GenerationState? {
|
private fun analyzeAndGenerate(environment: KotlinCoreEnvironment): GenerationState? {
|
||||||
val result = repeatAnalysisIfNeeded(analyze(environment, null), environment, null) ?: return null
|
val result = repeatAnalysisIfNeeded(analyze(environment, null), environment, null) ?: return null
|
||||||
|
|
||||||
if (!result.shouldGenerateCode) return null
|
if (!result.shouldGenerateCode) return null
|
||||||
|
|||||||
+11
-2
@@ -30,7 +30,12 @@ class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
|
|||||||
override fun findExternalAnnotation(listOwner: PsiModifierListOwner, annotationFQN: String): PsiAnnotation? = null
|
override fun findExternalAnnotation(listOwner: PsiModifierListOwner, annotationFQN: String): PsiAnnotation? = null
|
||||||
override fun findExternalAnnotations(listOwner: PsiModifierListOwner): Array<out PsiAnnotation>? = null
|
override fun findExternalAnnotations(listOwner: PsiModifierListOwner): Array<out PsiAnnotation>? = null
|
||||||
|
|
||||||
override fun annotateExternally(listOwner: PsiModifierListOwner, annotationFQName: String, fromFile: PsiFile, value: Array<out PsiNameValuePair>?) {
|
override fun annotateExternally(
|
||||||
|
listOwner: PsiModifierListOwner,
|
||||||
|
annotationFQName: String,
|
||||||
|
fromFile: PsiFile,
|
||||||
|
value: Array<out PsiNameValuePair>?
|
||||||
|
) {
|
||||||
throw UnsupportedOperationException("not implemented")
|
throw UnsupportedOperationException("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +43,11 @@ class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
|
|||||||
throw UnsupportedOperationException("not implemented")
|
throw UnsupportedOperationException("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun editExternalAnnotation(listOwner: PsiModifierListOwner, annotationFQN: String, value: Array<out PsiNameValuePair>?): Boolean {
|
override fun editExternalAnnotation(
|
||||||
|
listOwner: PsiModifierListOwner,
|
||||||
|
annotationFQN: String,
|
||||||
|
value: Array<out PsiNameValuePair>?
|
||||||
|
): Boolean {
|
||||||
throw UnsupportedOperationException("not implemented")
|
throw UnsupportedOperationException("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.cli.jvm.compiler;
|
|
||||||
|
|
||||||
public class ModuleExecutionException extends RuntimeException {
|
|
||||||
public ModuleExecutionException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleExecutionException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleExecutionException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+60
-59
@@ -50,7 +50,6 @@ import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
|
|||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
|
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
|
||||||
import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava
|
import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava
|
||||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
|
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
|
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
|
||||||
@@ -66,7 +65,6 @@ import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtens
|
|||||||
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
|
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
|
||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.reflect.KFunction1
|
import kotlin.reflect.KFunction1
|
||||||
@@ -75,16 +73,16 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun analyzeFilesWithJavaIntegration(
|
fun analyzeFilesWithJavaIntegration(
|
||||||
project: Project,
|
project: Project,
|
||||||
files: Collection<KtFile>,
|
files: Collection<KtFile>,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||||
declarationProviderFactory: (StorageManager, Collection<KtFile>) -> DeclarationProviderFactory = ::FileBasedDeclarationProviderFactory,
|
declarationProviderFactory: (StorageManager, Collection<KtFile>) -> DeclarationProviderFactory = ::FileBasedDeclarationProviderFactory,
|
||||||
sourceModuleSearchScope: GlobalSearchScope = newModuleSearchScope(project, files)
|
sourceModuleSearchScope: GlobalSearchScope = newModuleSearchScope(project, files)
|
||||||
): AnalysisResult {
|
): AnalysisResult {
|
||||||
val container = createContainer(
|
val container = createContainer(
|
||||||
project, files, trace, configuration, packagePartProvider, declarationProviderFactory, sourceModuleSearchScope
|
project, files, trace, configuration, packagePartProvider, declarationProviderFactory, sourceModuleSearchScope
|
||||||
)
|
)
|
||||||
|
|
||||||
val module = container.get<ModuleDescriptor>()
|
val module = container.get<ModuleDescriptor>()
|
||||||
@@ -118,13 +116,13 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createContainer(
|
fun createContainer(
|
||||||
project: Project,
|
project: Project,
|
||||||
files: Collection<KtFile>,
|
files: Collection<KtFile>,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||||
declarationProviderFactory: (StorageManager, Collection<KtFile>) -> DeclarationProviderFactory,
|
declarationProviderFactory: (StorageManager, Collection<KtFile>) -> DeclarationProviderFactory,
|
||||||
sourceModuleSearchScope: GlobalSearchScope = newModuleSearchScope(project, files)
|
sourceModuleSearchScope: GlobalSearchScope = newModuleSearchScope(project, files)
|
||||||
): ComponentProvider {
|
): ComponentProvider {
|
||||||
val createBuiltInsFromModule = configuration.getBoolean(JVMConfigurationKeys.CREATE_BUILT_INS_FROM_MODULE_DEPENDENCIES)
|
val createBuiltInsFromModule = configuration.getBoolean(JVMConfigurationKeys.CREATE_BUILT_INS_FROM_MODULE_DEPENDENCIES)
|
||||||
val moduleContext = createModuleContext(project, configuration, createBuiltInsFromModule)
|
val moduleContext = createModuleContext(project, configuration, createBuiltInsFromModule)
|
||||||
@@ -146,12 +144,11 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
val languageVersionSettings = configuration.languageVersionSettings
|
val languageVersionSettings = configuration.languageVersionSettings
|
||||||
|
|
||||||
val optionalBuiltInsModule =
|
val optionalBuiltInsModule =
|
||||||
if (configuration.getBoolean(JVMConfigurationKeys.ADD_BUILT_INS_FROM_COMPILER_TO_DEPENDENCIES)) {
|
if (configuration.getBoolean(JVMConfigurationKeys.ADD_BUILT_INS_FROM_COMPILER_TO_DEPENDENCIES)) {
|
||||||
if (createBuiltInsFromModule)
|
if (createBuiltInsFromModule)
|
||||||
JvmBuiltIns(storageManager).apply { initialize(module, languageVersionSettings) }.builtInsModule
|
JvmBuiltIns(storageManager).apply { initialize(module, languageVersionSettings) }.builtInsModule
|
||||||
else module.builtIns.builtInsModule
|
else module.builtIns.builtInsModule
|
||||||
}
|
} else null
|
||||||
else null
|
|
||||||
|
|
||||||
fun StorageComponentContainer.useJavac() {
|
fun StorageComponentContainer.useJavac() {
|
||||||
useImpl<JavacBasedClassFinder>()
|
useImpl<JavacBasedClassFinder>()
|
||||||
@@ -159,34 +156,38 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
useImpl<JavacBasedSourceElementFactory>()
|
useImpl<JavacBasedSourceElementFactory>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("USELESS_CAST")
|
||||||
val configureJavaClassFinder =
|
val configureJavaClassFinder =
|
||||||
if (configuration.getBoolean(JVMConfigurationKeys.USE_JAVAC)) StorageComponentContainer::useJavac
|
if (configuration.getBoolean(JVMConfigurationKeys.USE_JAVAC)) StorageComponentContainer::useJavac
|
||||||
else null as KFunction1<StorageComponentContainer, Unit>?
|
else null as KFunction1<StorageComponentContainer, Unit>?
|
||||||
|
|
||||||
val dependencyModule = if (separateModules) {
|
val dependencyModule = if (separateModules) {
|
||||||
val dependenciesContext = ContextForNewModule(
|
val dependenciesContext = ContextForNewModule(
|
||||||
moduleContext, Name.special("<dependencies of ${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>"),
|
moduleContext, Name.special("<dependencies of ${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>"),
|
||||||
module.builtIns, null
|
module.builtIns, null
|
||||||
)
|
)
|
||||||
|
|
||||||
// Scope for the dependency module contains everything except files present in the scope for the source module
|
// Scope for the dependency module contains everything except files present in the scope for the source module
|
||||||
val dependencyScope = GlobalSearchScope.notScope(sourceScope)
|
val dependencyScope = GlobalSearchScope.notScope(sourceScope)
|
||||||
|
|
||||||
val dependenciesContainer = createContainerForTopDownAnalyzerForJvm(
|
val dependenciesContainer = createContainerForTopDownAnalyzerForJvm(
|
||||||
dependenciesContext, trace, DeclarationProviderFactory.EMPTY, dependencyScope, lookupTracker, expectActualTracker,
|
dependenciesContext, trace, DeclarationProviderFactory.EMPTY, dependencyScope, lookupTracker, expectActualTracker,
|
||||||
packagePartProvider(dependencyScope), moduleClassResolver, jvmTarget, languageVersionSettings, configureJavaClassFinder
|
packagePartProvider(dependencyScope), moduleClassResolver, jvmTarget, languageVersionSettings, configureJavaClassFinder
|
||||||
)
|
)
|
||||||
|
|
||||||
moduleClassResolver.compiledCodeResolver = dependenciesContainer.get<JavaDescriptorResolver>()
|
moduleClassResolver.compiledCodeResolver = dependenciesContainer.get()
|
||||||
|
|
||||||
dependenciesContext.setDependencies(listOfNotNull(dependenciesContext.module, optionalBuiltInsModule))
|
dependenciesContext.setDependencies(listOfNotNull(dependenciesContext.module, optionalBuiltInsModule))
|
||||||
dependenciesContext.initializeModuleContents(CompositePackageFragmentProvider(listOf(
|
dependenciesContext.initializeModuleContents(
|
||||||
moduleClassResolver.compiledCodeResolver.packageFragmentProvider,
|
CompositePackageFragmentProvider(
|
||||||
dependenciesContainer.get<JvmBuiltInsPackageFragmentProvider>()
|
listOf(
|
||||||
)))
|
moduleClassResolver.compiledCodeResolver.packageFragmentProvider,
|
||||||
|
dependenciesContainer.get<JvmBuiltInsPackageFragmentProvider>()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
dependenciesContext.module
|
dependenciesContext.module
|
||||||
}
|
} else null
|
||||||
else null
|
|
||||||
|
|
||||||
val partProvider = packagePartProvider(sourceScope).let { fragment ->
|
val partProvider = packagePartProvider(sourceScope).let { fragment ->
|
||||||
if (targetIds == null || incrementalComponents == null) fragment
|
if (targetIds == null || incrementalComponents == null) fragment
|
||||||
@@ -198,23 +199,22 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
// to be stored in CliLightClassGenerationSupport, and it better be the source one (otherwise light classes would not be found)
|
// to be stored in CliLightClassGenerationSupport, and it better be the source one (otherwise light classes would not be found)
|
||||||
// TODO: get rid of duplicate invocation of CodeAnalyzerInitializer#initialize, or refactor CliLightClassGenerationSupport
|
// TODO: get rid of duplicate invocation of CodeAnalyzerInitializer#initialize, or refactor CliLightClassGenerationSupport
|
||||||
val container = createContainerForTopDownAnalyzerForJvm(
|
val container = createContainerForTopDownAnalyzerForJvm(
|
||||||
moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, lookupTracker, expectActualTracker,
|
moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, lookupTracker, expectActualTracker,
|
||||||
partProvider, moduleClassResolver, jvmTarget, languageVersionSettings, configureJavaClassFinder,
|
partProvider, moduleClassResolver, jvmTarget, languageVersionSettings, configureJavaClassFinder,
|
||||||
javaClassTracker = configuration[JVMConfigurationKeys.JAVA_CLASSES_TRACKER]
|
javaClassTracker = configuration[JVMConfigurationKeys.JAVA_CLASSES_TRACKER]
|
||||||
).apply {
|
).apply {
|
||||||
initJvmBuiltInsForTopDownAnalysis()
|
initJvmBuiltInsForTopDownAnalysis()
|
||||||
(partProvider as? IncrementalPackagePartProvider)?.deserializationConfiguration = get<DeserializationConfiguration>()
|
(partProvider as? IncrementalPackagePartProvider)?.deserializationConfiguration = get()
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleClassResolver.sourceCodeResolver = container.get<JavaDescriptorResolver>()
|
moduleClassResolver.sourceCodeResolver = container.get()
|
||||||
val additionalProviders = ArrayList<PackageFragmentProvider>()
|
val additionalProviders = ArrayList<PackageFragmentProvider>()
|
||||||
|
|
||||||
if (incrementalComponents != null) {
|
if (incrementalComponents != null) {
|
||||||
targetIds?.mapTo(additionalProviders) { targetId ->
|
targetIds?.mapTo(additionalProviders) { targetId ->
|
||||||
IncrementalPackageFragmentProvider(
|
IncrementalPackageFragmentProvider(
|
||||||
files, module, storageManager, container.get<DeserializationComponentsForJava>().components,
|
files, module, storageManager, container.get<DeserializationComponentsForJava>().components,
|
||||||
incrementalComponents.getIncrementalCache(targetId), targetId,
|
incrementalComponents.getIncrementalCache(targetId), targetId, container.get()
|
||||||
container.get<KotlinClassFinder>()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,13 +228,14 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
|
|
||||||
// TODO: remove dependencyModule from friends
|
// TODO: remove dependencyModule from friends
|
||||||
module.setDependencies(
|
module.setDependencies(
|
||||||
listOfNotNull(module, dependencyModule, optionalBuiltInsModule),
|
listOfNotNull(module, dependencyModule, optionalBuiltInsModule),
|
||||||
if (dependencyModule != null) setOf(dependencyModule) else emptySet()
|
if (dependencyModule != null) setOf(dependencyModule) else emptySet()
|
||||||
|
)
|
||||||
|
module.initialize(
|
||||||
|
CompositePackageFragmentProvider(
|
||||||
|
listOf(container.get<KotlinCodeAnalyzer>().packageFragmentProvider) + additionalProviders
|
||||||
|
)
|
||||||
)
|
)
|
||||||
module.initialize(CompositePackageFragmentProvider(
|
|
||||||
listOf(container.get<KotlinCodeAnalyzer>().packageFragmentProvider) +
|
|
||||||
additionalProviders
|
|
||||||
))
|
|
||||||
|
|
||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
@@ -251,7 +252,7 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
// 'isDirectory' check is needed because otherwise directories such as 'frontend.java' would be recognized
|
// 'isDirectory' check is needed because otherwise directories such as 'frontend.java' would be recognized
|
||||||
// as Java source files, which makes no sense
|
// as Java source files, which makes no sense
|
||||||
override fun contains(file: VirtualFile) =
|
override fun contains(file: VirtualFile) =
|
||||||
file.fileType === JavaFileType.INSTANCE && !file.isDirectory
|
file.fileType === JavaFileType.INSTANCE && !file.isDirectory
|
||||||
|
|
||||||
override fun toString() = "All Java sources in the project"
|
override fun toString() = "All Java sources in the project"
|
||||||
}
|
}
|
||||||
@@ -270,20 +271,20 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createContextWithSealedModule(project: Project, configuration: CompilerConfiguration): MutableModuleContext =
|
fun createContextWithSealedModule(project: Project, configuration: CompilerConfiguration): MutableModuleContext =
|
||||||
createModuleContext(project, configuration, false).apply {
|
createModuleContext(project, configuration, false).apply {
|
||||||
setDependencies(module, module.builtIns.builtInsModule)
|
setDependencies(module, module.builtIns.builtInsModule)
|
||||||
(module.builtIns as JvmBuiltIns).initialize(module, configuration.languageVersionSettings)
|
(module.builtIns as JvmBuiltIns).initialize(module, configuration.languageVersionSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createModuleContext(
|
private fun createModuleContext(
|
||||||
project: Project,
|
project: Project,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
createBuiltInsFromModule: Boolean
|
createBuiltInsFromModule: Boolean
|
||||||
): MutableModuleContext {
|
): MutableModuleContext {
|
||||||
val projectContext = ProjectContext(project)
|
val projectContext = ProjectContext(project)
|
||||||
val builtIns = JvmBuiltIns(projectContext.storageManager, !createBuiltInsFromModule)
|
val builtIns = JvmBuiltIns(projectContext.storageManager, !createBuiltInsFromModule)
|
||||||
return ContextForNewModule(
|
return ContextForNewModule(
|
||||||
projectContext, Name.special("<${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>"), builtIns, null
|
projectContext, Name.special("<${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>"), builtIns, null
|
||||||
).apply {
|
).apply {
|
||||||
if (createBuiltInsFromModule) {
|
if (createBuiltInsFromModule) {
|
||||||
builtIns.builtInsModule = module
|
builtIns.builtInsModule = module
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ fun CompilerConfiguration.addJavaSourceRoots(files: List<File>, packagePrefix: S
|
|||||||
}
|
}
|
||||||
|
|
||||||
val CompilerConfiguration.javaSourceRoots: Set<String>
|
val CompilerConfiguration.javaSourceRoots: Set<String>
|
||||||
get() = getList(JVMConfigurationKeys.CONTENT_ROOTS).mapNotNullTo(linkedSetOf<String>()) { root ->
|
get() = getList(JVMConfigurationKeys.CONTENT_ROOTS).mapNotNullTo(linkedSetOf()) { root ->
|
||||||
when (root) {
|
when (root) {
|
||||||
is KotlinSourceRoot -> root.path
|
is KotlinSourceRoot -> root.path
|
||||||
is JavaSourceRoot -> root.file.path
|
is JavaSourceRoot -> root.file.path
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -34,27 +34,27 @@ class JvmDependenciesDynamicCompoundIndex : JvmDependenciesIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addNewIndexForRoots(roots: Iterable<JavaRoot>): JvmDependenciesIndex? =
|
fun addNewIndexForRoots(roots: Iterable<JavaRoot>): JvmDependenciesIndex? =
|
||||||
lock.read {
|
lock.read {
|
||||||
val alreadyIndexed = indexedRoots.toHashSet()
|
val alreadyIndexed = indexedRoots.toHashSet()
|
||||||
val newRoots = roots.filter { root -> root !in alreadyIndexed }
|
val newRoots = roots.filter { root -> root !in alreadyIndexed }
|
||||||
if (newRoots.isEmpty()) null
|
if (newRoots.isEmpty()) null
|
||||||
else JvmDependenciesIndexImpl(newRoots).also(this::addIndex)
|
else JvmDependenciesIndexImpl(newRoots).also(this::addIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val indexedRoots: Sequence<JavaRoot> get() = indices.asSequence().flatMap { it.indexedRoots }
|
override val indexedRoots: Sequence<JavaRoot> get() = indices.asSequence().flatMap { it.indexedRoots }
|
||||||
|
|
||||||
override fun <T : Any> findClass(
|
override fun <T : Any> findClass(
|
||||||
classId: ClassId,
|
classId: ClassId,
|
||||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||||
): T? = lock.read {
|
): T? = lock.read {
|
||||||
indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull()
|
indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun traverseDirectoriesInPackage(
|
override fun traverseDirectoriesInPackage(
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||||
) = lock.read {
|
) = lock.read {
|
||||||
indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) }
|
indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,15 +25,15 @@ interface JvmDependenciesIndex {
|
|||||||
val indexedRoots: Sequence<JavaRoot>
|
val indexedRoots: Sequence<JavaRoot>
|
||||||
|
|
||||||
fun <T : Any> findClass(
|
fun <T : Any> findClass(
|
||||||
classId: ClassId,
|
classId: ClassId,
|
||||||
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
|
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
|
||||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||||
): T?
|
): T?
|
||||||
|
|
||||||
fun traverseDirectoriesInPackage(
|
fun traverseDirectoriesInPackage(
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
|
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
|
||||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import java.util.*
|
|||||||
// speeds up finding files/classes in classpath/java source roots
|
// speeds up finding files/classes in classpath/java source roots
|
||||||
// NOT THREADSAFE, needs to be adapted/removed if we want compiler to be multithreaded
|
// NOT THREADSAFE, needs to be adapted/removed if we want compiler to be multithreaded
|
||||||
// the main idea of this class is for each package to store roots which contains it to avoid excessive file system traversal
|
// the main idea of this class is for each package to store roots which contains it to avoid excessive file system traversal
|
||||||
class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex {
|
||||||
//these fields are computed based on _roots passed to constructor which are filled in later
|
//these fields are computed based on _roots passed to constructor which are filled in later
|
||||||
private val roots: List<JavaRoot> by lazy { _roots.toList() }
|
private val roots: List<JavaRoot> by lazy { _roots.toList() }
|
||||||
|
|
||||||
@@ -69,9 +69,9 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun traverseDirectoriesInPackage(
|
override fun traverseDirectoriesInPackage(
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||||
) {
|
) {
|
||||||
search(TraverseRequest(packageFqName, acceptedRootTypes)) { dir, rootType ->
|
search(TraverseRequest(packageFqName, acceptedRootTypes)) { dir, rootType ->
|
||||||
if (continueSearch(dir, rootType)) null else Unit
|
if (continueSearch(dir, rootType)) null else Unit
|
||||||
@@ -80,9 +80,9 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
|||||||
|
|
||||||
// findClassGivenDirectory MUST check whether the class with this classId exists in given package
|
// findClassGivenDirectory MUST check whether the class with this classId exists in given package
|
||||||
override fun <T : Any> findClass(
|
override fun <T : Any> findClass(
|
||||||
classId: ClassId,
|
classId: ClassId,
|
||||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||||
): T? {
|
): T? {
|
||||||
// make a decision based on information saved from last class search
|
// make a decision based on information saved from last class search
|
||||||
if (lastClassSearch?.first?.classId != classId) {
|
if (lastClassSearch?.first?.classId != classId) {
|
||||||
@@ -95,16 +95,14 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
|||||||
val limitedRootTypes = acceptedRootTypes - cachedRequest.acceptedRootTypes
|
val limitedRootTypes = acceptedRootTypes - cachedRequest.acceptedRootTypes
|
||||||
if (limitedRootTypes.isEmpty()) {
|
if (limitedRootTypes.isEmpty()) {
|
||||||
null
|
null
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
search(FindClassRequest(classId, limitedRootTypes), findClassGivenDirectory)
|
search(FindClassRequest(classId, limitedRootTypes), findClassGivenDirectory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is SearchResult.Found -> {
|
is SearchResult.Found -> {
|
||||||
if (cachedRequest.acceptedRootTypes == acceptedRootTypes) {
|
if (cachedRequest.acceptedRootTypes == acceptedRootTypes) {
|
||||||
findClassGivenDirectory(cachedResult.packageDirectory, cachedResult.root.type)
|
findClassGivenDirectory(cachedResult.packageDirectory, cachedResult.root.type)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
search(FindClassRequest(classId, acceptedRootTypes), findClassGivenDirectory)
|
search(FindClassRequest(classId, acceptedRootTypes), findClassGivenDirectory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,11 +149,11 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
|||||||
// try to find a target directory corresponding to package represented by packagesPath in a given root represented by index
|
// try to find a target directory corresponding to package represented by packagesPath in a given root represented by index
|
||||||
// possibly filling "Cache" objects with new information
|
// possibly filling "Cache" objects with new information
|
||||||
private fun travelPath(
|
private fun travelPath(
|
||||||
rootIndex: Int,
|
rootIndex: Int,
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
packagesPath: List<String>,
|
packagesPath: List<String>,
|
||||||
fillCachesAfter: Int,
|
fillCachesAfter: Int,
|
||||||
cachesPath: List<Cache>
|
cachesPath: List<Cache>
|
||||||
): VirtualFile? {
|
): VirtualFile? {
|
||||||
if (rootIndex >= maxIndex) {
|
if (rootIndex >= maxIndex) {
|
||||||
for (i in (fillCachesAfter + 1)..(cachesPath.size - 1)) {
|
for (i in (fillCachesAfter + 1)..(cachesPath.size - 1)) {
|
||||||
@@ -184,8 +182,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
|||||||
if (prefixPathSegments[pathIndex].identifier != subPackageName) {
|
if (prefixPathSegments[pathIndex].identifier != subPackageName) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
currentFile = currentFile.findChildPackage(subPackageName, pathRoot.type) ?: return null
|
currentFile = currentFile.findChildPackage(subPackageName, pathRoot.type) ?: return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,8 +232,8 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private data class TraverseRequest(
|
private data class TraverseRequest(
|
||||||
override val packageFqName: FqName,
|
override val packageFqName: FqName,
|
||||||
override val acceptedRootTypes: Set<JavaRoot.RootType>
|
override val acceptedRootTypes: Set<JavaRoot.RootType>
|
||||||
) : SearchRequest
|
) : SearchRequest
|
||||||
|
|
||||||
private interface SearchRequest {
|
private interface SearchRequest {
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ class SingleJavaFileRootsIndex(private val roots: List<JavaRoot>) {
|
|||||||
private val classIdsInRoots = ArrayList<List<ClassId>>(roots.size)
|
private val classIdsInRoots = ArrayList<List<ClassId>>(roots.size)
|
||||||
|
|
||||||
fun findJavaSourceClass(classId: ClassId): VirtualFile? =
|
fun findJavaSourceClass(classId: ClassId): VirtualFile? =
|
||||||
roots.indices
|
roots.indices
|
||||||
.find { index -> classId in getClassIdsForRootAt(index) }
|
.find { index -> classId in getClassIdsForRootAt(index) }
|
||||||
?.let { index -> roots[index].file }
|
?.let { index -> roots[index].file }
|
||||||
|
|
||||||
fun findJavaSourceClasses(packageFqName: FqName): List<ClassId> =
|
fun findJavaSourceClasses(packageFqName: FqName): List<ClassId> =
|
||||||
roots.indices.flatMap(this::getClassIdsForRootAt).filter { root -> root.packageFqName == packageFqName }
|
roots.indices.flatMap(this::getClassIdsForRootAt).filter { root -> root.packageFqName == packageFqName }
|
||||||
|
|
||||||
private fun getClassIdsForRootAt(index: Int): List<ClassId> {
|
private fun getClassIdsForRootAt(index: Int): List<ClassId> {
|
||||||
for (i in classIdsInRoots.size..index) {
|
for (i in classIdsInRoots.size..index) {
|
||||||
@@ -73,7 +73,7 @@ class SingleJavaFileRootsIndex(private val roots: List<JavaRoot>) {
|
|||||||
private fun tokenText(): String = lexer.tokenText
|
private fun tokenText(): String = lexer.tokenText
|
||||||
|
|
||||||
private fun atClass(): Boolean =
|
private fun atClass(): Boolean =
|
||||||
braceBalance == 0 && lexer.tokenType in CLASS_KEYWORDS
|
braceBalance == 0 && lexer.tokenType in CLASS_KEYWORDS
|
||||||
|
|
||||||
fun readClassIds(): List<ClassId> {
|
fun readClassIds(): List<ClassId> {
|
||||||
var packageFqName = FqName.ROOT
|
var packageFqName = FqName.ROOT
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ import java.io.PrintWriter
|
|||||||
import java.io.Writer
|
import java.io.Writer
|
||||||
|
|
||||||
class JavacLogger(
|
class JavacLogger(
|
||||||
context: Context,
|
context: Context,
|
||||||
errorWriter: PrintWriter,
|
errorWriter: PrintWriter,
|
||||||
warningWriter: PrintWriter,
|
warningWriter: PrintWriter,
|
||||||
infoWriter: PrintWriter
|
infoWriter: PrintWriter
|
||||||
) : Log(context, errorWriter, warningWriter, infoWriter) {
|
) : Log(context, errorWriter, warningWriter, infoWriter) {
|
||||||
init {
|
init {
|
||||||
context.put(Log.outKey, infoWriter)
|
context.put(Log.outKey, infoWriter)
|
||||||
@@ -39,18 +39,20 @@ class JavacLogger(
|
|||||||
companion object {
|
companion object {
|
||||||
fun preRegister(context: Context, messageCollector: MessageCollector) {
|
fun preRegister(context: Context, messageCollector: MessageCollector) {
|
||||||
context.put(Log.logKey, Context.Factory<Log> {
|
context.put(Log.logKey, Context.Factory<Log> {
|
||||||
JavacLogger(it,
|
JavacLogger(
|
||||||
PrintWriter(MessageCollectorAdapter(messageCollector, CompilerMessageSeverity.ERROR)),
|
it,
|
||||||
PrintWriter(MessageCollectorAdapter(messageCollector, CompilerMessageSeverity.WARNING)),
|
PrintWriter(MessageCollectorAdapter(messageCollector, CompilerMessageSeverity.ERROR)),
|
||||||
PrintWriter(MessageCollectorAdapter(messageCollector, CompilerMessageSeverity.INFO)))
|
PrintWriter(MessageCollectorAdapter(messageCollector, CompilerMessageSeverity.WARNING)),
|
||||||
|
PrintWriter(MessageCollectorAdapter(messageCollector, CompilerMessageSeverity.INFO))
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MessageCollectorAdapter(
|
private class MessageCollectorAdapter(
|
||||||
private val messageCollector: MessageCollector,
|
private val messageCollector: MessageCollector,
|
||||||
private val severity: CompilerMessageSeverity
|
private val severity: CompilerMessageSeverity
|
||||||
) : Writer() {
|
) : Writer() {
|
||||||
override fun write(buffer: CharArray, offset: Int, length: Int) {
|
override fun write(buffer: CharArray, offset: Int, length: Int) {
|
||||||
if (length == 1 && buffer[0] == '\n') return
|
if (length == 1 && buffer[0] == '\n') return
|
||||||
|
|||||||
+5
-4
@@ -38,9 +38,10 @@ class JavacWrapperKotlinResolverImpl(private val lightClassGenerationSupport: Li
|
|||||||
return supersCache[classOrObject]!!
|
return supersCache[classOrObject]!!
|
||||||
}
|
}
|
||||||
|
|
||||||
val classDescriptor = lightClassGenerationSupport.analyze(classOrObject).get(BindingContext.CLASS, classOrObject) ?: return emptyList()
|
val classDescriptor =
|
||||||
|
lightClassGenerationSupport.analyze(classOrObject).get(BindingContext.CLASS, classOrObject) ?: return emptyList()
|
||||||
val classIds = classDescriptor.defaultType.constructor.supertypes
|
val classIds = classDescriptor.defaultType.constructor.supertypes
|
||||||
.mapNotNull { (it.constructor.declarationDescriptor as? ClassDescriptor)?.classId }
|
.mapNotNull { (it.constructor.declarationDescriptor as? ClassDescriptor)?.classId }
|
||||||
supersCache[classOrObject] = classIds
|
supersCache[classOrObject] = classIds
|
||||||
|
|
||||||
return classIds
|
return classIds
|
||||||
@@ -49,12 +50,12 @@ class JavacWrapperKotlinResolverImpl(private val lightClassGenerationSupport: Li
|
|||||||
override fun findField(classOrObject: KtClassOrObject, name: String): JavaField? {
|
override fun findField(classOrObject: KtClassOrObject, name: String): JavaField? {
|
||||||
val lightClass = classOrObject.toLightClass() ?: return null
|
val lightClass = classOrObject.toLightClass() ?: return null
|
||||||
|
|
||||||
return lightClass.allFields.find { it.name == name}?.let(::MockKotlinField)
|
return lightClass.allFields.find { it.name == name }?.let(::MockKotlinField)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findField(ktFile: KtFile?, name: String): JavaField? {
|
override fun findField(ktFile: KtFile?, name: String): JavaField? {
|
||||||
val lightClass = ktFile?.findFacadeClass() ?: return null
|
val lightClass = ktFile?.findFacadeClass() ?: return null
|
||||||
|
|
||||||
return lightClass.allFields.find { it.name == name}?.let(::MockKotlinField)
|
return lightClass.allFields.find { it.name == name }?.let(::MockKotlinField)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,25 +29,23 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
object JavacWrapperRegistrar {
|
object JavacWrapperRegistrar {
|
||||||
|
|
||||||
private const val JAVAC_CONTEXT_CLASS = "com.sun.tools.javac.util.Context"
|
private const val JAVAC_CONTEXT_CLASS = "com.sun.tools.javac.util.Context"
|
||||||
|
|
||||||
fun registerJavac(
|
fun registerJavac(
|
||||||
project: MockProject,
|
project: MockProject,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
javaFiles: List<File>,
|
javaFiles: List<File>,
|
||||||
kotlinFiles: List<KtFile>,
|
kotlinFiles: List<KtFile>,
|
||||||
arguments: Array<String>?,
|
arguments: Array<String>?,
|
||||||
bootClasspath: List<File>?,
|
bootClasspath: List<File>?,
|
||||||
sourcePath: List<File>?,
|
sourcePath: List<File>?,
|
||||||
lightClassGenerationSupport: LightClassGenerationSupport
|
lightClassGenerationSupport: LightClassGenerationSupport
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class.forName(JAVAC_CONTEXT_CLASS)
|
Class.forName(JAVAC_CONTEXT_CLASS)
|
||||||
}
|
} catch (e: ClassNotFoundException) {
|
||||||
catch (e: ClassNotFoundException) {
|
|
||||||
messageCollector.report(ERROR, "'$JAVAC_CONTEXT_CLASS' class can't be found ('tools.jar' is not found)")
|
messageCollector.report(ERROR, "'$JAVAC_CONTEXT_CLASS' class can't be found ('tools.jar' is not found)")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -60,8 +58,10 @@ object JavacWrapperRegistrar {
|
|||||||
val compileJava = configuration.getBoolean(JVMConfigurationKeys.COMPILE_JAVA)
|
val compileJava = configuration.getBoolean(JVMConfigurationKeys.COMPILE_JAVA)
|
||||||
val kotlinSupertypesResolver = JavacWrapperKotlinResolverImpl(lightClassGenerationSupport)
|
val kotlinSupertypesResolver = JavacWrapperKotlinResolverImpl(lightClassGenerationSupport)
|
||||||
|
|
||||||
val javacWrapper = JavacWrapper(javaFiles, kotlinFiles, arguments, jvmClasspathRoots, bootClasspath, sourcePath,
|
val javacWrapper = JavacWrapper(
|
||||||
kotlinSupertypesResolver, compileJava, outputDirectory, context)
|
javaFiles, kotlinFiles, arguments, jvmClasspathRoots, bootClasspath, sourcePath,
|
||||||
|
kotlinSupertypesResolver, compileJava, outputDirectory, context
|
||||||
|
)
|
||||||
|
|
||||||
project.registerService(JavacWrapper::class.java, javacWrapper)
|
project.registerService(JavacWrapper::class.java, javacWrapper)
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class CliJavaModuleFinder(jrtFileSystemRoot: VirtualFile?) : JavaModuleFinder {
|
|||||||
get() = modulesRoot?.children.orEmpty().asSequence().mapNotNull(this::findSystemModule)
|
get() = modulesRoot?.children.orEmpty().asSequence().mapNotNull(this::findSystemModule)
|
||||||
|
|
||||||
override fun findModule(name: String): JavaModule? =
|
override fun findModule(name: String): JavaModule? =
|
||||||
modulesRoot?.findChild(name)?.let(this::findSystemModule) ?: userModules[name]
|
modulesRoot?.findChild(name)?.let(this::findSystemModule) ?: userModules[name]
|
||||||
|
|
||||||
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
|
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
|
||||||
val file = moduleRoot.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE) ?: return null
|
val file = moduleRoot.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE) ?: return null
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class CliJavaModuleFinder(jrtFileSystemRoot: VirtualFile?) : JavaModuleFinder {
|
|||||||
get() = modulesRoot?.children.orEmpty().asSequence().mapNotNull(this::findSystemModule)
|
get() = modulesRoot?.children.orEmpty().asSequence().mapNotNull(this::findSystemModule)
|
||||||
|
|
||||||
override fun findModule(name: String): JavaModule? =
|
override fun findModule(name: String): JavaModule? =
|
||||||
modulesRoot?.findChild(name)?.let(this::findSystemModule) ?: userModules[name]
|
modulesRoot?.findChild(name)?.let(this::findSystemModule) ?: userModules[name]
|
||||||
|
|
||||||
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
|
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class CliJavaModuleFinder(jrtFileSystemRoot: VirtualFile?) : JavaModuleFinder {
|
|||||||
get() = modulesRoot?.children.orEmpty().asSequence().mapNotNull(this::findSystemModule)
|
get() = modulesRoot?.children.orEmpty().asSequence().mapNotNull(this::findSystemModule)
|
||||||
|
|
||||||
override fun findModule(name: String): JavaModule? =
|
override fun findModule(name: String): JavaModule? =
|
||||||
modulesRoot?.findChild(name)?.let(this::findSystemModule) ?: userModules[name]
|
modulesRoot?.findChild(name)?.let(this::findSystemModule) ?: userModules[name]
|
||||||
|
|
||||||
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
|
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||||
|
|
||||||
class CliJavaModuleResolver(
|
class CliJavaModuleResolver(
|
||||||
private val moduleGraph: JavaModuleGraph,
|
private val moduleGraph: JavaModuleGraph,
|
||||||
private val userModules: List<JavaModule>,
|
private val userModules: List<JavaModule>,
|
||||||
private val systemModules: List<JavaModule.Explicit>
|
private val systemModules: List<JavaModule.Explicit>
|
||||||
) : JavaModuleResolver {
|
) : JavaModuleResolver {
|
||||||
init {
|
init {
|
||||||
assert(userModules.count(JavaModule::isSourceModule) <= 1) {
|
assert(userModules.count(JavaModule::isSourceModule) <= 1) {
|
||||||
@@ -52,10 +52,10 @@ class CliJavaModuleResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private operator fun JavaModule.contains(file: VirtualFile): Boolean =
|
private operator fun JavaModule.contains(file: VirtualFile): Boolean =
|
||||||
moduleRoots.any { (root, isBinary) -> isBinary && VfsUtilCore.isAncestor(root, file, false) }
|
moduleRoots.any { (root, isBinary) -> isBinary && VfsUtilCore.isAncestor(root, file, false) }
|
||||||
|
|
||||||
override fun checkAccessibility(
|
override fun checkAccessibility(
|
||||||
fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?
|
fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?
|
||||||
): JavaModuleResolver.AccessError? {
|
): JavaModuleResolver.AccessError? {
|
||||||
val ourModule = fileFromOurModule?.let(this::findJavaModule)
|
val ourModule = fileFromOurModule?.let(this::findJavaModule)
|
||||||
val theirModule = this.findJavaModule(referencedFile)
|
val theirModule = this.findJavaModule(referencedFile)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm.modules
|
package org.jetbrains.kotlin.cli.jvm.modules
|
||||||
|
|
||||||
import com.intellij.openapi.util.SystemInfo
|
|
||||||
import com.intellij.openapi.vfs.DeprecatedVirtualFileSystem
|
import com.intellij.openapi.vfs.DeprecatedVirtualFileSystem
|
||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
import com.intellij.openapi.vfs.StandardFileSystems
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
@@ -47,9 +46,9 @@ class CoreJrtFileSystem : DeprecatedVirtualFileSystem() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class CoreJrtHandler(
|
internal class CoreJrtHandler(
|
||||||
val virtualFileSystem: CoreJrtFileSystem,
|
val virtualFileSystem: CoreJrtFileSystem,
|
||||||
val jdkHomePath: String,
|
val jdkHomePath: String,
|
||||||
private val root: Path
|
private val root: Path
|
||||||
) {
|
) {
|
||||||
fun findFile(fileName: String): VirtualFile? {
|
fun findFile(fileName: String): VirtualFile? {
|
||||||
val path = root.resolve(fileName)
|
val path = root.resolve(fileName)
|
||||||
@@ -80,9 +79,9 @@ class CoreJrtFileSystem : DeprecatedVirtualFileSystem() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun loadJrtFsJar(jdkHome: File): File? =
|
private fun loadJrtFsJar(jdkHome: File): File? =
|
||||||
File(jdkHome, "lib/jrt-fs.jar").takeIf(File::exists)
|
File(jdkHome, "lib/jrt-fs.jar").takeIf(File::exists)
|
||||||
|
|
||||||
fun isModularJdk(jdkHome: File): Boolean =
|
fun isModularJdk(jdkHome: File): Boolean =
|
||||||
loadJrtFsJar(jdkHome) != null
|
loadJrtFsJar(jdkHome) != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ internal class CoreJrtVirtualFile(private val handler: CoreJrtHandler, private v
|
|||||||
override fun getFileSystem(): VirtualFileSystem = handler.virtualFileSystem
|
override fun getFileSystem(): VirtualFileSystem = handler.virtualFileSystem
|
||||||
|
|
||||||
override fun getName(): String =
|
override fun getName(): String =
|
||||||
path.fileName.toString()
|
path.fileName.toString()
|
||||||
|
|
||||||
override fun getPath(): String =
|
override fun getPath(): String =
|
||||||
FileUtil.toSystemIndependentName(handler.jdkHomePath + URLUtil.JAR_SEPARATOR + path)
|
FileUtil.toSystemIndependentName(handler.jdkHomePath + URLUtil.JAR_SEPARATOR + path)
|
||||||
|
|
||||||
override fun isWritable(): Boolean = false
|
override fun isWritable(): Boolean = false
|
||||||
|
|
||||||
@@ -55,8 +55,7 @@ internal class CoreJrtVirtualFile(private val handler: CoreJrtHandler, private v
|
|||||||
override fun getChildren(): Array<out VirtualFile> {
|
override fun getChildren(): Array<out VirtualFile> {
|
||||||
val paths = try {
|
val paths = try {
|
||||||
Files.newDirectoryStream(path).use(Iterable<Path>::toList)
|
Files.newDirectoryStream(path).use(Iterable<Path>::toList)
|
||||||
}
|
} catch (e: IOException) {
|
||||||
catch (e: IOException) {
|
|
||||||
emptyList<Path>()
|
emptyList<Path>()
|
||||||
}
|
}
|
||||||
return when {
|
return when {
|
||||||
@@ -66,26 +65,26 @@ internal class CoreJrtVirtualFile(private val handler: CoreJrtHandler, private v
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getOutputStream(requestor: Any, newModificationStamp: Long, newTimeStamp: Long): OutputStream =
|
override fun getOutputStream(requestor: Any, newModificationStamp: Long, newTimeStamp: Long): OutputStream =
|
||||||
throw UnsupportedOperationException()
|
throw UnsupportedOperationException()
|
||||||
|
|
||||||
override fun contentsToByteArray(): ByteArray =
|
override fun contentsToByteArray(): ByteArray =
|
||||||
Files.readAllBytes(path)
|
Files.readAllBytes(path)
|
||||||
|
|
||||||
override fun getTimeStamp(): Long =
|
override fun getTimeStamp(): Long =
|
||||||
attributes.lastModifiedTime().toMillis()
|
attributes.lastModifiedTime().toMillis()
|
||||||
|
|
||||||
override fun getLength(): Long = attributes.size()
|
override fun getLength(): Long = attributes.size()
|
||||||
|
|
||||||
override fun refresh(asynchronous: Boolean, recursive: Boolean, postRunnable: Runnable?) {}
|
override fun refresh(asynchronous: Boolean, recursive: Boolean, postRunnable: Runnable?) {}
|
||||||
|
|
||||||
override fun getInputStream(): InputStream =
|
override fun getInputStream(): InputStream =
|
||||||
VfsUtilCore.inputStreamSkippingBOM(Files.newInputStream(path).buffered(), this)
|
VfsUtilCore.inputStreamSkippingBOM(Files.newInputStream(path).buffered(), this)
|
||||||
|
|
||||||
override fun getModificationStamp(): Long = 0
|
override fun getModificationStamp(): Long = 0
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
override fun equals(other: Any?): Boolean =
|
||||||
other is CoreJrtVirtualFile && path == other.path && fileSystem == other.fileSystem
|
other is CoreJrtVirtualFile && path == other.path && fileSystem == other.fileSystem
|
||||||
|
|
||||||
override fun hashCode(): Int =
|
override fun hashCode(): Int =
|
||||||
path.hashCode()
|
path.hashCode()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
|||||||
|
|
||||||
class JavaModuleGraph(finder: JavaModuleFinder) {
|
class JavaModuleGraph(finder: JavaModuleFinder) {
|
||||||
private val module: (String) -> JavaModule? =
|
private val module: (String) -> JavaModule? =
|
||||||
LockBasedStorageManager.NO_LOCKS.createMemoizedFunctionWithNullableValues(finder::findModule)
|
LockBasedStorageManager.NO_LOCKS.createMemoizedFunctionWithNullableValues(finder::findModule)
|
||||||
|
|
||||||
fun getAllDependencies(moduleNames: List<String>): LinkedHashSet<String> {
|
fun getAllDependencies(moduleNames: List<String>): LinkedHashSet<String> {
|
||||||
val visited = LinkedHashSet(moduleNames)
|
val visited = LinkedHashSet(moduleNames)
|
||||||
|
|||||||
@@ -26,32 +26,31 @@ import org.jetbrains.kotlin.cli.jvm.BundledCompilerPlugins
|
|||||||
import org.jetbrains.kotlin.compiler.plugin.*
|
import org.jetbrains.kotlin.compiler.plugin.*
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URL
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
object PluginCliParser {
|
object PluginCliParser {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun loadPluginsSafe(pluginClasspaths: Array<String>?, pluginOptions: Array<String>?, configuration: CompilerConfiguration): ExitCode =
|
fun loadPluginsSafe(pluginClasspaths: Array<String>?, pluginOptions: Array<String>?, configuration: CompilerConfiguration): ExitCode =
|
||||||
loadPluginsSafe(pluginClasspaths?.asIterable(), pluginOptions?.asIterable(), configuration)
|
loadPluginsSafe(pluginClasspaths?.asIterable(), pluginOptions?.asIterable(), configuration)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun loadPluginsSafe(pluginClasspaths: Iterable<String>?, pluginOptions: Iterable<String>?, configuration: CompilerConfiguration): ExitCode {
|
fun loadPluginsSafe(
|
||||||
|
pluginClasspaths: Iterable<String>?,
|
||||||
|
pluginOptions: Iterable<String>?,
|
||||||
|
configuration: CompilerConfiguration
|
||||||
|
): ExitCode {
|
||||||
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PluginCliParser.loadPlugins(pluginClasspaths, pluginOptions, configuration)
|
PluginCliParser.loadPlugins(pluginClasspaths, pluginOptions, configuration)
|
||||||
}
|
} catch (e: PluginCliOptionProcessingException) {
|
||||||
catch (e: PluginCliOptionProcessingException) {
|
|
||||||
val message = e.message + "\n\n" + cliPluginUsageString(e.pluginId, e.options)
|
val message = e.message + "\n\n" + cliPluginUsageString(e.pluginId, e.options)
|
||||||
messageCollector.report(CompilerMessageSeverity.ERROR, message)
|
messageCollector.report(CompilerMessageSeverity.ERROR, message)
|
||||||
return ExitCode.INTERNAL_ERROR
|
return ExitCode.INTERNAL_ERROR
|
||||||
}
|
} catch (e: CliOptionProcessingException) {
|
||||||
catch (e: CliOptionProcessingException) {
|
|
||||||
messageCollector.report(CompilerMessageSeverity.ERROR, e.message!!)
|
messageCollector.report(CompilerMessageSeverity.ERROR, e.message!!)
|
||||||
return ExitCode.INTERNAL_ERROR
|
return ExitCode.INTERNAL_ERROR
|
||||||
}
|
} catch (t: Throwable) {
|
||||||
catch (t: Throwable) {
|
|
||||||
MessageCollectorUtil.reportException(messageCollector, t)
|
MessageCollectorUtil.reportException(messageCollector, t)
|
||||||
return ExitCode.INTERNAL_ERROR
|
return ExitCode.INTERNAL_ERROR
|
||||||
}
|
}
|
||||||
@@ -61,11 +60,11 @@ object PluginCliParser {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun loadPlugins(pluginClasspaths: Iterable<String>?, pluginOptions: Iterable<String>?, configuration: CompilerConfiguration) {
|
fun loadPlugins(pluginClasspaths: Iterable<String>?, pluginOptions: Iterable<String>?, configuration: CompilerConfiguration) {
|
||||||
val classLoader = PluginURLClassLoader(
|
val classLoader = PluginURLClassLoader(
|
||||||
pluginClasspaths
|
pluginClasspaths
|
||||||
?.map { File(it).toURI().toURL() }
|
?.map { File(it).toURI().toURL() }
|
||||||
?.toTypedArray()
|
?.toTypedArray()
|
||||||
?: arrayOf<URL>(),
|
?: emptyArray(),
|
||||||
this::class.java.classLoader
|
this::class.java.classLoader
|
||||||
)
|
)
|
||||||
|
|
||||||
val componentRegistrars = ServiceLoader.load(ComponentRegistrar::class.java, classLoader).toMutableList()
|
val componentRegistrars = ServiceLoader.load(ComponentRegistrar::class.java, classLoader).toMutableList()
|
||||||
@@ -76,9 +75,9 @@ object PluginCliParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processPluginOptions(
|
private fun processPluginOptions(
|
||||||
pluginOptions: Iterable<String>?,
|
pluginOptions: Iterable<String>?,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
classLoader: ClassLoader
|
classLoader: ClassLoader
|
||||||
) {
|
) {
|
||||||
val optionValuesByPlugin = pluginOptions?.map(::parsePluginOption)?.groupBy {
|
val optionValuesByPlugin = pluginOptions?.map(::parsePluginOption)?.groupBy {
|
||||||
if (it == null) throw CliOptionProcessingException("Wrong plugin option format: $it, should be ${CommonCompilerArguments.PLUGIN_OPTION_FORMAT}")
|
if (it == null) throw CliOptionProcessingException("Wrong plugin option format: $it, should be ${CommonCompilerArguments.PLUGIN_OPTION_FORMAT}")
|
||||||
@@ -94,7 +93,7 @@ object PluginCliParser {
|
|||||||
|
|
||||||
for (optionValue in optionValuesByPlugin[processor.pluginId].orEmpty()) {
|
for (optionValue in optionValuesByPlugin[processor.pluginId].orEmpty()) {
|
||||||
val option = declaredOptions[optionValue!!.optionName]
|
val option = declaredOptions[optionValue!!.optionName]
|
||||||
?: throw CliOptionProcessingException("Unsupported plugin option: $optionValue")
|
?: throw CliOptionProcessingException("Unsupported plugin option: $optionValue")
|
||||||
optionsToValues.putValue(option, optionValue)
|
optionsToValues.putValue(option, optionValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,15 +101,17 @@ object PluginCliParser {
|
|||||||
val values = optionsToValues[option]
|
val values = optionsToValues[option]
|
||||||
if (option.required && values.isEmpty()) {
|
if (option.required && values.isEmpty()) {
|
||||||
throw PluginCliOptionProcessingException(
|
throw PluginCliOptionProcessingException(
|
||||||
processor.pluginId,
|
processor.pluginId,
|
||||||
processor.pluginOptions,
|
processor.pluginOptions,
|
||||||
"Required plugin option not present: ${processor.pluginId}:${option.name}")
|
"Required plugin option not present: ${processor.pluginId}:${option.name}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (!option.allowMultipleOccurrences && values.size > 1) {
|
if (!option.allowMultipleOccurrences && values.size > 1) {
|
||||||
throw PluginCliOptionProcessingException(
|
throw PluginCliOptionProcessingException(
|
||||||
processor.pluginId,
|
processor.pluginId,
|
||||||
processor.pluginOptions,
|
processor.pluginOptions,
|
||||||
"Multiple values are not allowed for plugin option ${processor.pluginId}:${option.name}")
|
"Multiple values are not allowed for plugin option ${processor.pluginId}:${option.name}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (value in values) {
|
for (value in values) {
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ internal class PluginURLClassLoader(urls: Array<URL>, parent: ClassLoader) : Cla
|
|||||||
override fun loadClass(name: String, resolve: Boolean): Class<*> {
|
override fun loadClass(name: String, resolve: Boolean): Class<*> {
|
||||||
return try {
|
return try {
|
||||||
childClassLoader.findClass(name)
|
childClassLoader.findClass(name)
|
||||||
}
|
} catch (e: ClassNotFoundException) {
|
||||||
catch (e: ClassNotFoundException) {
|
|
||||||
super.loadClass(name, resolve)
|
super.loadClass(name, resolve)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,8 +44,7 @@ internal class PluginURLClassLoader(urls: Array<URL>, parent: ClassLoader) : Cla
|
|||||||
|
|
||||||
return try {
|
return try {
|
||||||
super.findClass(name)
|
super.findClass(name)
|
||||||
}
|
} catch (e: ClassNotFoundException) {
|
||||||
catch (e: ClassNotFoundException) {
|
|
||||||
onFail.loadClass(name)
|
onFail.loadClass(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-3
@@ -31,15 +31,17 @@ open class DelegatePackageMemberDeclarationProvider(var delegate: PackageMemberD
|
|||||||
|
|
||||||
override fun containsFile(file: KtFile) = delegate.containsFile(file)
|
override fun containsFile(file: KtFile) = delegate.containsFile(file)
|
||||||
|
|
||||||
override fun getDeclarations(kindFilter: DescriptorKindFilter,
|
override fun getDeclarations(
|
||||||
nameFilter: (Name) -> Boolean) = delegate.getDeclarations(kindFilter, nameFilter)
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean
|
||||||
|
) = delegate.getDeclarations(kindFilter, nameFilter)
|
||||||
|
|
||||||
override fun getFunctionDeclarations(name: Name) = delegate.getFunctionDeclarations(name)
|
override fun getFunctionDeclarations(name: Name) = delegate.getFunctionDeclarations(name)
|
||||||
|
|
||||||
override fun getPropertyDeclarations(name: Name) = delegate.getPropertyDeclarations(name)
|
override fun getPropertyDeclarations(name: Name) = delegate.getPropertyDeclarations(name)
|
||||||
|
|
||||||
override fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry> =
|
override fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry> =
|
||||||
delegate.getDestructuringDeclarationsEntries(name)
|
delegate.getDestructuringDeclarationsEntries(name)
|
||||||
|
|
||||||
override fun getClassOrObjectDeclarations(name: Name) = delegate.getClassOrObjectDeclarations(name)
|
override fun getClassOrObjectDeclarations(name: Name) = delegate.getClassOrObjectDeclarations(name)
|
||||||
|
|
||||||
|
|||||||
@@ -43,26 +43,28 @@ class ReplCompilerStageHistory(private val state: GenericReplCompilerState) : Ba
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkConsistent(removedCompiledLines: Iterable<ILineId>, removedAnalyzedLines: List<ReplCodeLine>) {
|
private fun checkConsistent(removedCompiledLines: Iterable<ILineId>, removedAnalyzedLines: List<ReplCodeLine>) {
|
||||||
removedCompiledLines.zip(removedAnalyzedLines).forEach {
|
removedCompiledLines.zip(removedAnalyzedLines).forEach { (removedCompiledLine, removedAnalyzedLine) ->
|
||||||
if (it.first != LineId(it.second)) {
|
if (removedCompiledLine != LineId(removedAnalyzedLine)) {
|
||||||
throw IllegalStateException("History mismatch when resetting lines: ${it.first.no} != ${it.second}")
|
throw IllegalStateException("History mismatch when resetting lines: ${removedCompiledLine.no} != $removedAnalyzedLine")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class GenericReplCheckerState: IReplStageState<ScriptDescriptor> {
|
abstract class GenericReplCheckerState : IReplStageState<ScriptDescriptor> {
|
||||||
|
|
||||||
// "line" - is the unit of evaluation here, could in fact consists of several character lines
|
// "line" - is the unit of evaluation here, could in fact consists of several character lines
|
||||||
class LineState(
|
class LineState(
|
||||||
val codeLine: ReplCodeLine,
|
val codeLine: ReplCodeLine,
|
||||||
val psiFile: KtFile,
|
val psiFile: KtFile,
|
||||||
val errorHolder: DiagnosticMessageHolder)
|
val errorHolder: DiagnosticMessageHolder
|
||||||
|
)
|
||||||
|
|
||||||
var lastLineState: LineState? = null // for transferring state to the compiler in most typical case
|
var lastLineState: LineState? = null // for transferring state to the compiler in most typical case
|
||||||
}
|
}
|
||||||
|
|
||||||
class GenericReplCompilerState(environment: KotlinCoreEnvironment, override val lock: ReentrantReadWriteLock = ReentrantReadWriteLock()) : IReplStageState<ScriptDescriptor>, GenericReplCheckerState() {
|
class GenericReplCompilerState(environment: KotlinCoreEnvironment, override val lock: ReentrantReadWriteLock = ReentrantReadWriteLock()) :
|
||||||
|
IReplStageState<ScriptDescriptor>, GenericReplCheckerState() {
|
||||||
|
|
||||||
override val history = ReplCompilerStageHistory(this)
|
override val history = ReplCompilerStageHistory(this)
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm.repl
|
package org.jetbrains.kotlin.cli.jvm.repl
|
||||||
|
|
||||||
|
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.openapi.vfs.CharsetToolkit
|
import com.intellij.openapi.vfs.CharsetToolkit
|
||||||
@@ -42,10 +41,10 @@ import kotlin.concurrent.write
|
|||||||
const val KOTLIN_REPL_JVM_TARGET_PROPERTY = "kotlin.repl.jvm.target"
|
const val KOTLIN_REPL_JVM_TARGET_PROPERTY = "kotlin.repl.jvm.target"
|
||||||
|
|
||||||
open class GenericReplChecker(
|
open class GenericReplChecker(
|
||||||
disposable: Disposable,
|
disposable: Disposable,
|
||||||
private val scriptDefinition: KotlinScriptDefinition,
|
private val scriptDefinition: KotlinScriptDefinition,
|
||||||
private val compilerConfiguration: CompilerConfiguration,
|
private val compilerConfiguration: CompilerConfiguration,
|
||||||
messageCollector: MessageCollector
|
messageCollector: MessageCollector
|
||||||
) : ReplCheckAction {
|
) : ReplCheckAction {
|
||||||
|
|
||||||
internal val environment = run {
|
internal val environment = run {
|
||||||
@@ -57,7 +56,7 @@ open class GenericReplChecker(
|
|||||||
if (get(JVMConfigurationKeys.JVM_TARGET) == null) {
|
if (get(JVMConfigurationKeys.JVM_TARGET) == null) {
|
||||||
put(JVMConfigurationKeys.JVM_TARGET,
|
put(JVMConfigurationKeys.JVM_TARGET,
|
||||||
System.getProperty(KOTLIN_REPL_JVM_TARGET_PROPERTY)?.let { JvmTarget.fromString(it) }
|
System.getProperty(KOTLIN_REPL_JVM_TARGET_PROPERTY)?.let { JvmTarget.fromString(it) }
|
||||||
?: if (getJavaVersion() >= 0x10008) JvmTarget.JVM_1_8 else JvmTarget.JVM_1_6)
|
?: if (getJavaVersion() >= 0x10008) JvmTarget.JVM_1_8 else JvmTarget.JVM_1_6)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KotlinCoreEnvironment.createForProduction(disposable, compilerConfiguration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
KotlinCoreEnvironment.createForProduction(disposable, compilerConfiguration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||||
@@ -72,11 +71,15 @@ open class GenericReplChecker(
|
|||||||
val checkerState = state.asState(GenericReplCheckerState::class.java)
|
val checkerState = state.asState(GenericReplCheckerState::class.java)
|
||||||
val scriptFileName = makeScriptBaseName(codeLine)
|
val scriptFileName = makeScriptBaseName(codeLine)
|
||||||
val virtualFile =
|
val virtualFile =
|
||||||
LightVirtualFile("$scriptFileName${KotlinParserDefinition.STD_SCRIPT_EXT}", KotlinLanguage.INSTANCE, StringUtil.convertLineSeparators(codeLine.code)).apply {
|
LightVirtualFile(
|
||||||
charset = CharsetToolkit.UTF8_CHARSET
|
"$scriptFileName${KotlinParserDefinition.STD_SCRIPT_EXT}",
|
||||||
}
|
KotlinLanguage.INSTANCE,
|
||||||
|
StringUtil.convertLineSeparators(codeLine.code)
|
||||||
|
).apply {
|
||||||
|
charset = CharsetToolkit.UTF8_CHARSET
|
||||||
|
}
|
||||||
val psiFile: KtFile = psiFileFactory.trySetupPsiForFile(virtualFile, KotlinLanguage.INSTANCE, true, false) as KtFile?
|
val psiFile: KtFile = psiFileFactory.trySetupPsiForFile(virtualFile, KotlinLanguage.INSTANCE, true, false) as KtFile?
|
||||||
?: error("Script file not analyzed at line ${codeLine.no}: ${codeLine.code}")
|
?: error("Script file not analyzed at line ${codeLine.no}: ${codeLine.code}")
|
||||||
|
|
||||||
val errorHolder = createDiagnosticHolder()
|
val errorHolder = createDiagnosticHolder()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm.repl
|
package org.jetbrains.kotlin.cli.jvm.repl
|
||||||
|
|
||||||
|
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||||
@@ -24,6 +23,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
|||||||
import org.jetbrains.kotlin.cli.common.repl.*
|
import org.jetbrains.kotlin.cli.common.repl.*
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||||
|
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
||||||
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
@@ -41,14 +41,18 @@ import kotlin.concurrent.write
|
|||||||
|
|
||||||
// WARNING: not thread safe, assuming external synchronization
|
// WARNING: not thread safe, assuming external synchronization
|
||||||
|
|
||||||
open class GenericReplCompiler(disposable: Disposable,
|
open class GenericReplCompiler(
|
||||||
scriptDefinition: KotlinScriptDefinition,
|
disposable: Disposable,
|
||||||
private val compilerConfiguration: CompilerConfiguration,
|
scriptDefinition: KotlinScriptDefinition,
|
||||||
messageCollector: MessageCollector
|
private val compilerConfiguration: CompilerConfiguration,
|
||||||
|
messageCollector: MessageCollector
|
||||||
) : ReplCompiler {
|
) : ReplCompiler {
|
||||||
|
|
||||||
constructor(scriptDefinition: KotlinScriptDefinition, compilerConfiguration: CompilerConfiguration, messageCollector: MessageCollector) :
|
constructor(
|
||||||
this(Disposer.newDisposable(), scriptDefinition, compilerConfiguration, messageCollector)
|
scriptDefinition: KotlinScriptDefinition,
|
||||||
|
compilerConfiguration: CompilerConfiguration,
|
||||||
|
messageCollector: MessageCollector
|
||||||
|
) : this(Disposer.newDisposable(), scriptDefinition, compilerConfiguration, messageCollector)
|
||||||
|
|
||||||
private val checker = GenericReplChecker(disposable, scriptDefinition, compilerConfiguration, messageCollector)
|
private val checker = GenericReplChecker(disposable, scriptDefinition, compilerConfiguration, messageCollector)
|
||||||
|
|
||||||
@@ -66,7 +70,8 @@ open class GenericReplCompiler(disposable: Disposable,
|
|||||||
when (res) {
|
when (res) {
|
||||||
is ReplCheckResult.Incomplete -> return@compile ReplCompileResult.Incomplete()
|
is ReplCheckResult.Incomplete -> return@compile ReplCompileResult.Incomplete()
|
||||||
is ReplCheckResult.Error -> return@compile ReplCompileResult.Error(res.message, res.location)
|
is ReplCheckResult.Error -> return@compile ReplCompileResult.Error(res.message, res.location)
|
||||||
is ReplCheckResult.Ok -> {} // continue
|
is ReplCheckResult.Ok -> {
|
||||||
|
} // continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pair(compilerState.lastLineState!!.psiFile, compilerState.lastLineState!!.errorHolder)
|
Pair(compilerState.lastLineState!!.psiFile, compilerState.lastLineState!!.errorHolder)
|
||||||
@@ -88,29 +93,28 @@ open class GenericReplCompiler(disposable: Disposable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val generationState = GenerationState.Builder(
|
val generationState = GenerationState.Builder(
|
||||||
psiFile.project,
|
psiFile.project,
|
||||||
ClassBuilderFactories.BINARIES,
|
ClassBuilderFactories.BINARIES,
|
||||||
compilerState.analyzerEngine.module,
|
compilerState.analyzerEngine.module,
|
||||||
compilerState.analyzerEngine.trace.bindingContext,
|
compilerState.analyzerEngine.trace.bindingContext,
|
||||||
listOf(psiFile),
|
listOf(psiFile),
|
||||||
compilerConfiguration
|
compilerConfiguration
|
||||||
).build()
|
).build()
|
||||||
generationState.replSpecific.scriptResultFieldName = SCRIPT_RESULT_FIELD_NAME
|
generationState.replSpecific.scriptResultFieldName = SCRIPT_RESULT_FIELD_NAME
|
||||||
generationState.replSpecific.earlierScriptsForReplInterpreter = compilerState.history.map { it.item }
|
generationState.replSpecific.earlierScriptsForReplInterpreter = compilerState.history.map { it.item }
|
||||||
generationState.beforeCompile()
|
generationState.beforeCompile()
|
||||||
KotlinCodegenFacade.generatePackage(
|
KotlinCodegenFacade.generatePackage(
|
||||||
generationState,
|
generationState,
|
||||||
psiFile.script!!.containingKtFile.packageFqName,
|
psiFile.script!!.containingKtFile.packageFqName,
|
||||||
setOf(psiFile.script!!.containingKtFile),
|
setOf(psiFile.script!!.containingKtFile),
|
||||||
org.jetbrains.kotlin.codegen.CompilationErrorHandler.THROW_EXCEPTION)
|
CompilationErrorHandler.THROW_EXCEPTION
|
||||||
|
)
|
||||||
|
|
||||||
val generatedClassname = makeScriptBaseName(codeLine)
|
val generatedClassname = makeScriptBaseName(codeLine)
|
||||||
compilerState.history.push(LineId(codeLine), scriptDescriptor)
|
compilerState.history.push(LineId(codeLine), scriptDescriptor)
|
||||||
|
|
||||||
val expression = psiFile.getChildOfType<KtScript>()?.
|
val expression = psiFile.getChildOfType<KtScript>()?.getChildOfType<KtBlockExpression>()?.getChildOfType<KtScriptInitializer>()
|
||||||
getChildOfType<KtBlockExpression>()?.
|
?.getChildOfType<KtExpression>()
|
||||||
getChildOfType<KtScriptInitializer>()?.
|
|
||||||
getChildOfType<KtExpression>()
|
|
||||||
|
|
||||||
val type = expression?.let {
|
val type = expression?.let {
|
||||||
compilerState.analyzerEngine.trace.bindingContext.getType(it)
|
compilerState.analyzerEngine.trace.bindingContext.getType(it)
|
||||||
@@ -118,17 +122,19 @@ open class GenericReplCompiler(disposable: Disposable,
|
|||||||
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(it)
|
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReplCompileResult.CompiledClasses(LineId(codeLine),
|
return ReplCompileResult.CompiledClasses(
|
||||||
compilerState.history.map { it.id },
|
LineId(codeLine),
|
||||||
generatedClassname,
|
compilerState.history.map { it.id },
|
||||||
generationState.factory.asList().map { CompiledClassData(it.relativePath, it.asByteArray()) },
|
generatedClassname,
|
||||||
generationState.replSpecific.hasResult,
|
generationState.factory.asList().map { CompiledClassData(it.relativePath, it.asByteArray()) },
|
||||||
classpathAddendum ?: emptyList(),
|
generationState.replSpecific.hasResult,
|
||||||
type)
|
classpathAddendum ?: emptyList(),
|
||||||
|
type
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val SCRIPT_RESULT_FIELD_NAME = "\$\$result"
|
private const val SCRIPT_RESULT_FIELD_NAME = "\$\$result"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,6 @@ import org.jetbrains.kotlin.resolve.scopes.utils.replaceImportingScopes
|
|||||||
import org.jetbrains.kotlin.script.ScriptPriorities
|
import org.jetbrains.kotlin.script.ScriptPriorities
|
||||||
|
|
||||||
class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
||||||
|
|
||||||
private val topDownAnalysisContext: TopDownAnalysisContext
|
private val topDownAnalysisContext: TopDownAnalysisContext
|
||||||
private val topDownAnalyzer: LazyTopDownAnalyzer
|
private val topDownAnalyzer: LazyTopDownAnalyzer
|
||||||
private val resolveSession: ResolveSession
|
private val resolveSession: ResolveSession
|
||||||
@@ -63,28 +62,29 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
|||||||
// to be found via ResolveSession. The latter is true as long as light classes are not needed in REPL (which is currently true
|
// to be found via ResolveSession. The latter is true as long as light classes are not needed in REPL (which is currently true
|
||||||
// because no symbol declared in the REPL session can be used from Java)
|
// because no symbol declared in the REPL session can be used from Java)
|
||||||
val container = TopDownAnalyzerFacadeForJVM.createContainer(
|
val container = TopDownAnalyzerFacadeForJVM.createContainer(
|
||||||
environment.project,
|
environment.project,
|
||||||
emptyList(),
|
emptyList(),
|
||||||
trace,
|
trace,
|
||||||
environment.configuration,
|
environment.configuration,
|
||||||
environment::createPackagePartProvider,
|
environment::createPackagePartProvider,
|
||||||
{ _, _ -> ScriptMutableDeclarationProviderFactory() }
|
{ _, _ -> ScriptMutableDeclarationProviderFactory() }
|
||||||
)
|
)
|
||||||
|
|
||||||
this.module = container.get<ModuleDescriptorImpl>()
|
this.module = container.get()
|
||||||
this.scriptDeclarationFactory = container.get<ScriptMutableDeclarationProviderFactory>()
|
this.scriptDeclarationFactory = container.get()
|
||||||
this.resolveSession = container.get<ResolveSession>()
|
this.resolveSession = container.get()
|
||||||
this.topDownAnalysisContext = TopDownAnalysisContext(
|
this.topDownAnalysisContext = TopDownAnalysisContext(
|
||||||
TopDownAnalysisMode.TopLevelDeclarations, DataFlowInfoFactory.EMPTY, resolveSession.declarationScopeProvider
|
TopDownAnalysisMode.TopLevelDeclarations, DataFlowInfoFactory.EMPTY, resolveSession.declarationScopeProvider
|
||||||
)
|
)
|
||||||
this.topDownAnalyzer = container.get<LazyTopDownAnalyzer>()
|
this.topDownAnalyzer = container.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ReplLineAnalysisResult {
|
interface ReplLineAnalysisResult {
|
||||||
val scriptDescriptor: ScriptDescriptor?
|
val scriptDescriptor: ScriptDescriptor?
|
||||||
val diagnostics: Diagnostics
|
val diagnostics: Diagnostics
|
||||||
|
|
||||||
data class Successful(override val scriptDescriptor: ScriptDescriptor, override val diagnostics: Diagnostics) : ReplLineAnalysisResult
|
data class Successful(override val scriptDescriptor: ScriptDescriptor, override val diagnostics: Diagnostics) :
|
||||||
|
ReplLineAnalysisResult
|
||||||
|
|
||||||
data class WithErrors(override val diagnostics: Diagnostics) : ReplLineAnalysisResult {
|
data class WithErrors(override val diagnostics: Diagnostics) : ReplLineAnalysisResult {
|
||||||
override val scriptDescriptor: ScriptDescriptor? get() = null
|
override val scriptDescriptor: ScriptDescriptor? get() = null
|
||||||
@@ -115,8 +115,7 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
|||||||
return if (hasErrors) {
|
return if (hasErrors) {
|
||||||
replState.lineFailure(linePsi, codeLine)
|
replState.lineFailure(linePsi, codeLine)
|
||||||
ReplLineAnalysisResult.WithErrors(diagnostics)
|
ReplLineAnalysisResult.WithErrors(diagnostics)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val scriptDescriptor = context.scripts[linePsi.script]!!
|
val scriptDescriptor = context.scripts[linePsi.script]!!
|
||||||
replState.lineSuccess(linePsi, codeLine, scriptDescriptor)
|
replState.lineSuccess(linePsi, codeLine, scriptDescriptor)
|
||||||
ReplLineAnalysisResult.Successful(scriptDescriptor, diagnostics)
|
ReplLineAnalysisResult.Successful(scriptDescriptor, diagnostics)
|
||||||
@@ -134,8 +133,7 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
|||||||
val provider = delegateFactory.getPackageMemberDeclarationProvider(FqName.ROOT)!!
|
val provider = delegateFactory.getPackageMemberDeclarationProvider(FqName.ROOT)!!
|
||||||
try {
|
try {
|
||||||
rootPackageProvider.addDelegateProvider(provider)
|
rootPackageProvider.addDelegateProvider(provider)
|
||||||
}
|
} catch (e: UninitializedPropertyAccessException) {
|
||||||
catch (e: UninitializedPropertyAccessException) {
|
|
||||||
rootPackageProvider = AdaptablePackageMemberDeclarationProvider(provider)
|
rootPackageProvider = AdaptablePackageMemberDeclarationProvider(provider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,7 +155,7 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AdaptablePackageMemberDeclarationProvider(
|
class AdaptablePackageMemberDeclarationProvider(
|
||||||
private var delegateProvider: PackageMemberDeclarationProvider
|
private var delegateProvider: PackageMemberDeclarationProvider
|
||||||
) : DelegatePackageMemberDeclarationProvider(delegateProvider) {
|
) : DelegatePackageMemberDeclarationProvider(delegateProvider) {
|
||||||
fun addDelegateProvider(provider: PackageMemberDeclarationProvider) {
|
fun addDelegateProvider(provider: PackageMemberDeclarationProvider) {
|
||||||
delegateProvider = CombinedPackageMemberDeclarationProvider(listOf(provider, delegateProvider))
|
delegateProvider = CombinedPackageMemberDeclarationProvider(listOf(provider, delegateProvider))
|
||||||
@@ -167,8 +165,8 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: merge with org.jetbrains.kotlin.resolve.repl.ReplState when switching to new REPL infrastruct everywhere
|
// TODO: merge with org.jetbrains.kotlin.resolve.repl.ReplState when switching to new REPL infrastructure everywhere
|
||||||
// TODO: review it's place in the extracted state infrastruct (now the analyzer itself is a part of the state
|
// TODO: review its place in the extracted state infrastructure (now the analyzer itself is a part of the state)
|
||||||
class ResettableAnalyzerState {
|
class ResettableAnalyzerState {
|
||||||
private val successfulLines = ReplHistory<LineInfo.SuccessfulLine>()
|
private val successfulLines = ReplHistory<LineInfo.SuccessfulLine>()
|
||||||
private val submittedLines = hashMapOf<KtFile, LineInfo>()
|
private val submittedLines = hashMapOf<KtFile, LineInfo>()
|
||||||
@@ -212,7 +210,12 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
|||||||
abstract val parentLine: SuccessfulLine?
|
abstract val parentLine: SuccessfulLine?
|
||||||
|
|
||||||
class SubmittedLine(override val linePsi: KtFile, override val parentLine: SuccessfulLine?) : LineInfo()
|
class SubmittedLine(override val linePsi: KtFile, override val parentLine: SuccessfulLine?) : LineInfo()
|
||||||
class SuccessfulLine(override val linePsi: KtFile, override val parentLine: SuccessfulLine?, val lineDescriptor: LazyScriptDescriptor) : LineInfo()
|
class SuccessfulLine(
|
||||||
|
override val linePsi: KtFile,
|
||||||
|
override val parentLine: SuccessfulLine?,
|
||||||
|
val lineDescriptor: LazyScriptDescriptor
|
||||||
|
) : LineInfo()
|
||||||
|
|
||||||
class FailedLine(override val linePsi: KtFile, override val parentLine: SuccessfulLine?) : LineInfo()
|
class FailedLine(override val linePsi: KtFile, override val parentLine: SuccessfulLine?) : LineInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
|||||||
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
|
||||||
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
|
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.configuration.ConsoleReplConfiguration
|
import org.jetbrains.kotlin.cli.jvm.repl.configuration.ConsoleReplConfiguration
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.configuration.ReplConfiguration
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.configuration.IdeReplConfiguration
|
import org.jetbrains.kotlin.cli.jvm.repl.configuration.IdeReplConfiguration
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.repl.configuration.ReplConfiguration
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.messages.unescapeLineBreaks
|
import org.jetbrains.kotlin.cli.jvm.repl.messages.unescapeLineBreaks
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
||||||
@@ -36,9 +36,9 @@ import java.util.concurrent.Executors
|
|||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
|
|
||||||
class ReplFromTerminal(
|
class ReplFromTerminal(
|
||||||
disposable: Disposable,
|
disposable: Disposable,
|
||||||
compilerConfiguration: CompilerConfiguration,
|
compilerConfiguration: CompilerConfiguration,
|
||||||
private val replConfiguration: ReplConfiguration
|
private val replConfiguration: ReplConfiguration
|
||||||
) {
|
) {
|
||||||
private val replInitializer: Future<ReplInterpreter> = Executors.newSingleThreadExecutor().submit(Callable {
|
private val replInitializer: Future<ReplInterpreter> = Executors.newSingleThreadExecutor().submit(Callable {
|
||||||
ReplInterpreter(disposable, compilerConfiguration, replConfiguration)
|
ReplInterpreter(disposable, compilerConfiguration, replConfiguration)
|
||||||
@@ -53,9 +53,11 @@ class ReplFromTerminal(
|
|||||||
|
|
||||||
private fun doRun() {
|
private fun doRun() {
|
||||||
try {
|
try {
|
||||||
with (writer) {
|
with(writer) {
|
||||||
printlnWelcomeMessage("Welcome to Kotlin version ${KotlinCompilerVersion.VERSION} " +
|
printlnWelcomeMessage(
|
||||||
"(JRE ${System.getProperty("java.runtime.version")})")
|
"Welcome to Kotlin version ${KotlinCompilerVersion.VERSION} " +
|
||||||
|
"(JRE ${System.getProperty("java.runtime.version")})"
|
||||||
|
)
|
||||||
printlnWelcomeMessage("Type :help for help, :quit for quit")
|
printlnWelcomeMessage("Type :help for help, :quit for quit")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,16 +73,13 @@ class ReplFromTerminal(
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (e: Exception) {
|
||||||
catch (e: Exception) {
|
|
||||||
replConfiguration.exceptionReporter.report(e)
|
replConfiguration.exceptionReporter.report(e)
|
||||||
throw e
|
throw e
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
try {
|
try {
|
||||||
replConfiguration.commandReader.flushHistory()
|
replConfiguration.commandReader.flushHistory()
|
||||||
}
|
} catch (e: Exception) {
|
||||||
catch (e: Exception) {
|
|
||||||
replConfiguration.exceptionReporter.report(e)
|
replConfiguration.exceptionReporter.report(e)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
@@ -99,7 +98,7 @@ class ReplFromTerminal(
|
|||||||
|
|
||||||
line = unescapeLineBreaks(line)
|
line = unescapeLineBreaks(line)
|
||||||
|
|
||||||
if (line.startsWith(":") && (line.length == 1 || line.get(1) != ':')) {
|
if (line.startsWith(":") && (line.length == 1 || line[1] != ':')) {
|
||||||
val notQuit = oneCommand(line.substring(1))
|
val notQuit = oneCommand(line.substring(1))
|
||||||
return if (notQuit) WhatNextAfterOneLine.READ_LINE else WhatNextAfterOneLine.QUIT
|
return if (notQuit) WhatNextAfterOneLine.READ_LINE else WhatNextAfterOneLine.QUIT
|
||||||
}
|
}
|
||||||
@@ -107,8 +106,7 @@ class ReplFromTerminal(
|
|||||||
val lineResult = eval(line)
|
val lineResult = eval(line)
|
||||||
return if (lineResult is ReplEvalResult.Incomplete) {
|
return if (lineResult is ReplEvalResult.Incomplete) {
|
||||||
WhatNextAfterOneLine.INCOMPLETE
|
WhatNextAfterOneLine.INCOMPLETE
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
WhatNextAfterOneLine.READ_LINE
|
WhatNextAfterOneLine.READ_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,22 +130,21 @@ class ReplFromTerminal(
|
|||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
private fun oneCommand(command: String): Boolean {
|
private fun oneCommand(command: String): Boolean {
|
||||||
val split = splitCommand(command)
|
val split = splitCommand(command)
|
||||||
if (split.size >= 1 && command == "help") {
|
if (split.isNotEmpty() && command == "help") {
|
||||||
writer.printlnHelpMessage("Available commands:\n" +
|
writer.printlnHelpMessage(
|
||||||
":help show this help\n" +
|
"Available commands:\n" +
|
||||||
":quit exit the interpreter\n" +
|
":help show this help\n" +
|
||||||
":dump bytecode dump classes to terminal\n" +
|
":quit exit the interpreter\n" +
|
||||||
":load <file> load script from specified file")
|
":dump bytecode dump classes to terminal\n" +
|
||||||
|
":load <file> load script from specified file"
|
||||||
|
)
|
||||||
return true
|
return true
|
||||||
}
|
} else if (split.size >= 2 && split[0] == "dump" && split[1] == "bytecode") {
|
||||||
else if (split.size >= 2 && split[0] == "dump" && split[1] == "bytecode") {
|
|
||||||
replInterpreter.dumpClasses(PrintWriter(System.out))
|
replInterpreter.dumpClasses(PrintWriter(System.out))
|
||||||
return true
|
return true
|
||||||
}
|
} else if (split.isNotEmpty() && split[0] == "quit") {
|
||||||
else if (split.size >= 1 && split[0] == "quit") {
|
|
||||||
return false
|
return false
|
||||||
}
|
} else if (split.size >= 2 && split[0] == "load") {
|
||||||
else if (split.size >= 2 && split[0] == "load") {
|
|
||||||
val fileName = split[1]
|
val fileName = split[1]
|
||||||
try {
|
try {
|
||||||
val scriptText = FileUtil.loadFile(File(fileName))
|
val scriptText = FileUtil.loadFile(File(fileName))
|
||||||
@@ -156,8 +153,7 @@ class ReplFromTerminal(
|
|||||||
writer.outputCompileError("Can not load script: ${e.message}")
|
writer.outputCompileError("Can not load script: ${e.message}")
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
writer.printlnHelpMessage("Unknown command\n" + "Type :help for help")
|
writer.printlnHelpMessage("Unknown command\n" + "Type :help for help")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -173,12 +169,10 @@ class ReplFromTerminal(
|
|||||||
val replConfiguration = if (replIdeMode) IdeReplConfiguration() else ConsoleReplConfiguration()
|
val replConfiguration = if (replIdeMode) IdeReplConfiguration() else ConsoleReplConfiguration()
|
||||||
return try {
|
return try {
|
||||||
ReplFromTerminal(disposable, configuration, replConfiguration).doRun()
|
ReplFromTerminal(disposable, configuration, replConfiguration).doRun()
|
||||||
}
|
} catch (e: Exception) {
|
||||||
catch (e: Exception) {
|
|
||||||
replConfiguration.exceptionReporter.report(e)
|
replConfiguration.exceptionReporter.report(e)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -33,9 +33,9 @@ import java.net.URLClassLoader
|
|||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
class ReplInterpreter(
|
class ReplInterpreter(
|
||||||
disposable: Disposable,
|
disposable: Disposable,
|
||||||
private val configuration: CompilerConfiguration,
|
private val configuration: CompilerConfiguration,
|
||||||
private val replConfiguration: ReplConfiguration
|
private val replConfiguration: ReplConfiguration
|
||||||
) {
|
) {
|
||||||
private val lineNumber = AtomicInteger()
|
private val lineNumber = AtomicInteger()
|
||||||
|
|
||||||
@@ -60,14 +60,18 @@ class ReplInterpreter(
|
|||||||
|
|
||||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
|
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
|
||||||
val msg = messageRenderer.render(severity, message, location).trimEnd()
|
val msg = messageRenderer.render(severity, message, location).trimEnd()
|
||||||
with (replConfiguration.writer) {
|
with(replConfiguration.writer) {
|
||||||
when (severity) {
|
when (severity) {
|
||||||
CompilerMessageSeverity.EXCEPTION -> sendInternalErrorReport(msg)
|
CompilerMessageSeverity.EXCEPTION -> sendInternalErrorReport(msg)
|
||||||
CompilerMessageSeverity.ERROR -> outputCompileError(msg)
|
CompilerMessageSeverity.ERROR -> outputCompileError(msg)
|
||||||
CompilerMessageSeverity.STRONG_WARNING -> {} // TODO consider reporting this and two below
|
CompilerMessageSeverity.STRONG_WARNING -> {
|
||||||
CompilerMessageSeverity.WARNING -> {}
|
} // TODO consider reporting this and two below
|
||||||
CompilerMessageSeverity.INFO -> {}
|
CompilerMessageSeverity.WARNING -> {
|
||||||
else -> {}
|
}
|
||||||
|
CompilerMessageSeverity.INFO -> {
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,14 +90,17 @@ class ReplInterpreter(
|
|||||||
private val evalState by lazy { scriptEvaluator.createState() }
|
private val evalState by lazy { scriptEvaluator.createState() }
|
||||||
|
|
||||||
fun eval(line: String): ReplEvalResult {
|
fun eval(line: String): ReplEvalResult {
|
||||||
|
|
||||||
val fullText = (previousIncompleteLines + line).joinToString(separator = "\n")
|
val fullText = (previousIncompleteLines + line).joinToString(separator = "\n")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
val evalRes = scriptEvaluator.compileAndEval(
|
||||||
val evalRes = scriptEvaluator.compileAndEval(evalState, ReplCodeLine(lineNumber.getAndIncrement(), 0, fullText), null, object : InvokeWrapper {
|
evalState,
|
||||||
override fun <T> invoke(body: () -> T): T = replConfiguration.executionInterceptor.execute(body)
|
ReplCodeLine(lineNumber.getAndIncrement(), 0, fullText),
|
||||||
})
|
null,
|
||||||
|
object : InvokeWrapper {
|
||||||
|
override fun <T> invoke(body: () -> T): T = replConfiguration.executionInterceptor.execute(body)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
when {
|
when {
|
||||||
evalRes !is ReplEvalResult.Incomplete -> previousIncompleteLines.clear()
|
evalRes !is ReplEvalResult.Incomplete -> previousIncompleteLines.clear()
|
||||||
@@ -101,8 +108,7 @@ class ReplInterpreter(
|
|||||||
else -> return ReplEvalResult.Error.CompileTime("incomplete code")
|
else -> return ReplEvalResult.Error.CompileTime("incomplete code")
|
||||||
}
|
}
|
||||||
return evalRes
|
return evalRes
|
||||||
}
|
} catch (e: Throwable) {
|
||||||
catch (e: Throwable) {
|
|
||||||
val writer = PrintWriter(System.err)
|
val writer = PrintWriter(System.err)
|
||||||
classLoader.dumpClasses(writer)
|
classLoader.dumpClasses(writer)
|
||||||
writer.flush()
|
writer.flush()
|
||||||
|
|||||||
+3
-2
@@ -27,8 +27,9 @@ class ConsoleDiagnosticMessageHolder : MessageCollectorBasedReporter, Diagnostic
|
|||||||
private val outputStream = ByteArrayOutputStream()
|
private val outputStream = ByteArrayOutputStream()
|
||||||
|
|
||||||
override val messageCollector: GroupingMessageCollector = GroupingMessageCollector(
|
override val messageCollector: GroupingMessageCollector = GroupingMessageCollector(
|
||||||
PrintingMessageCollector(PrintStream(outputStream), MessageRenderer.WITHOUT_PATHS, false),
|
PrintingMessageCollector(PrintStream(outputStream), MessageRenderer.WITHOUT_PATHS, false),
|
||||||
false)
|
false
|
||||||
|
)
|
||||||
|
|
||||||
override fun renderMessage(): String {
|
override fun renderMessage(): String {
|
||||||
messageCollector.flush()
|
messageCollector.flush()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.cli.jvm.repl.messages
|
|||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
|
|
||||||
// using '#' to avoid collisions with xml escaping
|
// using '#' to avoid collisions with xml escaping
|
||||||
internal val SOURCE_CHARS: Array<String> = arrayOf("\n", "#")
|
internal val SOURCE_CHARS: Array<String> = arrayOf("\n", "#")
|
||||||
internal val XML_REPLACEMENTS: Array<String> = arrayOf("#n", "#diez")
|
internal val XML_REPLACEMENTS: Array<String> = arrayOf("#n", "#diez")
|
||||||
|
|
||||||
fun unescapeLineBreaks(s: String) = StringUtil.replace(s, XML_REPLACEMENTS, SOURCE_CHARS)
|
fun unescapeLineBreaks(s: String) = StringUtil.replace(s, XML_REPLACEMENTS, SOURCE_CHARS)
|
||||||
+14
-16
@@ -28,26 +28,24 @@ import java.util.logging.Logger
|
|||||||
|
|
||||||
class ConsoleReplCommandReader : ReplCommandReader {
|
class ConsoleReplCommandReader : ReplCommandReader {
|
||||||
private val lineReader = LineReaderBuilder.builder()
|
private val lineReader = LineReaderBuilder.builder()
|
||||||
.appName("kotlin")
|
.appName("kotlin")
|
||||||
.terminal(TerminalBuilder.terminal())
|
.terminal(TerminalBuilder.terminal())
|
||||||
.variable(LineReader.HISTORY_FILE, File(File(System.getProperty("user.home")), ".kotlinc_history").absolutePath)
|
.variable(LineReader.HISTORY_FILE, File(File(System.getProperty("user.home")), ".kotlinc_history").absolutePath)
|
||||||
.build()
|
.build()
|
||||||
.apply {
|
.apply {
|
||||||
setOpt(LineReader.Option.DISABLE_EVENT_EXPANSION)
|
setOpt(LineReader.Option.DISABLE_EVENT_EXPANSION)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readLine(next: ReplFromTerminal.WhatNextAfterOneLine): String? {
|
override fun readLine(next: ReplFromTerminal.WhatNextAfterOneLine): String? {
|
||||||
val prompt = if (next == ReplFromTerminal.WhatNextAfterOneLine.INCOMPLETE) "... " else ">>> "
|
val prompt = if (next == ReplFromTerminal.WhatNextAfterOneLine.INCOMPLETE) "... " else ">>> "
|
||||||
try {
|
return try {
|
||||||
return lineReader.readLine(prompt)
|
lineReader.readLine(prompt)
|
||||||
}
|
} catch (e: UserInterruptException) {
|
||||||
catch (e: UserInterruptException) {
|
|
||||||
println("<interrupted>")
|
println("<interrupted>")
|
||||||
System.out.flush()
|
System.out.flush()
|
||||||
return ""
|
""
|
||||||
}
|
} catch (e: EndOfFileException) {
|
||||||
catch (e: EndOfFileException) {
|
null
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +53,7 @@ class ConsoleReplCommandReader : ReplCommandReader {
|
|||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
init {
|
init {
|
||||||
Logger.getLogger("org.jline").level = Level.OFF;
|
Logger.getLogger("org.jline").level = Level.OFF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ import java.io.InputStream
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory
|
import javax.xml.parsers.DocumentBuilderFactory
|
||||||
|
|
||||||
class ReplSystemInWrapper(
|
class ReplSystemInWrapper(
|
||||||
private val stdin: InputStream,
|
private val stdin: InputStream,
|
||||||
private val replWriter: ReplWriter
|
private val replWriter: ReplWriter
|
||||||
) : InputStream() {
|
) : InputStream() {
|
||||||
private var isXmlIncomplete = true
|
private var isXmlIncomplete = true
|
||||||
private var isLastByteProcessed = false
|
private var isLastByteProcessed = false
|
||||||
@@ -39,7 +39,8 @@ class ReplSystemInWrapper(
|
|||||||
private val isAtBufferEnd: Boolean
|
private val isAtBufferEnd: Boolean
|
||||||
get() = curBytePos == inputByteArray.size
|
get() = curBytePos == inputByteArray.size
|
||||||
|
|
||||||
@Volatile var isReplScriptExecuting = false
|
@Volatile
|
||||||
|
var isReplScriptExecuting = false
|
||||||
|
|
||||||
override fun read(): Int {
|
override fun read(): Int {
|
||||||
if (isLastByteProcessed) {
|
if (isLastByteProcessed) {
|
||||||
|
|||||||
@@ -43,16 +43,16 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
|
|||||||
override fun createArguments() = K2MetadataCompilerArguments()
|
override fun createArguments() = K2MetadataCompilerArguments()
|
||||||
|
|
||||||
override fun setupPlatformSpecificArgumentsAndServices(
|
override fun setupPlatformSpecificArgumentsAndServices(
|
||||||
configuration: CompilerConfiguration, arguments: K2MetadataCompilerArguments, services: Services
|
configuration: CompilerConfiguration, arguments: K2MetadataCompilerArguments, services: Services
|
||||||
) {
|
) {
|
||||||
// No specific arguments yet
|
// No specific arguments yet
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doExecute(
|
override fun doExecute(
|
||||||
arguments: K2MetadataCompilerArguments,
|
arguments: K2MetadataCompilerArguments,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
rootDisposable: Disposable,
|
rootDisposable: Disposable,
|
||||||
paths: KotlinPaths?
|
paths: KotlinPaths?
|
||||||
): ExitCode {
|
): ExitCode {
|
||||||
val collector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
val collector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
|
||||||
@@ -74,12 +74,16 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
|
|||||||
if (destination != null) {
|
if (destination != null) {
|
||||||
if (destination.endsWith(".jar")) {
|
if (destination.endsWith(".jar")) {
|
||||||
// TODO: support .jar destination
|
// TODO: support .jar destination
|
||||||
collector.report(STRONG_WARNING, ".jar destination is not yet supported, results will be written to the directory with the given name")
|
collector.report(
|
||||||
|
STRONG_WARNING,
|
||||||
|
".jar destination is not yet supported, results will be written to the directory with the given name"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
configuration.put(CLIConfigurationKeys.METADATA_DESTINATION_DIRECTORY, File(destination))
|
configuration.put(CLIConfigurationKeys.METADATA_DESTINATION_DIRECTORY, File(destination))
|
||||||
}
|
}
|
||||||
|
|
||||||
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.METADATA_CONFIG_FILES)
|
val environment =
|
||||||
|
KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.METADATA_CONFIG_FILES)
|
||||||
|
|
||||||
if (environment.getSourceFiles().isEmpty()) {
|
if (environment.getSourceFiles().isEmpty()) {
|
||||||
if (arguments.version) {
|
if (arguments.version) {
|
||||||
@@ -95,8 +99,7 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
|
|||||||
val metadataVersion =
|
val metadataVersion =
|
||||||
configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? BuiltInsBinaryVersion ?: BuiltInsBinaryVersion.INSTANCE
|
configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? BuiltInsBinaryVersion ?: BuiltInsBinaryVersion.INSTANCE
|
||||||
MetadataSerializer(metadataVersion, true).serialize(environment)
|
MetadataSerializer(metadataVersion, true).serialize(environment)
|
||||||
}
|
} catch (e: CompilationException) {
|
||||||
catch (e: CompilationException) {
|
|
||||||
collector.report(EXCEPTION, OutputMessageUtil.renderException(e), MessageUtil.psiElementToMessageLocation(e.element))
|
collector.report(EXCEPTION, OutputMessageUtil.renderException(e), MessageUtil.psiElementToMessageLocation(e.element))
|
||||||
return ExitCode.INTERNAL_ERROR
|
return ExitCode.INTERNAL_ERROR
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ open class MetadataSerializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected open fun performSerialization(
|
protected open fun performSerialization(
|
||||||
files: Collection<KtFile>, bindingContext: BindingContext, module: ModuleDescriptor, destDir: File
|
files: Collection<KtFile>, bindingContext: BindingContext, module: ModuleDescriptor, destDir: File
|
||||||
) {
|
) {
|
||||||
val packageTable = hashMapOf<FqName, PackageParts>()
|
val packageTable = hashMapOf<FqName, PackageParts>()
|
||||||
|
|
||||||
@@ -91,23 +91,29 @@ open class MetadataSerializer(
|
|||||||
for (declaration in file.declarations) {
|
for (declaration in file.declarations) {
|
||||||
declaration.accept(object : KtVisitorVoid() {
|
declaration.accept(object : KtVisitorVoid() {
|
||||||
override fun visitNamedFunction(function: KtNamedFunction) {
|
override fun visitNamedFunction(function: KtNamedFunction) {
|
||||||
members.add(bindingContext.get(BindingContext.FUNCTION, function)
|
members.add(
|
||||||
?: error("No descriptor found for function ${function.fqName}"))
|
bindingContext.get(BindingContext.FUNCTION, function)
|
||||||
|
?: error("No descriptor found for function ${function.fqName}")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitProperty(property: KtProperty) {
|
override fun visitProperty(property: KtProperty) {
|
||||||
members.add(bindingContext.get(BindingContext.VARIABLE, property)
|
members.add(
|
||||||
?: error("No descriptor found for property ${property.fqName}"))
|
bindingContext.get(BindingContext.VARIABLE, property)
|
||||||
|
?: error("No descriptor found for property ${property.fqName}")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTypeAlias(typeAlias: KtTypeAlias) {
|
override fun visitTypeAlias(typeAlias: KtTypeAlias) {
|
||||||
members.add(bindingContext.get(BindingContext.TYPE_ALIAS, typeAlias)
|
members.add(
|
||||||
?: error("No descriptor found for type alias ${typeAlias.fqName}"))
|
bindingContext.get(BindingContext.TYPE_ALIAS, typeAlias)
|
||||||
|
?: error("No descriptor found for type alias ${typeAlias.fqName}")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClassOrObject(classOrObject: KtClassOrObject) {
|
override fun visitClassOrObject(classOrObject: KtClassOrObject) {
|
||||||
val classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject)
|
val classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject)
|
||||||
?: error("No descriptor found for class ${classOrObject.fqName}")
|
?: error("No descriptor found for class ${classOrObject.fqName}")
|
||||||
val destFile = File(destDir, getClassFilePath(ClassId(packageFqName, classDescriptor.name)))
|
val destFile = File(destDir, getClassFilePath(ClassId(packageFqName, classDescriptor.name)))
|
||||||
PackageSerializer(listOf(classDescriptor), emptyList(), packageFqName, destFile).run()
|
PackageSerializer(listOf(classDescriptor), emptyList(), packageFqName, destFile).run()
|
||||||
}
|
}
|
||||||
@@ -139,17 +145,17 @@ open class MetadataSerializer(
|
|||||||
protected open fun createSerializerExtension(): KotlinSerializerExtensionBase = MetadataSerializerExtension(metadataVersion)
|
protected open fun createSerializerExtension(): KotlinSerializerExtensionBase = MetadataSerializerExtension(metadataVersion)
|
||||||
|
|
||||||
private fun getPackageFilePath(packageFqName: FqName, fileName: String): String =
|
private fun getPackageFilePath(packageFqName: FqName, fileName: String): String =
|
||||||
packageFqName.asString().replace('.', '/') + "/" +
|
packageFqName.asString().replace('.', '/') + "/" +
|
||||||
PackagePartClassUtils.getFilePartShortName(fileName) + DOT_METADATA_FILE_EXTENSION
|
PackagePartClassUtils.getFilePartShortName(fileName) + DOT_METADATA_FILE_EXTENSION
|
||||||
|
|
||||||
private fun getClassFilePath(classId: ClassId): String =
|
private fun getClassFilePath(classId: ClassId): String =
|
||||||
classId.asSingleFqName().asString().replace('.', '/') + DOT_METADATA_FILE_EXTENSION
|
classId.asSingleFqName().asString().replace('.', '/') + DOT_METADATA_FILE_EXTENSION
|
||||||
|
|
||||||
protected inner class PackageSerializer(
|
protected inner class PackageSerializer(
|
||||||
private val classes: Collection<DeclarationDescriptor>,
|
private val classes: Collection<DeclarationDescriptor>,
|
||||||
private val members: Collection<DeclarationDescriptor>,
|
private val members: Collection<DeclarationDescriptor>,
|
||||||
private val packageFqName: FqName,
|
private val packageFqName: FqName,
|
||||||
private val destFile: File
|
private val destFile: File
|
||||||
) {
|
) {
|
||||||
private val proto = ProtoBuf.PackageFragment.newBuilder()
|
private val proto = ProtoBuf.PackageFragment.newBuilder()
|
||||||
private val extension = createSerializerExtension()
|
private val extension = createSerializerExtension()
|
||||||
|
|||||||
Reference in New Issue
Block a user