diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt index a3d21285b10..0327f9e488f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt @@ -47,29 +47,28 @@ data class ReplaceWith(val pattern: String, val imports: List) object ReplaceWithAnnotationAnalyzer { fun analyzeCallableReplacement( - annotation: ReplaceWith, - symbolDescriptor: CallableDescriptor, - resolutionFacade: ResolutionFacade, - reformat: Boolean + annotation: ReplaceWith, + symbolDescriptor: CallableDescriptor, + resolutionFacade: ResolutionFacade, + reformat: Boolean ): CodeToInline? { - val originalDescriptor = (if (symbolDescriptor is CallableMemberDescriptor) - DescriptorUtils.unwrapFakeOverride(symbolDescriptor) - else - symbolDescriptor).original + val originalDescriptor = when (symbolDescriptor) { + is CallableMemberDescriptor -> DescriptorUtils.unwrapFakeOverride(symbolDescriptor) + else -> symbolDescriptor + }.original return analyzeOriginal(annotation, originalDescriptor, resolutionFacade, reformat) } private fun analyzeOriginal( - annotation: ReplaceWith, - symbolDescriptor: CallableDescriptor, - resolutionFacade: ResolutionFacade, - reformat: Boolean + annotation: ReplaceWith, + symbolDescriptor: CallableDescriptor, + resolutionFacade: ResolutionFacade, + reformat: Boolean ): CodeToInline? { val psiFactory = KtPsiFactory(resolutionFacade.project) val expression = try { psiFactory.createExpression(annotation.pattern) - } - catch(t: Throwable) { + } catch (t: Throwable) { return null } @@ -78,27 +77,28 @@ object ReplaceWithAnnotationAnalyzer { val defaultImportsScopes = buildDefaultImportsScopes(resolutionFacade, module) val languageVersionSettings = resolutionFacade.getFrontendService(LanguageVersionSettings::class.java) - val scope = getResolutionScope(symbolDescriptor, symbolDescriptor, - listOf(explicitImportsScope) + defaultImportsScopes, languageVersionSettings) ?: return null + val scope = getResolutionScope( + symbolDescriptor, symbolDescriptor, + listOf(explicitImportsScope) + defaultImportsScopes, languageVersionSettings + ) ?: return null val expressionTypingServices = resolutionFacade.getFrontendService(module, ExpressionTypingServices::class.java) fun analyzeExpression() = expression.analyzeInContext(scope, expressionTypingServices = expressionTypingServices) return CodeToInlineBuilder(symbolDescriptor, resolutionFacade) - .prepareCodeToInline(expression, emptyList(), ::analyzeExpression, reformat) + .prepareCodeToInline(expression, emptyList(), ::analyzeExpression, reformat) } fun analyzeClassifierReplacement( - annotation: ReplaceWith, - symbolDescriptor: ClassifierDescriptorWithTypeParameters, - resolutionFacade: ResolutionFacade + annotation: ReplaceWith, + symbolDescriptor: ClassifierDescriptorWithTypeParameters, + resolutionFacade: ResolutionFacade ): KtUserType? { val psiFactory = KtPsiFactory(resolutionFacade.project) val typeReference = try { psiFactory.createType(annotation.pattern) - } - catch(e: Exception) { + } catch (e: Exception) { return null } if (typeReference.typeElement !is KtUserType) return null @@ -108,10 +108,10 @@ object ReplaceWithAnnotationAnalyzer { val explicitImportsScope = buildExplicitImportsScope(annotation, resolutionFacade, module) val defaultImportScopes = buildDefaultImportsScopes(resolutionFacade, module) val scope = getResolutionScope( - symbolDescriptor, - symbolDescriptor, - listOf(explicitImportsScope) + defaultImportScopes, - resolutionFacade.getFrontendService(LanguageVersionSettings::class.java) + symbolDescriptor, + symbolDescriptor, + listOf(explicitImportsScope) + defaultImportScopes, + resolutionFacade.getFrontendService(LanguageVersionSettings::class.java) ) ?: return null val typeResolver = resolutionFacade.getFrontendService(TypeResolver::class.java) @@ -123,7 +123,8 @@ object ReplaceWithAnnotationAnalyzer { typeReference.forEachDescendantOfType { expression -> 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 + val targetClass = bindingTrace.bindingContext[BindingContext.REFERENCE_TARGET, expression] as? ClassDescriptor + ?: return@forEachDescendantOfType val fqName = targetClass.fqNameUnsafe if (fqName.isSafe) { typesToQualify.add(expression to fqName.toSafe()) @@ -143,52 +144,81 @@ object ReplaceWithAnnotationAnalyzer { // TODO: Create import directives from ImportPath, create ImportResolver, create LazyResolverScope, see FileScopeProviderImpl return listOf(buildExplicitImportsScope(aliasImports.map { it.fqName }, resolutionFacade, module)) + - allUnderImports.map { module.getPackage(it.fqName).memberScope.memberScopeAsImportingScope() }.asReversed() + allUnderImports.map { module.getPackage(it.fqName).memberScope.memberScopeAsImportingScope() }.asReversed() } - private fun buildExplicitImportsScope(annotation: ReplaceWith, resolutionFacade: ResolutionFacade, module: ModuleDescriptor): ExplicitImportsScope { + private fun buildExplicitImportsScope( + annotation: ReplaceWith, + resolutionFacade: ResolutionFacade, + module: ModuleDescriptor + ): ExplicitImportsScope { return buildExplicitImportsScope(importFqNames(annotation), resolutionFacade, module) } - private fun buildExplicitImportsScope(importFqNames: List, resolutionFacade: ResolutionFacade, module: ModuleDescriptor): ExplicitImportsScope { + private fun buildExplicitImportsScope( + importFqNames: List, + resolutionFacade: ResolutionFacade, + module: ModuleDescriptor + ): ExplicitImportsScope { val importedSymbols = importFqNames.flatMap { resolutionFacade.resolveImportReference(module, it) } return ExplicitImportsScope(importedSymbols) } private fun importFqNames(annotation: ReplaceWith): List { return annotation.imports - .filter { FqNameUnsafe.isValid(it) } - .map(::FqNameUnsafe) - .filter(FqNameUnsafe::isSafe) - .map(FqNameUnsafe::toSafe) + .filter { FqNameUnsafe.isValid(it) } + .map(::FqNameUnsafe) + .filter(FqNameUnsafe::isSafe) + .map(FqNameUnsafe::toSafe) } private fun getResolutionScope( - descriptor: DeclarationDescriptor, - ownerDescriptor: DeclarationDescriptor, - additionalScopes: Collection, - languageVersionSettings: LanguageVersionSettings + descriptor: DeclarationDescriptor, + ownerDescriptor: DeclarationDescriptor, + additionalScopes: Collection, + languageVersionSettings: LanguageVersionSettings ): LexicalScope? { return when (descriptor) { is PackageFragmentDescriptor -> { val moduleDescriptor = descriptor.containingDeclaration - getResolutionScope(moduleDescriptor.getPackage(descriptor.fqName), ownerDescriptor, additionalScopes, languageVersionSettings) + getResolutionScope( + moduleDescriptor.getPackage(descriptor.fqName), + ownerDescriptor, + additionalScopes, + languageVersionSettings + ) } is PackageViewDescriptor -> { LexicalScope.Base( - chainImportingScopes(listOf(descriptor.memberScope.memberScopeAsImportingScope()) + additionalScopes)!!, - ownerDescriptor) + chainImportingScopes(listOf(descriptor.memberScope.memberScopeAsImportingScope()) + additionalScopes)!!, + ownerDescriptor + ) } is ClassDescriptor -> { - val outerScope = getResolutionScope(descriptor.containingDeclaration, ownerDescriptor, additionalScopes, languageVersionSettings) ?: return null - ClassResolutionScopesSupport(descriptor, LockBasedStorageManager.NO_LOCKS, languageVersionSettings, { outerScope }).scopeForMemberDeclarationResolution() + val outerScope = getResolutionScope( + descriptor.containingDeclaration, ownerDescriptor, additionalScopes, languageVersionSettings + ) ?: return null + ClassResolutionScopesSupport( + descriptor, + LockBasedStorageManager.NO_LOCKS, + languageVersionSettings + ) { outerScope }.scopeForMemberDeclarationResolution() } is TypeAliasDescriptor -> { - val outerScope = getResolutionScope(descriptor.containingDeclaration, ownerDescriptor, additionalScopes, languageVersionSettings) ?: return null - LexicalScopeImpl(outerScope, descriptor, false, null, LexicalScopeKind.TYPE_ALIAS_HEADER, LocalRedeclarationChecker.DO_NOTHING) { + val outerScope = getResolutionScope( + descriptor.containingDeclaration, ownerDescriptor, additionalScopes, languageVersionSettings + ) ?: return null + LexicalScopeImpl( + outerScope, + descriptor, + false, + null, + LexicalScopeKind.TYPE_ALIAS_HEADER, + LocalRedeclarationChecker.DO_NOTHING + ) { for (typeParameter in descriptor.declaredTypeParameters) { addClassifierDescriptor(typeParameter) } @@ -196,14 +226,24 @@ object ReplaceWithAnnotationAnalyzer { } is FunctionDescriptor -> { - val outerScope = getResolutionScope(descriptor.containingDeclaration, ownerDescriptor, additionalScopes, languageVersionSettings) ?: return null + val outerScope = getResolutionScope( + descriptor.containingDeclaration, ownerDescriptor, additionalScopes, languageVersionSettings + ) ?: return null FunctionDescriptorUtil.getFunctionInnerScope(outerScope, descriptor, LocalRedeclarationChecker.DO_NOTHING) } is PropertyDescriptor -> { - val outerScope = getResolutionScope(descriptor.containingDeclaration, ownerDescriptor, additionalScopes, languageVersionSettings) ?: return null + val outerScope = getResolutionScope( + descriptor.containingDeclaration, ownerDescriptor, additionalScopes, languageVersionSettings + ) ?: return null val propertyHeader = ScopeUtils.makeScopeForPropertyHeader(outerScope, descriptor) - LexicalScopeImpl(propertyHeader, descriptor, false, descriptor.extensionReceiverParameter, LexicalScopeKind.PROPERTY_ACCESSOR_BODY) + LexicalScopeImpl( + propertyHeader, + descriptor, + false, + descriptor.extensionReceiverParameter, + LexicalScopeKind.PROPERTY_ACCESSOR_BODY + ) } else -> return null // something local, should not work with ReplaceWith