Minor: refactoring replaceWith package
This commit is contained in:
@@ -41,7 +41,7 @@ class DeprecatedSymbolUsageFix(
|
|||||||
|
|
||||||
override fun invoke(replacementStrategy: UsageReplacementStrategy, project: Project, editor: Editor?) {
|
override fun invoke(replacementStrategy: UsageReplacementStrategy, project: Project, editor: Editor?) {
|
||||||
val element = element ?: return
|
val element = element ?: return
|
||||||
val result = replacementStrategy.createReplacer(element)!!.invoke()
|
val result = replacementStrategy.createReplacer(element)?.invoke()
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
val offset = (result.getCalleeExpressionIfAny() ?: result).textOffset
|
val offset = (result.getCalleeExpressionIfAny() ?: result).textOffset
|
||||||
editor?.moveCaret(offset)
|
editor?.moveCaret(offset)
|
||||||
@@ -50,7 +50,7 @@ class DeprecatedSymbolUsageFix(
|
|||||||
|
|
||||||
companion object : KotlinSingleIntentionActionFactory() {
|
companion object : KotlinSingleIntentionActionFactory() {
|
||||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val (nameExpression, replacement) = DeprecatedSymbolUsageFixBase.extractDataFromDiagnostic(diagnostic) ?: return null
|
val (nameExpression, replacement) = extractDataFromDiagnostic(diagnostic) ?: return null
|
||||||
return DeprecatedSymbolUsageFix(nameExpression, replacement)
|
return DeprecatedSymbolUsageFix(nameExpression, replacement)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ class DeprecatedSymbolUsageFix(
|
|||||||
if (targetDescriptors.isEmpty()) return false
|
if (targetDescriptors.isEmpty()) return false
|
||||||
|
|
||||||
return targetDescriptors.all {
|
return targetDescriptors.all {
|
||||||
DeprecatedSymbolUsageFixBase.fetchReplaceWithPattern(it, import.project) != null
|
fetchReplaceWithPattern(it, import.project) != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -120,7 +120,7 @@ abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
else -> throw IllegalStateException("Bad QuickFixRegistrar configuration")
|
else -> throw IllegalStateException("Bad QuickFixRegistrar configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
val replacement = DeprecatedSymbolUsageFixBase.fetchReplaceWithPattern(descriptor, nameExpression.project) ?: return null
|
val replacement = fetchReplaceWithPattern(descriptor, nameExpression.project) ?: return null
|
||||||
return Data(nameExpression, replacement, descriptor)
|
return Data(nameExpression, replacement, descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,10 +135,10 @@ abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
val bindingContext = resolutionFacade.analyze(element, BodyResolveMode.PARTIAL)
|
val bindingContext = resolutionFacade.analyze(element, BodyResolveMode.PARTIAL)
|
||||||
var target = element.mainReference.resolveToDescriptors(bindingContext).singleOrNull() ?: return null
|
var target = element.mainReference.resolveToDescriptors(bindingContext).singleOrNull() ?: return null
|
||||||
|
|
||||||
var replacePatternFromSymbol = DeprecatedSymbolUsageFixBase.fetchReplaceWithPattern(target, resolutionFacade.project)
|
var replacePatternFromSymbol = fetchReplaceWithPattern(target, resolutionFacade.project)
|
||||||
if (replacePatternFromSymbol == null && target is ConstructorDescriptor) {
|
if (replacePatternFromSymbol == null && target is ConstructorDescriptor) {
|
||||||
target = target.containingDeclaration
|
target = target.containingDeclaration
|
||||||
replacePatternFromSymbol = DeprecatedSymbolUsageFixBase.fetchReplaceWithPattern(target, resolutionFacade.project)
|
replacePatternFromSymbol = fetchReplaceWithPattern(target, resolutionFacade.project)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that ReplaceWith hasn't changed
|
// check that ReplaceWith hasn't changed
|
||||||
@@ -207,7 +207,7 @@ abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
project: Project, classifier: ClassifierDescriptorWithTypeParameters, typeAlias: PsiElement
|
project: Project, classifier: ClassifierDescriptorWithTypeParameters, typeAlias: PsiElement
|
||||||
): ConstructorDescriptor? {
|
): ConstructorDescriptor? {
|
||||||
val specialReplaceWithForConstructor = classifier.constructors.filter {
|
val specialReplaceWithForConstructor = classifier.constructors.filter {
|
||||||
DeprecatedSymbolUsageFixBase.fetchReplaceWithPattern(it, project) != null
|
fetchReplaceWithPattern(it, project) != null
|
||||||
}.toSet()
|
}.toSet()
|
||||||
|
|
||||||
if (specialReplaceWithForConstructor.isEmpty()) {
|
if (specialReplaceWithForConstructor.isEmpty()) {
|
||||||
|
|||||||
+1
-2
@@ -77,8 +77,7 @@ class DeprecatedSymbolUsageInWholeProjectFix(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val (nameExpression, replacement, descriptor) =
|
val (nameExpression, replacement, descriptor) = extractDataFromDiagnostic(diagnostic) ?: return null
|
||||||
DeprecatedSymbolUsageFixBase.extractDataFromDiagnostic(diagnostic) ?: return null
|
|
||||||
val descriptorName = RENDERER.render(descriptor)
|
val descriptorName = RENDERER.render(descriptor)
|
||||||
return DeprecatedSymbolUsageInWholeProjectFix(
|
return DeprecatedSymbolUsageInWholeProjectFix(
|
||||||
nameExpression,
|
nameExpression,
|
||||||
|
|||||||
+29
-31
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.diagnostics.Errors
|
|||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||||
import org.jetbrains.kotlin.idea.quickfix.replaceWith.ReplaceProtectedToPublishedApiCallFix.Companion.newName
|
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -40,42 +39,42 @@ import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
|||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
|
||||||
class ReplaceProtectedToPublishedApiCallFix(
|
class ReplaceProtectedToPublishedApiCallFix(
|
||||||
element: KtExpression,
|
element: KtExpression,
|
||||||
val classOwnerPointer: SmartPsiElementPointer<KtClass>,
|
val classOwnerPointer: SmartPsiElementPointer<KtClass>,
|
||||||
val originalName: String,
|
val originalName: String,
|
||||||
val paramNames: Map<String, String>,
|
val paramNames: Map<String, String>,
|
||||||
val newSignature: String,
|
val newSignature: String,
|
||||||
val isProperty: Boolean,
|
val isProperty: Boolean,
|
||||||
val isVar: Boolean,
|
val isVar: Boolean,
|
||||||
val isPublishedMemberAlreadyExists: Boolean
|
val isPublishedMemberAlreadyExists: Boolean
|
||||||
) : KotlinQuickFixAction<KtExpression>(element) {
|
) : KotlinQuickFixAction<KtExpression>(element) {
|
||||||
|
|
||||||
override fun getFamilyName() = "Replace with @PublishedApi bridge call"
|
override fun getFamilyName() = "Replace with @PublishedApi bridge call"
|
||||||
|
|
||||||
override fun getText() = "Replace with generated @PublishedApi bridge call '${originalName.newNameQuoted}${if (!isProperty) "(...)" else ""}'"
|
override fun getText() =
|
||||||
|
"Replace with generated @PublishedApi bridge call '${originalName.newNameQuoted}${if (!isProperty) "(...)" else ""}'"
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
val element = element ?: return
|
val element = element ?: return
|
||||||
if (!isPublishedMemberAlreadyExists) {
|
if (!isPublishedMemberAlreadyExists) {
|
||||||
val classOwner = classOwnerPointer.element ?: return
|
val classOwner = classOwnerPointer.element ?: return
|
||||||
val newMember: KtDeclaration =
|
val newMember: KtDeclaration =
|
||||||
if (isProperty) {
|
if (isProperty) {
|
||||||
KtPsiFactory(classOwner).createProperty(
|
KtPsiFactory(classOwner).createProperty(
|
||||||
"@kotlin.PublishedApi\n" +
|
"@kotlin.PublishedApi\n" +
|
||||||
"internal " + newSignature +
|
"internal " + newSignature +
|
||||||
"\n" +
|
"\n" +
|
||||||
"get() = $originalName\n" +
|
"get() = $originalName\n" +
|
||||||
if (isVar) "set(value) { $originalName = value }" else ""
|
if (isVar) "set(value) { $originalName = value }" else ""
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
KtPsiFactory(classOwner).createFunction(
|
||||||
KtPsiFactory(classOwner).createFunction(
|
"@kotlin.PublishedApi\n" +
|
||||||
"@kotlin.PublishedApi\n" +
|
|
||||||
"internal " + newSignature +
|
"internal " + newSignature +
|
||||||
" = $originalName(${paramNames.keys.joinToString(", ") { it }})"
|
" = $originalName(${paramNames.keys.joinToString(", ") { it }})"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortenReferences.DEFAULT.process(classOwner.addDeclaration(newMember))
|
ShortenReferences.DEFAULT.process(classOwner.addDeclaration(newMember))
|
||||||
}
|
}
|
||||||
@@ -100,13 +99,12 @@ class ReplaceProtectedToPublishedApiCallFix(
|
|||||||
val signature = signatureRenderer.render(descriptor)
|
val signature = signatureRenderer.render(descriptor)
|
||||||
val originalName = descriptor.name.asString()
|
val originalName = descriptor.name.asString()
|
||||||
val newSignature =
|
val newSignature =
|
||||||
if (isProperty) {
|
if (isProperty) {
|
||||||
signature.replaceFirst("$originalName:", "${originalName.newNameQuoted}:")
|
signature.replaceFirst("$originalName:", "${originalName.newNameQuoted}:")
|
||||||
}
|
} else {
|
||||||
else {
|
signature.replaceFirst("$originalName(", "${originalName.newNameQuoted}(")
|
||||||
signature.replaceFirst("$originalName(", "${originalName.newNameQuoted}(")
|
}
|
||||||
}
|
val paramNameAndType = descriptor.valueParameters.associate { it.name.asString() to it.type.getJetTypeFqName(false) }
|
||||||
val paramNameAndType = descriptor.valueParameters.associate { it.name.asString() to it.type.getJetTypeFqName(false)}
|
|
||||||
val classDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return null
|
val classDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return null
|
||||||
val source = classDescriptor.source.getPsi() as? KtClass ?: return null
|
val source = classDescriptor.source.getPsi() as? KtClass ?: return null
|
||||||
|
|
||||||
@@ -119,8 +117,8 @@ class ReplaceProtectedToPublishedApiCallFix(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ReplaceProtectedToPublishedApiCallFix(
|
return ReplaceProtectedToPublishedApiCallFix(
|
||||||
psiElement, source.createSmartPointer(), originalName, paramNameAndType, newSignature,
|
psiElement, source.createSmartPointer(), originalName, paramNameAndType, newSignature,
|
||||||
isProperty, isVar, isPublishedMemberAlreadyExists
|
isProperty, isVar, isPublishedMemberAlreadyExists
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +126,6 @@ class ReplaceProtectedToPublishedApiCallFix(
|
|||||||
get() = "access\$$this"
|
get() = "access\$$this"
|
||||||
|
|
||||||
val String.newNameQuoted: String
|
val String.newNameQuoted: String
|
||||||
get() = "`$newName`"
|
get() = "`$newName`"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-17
@@ -72,14 +72,7 @@ object ReplaceWithAnnotationAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val module = resolutionFacade.moduleDescriptor
|
val module = resolutionFacade.moduleDescriptor
|
||||||
val explicitImportsScope = buildExplicitImportsScope(annotation, resolutionFacade, module)
|
val scope = buildScope(resolutionFacade, annotation, symbolDescriptor) ?: return null
|
||||||
val languageVersionSettings = resolutionFacade.frontendService<LanguageVersionSettings>()
|
|
||||||
val defaultImportsScopes = buildDefaultImportsScopes(resolutionFacade, module, languageVersionSettings)
|
|
||||||
|
|
||||||
val scope = getResolutionScope(
|
|
||||||
symbolDescriptor, symbolDescriptor,
|
|
||||||
listOf(explicitImportsScope), defaultImportsScopes, languageVersionSettings
|
|
||||||
) ?: return null
|
|
||||||
|
|
||||||
val expressionTypingServices = resolutionFacade.getFrontendService(module, ExpressionTypingServices::class.java)
|
val expressionTypingServices = resolutionFacade.getFrontendService(module, ExpressionTypingServices::class.java)
|
||||||
|
|
||||||
@@ -102,14 +95,7 @@ object ReplaceWithAnnotationAnalyzer {
|
|||||||
}
|
}
|
||||||
if (typeReference.typeElement !is KtUserType) return null
|
if (typeReference.typeElement !is KtUserType) return null
|
||||||
|
|
||||||
val module = resolutionFacade.moduleDescriptor
|
val scope = buildScope(resolutionFacade, annotation, symbolDescriptor) ?: return null
|
||||||
|
|
||||||
val explicitImportsScope = buildExplicitImportsScope(annotation, resolutionFacade, module)
|
|
||||||
val languageVersionSettings = resolutionFacade.frontendService<LanguageVersionSettings>()
|
|
||||||
val defaultImportScopes = buildDefaultImportsScopes(resolutionFacade, module, languageVersionSettings)
|
|
||||||
val scope = getResolutionScope(
|
|
||||||
symbolDescriptor, symbolDescriptor, listOf(explicitImportsScope), defaultImportScopes, languageVersionSettings
|
|
||||||
) ?: return null
|
|
||||||
|
|
||||||
val typeResolver = resolutionFacade.getFrontendService(TypeResolver::class.java)
|
val typeResolver = resolutionFacade.getFrontendService(TypeResolver::class.java)
|
||||||
val bindingTrace = BindingTraceContext()
|
val bindingTrace = BindingTraceContext()
|
||||||
@@ -121,7 +107,7 @@ object ReplaceWithAnnotationAnalyzer {
|
|||||||
val parentType = expression.parent as? KtUserType ?: return@forEachDescendantOfType
|
val parentType = expression.parent as? KtUserType ?: return@forEachDescendantOfType
|
||||||
if (parentType.qualifier != null) return@forEachDescendantOfType
|
if (parentType.qualifier != null) return@forEachDescendantOfType
|
||||||
val targetClass = bindingTrace.bindingContext[BindingContext.REFERENCE_TARGET, expression] as? ClassDescriptor
|
val targetClass = bindingTrace.bindingContext[BindingContext.REFERENCE_TARGET, expression] as? ClassDescriptor
|
||||||
?: return@forEachDescendantOfType
|
?: return@forEachDescendantOfType
|
||||||
val fqName = targetClass.fqNameUnsafe
|
val fqName = targetClass.fqNameUnsafe
|
||||||
if (fqName.isSafe) {
|
if (fqName.isSafe) {
|
||||||
typesToQualify.add(expression to fqName.toSafe())
|
typesToQualify.add(expression to fqName.toSafe())
|
||||||
@@ -135,6 +121,21 @@ object ReplaceWithAnnotationAnalyzer {
|
|||||||
return typeReference.typeElement as KtUserType
|
return typeReference.typeElement as KtUserType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun buildScope(
|
||||||
|
resolutionFacade: ResolutionFacade,
|
||||||
|
annotation: ReplaceWith,
|
||||||
|
symbolDescriptor: DeclarationDescriptor
|
||||||
|
): LexicalScope? {
|
||||||
|
val module = resolutionFacade.moduleDescriptor
|
||||||
|
val explicitImportsScope = buildExplicitImportsScope(annotation, resolutionFacade, module)
|
||||||
|
val languageVersionSettings = resolutionFacade.frontendService<LanguageVersionSettings>()
|
||||||
|
val defaultImportsScopes = buildDefaultImportsScopes(resolutionFacade, module, languageVersionSettings)
|
||||||
|
|
||||||
|
return getResolutionScope(
|
||||||
|
symbolDescriptor, symbolDescriptor, listOf(explicitImportsScope), defaultImportsScopes, languageVersionSettings
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildDefaultImportsScopes(
|
private fun buildDefaultImportsScopes(
|
||||||
resolutionFacade: ResolutionFacade,
|
resolutionFacade: ResolutionFacade,
|
||||||
module: ModuleDescriptor,
|
module: ModuleDescriptor,
|
||||||
|
|||||||
Reference in New Issue
Block a user