Minor. Parametrize MainFunctionDetector with LanguageVersionSettings

This commit is contained in:
Denis Zharkov
2018-09-07 12:13:55 +03:00
parent bc722f9c5f
commit 38be1f6947
15 changed files with 46 additions and 19 deletions
@@ -181,7 +181,7 @@ class GenerationState private constructor(
filter = if (wantsDiagnostics) BindingTraceFilter.ACCEPT_ALL else BindingTraceFilter.NO_DIAGNOSTICS filter = if (wantsDiagnostics) BindingTraceFilter.ACCEPT_ALL else BindingTraceFilter.NO_DIAGNOSTICS
) )
val bindingContext: BindingContext = bindingTrace.bindingContext val bindingContext: BindingContext = bindingTrace.bindingContext
val mainFunctionDetector = MainFunctionDetector(bindingContext) val mainFunctionDetector = MainFunctionDetector(bindingContext, languageVersionSettings)
private val isIrBackend = configuration.get(JVMConfigurationKeys.IR) ?: false private val isIrBackend = configuration.get(JVMConfigurationKeys.IR) ?: false
val typeMapper: KotlinTypeMapper = KotlinTypeMapper( val typeMapper: KotlinTypeMapper = KotlinTypeMapper(
this.bindingContext, this.bindingContext,
@@ -222,7 +222,7 @@ object KotlinToJVMBytecodeCompiler {
} }
private fun findMainClass(generationState: GenerationState, files: List<KtFile>): FqName? { private fun findMainClass(generationState: GenerationState, files: List<KtFile>): FqName? {
val mainFunctionDetector = MainFunctionDetector(generationState.bindingContext) val mainFunctionDetector = MainFunctionDetector(generationState.bindingContext, generationState.languageVersionSettings)
return files.asSequence() return files.asSequence()
.map { file -> .map { file ->
if (mainFunctionDetector.hasMain(file.declarations)) if (mainFunctionDetector.hasMain(file.declarations))
@@ -668,7 +668,7 @@ class ControlFlowInformationProvider private constructor(
if (anonymous && !languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName)) { if (anonymous && !languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName)) {
return return
} }
val mainFunctionDetector = MainFunctionDetector(trace.bindingContext) val mainFunctionDetector = MainFunctionDetector(trace.bindingContext, languageVersionSettings)
val isMain = owner is KtNamedFunction && mainFunctionDetector.isMain(owner) val isMain = owner is KtNamedFunction && mainFunctionDetector.isMain(owner)
val functionName = functionDescriptor.name val functionName = functionDescriptor.name
if (isMain if (isMain
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.idea package org.jetbrains.kotlin.idea
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
@@ -31,17 +32,20 @@ import org.jetbrains.kotlin.types.Variance
class MainFunctionDetector { class MainFunctionDetector {
private val getFunctionDescriptor: (KtNamedFunction) -> FunctionDescriptor? private val getFunctionDescriptor: (KtNamedFunction) -> FunctionDescriptor?
private val languageVersionSettings: LanguageVersionSettings
/** Assumes that the function declaration is already resolved and the descriptor can be found in the `bindingContext`. */ /** Assumes that the function declaration is already resolved and the descriptor can be found in the `bindingContext`. */
constructor(bindingContext: BindingContext) { constructor(bindingContext: BindingContext, languageVersionSettings: LanguageVersionSettings) {
this.getFunctionDescriptor = { function -> this.getFunctionDescriptor = { function ->
bindingContext.get(BindingContext.FUNCTION, function) bindingContext.get(BindingContext.FUNCTION, function)
?: throw IllegalStateException("No descriptor resolved for " + function + " " + function.text) ?: throw IllegalStateException("No descriptor resolved for " + function + " " + function.text)
} }
this.languageVersionSettings = languageVersionSettings
} }
constructor(functionResolver: (KtNamedFunction) -> FunctionDescriptor?) { constructor(languageVersionSettings: LanguageVersionSettings, functionResolver: (KtNamedFunction) -> FunctionDescriptor?) {
this.getFunctionDescriptor = functionResolver this.getFunctionDescriptor = functionResolver
this.languageVersionSettings = languageVersionSettings
} }
fun hasMain(declarations: List<KtDeclaration>): Boolean { fun hasMain(declarations: List<KtDeclaration>): Boolean {
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import com.intellij.util.containers.MultiMap import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.reportOnDeclaration import org.jetbrains.kotlin.diagnostics.reportOnDeclaration
@@ -31,10 +32,11 @@ import java.util.*
class OverloadResolver( class OverloadResolver(
private val trace: BindingTrace, private val trace: BindingTrace,
private val overloadFilter: OverloadFilter, private val overloadFilter: OverloadFilter,
private val overloadChecker: OverloadChecker private val overloadChecker: OverloadChecker,
languageVersionSettings: LanguageVersionSettings
) { ) {
private val mainFunctionDetector = MainFunctionDetector(trace.bindingContext) private val mainFunctionDetector = MainFunctionDetector(trace.bindingContext, languageVersionSettings)
fun checkOverloads(c: BodiesResolveContext) { fun checkOverloads(c: BodiesResolveContext) {
val inClasses = findConstructorsInNestedClassesAndTypeAliases(c) val inClasses = findConstructorsInNestedClassesAndTypeAliases(c)
@@ -56,6 +56,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightMethod;
import org.jetbrains.kotlin.idea.MainFunctionDetector; import org.jetbrains.kotlin.idea.MainFunctionDetector;
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
import org.jetbrains.kotlin.idea.core.FileIndexUtilsKt; import org.jetbrains.kotlin.idea.core.FileIndexUtilsKt;
import org.jetbrains.kotlin.idea.project.PlatformKt;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtDeclaration; import org.jetbrains.kotlin.psi.KtDeclaration;
import org.jetbrains.kotlin.psi.KtDeclarationContainer; import org.jetbrains.kotlin.psi.KtDeclarationContainer;
@@ -319,7 +320,8 @@ public class KotlinRunConfiguration extends JetRunConfiguration {
private static KtNamedFunction findMainFun(@NotNull PsiClass psiClass) { private static KtNamedFunction findMainFun(@NotNull PsiClass psiClass) {
for (KtNamedFunction function : getMainFunCandidates(psiClass)) { for (KtNamedFunction function : getMainFunCandidates(psiClass)) {
BindingContext bindingContext = ResolutionUtils.analyze(function, BodyResolveMode.FULL); BindingContext bindingContext = ResolutionUtils.analyze(function, BodyResolveMode.FULL);
MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(bindingContext); MainFunctionDetector mainFunctionDetector =
new MainFunctionDetector(bindingContext, PlatformKt.getLanguageVersionSettings(function));
if (mainFunctionDetector.isMain(function)) return function; if (mainFunctionDetector.isMain(function)) return function;
} }
return null; return null;
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
@@ -79,7 +80,8 @@ class KotlinRunConfigurationProducer : RunConfigurationProducer<KotlinRunConfigu
val psiFile = locationElement.containingFile val psiFile = locationElement.containingFile
if (!(psiFile is KtFile && ProjectRootsUtil.isInProjectOrLibSource(psiFile))) return null if (!(psiFile is KtFile && ProjectRootsUtil.isInProjectOrLibSource(psiFile))) return null
val mainFunctionDetector = MainFunctionDetector { it.resolveToDescriptorIfAny(BodyResolveMode.FULL) } val mainFunctionDetector =
MainFunctionDetector(psiFile.languageVersionSettings) { it.resolveToDescriptorIfAny(BodyResolveMode.FULL) }
var currentElement = locationElement.declarationContainer(false) var currentElement = locationElement.declarationContainer(false)
while (currentElement != null) { while (currentElement != null) {
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.platform.tooling import org.jetbrains.kotlin.idea.platform.tooling
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.project.platform import org.jetbrains.kotlin.idea.project.platform
import org.jetbrains.kotlin.idea.util.module import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
@@ -33,7 +34,7 @@ class KotlinRunLineMarkerContributor : RunLineMarkerContributor() {
if (function.nameIdentifier != element) return null if (function.nameIdentifier != element) return null
val detector = MainFunctionDetector { someFunction -> val detector = MainFunctionDetector(function.languageVersionSettings) { someFunction ->
someFunction.resolveToDescriptorIfAny() someFunction.resolveToDescriptorIfAny()
} }
@@ -46,4 +47,4 @@ class KotlinRunLineMarkerContributor : RunLineMarkerContributor() {
return null return null
} }
} }
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.core.setType import org.jetbrains.kotlin.idea.core.setType
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.KtAnnotationEntry
@@ -36,7 +37,9 @@ class MainFunctionReturnUnitInspection : AbstractKotlinInspection() {
val descriptor = function.descriptor as? FunctionDescriptor ?: return val descriptor = function.descriptor as? FunctionDescriptor ?: return
if (isMain) { if (isMain) {
if (!MainFunctionDetector { it.resolveToDescriptorIfAny() }.isMain(descriptor, checkReturnType = false)) return val mainFunctionDetector =
MainFunctionDetector(function.languageVersionSettings) { it.resolveToDescriptorIfAny() }
if (!mainFunctionDetector.isMain(descriptor, checkReturnType = false)) return
} else { } else {
val junitTestFqNames = listOf(FqName("org.junit.Test"), FqName("org.junit.jupiter.api.Test")) val junitTestFqNames = listOf(FqName("org.junit.Test"), FqName("org.junit.jupiter.api.Test"))
if (testAnnotations.none { it.fqName() in junitTestFqNames }) return if (testAnnotations.none { it.fqName() in junitTestFqNames }) return
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.core.isOverridable
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeSignatureConfiguration import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeSignatureConfiguration
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor
import org.jetbrains.kotlin.idea.refactoring.changeSignature.modify import org.jetbrains.kotlin.idea.refactoring.changeSignature.modify
@@ -77,7 +78,9 @@ class UnusedReceiverParameterInspection : AbstractKotlinInspection() {
val callable = callableDeclaration.descriptor ?: return val callable = callableDeclaration.descriptor ?: return
if (MainFunctionDetector { it.resolveToDescriptorIfAny() }.isMain(callable)) return val mainFunctionDetector =
MainFunctionDetector(callableDeclaration.languageVersionSettings) { it.resolveToDescriptorIfAny() }
if (mainFunctionDetector.isMain(callable)) return
val containingDeclaration = callable.containingDeclaration val containingDeclaration = callable.containingDeclaration
if (containingDeclaration != null && containingDeclaration == receiverTypeDeclaration) { if (containingDeclaration != null && containingDeclaration == receiverTypeDeclaration) {
@@ -30,6 +30,7 @@ import com.intellij.psi.PsiManager
import com.intellij.refactoring.RefactoringFactory import com.intellij.refactoring.RefactoringFactory
import com.intellij.testFramework.MapDataContext import com.intellij.testFramework.MapDataContext
import com.intellij.testFramework.PsiTestUtil import com.intellij.testFramework.PsiTestUtil
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.search.allScope import org.jetbrains.kotlin.idea.search.allScope
@@ -69,7 +70,7 @@ class RunConfigurationTest: KotlinCodeInsightTestCase() {
val assertIsNotMain = "no" in options val assertIsNotMain = "no" in options
val isMainFunction = val isMainFunction =
MainFunctionDetector { it.resolveToDescriptorIfAny() }.isMain(function) MainFunctionDetector(LanguageVersionSettingsImpl.DEFAULT) { it.resolveToDescriptorIfAny() }.isMain(function)
if (assertIsMain) { if (assertIsMain) {
Assert.assertTrue("The function ${function.fqName?.asString()} should be main", isMainFunction) Assert.assertTrue("The function ${function.fqName?.asString()} should be main", isMainFunction)
@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.jetbrains.kotlin.config.CommonConfigurationKeysKt.getLanguageVersionSettings;
import static org.jetbrains.kotlin.utils.PathUtil.getKotlinPathsForDistDirectory; import static org.jetbrains.kotlin.utils.PathUtil.getKotlinPathsForDistDirectory;
public class JsConfig { public class JsConfig {
@@ -135,6 +134,11 @@ public class JsConfig {
return getConfiguration().getList(JSConfigurationKeys.FRIEND_PATHS); return getConfiguration().getList(JSConfigurationKeys.FRIEND_PATHS);
} }
@NotNull
public LanguageVersionSettings getLanguageVersionSettings() {
return CommonConfigurationKeysKt.getLanguageVersionSettings(configuration);
}
public boolean isAtLeast(@NotNull LanguageVersion expected) { public boolean isAtLeast(@NotNull LanguageVersion expected) {
LanguageVersion actual = CommonConfigurationKeysKt.getLanguageVersionSettings(configuration).getLanguageVersion(); LanguageVersion actual = CommonConfigurationKeysKt.getLanguageVersionSettings(configuration).getLanguageVersion();
return actual.getMajor() > expected.getMajor() || return actual.getMajor() > expected.getMajor() ||
@@ -165,7 +169,10 @@ public class JsConfig {
Set<String> modules = new HashSet<>(); Set<String> modules = new HashSet<>();
boolean skipMetadataVersionCheck = getLanguageVersionSettings(configuration).getFlag(AnalysisFlag.getSkipMetadataVersionCheck()); boolean skipMetadataVersionCheck =
getLanguageVersionSettings().getFlag(
AnalysisFlag.getSkipMetadataVersionCheck()
);
for (String path : libraries) { for (String path : libraries) {
if (librariesToSkip != null && librariesToSkip.contains(path)) continue; if (librariesToSkip != null && librariesToSkip.contains(path)) continue;
@@ -463,7 +463,7 @@ public final class Translation {
) { ) {
StaticContext staticContext = new StaticContext(trace, config, moduleDescriptor, sourceFilePathResolver); StaticContext staticContext = new StaticContext(trace, config, moduleDescriptor, sourceFilePathResolver);
TranslationContext context = TranslationContext.rootContext(staticContext); TranslationContext context = TranslationContext.rootContext(staticContext);
MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(context.bindingContext()); MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(context.bindingContext(), config.getLanguageVersionSettings());
FunctionDescriptor functionDescriptor = mainFunctionDetector.getMainFunction(moduleDescriptor); FunctionDescriptor functionDescriptor = mainFunctionDetector.getMainFunction(moduleDescriptor);
if (functionDescriptor == null) { if (functionDescriptor == null) {
return null; return null;
+1
View File
@@ -30,6 +30,7 @@ dependencies {
compile(project(":compiler:light-classes")) { isTransitive = false } compile(project(":compiler:light-classes")) { isTransitive = false }
compile(project(":compiler:frontend")) { isTransitive = false } compile(project(":compiler:frontend")) { isTransitive = false }
compile(project(":compiler:frontend.java")) { isTransitive = false } compile(project(":compiler:frontend.java")) { isTransitive = false }
compile(project(":compiler:util")) { isTransitive = false }
compile(project(":js:js.frontend")) { isTransitive = false } compile(project(":js:js.frontend")) { isTransitive = false }
compile(projectClasses(":idea")) compile(projectClasses(":idea"))
compile(project(":idea:idea-jvm")) { isTransitive = false } compile(project(":idea:idea-jvm")) { isTransitive = false }
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.js.asJsModule
import org.jetbrains.kotlin.idea.js.jsProductionOutputFilePath import org.jetbrains.kotlin.idea.js.jsProductionOutputFilePath
import org.jetbrains.kotlin.idea.nodejs.TestElementPath import org.jetbrains.kotlin.idea.nodejs.TestElementPath
import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.run.addBuildTask import org.jetbrains.kotlin.idea.run.addBuildTask
import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
@@ -52,7 +53,7 @@ private class KotlinNodeJsRunConfigurationProducer :
val jsFilePath = module.jsProductionOutputFilePath ?: return null val jsFilePath = module.jsProductionOutputFilePath ?: return null
val declaration = element.getNonStrictParentOfType<KtNamedDeclaration>() val declaration = element.getNonStrictParentOfType<KtNamedDeclaration>()
if (declaration is KtNamedFunction) { if (declaration is KtNamedFunction) {
val detector = MainFunctionDetector { it.resolveToDescriptorIfAny() } val detector = MainFunctionDetector(declaration.languageVersionSettings) { it.resolveToDescriptorIfAny() }
if (!detector.isMain(declaration, false)) return null if (!detector.isMain(declaration, false)) return null
} else if (!TestElementPath.isModuleAssociatedDir(element, module)) return null } else if (!TestElementPath.isModuleAssociatedDir(element, module)) return null
return NodeJsConfigData(element, module, jsFilePath) return NodeJsConfigData(element, module, jsFilePath)
@@ -81,4 +82,4 @@ private class KotlinNodeJsRunConfigurationProducer :
val configData = getConfigurationData(context) ?: return false val configData = getConfigurationData(context) ?: return false
return configuration.inputPath == configData.jsOutputFilePath return configuration.inputPath == configData.jsOutputFilePath
} }
} }