Apply "unnamed boolean literal" to idea & J2K + other style fixes

This commit is contained in:
Mikhail Glukhikh
2019-05-06 17:13:33 +03:00
parent 955bfd6e7b
commit d517276a06
25 changed files with 388 additions and 278 deletions
@@ -300,7 +300,7 @@ class Fir2IrDeclarationStorage(
startOffset, endOffset, origin, symbol, startOffset, endOffset, origin, symbol,
constructor.name, constructor.visibility, constructor.name, constructor.visibility,
constructor.returnTypeRef.toIrType(session, this), constructor.returnTypeRef.toIrType(session, this),
false, false, isPrimary isInline = false, isExternal = false, isPrimary = isPrimary
).bindAndDeclareParameters(constructor, descriptor, setParent, shouldLeaveScope) ).bindAndDeclareParameters(constructor, descriptor, setParent, shouldLeaveScope)
} }
} }
@@ -167,18 +167,18 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
callableName, callableName,
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)), ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)), ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
Flags.IS_EXPECT_PROPERTY.get(flags), isExpect = Flags.IS_EXPECT_PROPERTY.get(flags),
false, isActual = false,
false, isOverride = false,
Flags.IS_CONST.get(flags), isConst = Flags.IS_CONST.get(flags),
Flags.IS_LATEINIT.get(flags), isLateInit = Flags.IS_LATEINIT.get(flags),
proto.receiverType(c.typeTable)?.toTypeRef(local), receiverTypeRef = proto.receiverType(c.typeTable)?.toTypeRef(local),
returnTypeRef, returnTypeRef = returnTypeRef,
Flags.IS_VAR.get(flags), isVar = Flags.IS_VAR.get(flags),
null, initializer = null,
FirDefaultPropertyGetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))), getter = FirDefaultPropertyGetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))),
FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags))), setter = FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags))),
null delegate = null
).apply { ).apply {
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.firUnsafe() } typeParameters += local.typeDeserializer.ownTypeParameters.map { it.firUnsafe() }
annotations += c.annotationDeserializer.loadPropertyAnnotations(proto, local.nameResolver) annotations += c.annotationDeserializer.loadPropertyAnnotations(proto, local.nameResolver)
@@ -209,16 +209,16 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)), ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)), ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
Flags.IS_EXPECT_FUNCTION.get(flags), Flags.IS_EXPECT_FUNCTION.get(flags),
false, isActual = false,
false, isOverride = false,
Flags.IS_OPERATOR.get(flags), isOperator = Flags.IS_OPERATOR.get(flags),
Flags.IS_INFIX.get(flags), isInfix = Flags.IS_INFIX.get(flags),
Flags.IS_INLINE.get(flags), isInline = Flags.IS_INLINE.get(flags),
Flags.IS_TAILREC.get(flags), isTailRec = Flags.IS_TAILREC.get(flags),
Flags.IS_EXTERNAL_FUNCTION.get(flags), isExternal = Flags.IS_EXTERNAL_FUNCTION.get(flags),
Flags.IS_SUSPEND.get(flags), isSuspend = Flags.IS_SUSPEND.get(flags),
proto.receiverType(local.typeTable)?.toTypeRef(local), receiverTypeRef = proto.receiverType(local.typeTable)?.toTypeRef(local),
proto.returnType(local.typeTable).toTypeRef(local) returnTypeRef = proto.returnType(local.typeTable).toTypeRef(local)
).apply { ).apply {
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.firUnsafe() } typeParameters += local.typeDeserializer.ownTypeParameters.map { it.firUnsafe() }
valueParameters += local.memberDeserializer.valueParameters(proto.valueParameterList) valueParameters += local.memberDeserializer.valueParameters(proto.valueParameterList)
@@ -22,7 +22,11 @@ interface SyntheticSymbol : ConeSymbol
class SyntheticPropertySymbol(callableId: CallableId) : FirPropertySymbol(callableId), SyntheticSymbol class SyntheticPropertySymbol(callableId: CallableId) : FirPropertySymbol(callableId), SyntheticSymbol
class FirSyntheticPropertiesScope(val session: FirSession, val baseScope: FirScope, val typeCalculator: ReturnTypeCalculator) : FirScope { class FirSyntheticPropertiesScope(
val session: FirSession,
private val baseScope: FirScope,
private val typeCalculator: ReturnTypeCalculator
) : FirScope {
val synthetic: MutableMap<ConeCallableSymbol, ConeVariableSymbol> = mutableMapOf() val synthetic: MutableMap<ConeCallableSymbol, ConeVariableSymbol> = mutableMapOf()
@@ -47,18 +51,18 @@ class FirSyntheticPropertiesScope(val session: FirSession, val baseScope: FirSco
name, name,
fir.visibility, fir.visibility,
fir.modality, fir.modality,
false, isExpect = false,
false, isActual = false,
false, isOverride = false,
false, isConst = false,
false, isLateInit = false,
null, receiverTypeRef = null,
returnTypeRef, returnTypeRef = returnTypeRef,
true, isVar = true,
null, initializer = null,
FirDefaultPropertyGetter(session, null, returnTypeRef, fir.visibility), getter = FirDefaultPropertyGetter(session, null, returnTypeRef, fir.visibility),
FirDefaultPropertySetter(session, null, returnTypeRef, fir.visibility), setter = FirDefaultPropertySetter(session, null, returnTypeRef, fir.visibility),
null delegate = null
) )
return processor(synthetic) return processor(synthetic)
} }
@@ -169,9 +169,9 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider
relativeClassName.shortName(), relativeClassName.shortName(),
Visibilities.PUBLIC, Visibilities.PUBLIC,
Modality.OPEN, Modality.OPEN,
false, isExpect = false,
false, isActual = false,
ClassKind.CLASS, classKind = ClassKind.CLASS,
isInner = false, isInner = false,
isCompanion = false, isCompanion = false,
isData = false, isData = false,
@@ -435,10 +435,10 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
null, null,
Name.identifier("it"), Name.identifier("it"),
FirResolvedTypeRefImpl(session, null, parameters.single(), emptyList()), FirResolvedTypeRefImpl(session, null, parameters.single(), emptyList()),
null, defaultValue = null,
false, isCrossinline = false,
false, isNoinline = false,
false isVararg = false
) )
else -> null else -> null
} }
@@ -85,7 +85,7 @@ object SourceNavigationHelper {
private fun Collection<GlobalSearchScope>.union(): List<GlobalSearchScope> = private fun Collection<GlobalSearchScope>.union(): List<GlobalSearchScope> =
if (this.isNotEmpty()) listOf(GlobalSearchScope.union(this.toTypedArray())) else emptyList() if (this.isNotEmpty()) listOf(GlobalSearchScope.union(this.toTypedArray())) else emptyList()
private fun haveRenamesInImports(files: Collection<KtFile>) = files.any { it.importDirectives.any { it.aliasName != null } } private fun haveRenamesInImports(files: Collection<KtFile>) = files.any { file -> file.importDirectives.any { it.aliasName != null } }
private fun findSpecialProperty(memberName: Name, containingClass: KtClass): KtNamedDeclaration? { private fun findSpecialProperty(memberName: Name, containingClass: KtClass): KtNamedDeclaration? {
// property constructor parameters // property constructor parameters
@@ -191,7 +191,7 @@ object SourceNavigationHelper {
): T? { ): T? {
val classFqName = entity.fqName ?: return null val classFqName = entity.fqName ?: return null
return targetScopes(entity, navigationKind).firstNotNullResult { scope -> return targetScopes(entity, navigationKind).firstNotNullResult { scope ->
index.get(classFqName.asString(), entity.project, scope).sortedBy { it.isExpectDeclaration() }.firstOrNull() index.get(classFqName.asString(), entity.project, scope).minBy { it.isExpectDeclaration() }
} }
} }
@@ -273,7 +273,15 @@ object SourceNavigationHelper {
SourceNavigationHelper.NavigationKind.SOURCES_TO_CLASS_FILES -> { SourceNavigationHelper.NavigationKind.SOURCES_TO_CLASS_FILES -> {
val file = from.containingFile val file = from.containingFile
if (file is KtFile && file.isCompiled) return from if (file is KtFile && file.isCompiled) return from
if (!ProjectRootsUtil.isInContent(from, false, true, false, true, false)) return from if (!ProjectRootsUtil.isInContent(
from,
includeProjectSource = false,
includeLibrarySource = true,
includeLibraryClasses = false,
includeScriptDependencies = true,
includeScriptsOutsideSourceRoots = false
)
) return from
if (KtPsiUtil.isLocal(from)) return from if (KtPsiUtil.isLocal(from)) return from
} }
} }
@@ -85,50 +85,109 @@ class KotlinSourceFilterScope private constructor(
companion object { companion object {
@JvmStatic @JvmStatic
fun sourcesAndLibraries(delegate: GlobalSearchScope, project: Project) = create(delegate, true, true, true, true, true, project) fun sourcesAndLibraries(delegate: GlobalSearchScope, project: Project) = create(
delegate,
includeProjectSourceFiles = true,
includeLibrarySourceFiles = true,
includeClassFiles = true,
includeScriptDependencies = true,
includeScriptsOutsideSourceRoots = true,
project = project
)
@JvmStatic @JvmStatic
fun sourceAndClassFiles(delegate: GlobalSearchScope, project: Project) = create(delegate, true, false, true, true, true, project) fun sourceAndClassFiles(delegate: GlobalSearchScope, project: Project) = create(
delegate,
includeProjectSourceFiles = true,
includeLibrarySourceFiles = false,
includeClassFiles = true,
includeScriptDependencies = true,
includeScriptsOutsideSourceRoots = true,
project = project
)
@JvmStatic @JvmStatic
fun projectSourceAndClassFiles(delegate: GlobalSearchScope, project: Project) = create(delegate, true, false, true, false, true, project) fun projectSourceAndClassFiles(delegate: GlobalSearchScope, project: Project) = create(
delegate,
includeProjectSourceFiles = true,
includeLibrarySourceFiles = false,
includeClassFiles = true,
includeScriptDependencies = false,
includeScriptsOutsideSourceRoots = true,
project = project
)
@JvmStatic @JvmStatic
fun projectSources(delegate: GlobalSearchScope, project: Project) = create(delegate, true, false, false, false, true, project) fun projectSources(delegate: GlobalSearchScope, project: Project) = create(
delegate,
includeProjectSourceFiles = true,
includeLibrarySourceFiles = false,
includeClassFiles = false,
includeScriptDependencies = false,
includeScriptsOutsideSourceRoots = true,
project = project
)
@JvmStatic @JvmStatic
fun librarySources(delegate: GlobalSearchScope, project: Project) = create(delegate, false, true, false, true, false, project) fun librarySources(delegate: GlobalSearchScope, project: Project) = create(
delegate,
includeProjectSourceFiles = false,
includeLibrarySourceFiles = true,
includeClassFiles = false,
includeScriptDependencies = true,
includeScriptsOutsideSourceRoots = false,
project = project
)
@JvmStatic @JvmStatic
fun libraryClassFiles(delegate: GlobalSearchScope, project: Project) = create(delegate, false, false, true, true, false, project) fun libraryClassFiles(delegate: GlobalSearchScope, project: Project) = create(
delegate,
includeProjectSourceFiles = false,
includeLibrarySourceFiles = false,
includeClassFiles = true,
includeScriptDependencies = true,
includeScriptsOutsideSourceRoots = false,
project = project
)
@JvmStatic @JvmStatic
fun projectAndLibrariesSources(delegate: GlobalSearchScope, project: Project) = create(delegate, true, true, false, false, true, project) fun projectAndLibrariesSources(delegate: GlobalSearchScope, project: Project) = create(
delegate,
includeProjectSourceFiles = true,
includeLibrarySourceFiles = true,
includeClassFiles = false,
includeScriptDependencies = false,
includeScriptsOutsideSourceRoots = true,
project = project
)
private fun create( private fun create(
delegate: GlobalSearchScope, delegate: GlobalSearchScope,
includeProjectSourceFiles: Boolean, includeProjectSourceFiles: Boolean,
includeLibrarySourceFiles: Boolean, includeLibrarySourceFiles: Boolean,
includeClassFiles: Boolean, includeClassFiles: Boolean,
includeScriptDependencies: Boolean, includeScriptDependencies: Boolean,
includeScriptsOutsideSourceRoots: Boolean, includeScriptsOutsideSourceRoots: Boolean,
project: Project project: Project
): GlobalSearchScope { ): GlobalSearchScope {
if (delegate === GlobalSearchScope.EMPTY_SCOPE) return delegate if (delegate === GlobalSearchScope.EMPTY_SCOPE) return delegate
if (delegate is KotlinSourceFilterScope) { if (delegate is KotlinSourceFilterScope) {
return KotlinSourceFilterScope( return KotlinSourceFilterScope(
delegate.myBaseScope, delegate.myBaseScope,
includeProjectSourceFiles = delegate.includeProjectSourceFiles && includeProjectSourceFiles, includeProjectSourceFiles = delegate.includeProjectSourceFiles && includeProjectSourceFiles,
includeLibrarySourceFiles = delegate.includeLibrarySourceFiles && includeLibrarySourceFiles, includeLibrarySourceFiles = delegate.includeLibrarySourceFiles && includeLibrarySourceFiles,
includeClassFiles = delegate.includeClassFiles && includeClassFiles, includeClassFiles = delegate.includeClassFiles && includeClassFiles,
includeScriptDependencies = delegate.includeScriptDependencies && includeScriptDependencies, includeScriptDependencies = delegate.includeScriptDependencies && includeScriptDependencies,
includeScriptsOutsideSourceRoots = delegate.includeScriptsOutsideSourceRoots && includeScriptsOutsideSourceRoots, includeScriptsOutsideSourceRoots = delegate.includeScriptsOutsideSourceRoots && includeScriptsOutsideSourceRoots,
project = project project = project
) )
} }
return KotlinSourceFilterScope(delegate, includeProjectSourceFiles, includeLibrarySourceFiles, includeClassFiles, includeScriptDependencies, includeScriptsOutsideSourceRoots, project) return KotlinSourceFilterScope(
delegate, includeProjectSourceFiles, includeLibrarySourceFiles, includeClassFiles,
includeScriptDependencies, includeScriptsOutsideSourceRoots, project
)
} }
} }
} }
@@ -87,8 +87,7 @@ class GroovyBuildScriptManipulator(
} }
} }
} }
} } else {
else {
val applyPluginDirective = getGroovyApplyPluginDirective(kotlinPluginName) val applyPluginDirective = getGroovyApplyPluginDirective(kotlinPluginName)
if (!containsDirective(scriptFile.text, applyPluginDirective)) { if (!containsDirective(scriptFile.text, applyPluginDirective)) {
val apply = GroovyPsiElementFactory.getInstance(scriptFile.project).createExpressionFromText(applyPluginDirective) val apply = GroovyPsiElementFactory.getInstance(scriptFile.project).createExpressionFromText(applyPluginDirective)
@@ -246,11 +245,11 @@ class GroovyBuildScriptManipulator(
.getBlockOrCreate("resolutionStrategy") .getBlockOrCreate("resolutionStrategy")
.getBlockOrCreate("eachPlugin") .getBlockOrCreate("eachPlugin")
.addLastStatementInBlockIfNeeded( .addLastStatementInBlockIfNeeded(
""" """
if (requested.id.id == "$pluginId") { if (requested.id.id == "$pluginId") {
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${'$'}{requested.version}") useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${'$'}{requested.version}")
} }
""".trimIndent() """.trimIndent()
) )
} }
@@ -415,9 +414,9 @@ class GroovyBuildScriptManipulator(
} }
companion object { companion object {
private val VERSION_TEMPLATE = "\$VERSION$" private const val VERSION_TEMPLATE = "\$VERSION$"
private val VERSION = String.format("ext.kotlin_version = '%s'", VERSION_TEMPLATE) private val VERSION = String.format("ext.kotlin_version = '%s'", VERSION_TEMPLATE)
private val GRADLE_PLUGIN_ID = "kotlin-gradle-plugin" private const val GRADLE_PLUGIN_ID = "kotlin-gradle-plugin"
private val CLASSPATH = "classpath \"$KOTLIN_GROUP_ID:$GRADLE_PLUGIN_ID:\$kotlin_version\"" private val CLASSPATH = "classpath \"$KOTLIN_GROUP_ID:$GRADLE_PLUGIN_ID:\$kotlin_version\""
private fun PsiElement.getBlockByName(name: String): GrClosableBlock? { private fun PsiElement.getBlockByName(name: String): GrClosableBlock? {
@@ -454,13 +453,13 @@ class GroovyBuildScriptManipulator(
} }
fun GrClosableBlock.addLastExpressionInBlockIfNeeded(expressionText: String): Boolean = fun GrClosableBlock.addLastExpressionInBlockIfNeeded(expressionText: String): Boolean =
addExpressionOrStatementInBlockIfNeeded(expressionText, false, false) addExpressionOrStatementInBlockIfNeeded(expressionText, isStatement = false, isFirst = false)
fun GrClosableBlock.addLastStatementInBlockIfNeeded(expressionText: String): Boolean = fun GrClosableBlock.addLastStatementInBlockIfNeeded(expressionText: String): Boolean =
addExpressionOrStatementInBlockIfNeeded(expressionText, true, false) addExpressionOrStatementInBlockIfNeeded(expressionText, isStatement = true, isFirst = false)
private fun GrClosableBlock.addFirstExpressionInBlockIfNeeded(expressionText: String): Boolean = private fun GrClosableBlock.addFirstExpressionInBlockIfNeeded(expressionText: String): Boolean =
addExpressionOrStatementInBlockIfNeeded(expressionText, false, true) addExpressionOrStatementInBlockIfNeeded(expressionText, isStatement = false, isFirst = true)
private fun GrClosableBlock.addExpressionOrStatementInBlockIfNeeded(text: String, isStatement: Boolean, isFirst: Boolean): Boolean { private fun GrClosableBlock.addExpressionOrStatementInBlockIfNeeded(text: String, isStatement: Boolean, isFirst: Boolean): Boolean {
if (statements.any { StringUtil.equalsIgnoreWhitespaces(it.text, text) }) return false if (statements.any { StringUtil.equalsIgnoreWhitespaces(it.text, text) }) return false
@@ -56,7 +56,9 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext) {
return runReadAction { doCompile(codeFragment, bindingContext, moduleDescriptor) } return runReadAction { doCompile(codeFragment, bindingContext, moduleDescriptor) }
} }
private fun doCompile(codeFragment: KtCodeFragment, bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor): CompilationResult { private fun doCompile(
codeFragment: KtCodeFragment, bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor
): CompilationResult {
require(codeFragment is KtBlockCodeFragment || codeFragment is KtExpressionCodeFragment) { require(codeFragment is KtBlockCodeFragment || codeFragment is KtExpressionCodeFragment) {
"Unsupported code fragment type: $codeFragment" "Unsupported code fragment type: $codeFragment"
} }
@@ -111,7 +113,7 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext) {
} }
val ownerClassName = typeMapper.mapOwner(parameter.targetDescriptor).internalName val ownerClassName = typeMapper.mapOwner(parameter.targetDescriptor).internalName
val lastDollarIndex = ownerClassName.lastIndexOf('$').takeIf { it >= 0} ?: continue val lastDollarIndex = ownerClassName.lastIndexOf('$').takeIf { it >= 0 } ?: continue
result[parameter.dumb] = ownerClassName.drop(lastDollarIndex) result[parameter.dumb] = ownerClassName.drop(lastDollarIndex)
} }
@@ -176,7 +178,12 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext) {
val parameters = parameterInfo.parameters.mapIndexed { index, parameter -> val parameters = parameterInfo.parameters.mapIndexed { index, parameter ->
ValueParameterDescriptorImpl( ValueParameterDescriptorImpl(
methodDescriptor, null, index, Annotations.EMPTY, Name.identifier("p$index"), methodDescriptor, null, index, Annotations.EMPTY, Name.identifier("p$index"),
parameter.targetType, false, false, false, null, SourceElement.NO_SOURCE parameter.targetType,
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = SourceElement.NO_SOURCE
) )
} }
@@ -37,11 +37,11 @@ import kotlin.reflect.KClass
// TODO: need to manage resources here, i.e. call replCompiler.dispose when engine is collected // TODO: need to manage resources here, i.e. call replCompiler.dispose when engine is collected
class KotlinJsr223JvmScriptEngine4Idea( class KotlinJsr223JvmScriptEngine4Idea(
factory: ScriptEngineFactory, factory: ScriptEngineFactory,
templateClasspath: List<File>, templateClasspath: List<File>,
templateClassName: String, templateClassName: String,
private val getScriptArgs: (ScriptContext, Array<out KClass<out Any>>?) -> ScriptArgsWithTypes?, private val getScriptArgs: (ScriptContext, Array<out KClass<out Any>>?) -> ScriptArgsWithTypes?,
private val scriptArgsTypes: Array<out KClass<out Any>>? private val scriptArgsTypes: Array<out KClass<out Any>>?
) : KotlinJsr223JvmScriptEngineBase(factory) { ) : KotlinJsr223JvmScriptEngineBase(factory) {
private val daemon by lazy { private val daemon by lazy {
@@ -53,28 +53,37 @@ class KotlinJsr223JvmScriptEngine4Idea(
val daemonReportMessages = arrayListOf<DaemonReportMessage>() val daemonReportMessages = arrayListOf<DaemonReportMessage>()
KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true) KotlinCompilerClient.connectToCompileService(
?: throw ScriptException("Unable to connect to repl server:" + daemonReportMessages.joinToString("\n ", prefix = "\n ") { "${it.category.name} ${it.message}" }) compilerId, daemonJVMOptions, daemonOptions,
DaemonReportingTargets(null, daemonReportMessages),
autostart = true, checkId = true
) ?: throw ScriptException(
"Unable to connect to repl server:" + daemonReportMessages.joinToString("\n ", prefix = "\n ") {
"${it.category.name} ${it.message}"
}
)
} }
private val messageCollector = MyMessageCollector() private val messageCollector = MyMessageCollector()
override val replCompiler: ReplCompiler by lazy { override val replCompiler: ReplCompiler by lazy {
daemon.let { KotlinRemoteReplCompilerClient(
KotlinRemoteReplCompilerClient(it, daemon,
makeAutodeletingFlagFile("idea-jsr223-repl-session"), makeAutodeletingFlagFile("idea-jsr223-repl-session"),
CompileService.TargetPlatform.JVM, CompileService.TargetPlatform.JVM,
emptyArray(), emptyArray(),
messageCollector, messageCollector,
templateClasspath, templateClasspath,
templateClassName) templateClassName
} )
} }
override fun overrideScriptArgs(context: ScriptContext): ScriptArgsWithTypes? = override fun overrideScriptArgs(context: ScriptContext): ScriptArgsWithTypes? =
getScriptArgs(getContext(), scriptArgsTypes) getScriptArgs(getContext(), scriptArgsTypes)
private val localEvaluator: ReplFullEvaluator by lazy { GenericReplCompilingEvaluator(replCompiler, templateClasspath, Thread.currentThread().contextClassLoader) } private val localEvaluator: ReplFullEvaluator by lazy {
GenericReplCompilingEvaluator(replCompiler, templateClasspath, Thread.currentThread().contextClassLoader)
}
override val replEvaluator: ReplFullEvaluator get() = localEvaluator override val replEvaluator: ReplFullEvaluator get() = localEvaluator
@@ -113,7 +113,7 @@ fun provideTypeHint(element: KtCallableDeclaration, offset: Int): List<InlayInfo
} }
append(getInlayHintsTypeRenderer(element.analyze(), element).renderType(type)) append(getInlayHintsTypeRenderer(element.analyze(), element).renderType(type))
} }
listOf(InlayInfo(declString, offset, false, true, true)) listOf(InlayInfo(declString, offset, isShowOnlyIfExistedBefore = false, isFilterByBlacklist = true, relatesToPrecedingText = true))
} else { } else {
emptyList() emptyList()
} }
@@ -105,7 +105,7 @@ private fun getActualTargetList(annotated: PsiTarget): AnnotationChecker.Compani
else -> T_MEMBER_FUNCTION else -> T_MEMBER_FUNCTION
} }
is PsiExpression -> T_EXPRESSION is PsiExpression -> T_EXPRESSION
is PsiField -> T_MEMBER_PROPERTY(true, false) is PsiField -> T_MEMBER_PROPERTY(backingField = true, delegate = false)
is PsiLocalVariable -> T_LOCAL_VARIABLE is PsiLocalVariable -> T_LOCAL_VARIABLE
is PsiParameter -> T_VALUE_PARAMETER_WITHOUT_VAL is PsiParameter -> T_VALUE_PARAMETER_WITHOUT_VAL
else -> EMPTY else -> EMPTY
@@ -130,7 +130,7 @@ abstract class TypeInfo(val variance: Variance) {
return Collections.singletonList(callableBuilder.currentFileModule.builtIns.anyType) return Collections.singletonList(callableBuilder.currentFileModule.builtIns.anyType)
} }
val scope = getScopeForTypeApproximation(callableBuilder.config, callableBuilder.placement) val scope = getScopeForTypeApproximation(callableBuilder.config, callableBuilder.placement)
val approximations = getResolvableApproximations(scope, false, true) val approximations = getResolvableApproximations(scope, checkTypeParameters = false, allowIntersections = true)
return when (variance) { return when (variance) {
Variance.IN_VARIANCE -> approximations.toList() Variance.IN_VARIANCE -> approximations.toList()
else -> listOf(approximations.firstOrNull() ?: this) else -> listOf(approximations.firstOrNull() ?: this)
@@ -125,8 +125,8 @@ internal class ChangeMethodParameters(
ValueParameterDescriptorImpl( ValueParameterDescriptorImpl(
this, null, index, Annotations.EMPTY, this, null, index, Annotations.EMPTY,
Name.identifier(parameter.name), Name.identifier(parameter.name),
parameter.ktType, false, parameter.ktType, declaresDefaultValue = false,
false, false, null, SourceElement.NO_SOURCE isCrossinline = false, isNoinline = false, varargElementType = null, source = SourceElement.NO_SOURCE
) )
}, },
functionDescriptor.returnType, functionDescriptor.returnType,
@@ -210,7 +210,12 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
val result = LinkedHashSet<PsiReference>() val result = LinkedHashSet<PsiReference>()
val searchScope = functionPsi.useScope val searchScope = functionPsi.useScope
val options = KotlinReferencesSearchOptions(true, false, false, false) val options = KotlinReferencesSearchOptions(
acceptCallableOverrides = true,
acceptOverloads = false,
acceptExtensionsOfDeclarationClass = false,
acceptCompanionObjectMembers = false
)
val parameters = KotlinReferencesSearchParameters(functionPsi, searchScope, false, null, options) val parameters = KotlinReferencesSearchParameters(functionPsi, searchScope, false, null, options)
result.addAll(ReferencesSearch.search(parameters).findAll()) result.addAll(ReferencesSearch.search(parameters).findAll())
if (functionPsi is KtProperty || functionPsi is KtParameter) { if (functionPsi is KtProperty || functionPsi is KtParameter) {
@@ -37,14 +37,14 @@ import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
class KotlinAwareDelegatingMoveDestination( class KotlinAwareDelegatingMoveDestination(
private val delegate: MoveDestination, private val delegate: MoveDestination,
private val targetPackage: PsiPackage?, private val targetPackage: PsiPackage?,
private val targetDirectory: PsiDirectory? private val targetDirectory: PsiDirectory?
) : MoveDestination by delegate { ) : MoveDestination by delegate {
override fun analyzeModuleConflicts( override fun analyzeModuleConflicts(
elements: MutableCollection<PsiElement>, elements: MutableCollection<PsiElement>,
conflicts: MultiMap<PsiElement, String>, conflicts: MultiMap<PsiElement, String>,
usages: Array<out UsageInfo> usages: Array<out UsageInfo>
) { ) {
delegate.analyzeModuleConflicts(elements, conflicts, usages) delegate.analyzeModuleConflicts(elements, conflicts, usages)
@@ -71,7 +71,7 @@ class KotlinAwareDelegatingMoveDestination(
super.visitElement(element) super.visitElement(element)
} }
} }
filesToProcess.flatMap {it.declarations}.forEach { it.accept(extraElementCollector) } filesToProcess.flatMap { it.declarations }.forEach { it.accept(extraElementCollector) }
val progressIndicator = ProgressManager.getInstance().progressIndicator!! val progressIndicator = ProgressManager.getInstance().progressIndicator!!
progressIndicator.pushState() progressIndicator.pushState()
@@ -80,13 +80,12 @@ class KotlinAwareDelegatingMoveDestination(
try { try {
progressIndicator.text = "Looking for Usages" progressIndicator.text = "Looking for Usages"
for ((index, element) in extraElementsForReferenceSearch.withIndex()) { for ((index, element) in extraElementsForReferenceSearch.withIndex()) {
progressIndicator.fraction = (index + 1)/extraElementsForReferenceSearch.size.toDouble() progressIndicator.fraction = (index + 1) / extraElementsForReferenceSearch.size.toDouble()
ReferencesSearch.search(element, projectScope).mapNotNullTo(extraUsages) { ref -> ReferencesSearch.search(element, projectScope).mapNotNullTo(extraUsages) { ref ->
createMoveUsageInfoIfPossible(ref, element, true, false) createMoveUsageInfoIfPossible(ref, element, addImportToOriginalFile = true, isInternal = false)
} }
} }
} } finally {
finally {
progressIndicator.popState() progressIndicator.popState()
} }
@@ -81,8 +81,7 @@ interface Mover : (KtNamedDeclaration, KtElement) -> KtNamedDeclaration {
val container = originalElement.containingClassOrObject val container = originalElement.containingClassOrObject
if (container is KtObjectDeclaration && container.isCompanion() && container.declarations.singleOrNull() == originalElement) { if (container is KtObjectDeclaration && container.isCompanion() && container.declarations.singleOrNull() == originalElement) {
container.deleteSingle() container.deleteSingle()
} } else {
else {
originalElement.deleteSingle() originalElement.deleteSingle()
} }
} }
@@ -142,11 +141,12 @@ private object ElementHashingStrategy : TObjectHashingStrategy<PsiElement> {
} }
class MoveKotlinDeclarationsProcessor( class MoveKotlinDeclarationsProcessor(
val descriptor: MoveDeclarationsDescriptor, val descriptor: MoveDeclarationsDescriptor,
val mover: Mover = Mover.Default) : BaseRefactoringProcessor(descriptor.project) { val mover: Mover = Mover.Default
) : BaseRefactoringProcessor(descriptor.project) {
companion object { companion object {
private val REFACTORING_NAME = "Move declarations" private const val REFACTORING_NAME = "Move declarations"
val REFACTORING_ID = "move.kotlin.declarations" const val REFACTORING_ID = "move.kotlin.declarations"
} }
val project get() = descriptor.project val project get() = descriptor.project
@@ -155,8 +155,8 @@ class MoveKotlinDeclarationsProcessor(
private val moveEntireFile = descriptor.moveSource is MoveSource.File private val moveEntireFile = descriptor.moveSource is MoveSource.File
private val elementsToMove = descriptor.moveSource.elementsToMove.filter { e -> e.parent != descriptor.moveTarget.getTargetPsiIfExists(e) } private val elementsToMove = descriptor.moveSource.elementsToMove.filter { e -> e.parent != descriptor.moveTarget.getTargetPsiIfExists(e) }
private val kotlinToLightElementsBySourceFile = elementsToMove private val kotlinToLightElementsBySourceFile = elementsToMove
.groupBy { it.containingKtFile } .groupBy { it.containingKtFile }
.mapValues { it.value.keysToMap { it.toLightElements().ifEmpty { listOf(it) } } } .mapValues { it.value.keysToMap { it.toLightElements().ifEmpty { listOf(it) } } }
private val conflicts = MultiMap<PsiElement, String>() private val conflicts = MultiMap<PsiElement, String>()
override fun getRefactoringId() = REFACTORING_ID override fun getRefactoringId() = REFACTORING_ID
@@ -207,23 +207,23 @@ class MoveKotlinDeclarationsProcessor(
val foundReferences = HashSet<PsiReference>() val foundReferences = HashSet<PsiReference>()
val results = ReferencesSearch val results = ReferencesSearch
.search(lightElement, searchScope) .search(lightElement, searchScope)
.mapNotNullTo(ArrayList()) { ref -> .mapNotNullTo(ArrayList()) { ref ->
if (foundReferences.add(ref) && elementsToMove.none { it.isAncestor(ref.element)}) { if (foundReferences.add(ref) && elementsToMove.none { it.isAncestor(ref.element)}) {
createMoveUsageInfoIfPossible(ref, lightElement, true, false) createMoveUsageInfoIfPossible(ref, lightElement, addImportToOriginalFile = true, isInternal = false)
}
else null
} }
else null
}
val name = lightElement.getKotlinFqName()?.quoteIfNeeded()?.asString() val name = lightElement.getKotlinFqName()?.quoteIfNeeded()?.asString()
if (name != null) { if (name != null) {
TextOccurrencesUtil.findNonCodeUsages( TextOccurrencesUtil.findNonCodeUsages(
lightElement, lightElement,
name, name,
descriptor.searchInCommentsAndStrings, descriptor.searchInCommentsAndStrings,
descriptor.searchInNonCode, descriptor.searchInNonCode,
FqName(newFqName).quoteIfNeeded().asString(), FqName(newFqName).quoteIfNeeded().asString(),
results results
) )
} }
@@ -237,11 +237,11 @@ class MoveKotlinDeclarationsProcessor(
val usages = ArrayList<UsageInfo>() val usages = ArrayList<UsageInfo>()
val conflictChecker = MoveConflictChecker( val conflictChecker = MoveConflictChecker(
project, project,
elementsToMove, elementsToMove,
descriptor.moveTarget, descriptor.moveTarget,
elementsToMove.first(), elementsToMove.first(),
allElementsToMove = descriptor.allElementsToMove allElementsToMove = descriptor.allElementsToMove
) )
for ((sourceFile, kotlinToLightElements) in kotlinToLightElementsBySourceFile) { for ((sourceFile, kotlinToLightElements) in kotlinToLightElementsBySourceFile) {
val internalUsages = LinkedHashSet<UsageInfo>() val internalUsages = LinkedHashSet<UsageInfo>()
@@ -249,12 +249,11 @@ class MoveKotlinDeclarationsProcessor(
if (moveEntireFile) { if (moveEntireFile) {
val changeInfo = ContainerChangeInfo( val changeInfo = ContainerChangeInfo(
ContainerInfo.Package(sourceFile.packageFqName), ContainerInfo.Package(sourceFile.packageFqName),
descriptor.moveTarget.targetContainerFqName?.let { ContainerInfo.Package(it) } ?: ContainerInfo.UnknownPackage descriptor.moveTarget.targetContainerFqName?.let { ContainerInfo.Package(it) } ?: ContainerInfo.UnknownPackage
) )
internalUsages += sourceFile.getInternalReferencesToUpdateOnPackageNameChange(changeInfo) internalUsages += sourceFile.getInternalReferencesToUpdateOnPackageNameChange(changeInfo)
} } else {
else {
kotlinToLightElements.keys.forEach { kotlinToLightElements.keys.forEach {
val packageNameInfo = descriptor.delegate.getContainerChangeInfo(it, descriptor.moveTarget) val packageNameInfo = descriptor.delegate.getContainerChangeInfo(it, descriptor.moveTarget)
internalUsages += it.getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo) internalUsages += it.getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo)
@@ -284,7 +283,7 @@ class MoveKotlinDeclarationsProcessor(
internal fun doPerformRefactoring(usages: List<UsageInfo>) { internal fun doPerformRefactoring(usages: List<UsageInfo>) {
fun moveDeclaration(declaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): KtNamedDeclaration { fun moveDeclaration(declaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): KtNamedDeclaration {
val targetContainer = moveTarget.getOrCreateTargetPsi(declaration) val targetContainer = moveTarget.getOrCreateTargetPsi(declaration)
?: throw AssertionError("Couldn't create Kotlin file for: ${declaration::class.java}: ${declaration.text}") ?: throw AssertionError("Couldn't create Kotlin file for: ${declaration::class.java}: ${declaration.text}")
descriptor.delegate.preprocessDeclaration(descriptor, declaration) descriptor.delegate.preprocessDeclaration(descriptor, declaration)
if (moveEntireFile) return declaration if (moveEntireFile) return declaration
return mover(declaration, targetContainer).apply { return mover(declaration, targetContainer).apply {
@@ -341,12 +340,10 @@ class MoveKotlinDeclarationsProcessor(
usagesToProcess += newInternalUsages usagesToProcess += newInternalUsages
nonCodeUsages = postProcessMoveUsages(usagesToProcess, oldToNewElementsMapping).toTypedArray() nonCodeUsages = postProcessMoveUsages(usagesToProcess, oldToNewElementsMapping).toTypedArray()
} } catch (e: IncorrectOperationException) {
catch (e: IncorrectOperationException) {
nonCodeUsages = null nonCodeUsages = null
RefactoringUIUtil.processIncorrectOperation(myProject, e) RefactoringUIUtil.processIncorrectOperation(myProject, e)
} } finally {
finally {
cleanUpInternalUsages(newInternalUsages + oldInternalUsages) cleanUpInternalUsages(newInternalUsages + oldInternalUsages)
} }
} }
@@ -38,11 +38,11 @@ import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
fun invokeMoveFilesOrDirectoriesRefactoring( fun invokeMoveFilesOrDirectoriesRefactoring(
moveDialog: KotlinAwareMoveFilesOrDirectoriesDialog?, moveDialog: KotlinAwareMoveFilesOrDirectoriesDialog?,
project: Project, project: Project,
elements: Array<out PsiElement>, elements: Array<out PsiElement>,
initialTargetDirectory: PsiDirectory?, initialTargetDirectory: PsiDirectory?,
moveCallback: MoveCallback? moveCallback: MoveCallback?
) { ) {
fun closeDialog() { fun closeDialog() {
moveDialog?.close(DialogWrapper.CANCEL_EXIT_CODE) moveDialog?.close(DialogWrapper.CANCEL_EXIT_CODE)
@@ -55,19 +55,19 @@ fun invokeMoveFilesOrDirectoriesRefactoring(
try { try {
val choice = if (elements.size > 1 || elements[0] is PsiDirectory) intArrayOf(-1) else null val choice = if (elements.size > 1 || elements[0] is PsiDirectory) intArrayOf(-1) else null
val elementsToMove = elements val elementsToMove = elements
.filterNot { .filterNot {
it is PsiFile it is PsiFile
&& runWriteAction { CopyFilesOrDirectoriesHandler.checkFileExist(selectedDir, choice, it, it.name, "Move") } && runWriteAction { CopyFilesOrDirectoriesHandler.checkFileExist(selectedDir, choice, it, it.name, "Move") }
}
.sortedWith( // process Kotlin files first so that light classes are updated before changing references in Java files
java.util.Comparator { o1, o2 ->
when {
o1 is KtElement && o2 !is KtElement -> -1
o1 !is KtElement && o2 is KtElement -> 1
else -> 0
}
} }
.sortedWith( // process Kotlin files first so that light classes are updated before changing references in Java files )
java.util.Comparator { o1, o2 ->
when {
o1 is KtElement && o2 !is KtElement -> -1
o1 !is KtElement && o2 is KtElement -> 1
else -> 0
}
}
)
elementsToMove.forEach { elementsToMove.forEach {
MoveFilesOrDirectoriesUtil.checkMove(it, selectedDir) MoveFilesOrDirectoriesUtil.checkMove(it, selectedDir)
@@ -79,22 +79,20 @@ fun invokeMoveFilesOrDirectoriesRefactoring(
if (elementsToMove.isNotEmpty()) { if (elementsToMove.isNotEmpty()) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val processor = KotlinAwareMoveFilesOrDirectoriesProcessor( val processor = KotlinAwareMoveFilesOrDirectoriesProcessor(
project, project,
elementsToMove as List<KtFile>, elementsToMove as List<KtFile>,
selectedDir, selectedDir,
moveDialog?.searchReferences ?: true, searchReferences = moveDialog?.searchReferences ?: true,
false, searchInComments = false,
false, searchInNonJavaFiles = false,
moveCallback, moveCallback = moveCallback,
Runnable(::closeDialog) prepareSuccessfulCallback = Runnable(::closeDialog)
) )
processor.run() processor.run()
} } else {
else {
closeDialog() closeDialog()
} }
} } catch (e: IncorrectOperationException) {
catch (e: IncorrectOperationException) {
CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("error.title"), e.message, "refactoring.moveFile", project) CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("error.title"), e.message, "refactoring.moveFile", project)
} }
} }
@@ -102,12 +100,12 @@ fun invokeMoveFilesOrDirectoriesRefactoring(
// Mostly copied from MoveFilesOrDirectoriesUtil.doMove() // Mostly copied from MoveFilesOrDirectoriesUtil.doMove()
fun moveFilesOrDirectories( fun moveFilesOrDirectories(
project: Project, project: Project,
elements: Array<PsiElement>, elements: Array<PsiElement>,
targetElement: PsiElement?, targetElement: PsiElement?,
moveCallback: MoveCallback? = null moveCallback: MoveCallback? = null
) { ) {
elements.forEach { if (it !is PsiFile && it !is PsiDirectory) throw IllegalArgumentException("unexpected element type: " + it) } elements.forEach { if (it !is PsiFile && it !is PsiDirectory) throw IllegalArgumentException("unexpected element type: $it") }
val targetDirectory = MoveFilesOrDirectoriesUtil.resolveToDirectory(project, targetElement) val targetDirectory = MoveFilesOrDirectoriesUtil.resolveToDirectory(project, targetElement)
if (targetElement != null && targetDirectory == null) return if (targetElement != null && targetDirectory == null) return
@@ -185,7 +185,7 @@ fun KtElement.processInternalReferencesToUpdateOnPackageNameChange(
val declarationNotNull = declaration ?: return null val declarationNotNull = declaration ?: return null
if (isExtension || containerFqName != null || isImported) return { if (isExtension || containerFqName != null || isImported) return {
createMoveUsageInfoIfPossible(it.mainReference, declarationNotNull, false, true) createMoveUsageInfoIfPossible(it.mainReference, declarationNotNull, addImportToOriginalFile = false, isInternal = true)
} }
return null return null
@@ -33,19 +33,20 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
fun wrapOrSkip(s: String, inCode: Boolean) = if (inCode) "<code>$s</code>" else s fun wrapOrSkip(s: String, inCode: Boolean) = if (inCode) "<code>$s</code>" else s
fun formatClassDescriptor(classDescriptor: DeclarationDescriptor) = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.render(classDescriptor) fun formatClassDescriptor(classDescriptor: DeclarationDescriptor) =
IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.render(classDescriptor)
fun formatPsiClass( fun formatPsiClass(
psiClass: PsiClass, psiClass: PsiClass,
markAsJava: Boolean, markAsJava: Boolean,
inCode: Boolean inCode: Boolean
): String { ): String {
var description: String var description: String
val kind = if (psiClass.isInterface) "interface " else "class " val kind = if (psiClass.isInterface) "interface " else "class "
description = kind + PsiFormatUtil.formatClass( description = kind + PsiFormatUtil.formatClass(
psiClass, psiClass,
PsiFormatUtilBase.SHOW_CONTAINING_CLASS or PsiFormatUtilBase.SHOW_NAME or PsiFormatUtilBase.SHOW_PARAMETERS or PsiFormatUtilBase.SHOW_TYPE PsiFormatUtilBase.SHOW_CONTAINING_CLASS or PsiFormatUtilBase.SHOW_NAME or PsiFormatUtilBase.SHOW_PARAMETERS or PsiFormatUtilBase.SHOW_TYPE
) )
description = wrapOrSkip(description, inCode) description = wrapOrSkip(description, inCode)
@@ -56,8 +57,7 @@ fun formatClass(classDescriptor: DeclarationDescriptor, inCode: Boolean): String
val element = DescriptorToSourceUtils.descriptorToDeclaration(classDescriptor) val element = DescriptorToSourceUtils.descriptorToDeclaration(classDescriptor)
return if (element is PsiClass) { return if (element is PsiClass) {
formatPsiClass(element, false, inCode) formatPsiClass(element, false, inCode)
} } else {
else {
wrapOrSkip(formatClassDescriptor(classDescriptor), inCode) wrapOrSkip(formatClassDescriptor(classDescriptor), inCode)
} }
} }
@@ -66,8 +66,7 @@ fun formatFunction(functionDescriptor: DeclarationDescriptor, inCode: Boolean):
val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor) val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)
return if (element is PsiMethod) { return if (element is PsiMethod) {
formatPsiMethod(element, false, inCode) formatPsiMethod(element, false, inCode)
} } else {
else {
wrapOrSkip(formatFunctionDescriptor(functionDescriptor), inCode) wrapOrSkip(formatFunctionDescriptor(functionDescriptor), inCode)
} }
} }
@@ -75,9 +74,9 @@ fun formatFunction(functionDescriptor: DeclarationDescriptor, inCode: Boolean):
private fun formatFunctionDescriptor(functionDescriptor: DeclarationDescriptor) = DescriptorRenderer.COMPACT.render(functionDescriptor) private fun formatFunctionDescriptor(functionDescriptor: DeclarationDescriptor) = DescriptorRenderer.COMPACT.render(functionDescriptor)
fun formatPsiMethod( fun formatPsiMethod(
psiMethod: PsiMethod, psiMethod: PsiMethod,
showContainingClass: Boolean, showContainingClass: Boolean,
inCode: Boolean inCode: Boolean
): String { ): String {
var options = PsiFormatUtilBase.SHOW_NAME or PsiFormatUtilBase.SHOW_PARAMETERS or PsiFormatUtilBase.SHOW_TYPE var options = PsiFormatUtilBase.SHOW_NAME or PsiFormatUtilBase.SHOW_PARAMETERS or PsiFormatUtilBase.SHOW_TYPE
if (showContainingClass) { if (showContainingClass) {
@@ -95,9 +94,8 @@ fun formatJavaOrLightMethod(method: PsiMethod): String {
val originalDeclaration = method.unwrapped val originalDeclaration = method.unwrapped
return if (originalDeclaration is KtDeclaration) { return if (originalDeclaration is KtDeclaration) {
formatFunctionDescriptor(originalDeclaration.unsafeResolveToDescriptor()) formatFunctionDescriptor(originalDeclaration.unsafeResolveToDescriptor())
} } else {
else { formatPsiMethod(method, showContainingClass = false, inCode = false)
formatPsiMethod(method, false, false)
} }
} }
@@ -190,11 +190,11 @@ class AnnotationConverter(private val converter: Converter) {
if (returnType is PsiArrayType && value !is PsiArrayInitializerMemberValue) { if (returnType is PsiArrayType && value !is PsiArrayInitializerMemberValue) {
return converter.deferredElement { codeConverter -> return converter.deferredElement { codeConverter ->
converter.typeConverter.convertType(returnType) as ArrayType converter.typeConverter.convertType(returnType) as ArrayType
val convertAttributeValue = convertAttributeValue(value, returnType.componentType, false, false) val convertAttributeValue = convertAttributeValue(value, returnType.componentType, isVararg = false, isUnnamed = false)
createArrayLiteralExpression(codeConverter, convertAttributeValue.toList()) createArrayLiteralExpression(codeConverter, convertAttributeValue.toList())
} }
} }
return converter.deferredElement(convertAttributeValue(value, returnType, false, false).single()) return converter.deferredElement(convertAttributeValue(value, returnType, isVararg = false, isUnnamed = false).single())
} }
private fun convertAttributeValue(value: PsiAnnotationMemberValue?, expectedType: PsiType?, isVararg: Boolean, isUnnamed: Boolean): List<(CodeConverter) -> Expression> { private fun convertAttributeValue(value: PsiAnnotationMemberValue?, expectedType: PsiType?, isVararg: Boolean, isUnnamed: Boolean): List<(CodeConverter) -> Expression> {
@@ -82,7 +82,7 @@ class CodeConverter(
val explicitType = type.takeIf { settings.specifyLocalVariableTypeByDefault || converter.shouldDeclareVariableType(variable, type, isVal) } val explicitType = type.takeIf { settings.specifyLocalVariableTypeByDefault || converter.shouldDeclareVariableType(variable, type, isVal) }
return LocalVariable(variable.declarationIdentifier(), return LocalVariable(variable.declarationIdentifier(),
converter.convertAnnotations(variable), converter.convertAnnotations(variable),
converter.convertModifiers(variable, false, false), converter.convertModifiers(variable, isMethodInOpenClass = false, isInObject = false),
explicitType, explicitType,
convertExpression(variable.initializer, variable.type), convertExpression(variable.initializer, variable.type),
isVal).assignPrototype(variable) isVal).assignPrototype(variable)
+15 -9
View File
@@ -162,7 +162,7 @@ class Converter private constructor(
} }
val annotations = convertAnnotations(psiClass) val annotations = convertAnnotations(psiClass)
var modifiers = convertModifiers(psiClass, false, false) var modifiers = convertModifiers(psiClass, isMethodInOpenClass = false, isInObject = false)
val typeParameters = convertTypeParameterList(psiClass.typeParameterList) val typeParameters = convertTypeParameterList(psiClass.typeParameterList)
val extendsTypes = convertToNotNullableTypes(psiClass.extendsList) val extendsTypes = convertToNotNullableTypes(psiClass.extendsList)
val implementsTypes = convertToNotNullableTypes(psiClass.implementsList) val implementsTypes = convertToNotNullableTypes(psiClass.implementsList)
@@ -293,14 +293,20 @@ class Converter private constructor(
classBody = ClassBody(null, constructorSignature, classBody.baseClassParams, classBody.members, classBody = ClassBody(null, constructorSignature, classBody.baseClassParams, classBody.members,
classBody.companionObjectMembers, classBody.lBrace, classBody.rBrace, classBody.classKind) classBody.companionObjectMembers, classBody.lBrace, classBody.rBrace, classBody.classKind)
return Class(psiClass.declarationIdentifier(), return Class(
convertAnnotations(psiClass), psiClass.declarationIdentifier(),
convertModifiers(psiClass, false, false).with(Modifier.ANNOTATION).without(Modifier.ABSTRACT), convertAnnotations(psiClass),
TypeParameterList.Empty, convertModifiers(
listOf(), psiClass,
null, isMethodInOpenClass = false,
listOf(), isInObject = false
classBody).assignPrototype(psiClass) ).with(Modifier.ANNOTATION).without(Modifier.ABSTRACT),
TypeParameterList.Empty,
listOf(),
null,
listOf(),
classBody
).assignPrototype(psiClass)
} }
fun convertInitializer(initializer: PsiClassInitializer): Initializer { fun convertInitializer(initializer: PsiClassInitializer): Initializer {
@@ -31,17 +31,17 @@ import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.* import java.util.*
class PropertyInfo( class PropertyInfo(
val identifier: Identifier, val identifier: Identifier,
val isVar: Boolean, val isVar: Boolean,
val psiType: PsiType, val psiType: PsiType,
val field: PsiField?, val field: PsiField?,
val getMethod: PsiMethod?, val getMethod: PsiMethod?,
val setMethod: PsiMethod?, val setMethod: PsiMethod?,
val isGetMethodBodyFieldAccess: Boolean, val isGetMethodBodyFieldAccess: Boolean,
val isSetMethodBodyFieldAccess: Boolean, val isSetMethodBodyFieldAccess: Boolean,
val modifiers: Modifiers, val modifiers: Modifiers,
val specialSetterAccess: Modifier?, val specialSetterAccess: Modifier?,
val superInfo: SuperInfo? val superInfo: SuperInfo?
) { ) {
init { init {
assert(field != null || getMethod != null || setMethod != null) assert(field != null || getMethod != null || setMethod != null)
@@ -79,7 +79,8 @@ class PropertyInfo(
if (setMethod.body != null && !isSetMethodBodyFieldAccess) if (setMethod.body != null && !isSetMethodBodyFieldAccess)
return true return true
} }
return modifiers.contains(Modifier.EXTERNAL) || modifiers.contains(Modifier.OVERRIDE) && this.field == null && !modifiers.contains(Modifier.ABSTRACT) return modifiers.contains(Modifier.EXTERNAL) ||
modifiers.contains(Modifier.OVERRIDE) && this.field == null && !modifiers.contains(Modifier.ABSTRACT)
} }
companion object { companion object {
@@ -87,7 +88,16 @@ class PropertyInfo(
val isVar = field.isVar(converter.referenceSearcher) val isVar = field.isVar(converter.referenceSearcher)
val isInObject = field.containingClass?.let { converter.shouldConvertIntoObject(it) } == true val isInObject = field.containingClass?.let { converter.shouldConvertIntoObject(it) } == true
val modifiers = converter.convertModifiers(field, false, isInObject) val modifiers = converter.convertModifiers(field, false, isInObject)
return PropertyInfo(field.declarationIdentifier(), isVar, field.type, field, null, null, false, false, modifiers, null, null) return PropertyInfo(
field.declarationIdentifier(), isVar, field.type, field,
getMethod = null,
setMethod = null,
isGetMethodBodyFieldAccess = false,
isSetMethodBodyFieldAccess = false,
modifiers = modifiers,
specialSetterAccess = null,
superInfo = null
)
} }
} }
} }
@@ -108,10 +118,10 @@ class PropertyDetectionCache(private val converter: Converter) {
sealed class SuperInfo { sealed class SuperInfo {
class Property( class Property(
val isVar: Boolean, val isVar: Boolean,
val name: String, val name: String,
val hasAbstractModifier: Boolean val hasAbstractModifier: Boolean
//TODO: add visibility //TODO: add visibility
) : SuperInfo() ) : SuperInfo()
object Function : SuperInfo() object Function : SuperInfo()
@@ -122,8 +132,8 @@ sealed class SuperInfo {
} }
private class PropertyDetector( private class PropertyDetector(
private val psiClass: PsiClass, private val psiClass: PsiClass,
private val converter: Converter private val converter: Converter
) { ) {
private val isOpenClass = converter.needOpenModifier(psiClass) private val isOpenClass = converter.needOpenModifier(psiClass)
@@ -137,8 +147,8 @@ private class PropertyDetector(
dropPropertiesConflictingWithFields(memberToPropertyInfo) dropPropertiesConflictingWithFields(memberToPropertyInfo)
val mappedFields = memberToPropertyInfo.values val mappedFields = memberToPropertyInfo.values
.mapNotNull { it.field } .mapNotNull { it.field }
.toSet() .toSet()
// map all other fields // map all other fields
for (field in psiClass.fields) { for (field in psiClass.fields) {
@@ -192,13 +202,18 @@ private class PropertyDetector(
if (getterInfo != null && getterInfo.field == null) { if (getterInfo != null && getterInfo.field == null) {
if (!field.hasModifierProperty(PsiModifier.PRIVATE) if (!field.hasModifierProperty(PsiModifier.PRIVATE)
|| converter.referenceSearcher.findVariableUsages(field, psiClass).any { PsiUtil.isAccessedForReading(it) && !it.canBeReplacedWithFieldAccess() }) { || converter.referenceSearcher.findVariableUsages(field, psiClass).any {
PsiUtil.isAccessedForReading(it) && !it.canBeReplacedWithFieldAccess()
}
) {
field = null field = null
} }
} } else if (setterInfo != null && setterInfo.field == null) {
else if (setterInfo != null && setterInfo.field == null) {
if (!field.hasModifierProperty(PsiModifier.PRIVATE) if (!field.hasModifierProperty(PsiModifier.PRIVATE)
|| converter.referenceSearcher.findVariableUsages(field, psiClass).any { PsiUtil.isAccessedForWriting(it) && !it.canBeReplacedWithFieldAccess() }) { || converter.referenceSearcher.findVariableUsages(field, psiClass).any {
PsiUtil.isAccessedForWriting(it) && !it.canBeReplacedWithFieldAccess()
}
) {
field = null field = null
} }
} }
@@ -222,24 +237,26 @@ private class PropertyDetector(
val propertyAccess = modifiers.accessModifier() val propertyAccess = modifiers.accessModifier()
val setterAccess = if (setterInfo != null) val setterAccess = if (setterInfo != null)
converter.convertModifiers(setterInfo.method, false, false).accessModifier() converter.convertModifiers(setterInfo.method, isMethodInOpenClass = false, isInObject = false).accessModifier()
else if (field != null && field.isVar(converter.referenceSearcher)) else if (field != null && field.isVar(converter.referenceSearcher))
converter.convertModifiers(field, false, false).accessModifier() converter.convertModifiers(field, isMethodInOpenClass = false, isInObject = false).accessModifier()
else else
propertyAccess propertyAccess
val specialSetterAccess = setterAccess?.takeIf { it != propertyAccess } val specialSetterAccess = setterAccess?.takeIf { it != propertyAccess }
val propertyInfo = PropertyInfo(Identifier.withNoPrototype(propertyName), val propertyInfo = PropertyInfo(
isVar, Identifier.withNoPrototype(propertyName),
type, isVar,
field, type,
getterInfo?.method, field,
setterInfo?.method, getterInfo?.method,
field != null && getterInfo?.field == field, setterInfo?.method,
field != null && setterInfo?.field == field, field != null && getterInfo?.field == field,
modifiers, field != null && setterInfo?.field == field,
specialSetterAccess, modifiers,
superProperty) specialSetterAccess,
superProperty
)
propertyInfos.add(propertyInfo) propertyInfos.add(propertyInfo)
} }
return propertyInfos return propertyInfos
@@ -252,8 +269,7 @@ private class PropertyDetector(
if (field != null) { if (field != null) {
if (memberToPropertyInfo.containsKey(field)) { // field already in use by other property if (memberToPropertyInfo.containsKey(field)) { // field already in use by other property
continue continue
} } else {
else {
memberToPropertyInfo[field] = propertyInfo memberToPropertyInfo[field] = propertyInfo
} }
} }
@@ -265,8 +281,8 @@ private class PropertyDetector(
} }
private fun detectGetters( private fun detectGetters(
methodsToCheck: List<Pair<PsiMethod, SuperInfo.Property?>>, methodsToCheck: List<Pair<PsiMethod, SuperInfo.Property?>>,
propertyNamesWithConflict: MutableSet<String> propertyNamesWithConflict: MutableSet<String>
): Map<String, AccessorInfo> { ): Map<String, AccessorInfo> {
val propertyNameToGetterInfo = LinkedHashMap<String, AccessorInfo>() val propertyNameToGetterInfo = LinkedHashMap<String, AccessorInfo>()
for ((method, superInfo) in methodsToCheck) { for ((method, superInfo) in methodsToCheck) {
@@ -284,9 +300,9 @@ private class PropertyDetector(
} }
private fun detectSetters( private fun detectSetters(
methodsToCheck: List<Pair<PsiMethod, SuperInfo.Property?>>, methodsToCheck: List<Pair<PsiMethod, SuperInfo.Property?>>,
propertyNamesFromGetters: Set<String>, propertyNamesFromGetters: Set<String>,
propertyNamesWithConflict: MutableSet<String> propertyNamesWithConflict: MutableSet<String>
): Map<String, AccessorInfo> { ): Map<String, AccessorInfo> {
val propertyNameToSetterInfo = LinkedHashMap<String, AccessorInfo>() val propertyNameToSetterInfo = LinkedHashMap<String, AccessorInfo>()
for ((method, superInfo) in methodsToCheck) { for ((method, superInfo) in methodsToCheck) {
@@ -310,9 +326,9 @@ private class PropertyDetector(
//TODO: bases //TODO: bases
val prohibitedSignatures = psiClass.methods val prohibitedSignatures = psiClass.methods
.filter { it !in mappedMethods } .filter { it !in mappedMethods }
.map { it.getSignature(PsiSubstitutor.EMPTY) } .map { it.getSignature(PsiSubstitutor.EMPTY) }
.toSet() .toSet()
for (propertyInfo in propertyInfos) { for (propertyInfo in propertyInfos) {
if (propertyInfo.modifiers.contains(Modifier.OVERRIDE)) continue // cannot drop override if (propertyInfo.modifiers.contains(Modifier.OVERRIDE)) continue // cannot drop override
@@ -327,7 +343,9 @@ private class PropertyDetector(
if (propertyInfo.isVar) { if (propertyInfo.isVar) {
val setterName = JvmAbi.setterName(propertyInfo.name) val setterName = JvmAbi.setterName(propertyInfo.name)
val setterSignature = MethodSignatureUtil.createMethodSignature(setterName, arrayOf(propertyInfo.psiType), emptyArray(), PsiSubstitutor.EMPTY) val setterSignature = MethodSignatureUtil.createMethodSignature(
setterName, arrayOf(propertyInfo.psiType), emptyArray(), PsiSubstitutor.EMPTY
)
if (setterSignature in prohibitedSignatures) { if (setterSignature in prohibitedSignatures) {
memberToPropertyInfo.dropProperty(propertyInfo) memberToPropertyInfo.dropProperty(propertyInfo)
continue continue
@@ -367,7 +385,9 @@ private class PropertyDetector(
} }
private fun convertModifiers(field: PsiField?, getMethod: PsiMethod?, setMethod: PsiMethod?, isOverride: Boolean): Modifiers { private fun convertModifiers(field: PsiField?, getMethod: PsiMethod?, setMethod: PsiMethod?, isOverride: Boolean): Modifiers {
val fieldModifiers = field?.let { converter.convertModifiers(it, false, false) } ?: Modifiers.Empty val fieldModifiers = field?.let {
converter.convertModifiers(it, isMethodInOpenClass = false, isInObject = false)
} ?: Modifiers.Empty
val getterModifiers = getMethod?.let { converter.convertModifiers(it, isOpenClass, false) } ?: Modifiers.Empty val getterModifiers = getMethod?.let { converter.convertModifiers(it, isOpenClass, false) } ?: Modifiers.Empty
val setterModifiers = setMethod?.let { converter.convertModifiers(it, isOpenClass, false) } ?: Modifiers.Empty val setterModifiers = setMethod?.let { converter.convertModifiers(it, isOpenClass, false) } ?: Modifiers.Empty
@@ -395,16 +415,16 @@ private class PropertyDetector(
} }
val prototypes = listOfNotNull<PsiElement>(field, getMethod, setMethod) val prototypes = listOfNotNull<PsiElement>(field, getMethod, setMethod)
.map { PrototypeInfo(it, CommentsAndSpacesInheritance.NO_SPACES) } .map { PrototypeInfo(it, CommentsAndSpacesInheritance.NO_SPACES) }
return Modifiers(modifiers).assignPrototypes(*prototypes.toTypedArray()) return Modifiers(modifiers).assignPrototypes(*prototypes.toTypedArray())
} }
private class AccessorInfo( private class AccessorInfo(
val method: PsiMethod, val method: PsiMethod,
val field: PsiField?, val field: PsiField?,
val kind: AccessorKind, val kind: AccessorKind,
val propertyName: String, val propertyName: String,
val superProperty: SuperInfo.Property? val superProperty: SuperInfo.Property?
) )
private fun getGetterInfo(method: PsiMethod, superProperty: SuperInfo.Property?): AccessorInfo? { private fun getGetterInfo(method: PsiMethod, superProperty: SuperInfo.Property?): AccessorInfo? {
@@ -432,8 +452,11 @@ private class PropertyDetector(
return when { return when {
converter.inConversionScope(containingClass) -> { converter.inConversionScope(containingClass) -> {
val propertyInfo = converter.propertyDetectionCache[containingClass][superMethod] val propertyInfo = converter.propertyDetectionCache[containingClass][superMethod]
if (propertyInfo != null) SuperInfo.Property(propertyInfo.isVar, propertyInfo.name, propertyInfo.modifiers.contains(Modifier.ABSTRACT)) if (propertyInfo != null) {
else SuperInfo.Function SuperInfo.Property(propertyInfo.isVar, propertyInfo.name, propertyInfo.modifiers.contains(Modifier.ABSTRACT))
} else {
SuperInfo.Function
}
} }
superMethod is KtLightMethod -> { superMethod is KtLightMethod -> {
val origin = superMethod.kotlinOrigin val origin = superMethod.kotlinOrigin
@@ -510,8 +533,7 @@ private class PropertyDetector(
val refExpr = expression as? PsiReferenceExpression ?: return null val refExpr = expression as? PsiReferenceExpression ?: return null
if (static) { if (static) {
if (!refExpr.isQualifierEmptyOrClass(psiClass)) return null if (!refExpr.isQualifierEmptyOrClass(psiClass)) return null
} } else {
else {
if (!refExpr.isQualifierEmptyOrThis()) return null if (!refExpr.isQualifierEmptyOrThis()) return null
} }
val field = refExpr.resolve() as? PsiField ?: return null val field = refExpr.resolve() as? PsiField ?: return null
@@ -21,8 +21,7 @@ import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
//copied from old j2k //copied from old j2k
fun canKeepEqEq(left: PsiExpression, right: PsiExpression?): Boolean { fun canKeepEqEq(left: PsiExpression, right: PsiExpression?): Boolean {
if (left.isNullLiteral() || (right?.isNullLiteral() == true)) return true if (left.isNullLiteral() || (right?.isNullLiteral() == true)) return true
val type = left.type when (val type = left.type) {
when (type) {
is PsiPrimitiveType, is PsiArrayType -> return true is PsiPrimitiveType, is PsiArrayType -> return true
is PsiClassType -> { is PsiClassType -> {
@@ -84,7 +83,7 @@ fun PsiMember.modality(assignNonCodeElements: ((JKNonCodeElementsListOwner, PsiE
private fun PsiMember.handleProtectedVisibility(referenceSearcher: ReferenceSearcher): Visibility { private fun PsiMember.handleProtectedVisibility(referenceSearcher: ReferenceSearcher): Visibility {
val originalClass = containingClass ?: return Visibility.PROTECTED val originalClass = containingClass ?: return Visibility.PROTECTED
// Search for usages only in Java because java-protected member cannot be used in Kotlin from same package // Search for usages only in Java because java-protected member cannot be used in Kotlin from same package
val usages = referenceSearcher.findUsagesForExternalCodeProcessing(this, true, false) val usages = referenceSearcher.findUsagesForExternalCodeProcessing(this, searchJava = true, searchKotlin = false)
return if (usages.any { !allowProtected(it.element, this, originalClass) }) return if (usages.any { !allowProtected(it.element, this, originalClass) })
Visibility.PUBLIC Visibility.PUBLIC