Minor: refactoring replaceWith package

This commit is contained in:
Dmitry Gridin
2019-03-27 16:23:31 +07:00
parent c343876f7c
commit b0f7ddd693
5 changed files with 55 additions and 57 deletions
@@ -41,7 +41,7 @@ class DeprecatedSymbolUsageFix(
override fun invoke(replacementStrategy: UsageReplacementStrategy, project: Project, editor: Editor?) {
val element = element ?: return
val result = replacementStrategy.createReplacer(element)!!.invoke()
val result = replacementStrategy.createReplacer(element)?.invoke()
if (result != null) {
val offset = (result.getCalleeExpressionIfAny() ?: result).textOffset
editor?.moveCaret(offset)
@@ -50,7 +50,7 @@ class DeprecatedSymbolUsageFix(
companion object : KotlinSingleIntentionActionFactory() {
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)
}
@@ -61,7 +61,7 @@ class DeprecatedSymbolUsageFix(
if (targetDescriptors.isEmpty()) return false
return targetDescriptors.all {
DeprecatedSymbolUsageFixBase.fetchReplaceWithPattern(it, import.project) != null
fetchReplaceWithPattern(it, import.project) != null
}
}
}
@@ -120,7 +120,7 @@ abstract class DeprecatedSymbolUsageFixBase(
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)
}
@@ -135,10 +135,10 @@ abstract class DeprecatedSymbolUsageFixBase(
val bindingContext = resolutionFacade.analyze(element, BodyResolveMode.PARTIAL)
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) {
target = target.containingDeclaration
replacePatternFromSymbol = DeprecatedSymbolUsageFixBase.fetchReplaceWithPattern(target, resolutionFacade.project)
replacePatternFromSymbol = fetchReplaceWithPattern(target, resolutionFacade.project)
}
// check that ReplaceWith hasn't changed
@@ -207,7 +207,7 @@ abstract class DeprecatedSymbolUsageFixBase(
project: Project, classifier: ClassifierDescriptorWithTypeParameters, typeAlias: PsiElement
): ConstructorDescriptor? {
val specialReplaceWithForConstructor = classifier.constructors.filter {
DeprecatedSymbolUsageFixBase.fetchReplaceWithPattern(it, project) != null
fetchReplaceWithPattern(it, project) != null
}.toSet()
if (specialReplaceWithForConstructor.isEmpty()) {
@@ -77,8 +77,7 @@ class DeprecatedSymbolUsageInWholeProjectFix(
}
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val (nameExpression, replacement, descriptor) =
DeprecatedSymbolUsageFixBase.extractDataFromDiagnostic(diagnostic) ?: return null
val (nameExpression, replacement, descriptor) = extractDataFromDiagnostic(diagnostic) ?: return null
val descriptorName = RENDERER.render(descriptor)
return DeprecatedSymbolUsageInWholeProjectFix(
nameExpression,
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.core.ShortenReferences
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
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.js.descriptorUtils.getJetTypeFqName
import org.jetbrains.kotlin.name.Name
@@ -40,42 +39,42 @@ import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.resolve.source.getPsi
class ReplaceProtectedToPublishedApiCallFix(
element: KtExpression,
val classOwnerPointer: SmartPsiElementPointer<KtClass>,
val originalName: String,
val paramNames: Map<String, String>,
val newSignature: String,
val isProperty: Boolean,
val isVar: Boolean,
val isPublishedMemberAlreadyExists: Boolean
) : KotlinQuickFixAction<KtExpression>(element) {
element: KtExpression,
val classOwnerPointer: SmartPsiElementPointer<KtClass>,
val originalName: String,
val paramNames: Map<String, String>,
val newSignature: String,
val isProperty: Boolean,
val isVar: Boolean,
val isPublishedMemberAlreadyExists: Boolean
) : KotlinQuickFixAction<KtExpression>(element) {
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) {
val element = element ?: return
if (!isPublishedMemberAlreadyExists) {
val classOwner = classOwnerPointer.element ?: return
val newMember: KtDeclaration =
if (isProperty) {
KtPsiFactory(classOwner).createProperty(
"@kotlin.PublishedApi\n" +
if (isProperty) {
KtPsiFactory(classOwner).createProperty(
"@kotlin.PublishedApi\n" +
"internal " + newSignature +
"\n" +
"get() = $originalName\n" +
if (isVar) "set(value) { $originalName = value }" else ""
)
)
}
else {
KtPsiFactory(classOwner).createFunction(
"@kotlin.PublishedApi\n" +
} else {
KtPsiFactory(classOwner).createFunction(
"@kotlin.PublishedApi\n" +
"internal " + newSignature +
" = $originalName(${paramNames.keys.joinToString(", ") { it }})"
)
}
)
}
ShortenReferences.DEFAULT.process(classOwner.addDeclaration(newMember))
}
@@ -100,13 +99,12 @@ class ReplaceProtectedToPublishedApiCallFix(
val signature = signatureRenderer.render(descriptor)
val originalName = descriptor.name.asString()
val newSignature =
if (isProperty) {
signature.replaceFirst("$originalName:", "${originalName.newNameQuoted}:")
}
else {
signature.replaceFirst("$originalName(", "${originalName.newNameQuoted}(")
}
val paramNameAndType = descriptor.valueParameters.associate { it.name.asString() to it.type.getJetTypeFqName(false)}
if (isProperty) {
signature.replaceFirst("$originalName:", "${originalName.newNameQuoted}:")
} else {
signature.replaceFirst("$originalName(", "${originalName.newNameQuoted}(")
}
val paramNameAndType = descriptor.valueParameters.associate { it.name.asString() to it.type.getJetTypeFqName(false) }
val classDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return null
val source = classDescriptor.source.getPsi() as? KtClass ?: return null
@@ -119,8 +117,8 @@ class ReplaceProtectedToPublishedApiCallFix(
}
return ReplaceProtectedToPublishedApiCallFix(
psiElement, source.createSmartPointer(), originalName, paramNameAndType, newSignature,
isProperty, isVar, isPublishedMemberAlreadyExists
psiElement, source.createSmartPointer(), originalName, paramNameAndType, newSignature,
isProperty, isVar, isPublishedMemberAlreadyExists
)
}
@@ -128,6 +126,6 @@ class ReplaceProtectedToPublishedApiCallFix(
get() = "access\$$this"
val String.newNameQuoted: String
get() = "`$newName`"
get() = "`$newName`"
}
}
@@ -72,14 +72,7 @@ object ReplaceWithAnnotationAnalyzer {
}
val module = resolutionFacade.moduleDescriptor
val explicitImportsScope = buildExplicitImportsScope(annotation, resolutionFacade, module)
val languageVersionSettings = resolutionFacade.frontendService<LanguageVersionSettings>()
val defaultImportsScopes = buildDefaultImportsScopes(resolutionFacade, module, languageVersionSettings)
val scope = getResolutionScope(
symbolDescriptor, symbolDescriptor,
listOf(explicitImportsScope), defaultImportsScopes, languageVersionSettings
) ?: return null
val scope = buildScope(resolutionFacade, annotation, symbolDescriptor) ?: return null
val expressionTypingServices = resolutionFacade.getFrontendService(module, ExpressionTypingServices::class.java)
@@ -102,14 +95,7 @@ object ReplaceWithAnnotationAnalyzer {
}
if (typeReference.typeElement !is KtUserType) return null
val module = resolutionFacade.moduleDescriptor
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 scope = buildScope(resolutionFacade, annotation, symbolDescriptor) ?: return null
val typeResolver = resolutionFacade.getFrontendService(TypeResolver::class.java)
val bindingTrace = BindingTraceContext()
@@ -121,7 +107,7 @@ object ReplaceWithAnnotationAnalyzer {
val parentType = expression.parent as? KtUserType ?: return@forEachDescendantOfType
if (parentType.qualifier != null) return@forEachDescendantOfType
val targetClass = bindingTrace.bindingContext[BindingContext.REFERENCE_TARGET, expression] as? ClassDescriptor
?: return@forEachDescendantOfType
?: return@forEachDescendantOfType
val fqName = targetClass.fqNameUnsafe
if (fqName.isSafe) {
typesToQualify.add(expression to fqName.toSafe())
@@ -135,6 +121,21 @@ object ReplaceWithAnnotationAnalyzer {
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(
resolutionFacade: ResolutionFacade,
module: ModuleDescriptor,