idea: cleanup code

This commit is contained in:
Dmitry Gridin
2019-12-13 22:11:25 +07:00
parent e77d8657f4
commit 8dbbd64beb
897 changed files with 13161 additions and 18514 deletions
+2 -4
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -125,7 +125,6 @@ class FirExplorerToolWindow(private val project: Project, private val toolWindow
val psi = (data as? FirElement)?.psi val psi = (data as? FirElement)?.psi
if (data is FirElement && psi != null) { if (data is FirElement && psi != null) {
if (FileDocumentManager.getInstance().getFile(currentEditor.document) == psi.containingFile.virtualFile) { if (FileDocumentManager.getInstance().getFile(currentEditor.document) == psi.containingFile.virtualFile) {
rangeHighlightMarkers += currentEditor.markupModel.addRangeHighlighter( rangeHighlightMarkers += currentEditor.markupModel.addRangeHighlighter(
psi.startOffset, psi.startOffset,
min(currentEditor.document.textLength, psi.endOffset), min(currentEditor.document.textLength, psi.endOffset),
@@ -288,8 +287,7 @@ private fun KType.renderSimple(): String {
} }
return buildString { return buildString {
val classifier = classifier when (val classifier = classifier) {
when (classifier) {
is KClass<*> -> append(classifier.simpleName) is KClass<*> -> append(classifier.simpleName)
is KTypeParameter -> append(classifier.name) is KTypeParameter -> append(classifier.name)
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.analysis package org.jetbrains.kotlin.idea.analysis
@@ -37,7 +26,8 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor
@JvmOverloads fun KtExpression.computeTypeInfoInContext( @JvmOverloads
fun KtExpression.computeTypeInfoInContext(
scope: LexicalScope, scope: LexicalScope,
contextExpression: KtExpression = this, contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(), trace: BindingTrace = BindingTraceContext(),
@@ -53,7 +43,8 @@ import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor
) )
} }
@JvmOverloads fun KtExpression.analyzeInContext( @JvmOverloads
fun KtExpression.analyzeInContext(
scope: LexicalScope, scope: LexicalScope,
contextExpression: KtExpression = this, contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(), trace: BindingTrace = BindingTraceContext(),
@@ -63,37 +54,47 @@ import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor
contextDependency: ContextDependency = ContextDependency.INDEPENDENT, contextDependency: ContextDependency = ContextDependency.INDEPENDENT,
expressionTypingServices: ExpressionTypingServices = contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>() expressionTypingServices: ExpressionTypingServices = contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>()
): BindingContext { ): BindingContext {
computeTypeInfoInContext(scope, contextExpression, trace, dataFlowInfo, expectedType, isStatement, contextDependency, expressionTypingServices) computeTypeInfoInContext(
scope,
contextExpression,
trace,
dataFlowInfo,
expectedType,
isStatement,
contextDependency,
expressionTypingServices
)
return trace.bindingContext return trace.bindingContext
} }
@JvmOverloads fun KtExpression.computeTypeInContext( @JvmOverloads
fun KtExpression.computeTypeInContext(
scope: LexicalScope, scope: LexicalScope,
contextExpression: KtExpression = this, contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(), trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY, dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
expectedType: KotlinType = TypeUtils.NO_EXPECTED_TYPE expectedType: KotlinType = TypeUtils.NO_EXPECTED_TYPE
): KotlinType? { ): KotlinType? = computeTypeInfoInContext(scope, contextExpression, trace, dataFlowInfo, expectedType).type
return computeTypeInfoInContext(scope, contextExpression, trace, dataFlowInfo, expectedType).type
}
@JvmOverloads fun KtExpression.analyzeAsReplacement( @JvmOverloads
fun KtExpression.analyzeAsReplacement(
expressionToBeReplaced: KtExpression, expressionToBeReplaced: KtExpression,
bindingContext: BindingContext, bindingContext: BindingContext,
scope: LexicalScope, scope: LexicalScope,
trace: BindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for analyzeAsReplacement()"), trace: BindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for analyzeAsReplacement()"),
contextDependency: ContextDependency = ContextDependency.INDEPENDENT contextDependency: ContextDependency = ContextDependency.INDEPENDENT
): BindingContext { ): BindingContext = analyzeInContext(
return analyzeInContext(scope, scope,
expressionToBeReplaced, expressionToBeReplaced,
dataFlowInfo = bindingContext.getDataFlowInfoBefore(expressionToBeReplaced), dataFlowInfo = bindingContext.getDataFlowInfoBefore(expressionToBeReplaced),
expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, expressionToBeReplaced] ?: TypeUtils.NO_EXPECTED_TYPE, expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, expressionToBeReplaced] ?: TypeUtils.NO_EXPECTED_TYPE,
isStatement = expressionToBeReplaced.isUsedAsStatement(bindingContext), isStatement = expressionToBeReplaced.isUsedAsStatement(bindingContext),
trace = trace, trace = trace,
contextDependency = contextDependency) contextDependency = contextDependency
} )
@JvmOverloads fun KtExpression.analyzeAsReplacement( @JvmOverloads
fun KtExpression.analyzeAsReplacement(
expressionToBeReplaced: KtExpression, expressionToBeReplaced: KtExpression,
bindingContext: BindingContext, bindingContext: BindingContext,
resolutionFacade: ResolutionFacade = expressionToBeReplaced.getResolutionFacade(), resolutionFacade: ResolutionFacade = expressionToBeReplaced.getResolutionFacade(),
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
@file:JvmName("ResolutionUtils") @file:JvmName("ResolutionUtils")
@@ -20,7 +9,8 @@ package org.jetbrains.kotlin.idea.caches.resolve
import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -165,7 +155,8 @@ inline fun <reified T> T.analyzeWithContent(): BindingContext where T : KtDeclar
* @ref [org.jetbrains.kotlin.idea.caches.resolve.PerFileAnalysisCache] * @ref [org.jetbrains.kotlin.idea.caches.resolve.PerFileAnalysisCache]
*/ */
fun KtFile.analyzeWithAllCompilerChecks(vararg extraFiles: KtFile): AnalysisResult = fun KtFile.analyzeWithAllCompilerChecks(vararg extraFiles: KtFile): AnalysisResult =
KotlinCacheService.getInstance(project).getResolutionFacade(listOf(this) + extraFiles.toList()).analyzeWithAllCompilerChecks(listOf(this)) KotlinCacheService.getInstance(project).getResolutionFacade(listOf(this) + extraFiles.toList())
.analyzeWithAllCompilerChecks(listOf(this))
/** /**
* This function is expected to produce the same result as compiler for the given element and its children (including diagnostics, * This function is expected to produce the same result as compiler for the given element and its children (including diagnostics,
@@ -193,7 +184,12 @@ fun ResolutionFacade.resolveImportReference(
val importDirective = KtPsiFactory(project).createImportDirective(ImportPath(fqName, false)) val importDirective = KtPsiFactory(project).createImportDirective(ImportPath(fqName, false))
val qualifiedExpressionResolver = this.getFrontendService(moduleDescriptor, QualifiedExpressionResolver::class.java) val qualifiedExpressionResolver = this.getFrontendService(moduleDescriptor, QualifiedExpressionResolver::class.java)
return qualifiedExpressionResolver.processImportReference( return qualifiedExpressionResolver.processImportReference(
importDirective, moduleDescriptor, BindingTraceContext(), excludedImportNames = emptyList(), packageFragmentForVisibilityCheck = null)?.getContributedDescriptors() ?: emptyList() importDirective,
moduleDescriptor,
BindingTraceContext(),
excludedImportNames = emptyList(),
packageFragmentForVisibilityCheck = null
)?.getContributedDescriptors() ?: emptyList()
} }
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.codeInsight package org.jetbrains.kotlin.idea.codeInsight
@@ -241,9 +230,10 @@ class ReferenceVariantsHelper(
if (callType == CallType.SUPER_MEMBERS) { // we need to unwrap fake overrides in case of "super." because ShadowedDeclarationsFilter does not work correctly if (callType == CallType.SUPER_MEMBERS) { // we need to unwrap fake overrides in case of "super." because ShadowedDeclarationsFilter does not work correctly
return descriptors.flatMapTo(LinkedHashSet<DeclarationDescriptor>()) { return descriptors.flatMapTo(LinkedHashSet<DeclarationDescriptor>()) {
if (it is CallableMemberDescriptor && it.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) it.overriddenDescriptors else listOf( if (it is CallableMemberDescriptor && it.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
it it.overriddenDescriptors
) else
listOf(it)
} }
} }
@@ -479,8 +469,9 @@ fun ResolutionScope.collectSyntheticStaticMembersAndConstructors(
nameFilter: (Name) -> Boolean nameFilter: (Name) -> Boolean
): List<FunctionDescriptor> { ): List<FunctionDescriptor> {
val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java) val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java)
return (syntheticScopes.forceEnableSamAdapters().collectSyntheticStaticFunctions(this) + syntheticScopes.collectSyntheticConstructors(this)) return (syntheticScopes.forceEnableSamAdapters().collectSyntheticStaticFunctions(this) + syntheticScopes.collectSyntheticConstructors(
.filter { kindFilter.accepts(it) && nameFilter(it.name) } this
)).filter { kindFilter.accepts(it) && nameFilter(it.name) }
} }
// New Inference disables scope with synthetic SAM-adapters because it uses conversions for resolution // New Inference disables scope with synthetic SAM-adapters because it uses conversions for resolution
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.kdoc package org.jetbrains.kotlin.idea.kdoc
@@ -22,14 +11,24 @@ import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
interface SampleResolutionService { interface SampleResolutionService {
fun resolveSample(context: BindingContext, fromDescriptor: DeclarationDescriptor, resolutionFacade: ResolutionFacade, qualifiedName: List<String>): Collection<DeclarationDescriptor> fun resolveSample(
context: BindingContext,
fromDescriptor: DeclarationDescriptor,
resolutionFacade: ResolutionFacade,
qualifiedName: List<String>
): Collection<DeclarationDescriptor>
companion object { companion object {
/** /**
* It's internal implementation, please use [resolveKDocSampleLink], or [resolveKDocLink] * It's internal implementation, please use [resolveKDocSampleLink], or [resolveKDocLink]
*/ */
internal fun resolveSample(context: BindingContext, fromDescriptor: DeclarationDescriptor, resolutionFacade: ResolutionFacade, qualifiedName: List<String>): Collection<DeclarationDescriptor> { internal fun resolveSample(
context: BindingContext,
fromDescriptor: DeclarationDescriptor,
resolutionFacade: ResolutionFacade,
qualifiedName: List<String>
): Collection<DeclarationDescriptor> {
val instance = ServiceManager.getService(resolutionFacade.project, SampleResolutionService::class.java) val instance = ServiceManager.getService(resolutionFacade.project, SampleResolutionService::class.java)
return instance?.resolveSample(context, fromDescriptor, resolutionFacade, qualifiedName) ?: emptyList() return instance?.resolveSample(context, fromDescriptor, resolutionFacade, qualifiedName) ?: emptyList()
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.kdoc package org.jetbrains.kotlin.idea.kdoc
@@ -51,8 +40,7 @@ fun resolveKDocLink(
fromDescriptor: DeclarationDescriptor, fromDescriptor: DeclarationDescriptor,
fromSubjectOfTag: KDocTag?, fromSubjectOfTag: KDocTag?,
qualifiedName: List<String> qualifiedName: List<String>
): Collection<DeclarationDescriptor> = ): Collection<DeclarationDescriptor> = when (fromSubjectOfTag?.knownTag) {
when (fromSubjectOfTag?.knownTag) {
KDocKnownTag.PARAM -> resolveParamLink(fromDescriptor, qualifiedName) KDocKnownTag.PARAM -> resolveParamLink(fromDescriptor, qualifiedName)
KDocKnownTag.SAMPLE -> resolveKDocSampleLink(context, resolutionFacade, fromDescriptor, qualifiedName) KDocKnownTag.SAMPLE -> resolveKDocSampleLink(context, resolutionFacade, fromDescriptor, qualifiedName)
else -> resolveDefaultKDocLink(context, resolutionFacade, fromDescriptor, qualifiedName) else -> resolveDefaultKDocLink(context, resolutionFacade, fromDescriptor, qualifiedName)
@@ -137,8 +125,13 @@ private fun resolveDefaultKDocLink(
val factory = KtPsiFactory(resolutionFacade.project) val factory = KtPsiFactory(resolutionFacade.project)
// TODO escape identifiers // TODO escape identifiers
val codeFragment = factory.createExpressionCodeFragment(qualifiedName.joinToString("."), contextElement) val codeFragment = factory.createExpressionCodeFragment(qualifiedName.joinToString("."), contextElement)
val qualifiedExpression = codeFragment.findElementAt(codeFragment.textLength - 1)?.getStrictParentOfType<KtQualifiedExpression>() ?: return emptyList() val qualifiedExpression =
val (descriptor, memberName) = qualifiedExpressionResolver.resolveClassOrPackageInQualifiedExpression(qualifiedExpression, contextScope, context) codeFragment.findElementAt(codeFragment.textLength - 1)?.getStrictParentOfType<KtQualifiedExpression>() ?: return emptyList()
val (descriptor, memberName) = qualifiedExpressionResolver.resolveClassOrPackageInQualifiedExpression(
qualifiedExpression,
contextScope,
context
)
if (descriptor == null) return emptyList() if (descriptor == null) return emptyList()
if (memberName != null) { if (memberName != null) {
val memberScope = getKDocLinkMemberScope(descriptor, contextScope) val memberScope = getKDocLinkMemberScope(descriptor, contextScope)
@@ -155,8 +148,10 @@ private fun getPackageInnerScope(descriptor: PackageFragmentDescriptor): MemberS
private fun getClassInnerScope(outerScope: LexicalScope, descriptor: ClassDescriptor): LexicalScope { private fun getClassInnerScope(outerScope: LexicalScope, descriptor: ClassDescriptor): LexicalScope {
val headerScope = LexicalScopeImpl(outerScope, descriptor, false, descriptor.thisAsReceiverParameter, val headerScope = LexicalScopeImpl(
LexicalScopeKind.SYNTHETIC) { outerScope, descriptor, false, descriptor.thisAsReceiverParameter,
LexicalScopeKind.SYNTHETIC
) {
descriptor.declaredTypeParameters.forEach { addClassifierDescriptor(it) } descriptor.declaredTypeParameters.forEach { addClassifierDescriptor(it) }
descriptor.constructors.forEach { addFunctionDescriptor(it) } descriptor.constructors.forEach { addFunctionDescriptor(it) }
} }
@@ -180,9 +175,10 @@ fun getKDocLinkResolutionScope(resolutionFacade: ResolutionFacade, contextDescri
is ClassDescriptor -> is ClassDescriptor ->
getClassInnerScope(getOuterScope(contextDescriptor, resolutionFacade), contextDescriptor) getClassInnerScope(getOuterScope(contextDescriptor, resolutionFacade), contextDescriptor)
is FunctionDescriptor -> is FunctionDescriptor -> FunctionDescriptorUtil.getFunctionInnerScope(
FunctionDescriptorUtil.getFunctionInnerScope(getOuterScope(contextDescriptor, resolutionFacade), getOuterScope(contextDescriptor, resolutionFacade),
contextDescriptor, LocalRedeclarationChecker.DO_NOTHING) contextDescriptor, LocalRedeclarationChecker.DO_NOTHING
)
is PropertyDescriptor -> is PropertyDescriptor ->
ScopeUtils.makeScopeForPropertyHeader(getOuterScope(contextDescriptor, resolutionFacade), contextDescriptor) ScopeUtils.makeScopeForPropertyHeader(getOuterScope(contextDescriptor, resolutionFacade), contextDescriptor)
@@ -197,13 +193,14 @@ fun getKDocLinkResolutionScope(resolutionFacade: ResolutionFacade, contextDescri
private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, resolutionFacade: ResolutionFacade): LexicalScope { private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, resolutionFacade: ResolutionFacade): LexicalScope {
val parent = descriptor.containingDeclaration!! val parent = descriptor.containingDeclaration!!
if (parent is PackageFragmentDescriptor) { if (parent is PackageFragmentDescriptor) {
val containingFile = (descriptor.source as? PsiSourceElement)?.psi?.containingFile as? KtFile val containingFile = (descriptor.source as? PsiSourceElement)?.psi?.containingFile as? KtFile ?: return LexicalScope.Base(
?: return LexicalScope.Base(ImportingScope.Empty, parent) ImportingScope.Empty,
parent
)
val kotlinCacheService = ServiceManager.getService(containingFile.project, KotlinCacheService::class.java) val kotlinCacheService = ServiceManager.getService(containingFile.project, KotlinCacheService::class.java)
val facadeToUse = kotlinCacheService?.getResolutionFacade(listOf(containingFile)) ?: resolutionFacade val facadeToUse = kotlinCacheService?.getResolutionFacade(listOf(containingFile)) ?: resolutionFacade
return facadeToUse.getFileResolutionScope(containingFile) return facadeToUse.getFileResolutionScope(containingFile)
} } else {
else {
return getKDocLinkResolutionScope(resolutionFacade, parent) return getKDocLinkResolutionScope(resolutionFacade, parent)
} }
} }
@@ -215,12 +212,14 @@ fun getKDocLinkMemberScope(descriptor: DeclarationDescriptor, contextScope: Lexi
is PackageViewDescriptor -> descriptor.memberScope is PackageViewDescriptor -> descriptor.memberScope
is ClassDescriptor -> { is ClassDescriptor -> {
ChainedMemberScope("Member scope for KDoc resolve", listOfNotNull( ChainedMemberScope(
"Member scope for KDoc resolve", listOfNotNull(
descriptor.unsubstitutedMemberScope, descriptor.unsubstitutedMemberScope,
descriptor.staticScope, descriptor.staticScope,
descriptor.companionObjectDescriptor?.unsubstitutedMemberScope, descriptor.companionObjectDescriptor?.unsubstitutedMemberScope,
ExtensionsScope(descriptor, contextScope) ExtensionsScope(descriptor, contextScope)
)) )
)
} }
else -> MemberScope.Empty else -> MemberScope.Empty
@@ -234,34 +233,47 @@ private class ExtensionsScope(
private val receiverTypes = listOf(receiverClass.defaultType) private val receiverTypes = listOf(receiverClass.defaultType)
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> { override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
return contextScope.collectFunctions(name, location) return contextScope.collectFunctions(name, location).flatMap {
.flatMap { if (it is SimpleFunctionDescriptor && it.isExtension) it.substituteExtensionIfCallable(receiverTypes, CallType.DOT) else emptyList() } if (it is SimpleFunctionDescriptor && it.isExtension) it.substituteExtensionIfCallable(
receiverTypes,
CallType.DOT
) else emptyList()
}
} }
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> { override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
return contextScope.collectVariables(name, location) return contextScope.collectVariables(name, location).flatMap {
.flatMap { if (it is PropertyDescriptor && it.isExtension) it.substituteExtensionIfCallable(receiverTypes, CallType.DOT) else emptyList() } if (it is PropertyDescriptor && it.isExtension) it.substituteExtensionIfCallable(
receiverTypes,
CallType.DOT
) else emptyList()
}
} }
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> { override fun getContributedDescriptors(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> {
if (DescriptorKindExclude.Extensions in kindFilter.excludes) return emptyList() if (DescriptorKindExclude.Extensions in kindFilter.excludes) return emptyList()
return contextScope.collectDescriptorsFiltered(kindFilter exclude DescriptorKindExclude.NonExtensions, nameFilter, changeNamesForAliased = true) return contextScope.collectDescriptorsFiltered(
.flatMap { if (it is CallableDescriptor && it.isExtension) it.substituteExtensionIfCallable(receiverTypes, CallType.DOT) else emptyList() } kindFilter exclude DescriptorKindExclude.NonExtensions,
nameFilter,
changeNamesForAliased = true
).flatMap {
if (it is CallableDescriptor && it.isExtension) it.substituteExtensionIfCallable(
receiverTypes,
CallType.DOT
) else emptyList()
}
} }
override fun getFunctionNames(): Set<Name> { override fun getFunctionNames(): Set<Name> =
return getContributedDescriptors(kindFilter = DescriptorKindFilter.FUNCTIONS) getContributedDescriptors(kindFilter = DescriptorKindFilter.FUNCTIONS).map { it.name }.toSet()
.map { it.name }
.toSet()
}
override fun getVariableNames(): Set<Name> { override fun getVariableNames(): Set<Name> =
return getContributedDescriptors(kindFilter = DescriptorKindFilter.VARIABLES) getContributedDescriptors(kindFilter = DescriptorKindFilter.VARIABLES).map { it.name }.toSet()
.map { it.name }
.toSet()
}
override fun getClassifierNames() = null override fun getClassifierNames() = null
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.refactoring.introduce package org.jetbrains.kotlin.idea.refactoring.introduce
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.resolve package org.jetbrains.kotlin.idea.resolve
@@ -51,8 +40,6 @@ interface ResolutionFacade {
} }
inline fun <reified T : Any> ResolutionFacade.frontendService(): T inline fun <reified T : Any> ResolutionFacade.frontendService(): T = this.getFrontendService(T::class.java)
= this.getFrontendService(T::class.java)
inline fun <reified T : Any> ResolutionFacade.ideService(): T inline fun <reified T : Any> ResolutionFacade.ideService(): T = this.getIdeService(T::class.java)
= this.getIdeService(T::class.java)
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.util package org.jetbrains.kotlin.idea.util
@@ -146,7 +135,8 @@ sealed class CallTypeAndReceiver<TReceiver : KtElement?, out TCallType : CallTyp
CallType.IMPORT_DIRECTIVE, receiver CallType.IMPORT_DIRECTIVE, receiver
) )
class PACKAGE_DIRECTIVE(receiver: KtExpression?) : CallTypeAndReceiver<KtExpression?, CallType.PACKAGE_DIRECTIVE>(CallType.PACKAGE_DIRECTIVE, receiver) class PACKAGE_DIRECTIVE(receiver: KtExpression?) :
CallTypeAndReceiver<KtExpression?, CallType.PACKAGE_DIRECTIVE>(CallType.PACKAGE_DIRECTIVE, receiver)
class TYPE(receiver: KtExpression?) : CallTypeAndReceiver<KtExpression?, CallType.TYPE>(CallType.TYPE, receiver) class TYPE(receiver: KtExpression?) : CallTypeAndReceiver<KtExpression?, CallType.TYPE>(CallType.TYPE, receiver)
class DELEGATE(receiver: KtExpression?) : CallTypeAndReceiver<KtExpression?, CallType.DELEGATE>(CallType.DELEGATE, receiver) class DELEGATE(receiver: KtExpression?) : CallTypeAndReceiver<KtExpression?, CallType.DELEGATE>(CallType.DELEGATE, receiver)
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
@file:JvmName("FuzzyTypeUtils") @file:JvmName("FuzzyTypeUtils")
@@ -27,7 +16,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.StrictEqualityTypeChecker import org.jetbrains.kotlin.types.checker.StrictEqualityTypeChecker
import org.jetbrains.kotlin.types.typeUtil.* import org.jetbrains.kotlin.types.typeUtil.*
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.* import java.util.*
fun CallableDescriptor.fuzzyReturnType() = returnType?.toFuzzyType(typeParameters) fun CallableDescriptor.fuzzyReturnType() = returnType?.toFuzzyType(typeParameters)
@@ -79,12 +67,10 @@ class FuzzyType(
if (usedTypeParameters.isNotEmpty()) { if (usedTypeParameters.isNotEmpty()) {
val originalFreeParameters = freeParameters.map { it.toOriginal() }.toSet() val originalFreeParameters = freeParameters.map { it.toOriginal() }.toSet()
this.freeParameters = usedTypeParameters.filter { it.toOriginal() in originalFreeParameters }.toSet() this.freeParameters = usedTypeParameters.filter { it.toOriginal() in originalFreeParameters }.toSet()
} } else {
else {
this.freeParameters = emptySet() this.freeParameters = emptySet()
} }
} } else {
else {
this.freeParameters = emptySet() this.freeParameters = emptySet()
} }
} }
@@ -115,17 +101,13 @@ class FuzzyType(
} }
} }
fun checkIsSubtypeOf(otherType: FuzzyType): TypeSubstitutor? fun checkIsSubtypeOf(otherType: FuzzyType): TypeSubstitutor? = matchedSubstitutor(otherType, MatchKind.IS_SUBTYPE)
= matchedSubstitutor(otherType, MatchKind.IS_SUBTYPE)
fun checkIsSuperTypeOf(otherType: FuzzyType): TypeSubstitutor? fun checkIsSuperTypeOf(otherType: FuzzyType): TypeSubstitutor? = matchedSubstitutor(otherType, MatchKind.IS_SUPERTYPE)
= matchedSubstitutor(otherType, MatchKind.IS_SUPERTYPE)
fun checkIsSubtypeOf(otherType: KotlinType): TypeSubstitutor? fun checkIsSubtypeOf(otherType: KotlinType): TypeSubstitutor? = checkIsSubtypeOf(otherType.toFuzzyType(emptyList()))
= checkIsSubtypeOf(otherType.toFuzzyType(emptyList()))
fun checkIsSuperTypeOf(otherType: KotlinType): TypeSubstitutor? fun checkIsSuperTypeOf(otherType: KotlinType): TypeSubstitutor? = checkIsSuperTypeOf(otherType.toFuzzyType(emptyList()))
= checkIsSuperTypeOf(otherType.toFuzzyType(emptyList()))
private enum class MatchKind { private enum class MatchKind {
IS_SUBTYPE, IS_SUBTYPE,
@@ -199,7 +181,10 @@ fun TypeSubstitution.hasConflictWith(other: TypeSubstitution, freeParameters: Co
val type = parameter.defaultType val type = parameter.defaultType
val substituted1 = this[type] ?: return@any false val substituted1 = this[type] ?: return@any false
val substituted2 = other[type] ?: return@any false val substituted2 = other[type] ?: return@any false
!StrictEqualityTypeChecker.strictEqualTypes(substituted1.type.unwrap(), substituted2.type.unwrap()) || substituted1.projectionKind != substituted2.projectionKind !StrictEqualityTypeChecker.strictEqualTypes(
substituted1.type.unwrap(),
substituted2.type.unwrap()
) || substituted1.projectionKind != substituted2.projectionKind
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.util package org.jetbrains.kotlin.idea.util
@@ -33,11 +22,16 @@ abstract class ImportInsertHelper {
abstract val importSortComparator: Comparator<ImportPath> abstract val importSortComparator: Comparator<ImportPath>
abstract fun importDescriptor(file: KtFile, descriptor: DeclarationDescriptor, forceAllUnderImport: Boolean = false): ImportDescriptorResult abstract fun importDescriptor(
file: KtFile,
descriptor: DeclarationDescriptor,
forceAllUnderImport: Boolean = false
): ImportDescriptorResult
companion object { companion object {
@JvmStatic fun getInstance(project: Project): ImportInsertHelper @JvmStatic
= ServiceManager.getService<ImportInsertHelper>(project, ImportInsertHelper::class.java) fun getInstance(project: Project): ImportInsertHelper =
ServiceManager.getService<ImportInsertHelper>(project, ImportInsertHelper::class.java)
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.util package org.jetbrains.kotlin.idea.util
@@ -1,23 +1,11 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.util package org.jetbrains.kotlin.idea.util
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
@@ -73,12 +61,8 @@ class ShadowedDeclarationsFilter(
private val psiFactory = KtPsiFactory(resolutionFacade.project) private val psiFactory = KtPsiFactory(resolutionFacade.project)
private val dummyExpressionFactory = DummyExpressionFactory(psiFactory) private val dummyExpressionFactory = DummyExpressionFactory(psiFactory)
fun <TDescriptor : DeclarationDescriptor> filter(declarations: Collection<TDescriptor>): Collection<TDescriptor> { fun <TDescriptor : DeclarationDescriptor> filter(declarations: Collection<TDescriptor>): Collection<TDescriptor> =
return declarations declarations.groupBy { signature(it) }.values.flatMap { group -> filterEqualSignatureGroup(group) }
.groupBy { signature(it) }
.values
.flatMap { group -> filterEqualSignatureGroup(group) }
}
fun <TDescriptor : DeclarationDescriptor> createNonImportedDeclarationsFilter( fun <TDescriptor : DeclarationDescriptor> createNonImportedDeclarationsFilter(
importedDeclarations: Collection<DeclarationDescriptor> importedDeclarations: Collection<DeclarationDescriptor>
@@ -103,8 +87,7 @@ class ShadowedDeclarationsFilter(
} }
} }
private fun signature(descriptor: DeclarationDescriptor): Any = private fun signature(descriptor: DeclarationDescriptor): Any = when (descriptor) {
when (descriptor) {
is SimpleFunctionDescriptor -> FunctionSignature(descriptor) is SimpleFunctionDescriptor -> FunctionSignature(descriptor)
is VariableDescriptor -> descriptor.name is VariableDescriptor -> descriptor.name
is ClassDescriptor -> descriptor.importableFqName ?: descriptor is ClassDescriptor -> descriptor.importableFqName ?: descriptor
@@ -143,7 +126,8 @@ class ShadowedDeclarationsFilter(
} }
val firstVarargIndex = parameters.withIndex().firstOrNull { it.value.varargElementType != null }?.index val firstVarargIndex = parameters.withIndex().firstOrNull { it.value.varargElementType != null }?.index
val useNamedFromIndex = if (firstVarargIndex != null && firstVarargIndex != parameters.lastIndex) firstVarargIndex else parameters.size val useNamedFromIndex =
if (firstVarargIndex != null && firstVarargIndex != parameters.lastIndex) firstVarargIndex else parameters.size
class DummyArgument(val index: Int) : ValueArgument { class DummyArgument(val index: Int) : ValueArgument {
private val expression = dummyArgumentExpressions[index] private val expression = dummyArgumentExpressions[index]
@@ -153,8 +137,7 @@ class ShadowedDeclarationsFilter(
override val asName = parameters[index].name override val asName = parameters[index].name
override val referenceExpression = null override val referenceExpression = null
} }
} } else {
else {
null null
} }
@@ -206,17 +189,23 @@ class ShadowedDeclarationsFilter(
} }
val dataFlowInfo = bindingContext.getDataFlowInfoBefore(context) val dataFlowInfo = bindingContext.getDataFlowInfoBefore(context)
val context = BasicCallResolutionContext.create(bindingTrace, scope, newCall, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, val context = BasicCallResolutionContext.create(
bindingTrace, scope, newCall, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo,
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
false, /* languageVersionSettings */ resolutionFacade.frontendService(), false, /* languageVersionSettings */ resolutionFacade.frontendService(),
resolutionFacade.frontendService<DataFlowValueFactory>()) resolutionFacade.frontendService<DataFlowValueFactory>()
)
val callResolver = resolutionFacade.frontendService<CallResolver>() val callResolver = resolutionFacade.frontendService<CallResolver>()
val results = if (isFunction) callResolver.resolveFunctionCall(context) else callResolver.resolveSimpleProperty(context) val results = if (isFunction) callResolver.resolveFunctionCall(context) else callResolver.resolveSimpleProperty(context)
val resultingDescriptors = results.resultingCalls.map { it.resultingDescriptor } val resultingDescriptors = results.resultingCalls.map { it.resultingDescriptor }
val resultingOriginals = resultingDescriptors.mapTo(HashSet<DeclarationDescriptor>()) { it.original } val resultingOriginals = resultingDescriptors.mapTo(HashSet<DeclarationDescriptor>()) { it.original }
val filtered = descriptors.filter { candidateDescriptor -> val filtered = descriptors.filter { candidateDescriptor ->
candidateDescriptor.original in resultingOriginals /* optimization */ candidateDescriptor.original in resultingOriginals /* optimization */ && resultingDescriptors.any {
&& resultingDescriptors.any { descriptorsEqualWithSubstitution(it, candidateDescriptor) } descriptorsEqualWithSubstitution(
it,
candidateDescriptor
)
}
} }
return if (filtered.isNotEmpty()) filtered else descriptors /* something went wrong, none of our declarations among resolve candidates, let's not filter anything */ return if (filtered.isNotEmpty()) filtered else descriptors /* something went wrong, none of our declarations among resolve candidates, let's not filter anything */
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
@file:JvmName("TypeUtils") @file:JvmName("TypeUtils")
@@ -69,9 +58,8 @@ private fun KotlinType.approximateNonDynamicFlexibleTypes(
approximation = if (nullability() == TypeNullability.NOT_NULL) approximation.makeNullableAsSpecified(false) else approximation approximation = if (nullability() == TypeNullability.NOT_NULL) approximation.makeNullableAsSpecified(false) else approximation
if (approximation.isMarkedNullable && !flexible.lowerBound.isMarkedNullable && TypeUtils.isTypeParameter(approximation) && TypeUtils.hasNullableSuperType( if (approximation.isMarkedNullable && !flexible.lowerBound
approximation .isMarkedNullable && TypeUtils.isTypeParameter(approximation) && TypeUtils.hasNullableSuperType(approximation)
)
) { ) {
approximation = approximation.makeNullableAsSpecified(false) approximation = approximation.makeNullableAsSpecified(false)
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.util package org.jetbrains.kotlin.idea.util
@@ -63,7 +52,14 @@ fun SmartCastManager.getSmartCastVariantsWithLessSpecificExcluded(
languageVersionSettings: LanguageVersionSettings, languageVersionSettings: LanguageVersionSettings,
dataFlowValueFactory: DataFlowValueFactory dataFlowValueFactory: DataFlowValueFactory
): List<KotlinType> { ): List<KotlinType> {
val variants = getSmartCastVariants(receiverToCast, bindingContext, containingDeclarationOrModule, dataFlowInfo, languageVersionSettings, dataFlowValueFactory) val variants = getSmartCastVariants(
receiverToCast,
bindingContext,
containingDeclarationOrModule,
dataFlowInfo,
languageVersionSettings,
dataFlowValueFactory
)
return variants.filter { type -> return variants.filter { type ->
variants.all { another -> another === type || chooseMoreSpecific(type, another).let { it == null || it === type } } variants.all { another -> another === type || chooseMoreSpecific(type, another).let { it == null || it === type } }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
@file:JvmName("ExtensionUtils") @file:JvmName("ExtensionUtils")
@@ -44,8 +33,7 @@ fun <TCallable : CallableDescriptor> TCallable.substituteExtensionIfCallable(
} }
val extensionReceiverType = fuzzyExtensionReceiverType()!! val extensionReceiverType = fuzzyExtensionReceiverType()!!
val substitutors = types val substitutors = types.mapNotNull {
.mapNotNull {
var substitutor = extensionReceiverType.checkIsSuperTypeOf(it) var substitutor = extensionReceiverType.checkIsSuperTypeOf(it)
// check if we may fail due to receiver expression being nullable // check if we may fail due to receiver expression being nullable
if (substitutor == null && it.nullability() == TypeNullability.NULLABLE && extensionReceiverType.nullability() == TypeNullability.NOT_NULL) { if (substitutor == null && it.nullability() == TypeNullability.NULLABLE && extensionReceiverType.nullability() == TypeNullability.NOT_NULL) {
@@ -55,8 +43,7 @@ fun <TCallable : CallableDescriptor> TCallable.substituteExtensionIfCallable(
} }
return if (typeParameters.isEmpty()) { // optimization for non-generic callables return if (typeParameters.isEmpty()) { // optimization for non-generic callables
if (substitutors.any()) listOf(this) else listOf() if (substitutors.any()) listOf(this) else listOf()
} } else {
else {
substitutors substitutors
.mapNotNull { @Suppress("UNCHECKED_CAST") (substitute(it) as TCallable?) } .mapNotNull { @Suppress("UNCHECKED_CAST") (substitute(it) as TCallable?) }
.toList() .toList()
@@ -76,20 +63,16 @@ fun ReceiverValue?.getThisReceiverOwner(bindingContext: BindingContext): Declara
} }
} }
fun ReceiverValue?.getReceiverTargetDescriptor(bindingContext: BindingContext): DeclarationDescriptor? { fun ReceiverValue?.getReceiverTargetDescriptor(bindingContext: BindingContext): DeclarationDescriptor? = when (this) {
return when (this) { is ExpressionReceiver -> when (val expression = KtPsiUtil.deparenthesize(this.expression)) {
is ExpressionReceiver -> {
val expression = KtPsiUtil.deparenthesize(this.expression)
val refExpression = when (expression) {
is KtThisExpression -> expression.instanceReference is KtThisExpression -> expression.instanceReference
is KtReferenceExpression -> expression is KtReferenceExpression -> expression
else -> null else -> null
} ?: return null }?.let { referenceExpression ->
bindingContext[BindingContext.REFERENCE_TARGET, refExpression] bindingContext[BindingContext.REFERENCE_TARGET, referenceExpression]
} }
is ImplicitReceiver -> this.declarationDescriptor is ImplicitReceiver -> this.declarationDescriptor
else -> null else -> null
} }
}
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.util package org.jetbrains.kotlin.idea.util
@@ -42,14 +31,10 @@ interface ReceiverExpressionFactory {
fun createExpression(psiFactory: KtPsiFactory, shortThis: Boolean = true): KtExpression fun createExpression(psiFactory: KtPsiFactory, shortThis: Boolean = true): KtExpression
} }
fun LexicalScope.getFactoryForImplicitReceiverWithSubtypeOf(receiverType: KotlinType): ReceiverExpressionFactory? { fun LexicalScope.getFactoryForImplicitReceiverWithSubtypeOf(receiverType: KotlinType): ReceiverExpressionFactory? =
return getImplicitReceiversWithInstanceToExpression() getImplicitReceiversWithInstanceToExpression().entries.firstOrNull { (receiverDescriptor, _) ->
.entries
.firstOrNull { (receiverDescriptor, _) ->
receiverDescriptor.type.isSubtypeOf(receiverType) receiverDescriptor.type.isSubtypeOf(receiverType)
} }?.value
?.value
}
fun LexicalScope.getImplicitReceiversWithInstanceToExpression( fun LexicalScope.getImplicitReceiversWithInstanceToExpression(
excludeShadowedByDslMarkers: Boolean = false excludeShadowedByDslMarkers: Boolean = false
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.util.psi.patternMatching package org.jetbrains.kotlin.idea.util.psi.patternMatching
@@ -76,8 +65,7 @@ interface KotlinPsiRange {
if (result is UnificationResult.StronglyMatched) { if (result is UnificationResult.StronglyMatched) {
matches.add(result) matches.add(result)
} } else {
else {
val matchCountSoFar = matches.size val matchCountSoFar = matches.size
super.visitKtElement(element) super.visitKtElement(element)
if (result is UnificationResult.WeaklyMatched && matches.size == matchCountSoFar) { if (result is UnificationResult.WeaklyMatched && matches.size == matchCountSoFar) {
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.util.psi.patternMatching package org.jetbrains.kotlin.idea.util.psi.patternMatching
@@ -212,12 +201,10 @@ class KotlinPsiUnifier(
val (implicitReceiver, explicitReceiver) = val (implicitReceiver, explicitReceiver) =
when (explicitCall.explicitReceiverKind) { when (explicitCall.explicitReceiverKind) {
ExplicitReceiverKind.EXTENSION_RECEIVER -> ExplicitReceiverKind.EXTENSION_RECEIVER ->
(implicitCall.extensionReceiver as? ImplicitReceiver) to (implicitCall.extensionReceiver as? ImplicitReceiver) to (explicitCall.extensionReceiver as? ExpressionReceiver)
(explicitCall.extensionReceiver as? ExpressionReceiver)
ExplicitReceiverKind.DISPATCH_RECEIVER -> ExplicitReceiverKind.DISPATCH_RECEIVER ->
(implicitCall.dispatchReceiver as? ImplicitReceiver) to (implicitCall.dispatchReceiver as? ImplicitReceiver) to (explicitCall.dispatchReceiver as? ExpressionReceiver)
(explicitCall.dispatchReceiver as? ExpressionReceiver)
else -> else ->
null to null null to null
@@ -236,7 +223,10 @@ class KotlinPsiUnifier(
return when { return when {
rc1.explicitReceiverKind == rc2.explicitReceiverKind -> { rc1.explicitReceiverKind == rc2.explicitReceiverKind -> {
matchReceivers(rc1.extensionReceiver, rc2.extensionReceiver) && matchReceivers(rc1.extensionReceiver, rc2.extensionReceiver) &&
(rc1.explicitReceiverKind == ExplicitReceiverKind.BOTH_RECEIVERS || matchReceivers(rc1.dispatchReceiver, rc2.dispatchReceiver)) (rc1.explicitReceiverKind == ExplicitReceiverKind.BOTH_RECEIVERS || matchReceivers(
rc1.dispatchReceiver,
rc2.dispatchReceiver
))
} }
rc1.explicitReceiverKind == ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> checkImplicitReceiver(rc1, rc2) rc1.explicitReceiverKind == ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> checkImplicitReceiver(rc1, rc2)
@@ -279,8 +269,7 @@ class KotlinPsiUnifier(
private fun KtElement.getAdjustedResolvedCall(): ResolvedCall<*>? { private fun KtElement.getAdjustedResolvedCall(): ResolvedCall<*>? {
val rc = if (this is KtArrayAccessExpression) { val rc = if (this is KtArrayAccessExpression) {
bindingContext[BindingContext.INDEXED_LVALUE_GET, this] bindingContext[BindingContext.INDEXED_LVALUE_GET, this]
} } else {
else {
getResolvedCall(bindingContext)?.let { getResolvedCall(bindingContext)?.let {
when { when {
it !is VariableAsFunctionResolvedCall -> it it !is VariableAsFunctionResolvedCall -> it
@@ -338,7 +327,12 @@ class KotlinPsiUnifier(
if (type1 != null && type2 != null) { if (type1 != null && type2 != null) {
val unwrappedType1 = type1.unwrap() val unwrappedType1 = type1.unwrap()
val unwrappedType2 = type2.unwrap() val unwrappedType2 = type2.unwrap()
if (unwrappedType1 !== type1 || unwrappedType2 !== type2) return matchTypes(unwrappedType1, unwrappedType2, typeRef1, typeRef2) if (unwrappedType1 !== type1 || unwrappedType2 !== type2) return matchTypes(
unwrappedType1,
unwrappedType2,
typeRef1,
typeRef2
)
if (type1.isError || type2.isError) return null if (type1.isError || type2.isError) return null
if (type1 is AbbreviatedType != type2 is AbbreviatedType) return UNMATCHED if (type1 is AbbreviatedType != type2 is AbbreviatedType) return UNMATCHED
@@ -348,7 +342,9 @@ class KotlinPsiUnifier(
if (type1.isMarkedNullable != type2.isMarkedNullable) return UNMATCHED if (type1.isMarkedNullable != type2.isMarkedNullable) return UNMATCHED
if (!matchDescriptors( if (!matchDescriptors(
type1.constructor.declarationDescriptor, type1.constructor.declarationDescriptor,
type2.constructor.declarationDescriptor)) return UNMATCHED type2.constructor.declarationDescriptor
)
) return UNMATCHED
val args1 = type1.arguments val args1 = type1.arguments
val args2 = type2.arguments val args2 = type2.arguments
@@ -382,11 +378,10 @@ class KotlinPsiUnifier(
val status = if (!checkEquivalence && typeRef1 != null && typeRef2 != null) { val status = if (!checkEquivalence && typeRef1 != null && typeRef2 != null) {
val typePsi1 = argType1.constructor.declarationDescriptor?.source?.getPsi() val typePsi1 = argType1.constructor.declarationDescriptor?.source?.getPsi()
val typePsi2 = argType2.constructor.declarationDescriptor?.source?.getPsi() val typePsi2 = argType2.constructor.declarationDescriptor?.source?.getPsi()
descriptorToParameter[typePsi1]?.let { substitute(it, typeArgRef2) } ?: descriptorToParameter[typePsi1]?.let { substitute(it, typeArgRef2) }
descriptorToParameter[typePsi2]?.let { substitute(it, typeArgRef1) } ?: ?: descriptorToParameter[typePsi2]?.let { substitute(it, typeArgRef1) }
matchTypes(argType1, argType2, typeArgRef1, typeArgRef2) ?: matchTypes(argType1, argType2, typeArgRef1, typeArgRef2)
} } else matchTypes(argType1, argType2, typeArgRef1, typeArgRef2)
else matchTypes(argType1, argType2, typeArgRef1, typeArgRef2)
return status == MATCHED return status == MATCHED
} }
@@ -413,12 +408,11 @@ class KotlinPsiUnifier(
else -> false else -> false
} }
private fun KtBinaryExpression.matchComplexAssignmentWithSimple(simple: KtBinaryExpression): Status? { private fun KtBinaryExpression.matchComplexAssignmentWithSimple(simple: KtBinaryExpression): Status? =
return when { when (doUnify(left, simple.left)) {
doUnify(left, simple.left) == UNMATCHED -> UNMATCHED UNMATCHED -> UNMATCHED
else -> simple.right?.let { matchCalls(this, it) } ?: UNMATCHED else -> simple.right?.let { matchCalls(this, it) } ?: UNMATCHED
} }
}
private fun KtBinaryExpression.matchAssignment(e: KtElement): Status? { private fun KtBinaryExpression.matchAssignment(e: KtElement): Status? {
val operationType = operationReference.getReferencedNameElementType() as KtToken val operationType = operationReference.getReferencedNameElementType() as KtToken
@@ -435,11 +429,13 @@ class KotlinPsiUnifier(
val setResolvedCall = bindingContext[BindingContext.INDEXED_LVALUE_SET, lhs] val setResolvedCall = bindingContext[BindingContext.INDEXED_LVALUE_SET, lhs]
val resolvedCallToMatch = e.getAdjustedResolvedCall() val resolvedCallToMatch = e.getAdjustedResolvedCall()
return if (setResolvedCall == null || resolvedCallToMatch == null) null else matchResolvedCalls(setResolvedCall, resolvedCallToMatch) return if (setResolvedCall == null || resolvedCallToMatch == null) null else matchResolvedCalls(
setResolvedCall,
resolvedCallToMatch
)
} }
val assignResolvedCall = getAdjustedResolvedCall() val assignResolvedCall = getAdjustedResolvedCall() ?: return UNMATCHED
if (assignResolvedCall == null) return UNMATCHED
val operationName = OperatorConventions.getNameForOperationSymbol(operationType) val operationName = OperatorConventions.getNameForOperationSymbol(operationType)
if (assignResolvedCall.resultingDescriptor?.name == operationName) return matchCalls(this, e) if (assignResolvedCall.resultingDescriptor?.name == operationName) return matchCalls(this, e)
@@ -456,9 +452,7 @@ class KotlinPsiUnifier(
private fun PsiElement.isIncrement(): Boolean { private fun PsiElement.isIncrement(): Boolean {
val parent = parent val parent = parent
return parent is KtUnaryExpression return parent is KtUnaryExpression && this == parent.operationReference && ((parent.operationToken as KtToken) in OperatorConventions.INCREMENT_OPERATIONS)
&& this == parent.operationReference
&& ((parent.operationToken as KtToken) in OperatorConventions.INCREMENT_OPERATIONS)
} }
private fun KtCallableReferenceExpression.hasExpressionReceiver(): Boolean = private fun KtCallableReferenceExpression.hasExpressionReceiver(): Boolean =
@@ -513,7 +507,8 @@ class KotlinPsiUnifier(
decl1: KtDeclaration, decl1: KtDeclaration,
decl2: KtDeclaration, decl2: KtDeclaration,
desc1: CallableDescriptor, desc1: CallableDescriptor,
desc2: CallableDescriptor): Status? { desc2: CallableDescriptor
): Status? {
fun needToCompareReturnTypes(): Boolean { fun needToCompareReturnTypes(): Boolean {
if (decl1 !is KtCallableDeclaration) return true if (decl1 !is KtCallableDeclaration) return true
return decl1.typeReference != null || (decl2 as KtCallableDeclaration).typeReference != null return decl1.typeReference != null || (decl2 as KtCallableDeclaration).typeReference != null
@@ -527,8 +522,11 @@ class KotlinPsiUnifier(
val type1 = desc1.returnType val type1 = desc1.returnType
val type2 = desc2.returnType val type2 = desc2.returnType
if (type1 != type2 if (type1 != type2 && (type1 == null || type2 == null || type1.isError || type2.isError || matchTypes(
&& (type1 == null || type2 == null || type1.isError || type2.isError || matchTypes(type1, type2) != MATCHED)) { type1,
type2
) != MATCHED)
) {
return UNMATCHED return UNMATCHED
} }
} }
@@ -570,7 +568,12 @@ class KotlinPsiUnifier(
return parent is KtClassBody || parent is KtFile return parent is KtClassBody || parent is KtFile
} }
private fun matchNames(decl1: KtDeclaration, decl2: KtDeclaration, desc1: DeclarationDescriptor, desc2: DeclarationDescriptor): Boolean { private fun matchNames(
decl1: KtDeclaration,
decl2: KtDeclaration,
desc1: DeclarationDescriptor,
desc2: DeclarationDescriptor
): Boolean {
return (!decl1.isNameRelevant() && !decl2.isNameRelevant()) || desc1.name == desc2.name return (!decl1.isNameRelevant() && !decl2.isNameRelevant()) || desc1.name == desc2.name
} }
@@ -590,7 +593,8 @@ class KotlinPsiUnifier(
decl1: KtClassOrObject, decl1: KtClassOrObject,
decl2: KtClassOrObject, decl2: KtClassOrObject,
desc1: ClassDescriptor, desc1: ClassDescriptor,
desc2: ClassDescriptor): Status? { desc2: ClassDescriptor
): Status? {
class OrderInfo<out T>( class OrderInfo<out T>(
val orderSensitive: List<T>, val orderSensitive: List<T>,
val orderInsensitive: List<T> val orderInsensitive: List<T>
@@ -610,9 +614,8 @@ class KotlinPsiUnifier(
} }
fun resolveAndSortDeclarationsByDescriptor(declarations: List<KtDeclaration>): List<Pair<KtDeclaration, DeclarationDescriptor?>> { fun resolveAndSortDeclarationsByDescriptor(declarations: List<KtDeclaration>): List<Pair<KtDeclaration, DeclarationDescriptor?>> {
return declarations return declarations.map { it to it.bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, it] }
.map { it to it.bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, it] } .sortedBy { it.second?.let { descriptor -> IdeDescriptorRenderers.SOURCE_CODE.render(descriptor) } ?: "" }
.sortedBy { it.second?.let { IdeDescriptorRenderers.SOURCE_CODE.render(it) } ?: "" }
} }
fun sortDeclarationsByElementType(declarations: List<KtDeclaration>): List<KtDeclaration> { fun sortDeclarationsByElementType(declarations: List<KtDeclaration>): List<KtDeclaration> {
@@ -642,7 +645,10 @@ class KotlinPsiUnifier(
return UNMATCHED return UNMATCHED
} }
val status = doUnify((decl1 as? KtClass)?.getPrimaryConstructorParameterList(), (decl2 as? KtClass)?.getPrimaryConstructorParameterList()) and val status = doUnify(
(decl1 as? KtClass)?.getPrimaryConstructorParameterList(),
(decl2 as? KtClass)?.getPrimaryConstructorParameterList()
) and
doUnify((decl1 as? KtClass)?.typeParameterList, (decl2 as? KtClass)?.typeParameterList) and doUnify((decl1 as? KtClass)?.typeParameterList, (decl2 as? KtClass)?.typeParameterList) and
doUnify(delegationInfo1.orderSensitive.toRange(), delegationInfo2.orderSensitive.toRange()) doUnify(delegationInfo1.orderSensitive.toRange(), delegationInfo2.orderSensitive.toRange())
if (status == UNMATCHED) return UNMATCHED if (status == UNMATCHED) return UNMATCHED
@@ -656,7 +662,8 @@ class KotlinPsiUnifier(
if (sortedMembers1.zip(sortedMembers2).any { if (sortedMembers1.zip(sortedMembers2).any {
val (d1, d2) = it val (d1, d2) = it
(matchDeclarations(d1.first, d2.first, d1.second, d2.second) ?: doUnify(d1.first, d2.first)) == UNMATCHED (matchDeclarations(d1.first, d2.first, d1.second, d2.second) ?: doUnify(d1.first, d2.first)) == UNMATCHED
}) return UNMATCHED }
) return UNMATCHED
return doUnify( return doUnify(
sortDeclarationsByElementType(membersInfo1.orderSensitive).toRange(), sortDeclarationsByElementType(membersInfo1.orderSensitive).toRange(),
@@ -685,15 +692,19 @@ class KotlinPsiUnifier(
decl1: KtDeclaration, decl1: KtDeclaration,
decl2: KtDeclaration, decl2: KtDeclaration,
desc1: DeclarationDescriptor?, desc1: DeclarationDescriptor?,
desc2: DeclarationDescriptor?): Status? { desc2: DeclarationDescriptor?
): Status? {
if (decl1::class.java != decl2::class.java) return UNMATCHED if (decl1::class.java != decl2::class.java) return UNMATCHED
if (desc1 == null || desc2 == null) { if (desc1 == null || desc2 == null) {
if (decl1 is KtParameter return if (decl1 is KtParameter
&& decl2 is KtParameter && decl2 is KtParameter
&& decl1.getStrictParentOfType<KtTypeElement>() != null && decl1.getStrictParentOfType<KtTypeElement>() != null
&& decl2.getStrictParentOfType<KtTypeElement>() != null) return null && decl2.getStrictParentOfType<KtTypeElement>() != null
return UNMATCHED )
null
else
UNMATCHED
} }
if (ErrorUtils.isError(desc1) || ErrorUtils.isError(desc2)) return UNMATCHED if (ErrorUtils.isError(desc1) || ErrorUtils.isError(desc2)) return UNMATCHED
if (desc1::class.java != desc2::class.java) return UNMATCHED if (desc1::class.java != desc2::class.java) return UNMATCHED
@@ -801,8 +812,7 @@ class KotlinPsiUnifier(
val patternText = pattern.startEntry.text.substring(prefixLength) val patternText = pattern.startEntry.text.substring(prefixLength)
if (!targetEntryText.endsWith(patternText)) continue if (!targetEntryText.endsWith(patternText)) continue
targetEntryText.substring(0, targetEntryText.length - patternText.length) targetEntryText.substring(0, targetEntryText.length - patternText.length)
} } else ""
else ""
val lastTargetEntry = targetEntries[index + patternEntries.lastIndex] val lastTargetEntry = targetEntries[index + patternEntries.lastIndex]
@@ -813,8 +823,7 @@ class KotlinPsiUnifier(
val lastTargetEntryText = lastTargetEntry.text val lastTargetEntryText = lastTargetEntry.text
if (!lastTargetEntryText.startsWith(patternText)) continue if (!lastTargetEntryText.startsWith(patternText)) continue
lastTargetEntryText.substring(patternText.length) lastTargetEntryText.substring(patternText.length)
} } else ""
else ""
val fromIndex = if (matchStartByText) 1 else 0 val fromIndex = if (matchStartByText) 1 else 0
val toIndex = if (matchEndByText) patternEntries.lastIndex - 1 else patternEntries.lastIndex val toIndex = if (matchEndByText) patternEntries.lastIndex - 1 else patternEntries.lastIndex
@@ -846,8 +855,7 @@ class KotlinPsiUnifier(
} }
} }
private fun ASTNode.getChildrenRange(): KotlinPsiRange = private fun ASTNode.getChildrenRange(): KotlinPsiRange = getChildren(null).mapNotNull { it.psi }.toRange()
getChildren(null).mapNotNull { it.psi }.toRange()
private fun PsiElement.unwrapWeakly(): KtElement? { private fun PsiElement.unwrapWeakly(): KtElement? {
return when { return when {
@@ -878,10 +886,9 @@ class KotlinPsiUnifier(
return status return status
} }
private fun substitute(parameter: UnifierParameter, targetElement: PsiElement?): Status { private fun substitute(parameter: UnifierParameter, targetElement: PsiElement?): Status =
val existingArgument = substitution[parameter] when (val existingArgument = substitution[parameter]) {
return when { null -> {
existingArgument == null -> {
substitution[parameter] = targetElement as KtElement substitution[parameter] = targetElement as KtElement
MATCHED MATCHED
} }
@@ -893,7 +900,6 @@ class KotlinPsiUnifier(
status status
} }
} }
}
fun doUnify( fun doUnify(
targetElement: PsiElement?, targetElement: PsiElement?,
@@ -922,8 +928,7 @@ class KotlinPsiUnifier(
if (referencedPatternDeclaration != null && parameter != null) { if (referencedPatternDeclaration != null && parameter != null) {
if (targetElementUnwrapped is KtExpression) { if (targetElementUnwrapped is KtExpression) {
if (!targetElementUnwrapped.checkType(parameter)) return UNMATCHED if (!targetElementUnwrapped.checkType(parameter)) return UNMATCHED
} } else if (targetElementUnwrapped !is KtUserType) return UNMATCHED
else if (targetElementUnwrapped !is KtUserType) return UNMATCHED
return substitute(parameter, targetElementUnwrapped) return substitute(parameter, targetElementUnwrapped)
} }
@@ -958,13 +963,11 @@ class KotlinPsiUnifier(
private val descriptorToParameter = parameters.associateBy { (it.descriptor as? DeclarationDescriptorWithSource)?.source?.getPsi() } private val descriptorToParameter = parameters.associateBy { (it.descriptor as? DeclarationDescriptorWithSource)?.source?.getPsi() }
private fun PsiElement.unwrap(): PsiElement? { private fun PsiElement.unwrap(): PsiElement? = when (this) {
return when (this) {
is KtExpression -> KtPsiUtil.deparenthesize(this) is KtExpression -> KtPsiUtil.deparenthesize(this)
is KtStringTemplateEntryWithExpression -> KtPsiUtil.deparenthesize(expression) is KtStringTemplateEntryWithExpression -> KtPsiUtil.deparenthesize(expression)
else -> this else -> this
} }
}
private fun PsiElement.unquotedText(): String { private fun PsiElement.unquotedText(): String {
val text = text ?: "" val text = text ?: ""
@@ -975,8 +978,7 @@ class KotlinPsiUnifier(
return with(Context(target, pattern)) { return with(Context(target, pattern)) {
val status = doUnify(target, pattern) val status = doUnify(target, pattern)
when { when {
substitution.size != descriptorToParameter.size -> substitution.size != descriptorToParameter.size -> Unmatched
Unmatched
status == MATCHED -> { status == MATCHED -> {
val targetRange = targetSubstringInfo?.createExpression()?.toRange() ?: target val targetRange = targetSubstringInfo?.createExpression()?.toRange() ?: target
if (weakMatches.isEmpty()) { if (weakMatches.isEmpty()) {
@@ -985,8 +987,7 @@ class KotlinPsiUnifier(
WeaklyMatched(targetRange, substitution, weakMatches) WeaklyMatched(targetRange, substitution, weakMatches)
} }
} }
else -> else -> Unmatched
Unmatched
} }
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
@file:JvmName("ScopeUtils") @file:JvmName("ScopeUtils")
@@ -44,11 +33,13 @@ fun LexicalScope.getAllAccessibleVariables(name: Name): Collection<VariableDescr
} }
fun LexicalScope.getAllAccessibleFunctions(name: Name): Collection<FunctionDescriptor> { fun LexicalScope.getAllAccessibleFunctions(name: Name): Collection<FunctionDescriptor> {
return getImplicitReceiversWithInstance().flatMap { it.type.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_IDE) } + return getImplicitReceiversWithInstance().flatMap {
collectFunctions(name, NoLookupLocation.FROM_IDE) it.type.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_IDE)
} + collectFunctions(name, NoLookupLocation.FROM_IDE)
} }
fun LexicalScope.getVariablesFromImplicitReceivers(name: Name): Collection<VariableDescriptor> = getImplicitReceiversWithInstance().flatMap { fun LexicalScope.getVariablesFromImplicitReceivers(name: Name): Collection<VariableDescriptor> =
getImplicitReceiversWithInstance().flatMap {
it.type.memberScope.getContributedVariables(name, NoLookupLocation.FROM_IDE) it.type.memberScope.getContributedVariables(name, NoLookupLocation.FROM_IDE)
} }
@@ -80,13 +71,13 @@ fun PsiElement.getResolutionScope(bindingContext: BindingContext): LexicalScope?
return null return null
} }
fun PsiElement.getResolutionScope(bindingContext: BindingContext, resolutionFacade: ResolutionFacade/*TODO: get rid of this parameter*/): LexicalScope { fun PsiElement.getResolutionScope(
return getResolutionScope(bindingContext) ?: bindingContext: BindingContext,
when (containingFile) { resolutionFacade: ResolutionFacade/*TODO: get rid of this parameter*/
): LexicalScope = getResolutionScope(bindingContext) ?: when (containingFile) {
is KtFile -> resolutionFacade.getFileResolutionScope(containingFile as KtFile) is KtFile -> resolutionFacade.getFileResolutionScope(containingFile as KtFile)
else -> error("Not in KtFile") else -> error("Not in KtFile")
} }
}
fun KtElement.getResolutionScope(): LexicalScope { fun KtElement.getResolutionScope(): LexicalScope {
val resolutionFacade = getResolutionFacade() val resolutionFacade = getResolutionFacade()
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.resolve.lazy package org.jetbrains.kotlin.resolve.lazy
@@ -21,12 +10,16 @@ import org.jetbrains.kotlin.resolve.BindingTraceFilter
enum class BodyResolveMode(val bindingTraceFilter: BindingTraceFilter, val doControlFlowAnalysis: Boolean) { enum class BodyResolveMode(val bindingTraceFilter: BindingTraceFilter, val doControlFlowAnalysis: Boolean) {
// All body statements are analyzed, diagnostics included // All body statements are analyzed, diagnostics included
FULL(BindingTraceFilter.ACCEPT_ALL, doControlFlowAnalysis = true), FULL(BindingTraceFilter.ACCEPT_ALL, doControlFlowAnalysis = true),
// Analyzes only dependent statements, including all declaration statements (difference from PARTIAL_WITH_CFA) // Analyzes only dependent statements, including all declaration statements (difference from PARTIAL_WITH_CFA)
PARTIAL_FOR_COMPLETION(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = true), PARTIAL_FOR_COMPLETION(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = true),
// Analyzes only dependent statements, diagnostics included // Analyzes only dependent statements, diagnostics included
PARTIAL_WITH_DIAGNOSTICS(BindingTraceFilter.ACCEPT_ALL, doControlFlowAnalysis = true), PARTIAL_WITH_DIAGNOSTICS(BindingTraceFilter.ACCEPT_ALL, doControlFlowAnalysis = true),
// Analyzes only dependent statements, performs control flow analysis (mostly needed for isUsedAsExpression / AsStatement) // Analyzes only dependent statements, performs control flow analysis (mostly needed for isUsedAsExpression / AsStatement)
PARTIAL_WITH_CFA(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = true), PARTIAL_WITH_CFA(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = true),
// Analyzes only dependent statements, including only used declaration statements, does not perform control flow analysis // Analyzes only dependent statements, including only used declaration statements, does not perform control flow analysis
PARTIAL(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = false) PARTIAL(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = false)
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.resolve.lazy package org.jetbrains.kotlin.resolve.lazy
@@ -59,8 +48,7 @@ class PartialBodyResolveFilter(
if (name != null) { if (name != null) {
if (declaration is KtNamedFunction) { if (declaration is KtNamedFunction) {
contextNothingFunctionNames.add(name) contextNothingFunctionNames.add(name)
} } else {
else {
contextNothingVariableNames.add(name) contextNothingVariableNames.add(name)
} }
} }
@@ -91,8 +79,7 @@ class PartialBodyResolveFilter(
if (name != null && nameFilter(name)) { if (name != null && nameFilter(name)) {
statementMarks.mark(statement, MarkLevel.NEED_REFERENCE_RESOLVE) statementMarks.mark(statement, MarkLevel.NEED_REFERENCE_RESOLVE)
} }
} } else if (statement is KtDestructuringDeclaration) {
else if (statement is KtDestructuringDeclaration) {
if (statement.entries.any { if (statement.entries.any {
val name = it.name val name = it.name
name != null && nameFilter(name) name != null && nameFilter(name)
@@ -235,9 +222,9 @@ class PartialBodyResolveFilter(
if (thenBranch != null && elseBranch != null) { if (thenBranch != null && elseBranch != null) {
val thenCasts = potentialSmartCastPlaces(thenBranch, filter) val thenCasts = potentialSmartCastPlaces(thenBranch, filter)
if (!thenCasts.isEmpty()) { if (thenCasts.isNotEmpty()) {
val elseCasts = potentialSmartCastPlaces(elseBranch) { filter(it) && thenCasts.containsKey(it) } val elseCasts = potentialSmartCastPlaces(elseBranch) { filter(it) && thenCasts.containsKey(it) }
if (!elseCasts.isEmpty()) { if (elseCasts.isNotEmpty()) {
for ((name, places) in thenCasts) { for ((name, places) in thenCasts) {
if (elseCasts.containsKey(name)) { // need filtering by cast names in else-branch if (elseCasts.containsKey(name)) { // need filtering by cast names in else-branch
addPlaces(name, places) addPlaces(name, places)
@@ -262,8 +249,7 @@ class PartialBodyResolveFilter(
// we need to enter the body only for "while(true)" // we need to enter the body only for "while(true)"
if (condition.isTrueConstant()) { if (condition.isTrueConstant()) {
expression.acceptChildren(this) expression.acceptChildren(this)
} } else {
else {
condition?.accept(this) condition?.accept(this)
} }
} }
@@ -406,8 +392,7 @@ class PartialBodyResolveFilter(
insideLoopLevel++ insideLoopLevel++
loop.body?.accept(this) loop.body?.accept(this)
insideLoopLevel-- insideLoopLevel--
} } else {
else {
// do not make sense to search exits inside while-loop as not necessary enter it at all // do not make sense to search exits inside while-loop as not necessary enter it at all
condition.accept(this) condition.accept(this)
} }
@@ -451,8 +436,7 @@ class PartialBodyResolveFilter(
if (expression.operationToken == KtTokens.ELVIS) { if (expression.operationToken == KtTokens.ELVIS) {
// do not search exits after "?:" // do not search exits after "?:"
expression.left?.accept(this) expression.left?.accept(this)
} } else {
else {
super.visitBinaryExpression(expression) super.visitBinaryExpression(expression)
} }
} }
@@ -482,7 +466,7 @@ class PartialBodyResolveFilter(
} }
} }
override fun toString(): String = if (receiverName != null) receiverName.toString() + "." + selectorName else selectorName ?: "this" override fun toString(): String = if (receiverName != null) "$receiverName.$selectorName" else selectorName ?: "this"
fun affectsNames(nameFilter: (String) -> Boolean): Boolean { fun affectsNames(nameFilter: (String) -> Boolean): Boolean {
if (selectorName == null) return true if (selectorName == null) return true
@@ -533,8 +517,7 @@ class PartialBodyResolveFilter(
if (names == null) return if (names == null) return
if (filter.names == null) { if (filter.names == null) {
names = null names = null
} } else {
else {
names!!.addAll(filter.names!!) names!!.addAll(filter.names!!)
} }
} }
@@ -562,15 +545,12 @@ class PartialBodyResolveFilter(
private fun KtExpression?.isNullLiteral() = this?.node?.elementType == KtNodeTypes.NULL private fun KtExpression?.isNullLiteral() = this?.node?.elementType == KtNodeTypes.NULL
private fun KtExpression?.isTrueConstant() private fun KtExpression?.isTrueConstant() = this != null && node?.elementType == KtNodeTypes.BOOLEAN_CONSTANT && text == "true"
= this != null && node?.elementType == KtNodeTypes.BOOLEAN_CONSTANT && text == "true"
private fun <T : Any> T?.singletonOrEmptySet(): Set<T> = if (this != null) setOf(this) else setOf() private fun <T : Any> T?.singletonOrEmptySet(): Set<T> = if (this != null) setOf(this) else setOf()
//TODO: review logic //TODO: review logic
private fun isValueNeeded(expression: KtExpression): Boolean { private fun isValueNeeded(expression: KtExpression): Boolean = when (val parent = expression.parent) {
val parent = expression.parent
return when (parent) {
is KtBlockExpression -> expression == parent.lastStatement() && isValueNeeded(parent) is KtBlockExpression -> expression == parent.lastStatement() && isValueNeeded(parent)
is KtContainerNode -> { //TODO - not quite correct is KtContainerNode -> { //TODO - not quite correct
@@ -589,15 +569,14 @@ class PartialBodyResolveFilter(
else -> true else -> true
} }
}
private fun KtBlockExpression.lastStatement(): KtExpression? private fun KtBlockExpression.lastStatement(): KtExpression? =
= lastChild?.siblings(forward = false)?.firstIsInstanceOrNull<KtExpression>() lastChild?.siblings(forward = false)?.firstIsInstanceOrNull<KtExpression>()
private fun PsiElement.isStatement() = this is KtExpression && parent is KtBlockExpression private fun PsiElement.isStatement() = this is KtExpression && parent is KtBlockExpression
private fun KtTypeReference?.containsProbablyNothing() private fun KtTypeReference?.containsProbablyNothing() =
= this?.typeElement?.anyDescendantOfType<KtUserType> { it.isProbablyNothing() } ?: false this?.typeElement?.anyDescendantOfType<KtUserType> { it.isProbablyNothing() } ?: false
} }
private inner class StatementMarks { private inner class StatementMarks {
@@ -627,11 +606,9 @@ class PartialBodyResolveFilter(
} }
} }
fun statementMark(statement: KtExpression): MarkLevel fun statementMark(statement: KtExpression): MarkLevel = statementMarks[statement] ?: MarkLevel.NONE
= statementMarks[statement] ?: MarkLevel.NONE
fun allMarkedStatements(): Collection<KtExpression> fun allMarkedStatements(): Collection<KtExpression> = statementMarks.keys
= statementMarks.keys
fun lastMarkedStatement(block: KtBlockExpression, minLevel: MarkLevel): KtExpression? { fun lastMarkedStatement(block: KtBlockExpression, minLevel: MarkLevel): KtExpression? {
val level = blockLevels[block] ?: MarkLevel.NONE val level = blockLevels[block] ?: MarkLevel.NONE
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.resolve.scopes package org.jetbrains.kotlin.resolve.scopes
@@ -23,20 +12,22 @@ import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
class ExplicitImportsScope(private val descriptors: Collection<DeclarationDescriptor>) : BaseImportingScope(null) { class ExplicitImportsScope(private val descriptors: Collection<DeclarationDescriptor>) : BaseImportingScope(null) {
override fun getContributedClassifier(name: Name, location: LookupLocation) override fun getContributedClassifier(name: Name, location: LookupLocation) =
= descriptors.filter { it.name == name }.firstIsInstanceOrNull<ClassifierDescriptor>() descriptors.filter { it.name == name }.firstIsInstanceOrNull<ClassifierDescriptor>()
override fun getContributedPackage(name: Name) override fun getContributedPackage(name: Name) = descriptors.filter { it.name == name }.firstIsInstanceOrNull<PackageViewDescriptor>()
= descriptors.filter { it.name == name }.firstIsInstanceOrNull<PackageViewDescriptor>()
override fun getContributedVariables(name: Name, location: LookupLocation) override fun getContributedVariables(name: Name, location: LookupLocation) =
= descriptors.filter { it.name == name }.filterIsInstance<VariableDescriptor>() descriptors.filter { it.name == name }.filterIsInstance<VariableDescriptor>()
override fun getContributedFunctions(name: Name, location: LookupLocation) override fun getContributedFunctions(name: Name, location: LookupLocation) =
= descriptors.filter { it.name == name }.filterIsInstance<FunctionDescriptor>() descriptors.filter { it.name == name }.filterIsInstance<FunctionDescriptor>()
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, changeNamesForAliased: Boolean) override fun getContributedDescriptors(
= descriptors kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean,
changeNamesForAliased: Boolean
) = descriptors
override fun computeImportedNames() = descriptors.mapTo(hashSetOf()) { it.name } override fun computeImportedNames() = descriptors.mapTo(hashSetOf()) { it.name }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.util package org.jetbrains.kotlin.util
@@ -48,7 +37,8 @@ fun descriptorsEqualWithSubstitution(
if (typeParam1 != null if (typeParam1 != null
&& typeParam2 != null && typeParam2 != null
&& typeParam1.containingDeclaration == descriptor1 && typeParam1.containingDeclaration == descriptor1
&& typeParam2.containingDeclaration == descriptor2) { && typeParam2.containingDeclaration == descriptor2
) {
return typeParam1.index == typeParam2.index return typeParam1.index == typeParam2.index
} }
@@ -84,9 +74,9 @@ fun ClassDescriptor.findCallableMemberBySignature(
fun TypeConstructor.supertypesWithAny(): Collection<KotlinType> { fun TypeConstructor.supertypesWithAny(): Collection<KotlinType> {
val supertypes = supertypes val supertypes = supertypes
val noSuperClass = supertypes val noSuperClass = supertypes.map { it.constructor.declarationDescriptor as? ClassDescriptor }.all {
.map { it.constructor.declarationDescriptor as? ClassDescriptor } it == null || it.kind == ClassKind.INTERFACE
.all { it == null || it.kind == ClassKind.INTERFACE } }
return if (noSuperClass) supertypes + builtIns.anyType else supertypes return if (noSuperClass) supertypes + builtIns.anyType else supertypes
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.types.substitutions package org.jetbrains.kotlin.types.substitutions
@@ -20,7 +9,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
import java.util.LinkedHashMap import java.util.*
fun getTypeSubstitution(baseType: KotlinType, derivedType: KotlinType): LinkedHashMap<TypeConstructor, TypeProjection>? { fun getTypeSubstitution(baseType: KotlinType, derivedType: KotlinType): LinkedHashMap<TypeConstructor, TypeProjection>? {
val substitutedType = TypeCheckingProcedure.findCorrespondingSupertype(derivedType, baseType) ?: return null val substitutedType = TypeCheckingProcedure.findCorrespondingSupertype(derivedType, baseType) ?: return null
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea package org.jetbrains.kotlin.idea
@@ -136,8 +125,7 @@ class KotlinIconProvider : IconProvider(), DumbAware {
is KtParameter -> { is KtParameter -> {
if (KtPsiUtil.getClassIfParameterIsProperty(this) != null) { if (KtPsiUtil.getClassIfParameterIsProperty(this) != null) {
if (isMutable) KotlinIcons.FIELD_VAR else KotlinIcons.FIELD_VAL if (isMutable) KotlinIcons.FIELD_VAR else KotlinIcons.FIELD_VAL
} } else
else
KotlinIcons.PARAMETER KotlinIcons.PARAMETER
} }
is KtProperty -> if (isVar) KotlinIcons.FIELD_VAR else KotlinIcons.FIELD_VAL is KtProperty -> if (isVar) KotlinIcons.FIELD_VAR else KotlinIcons.FIELD_VAL
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.caches package org.jetbrains.kotlin.idea.caches
@@ -97,7 +86,8 @@ class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache()
LOG.error( LOG.error(
"A declaration obtained from index has non-matching name:" + "A declaration obtained from index has non-matching name:" +
"\nin index: $name" + "\nin index: $name" +
"\ndeclared: ${fqName.shortName()}($fqName)") "\ndeclared: ${fqName.shortName()}($fqName)"
)
return@Processor true return@Processor true
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -63,8 +63,7 @@ class KotlinPackageContentModificationListener(private val project: Project): Di
if (events.size >= FULL_DROP_THRESHOLD) { if (events.size >= FULL_DROP_THRESHOLD) {
service.onTooComplexChange() service.onTooComplexChange()
} else { } else {
events events.asSequence()
.asSequence()
.filter(::isRelevant) .filter(::isRelevant)
.filter { (it.isValid || it !is VFileCreateEvent) && it.file != null } .filter { (it.isValid || it !is VFileCreateEvent) && it.file != null }
.filter { .filter {
@@ -303,7 +302,9 @@ class PerModulePackageCacheService(private val project: Project) : Disposable {
pendingKtFileChanges.processPending { file -> pendingKtFileChanges.processPending { file ->
if (file.virtualFile != null && file.virtualFile !in projectScope) { if (file.virtualFile != null && file.virtualFile !in projectScope) {
LOG.debugIfEnabled(project) { "Skip $file without vFile, or not in scope: ${file.virtualFile?.let { it !in projectScope }}" } LOG.debugIfEnabled(project) {
"Skip $file without vFile, or not in scope: ${file.virtualFile?.let { it !in projectScope }}"
}
return@processPending return@processPending
} }
val nullableModuleInfo = file.getNullableModuleInfo() val nullableModuleInfo = file.getNullableModuleInfo()
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.caches.lightClasses package org.jetbrains.kotlin.idea.caches.lightClasses
@@ -111,7 +100,12 @@ internal object IDELightClassContexts {
"Class descriptor was not found for ${classOrObject.getElementTextWithContext()}" "Class descriptor was not found for ${classOrObject.getElementTextWithContext()}"
} }
ForceResolveUtil.forceResolveAllContents(classDescriptor) ForceResolveUtil.forceResolveAllContents(classDescriptor)
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, classOrObject.languageVersionSettings, EXACT) return IDELightClassConstructionContext(
bindingContext,
resolutionFacade.moduleDescriptor,
classOrObject.languageVersionSettings,
EXACT
)
} }
fun contextForLocalClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext { fun contextForLocalClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext {
@@ -122,12 +116,22 @@ internal object IDELightClassContexts {
if (descriptor == null) { if (descriptor == null) {
LOG.warn("No class descriptor in context for class: " + classOrObject.getElementTextWithContext()) LOG.warn("No class descriptor in context for class: " + classOrObject.getElementTextWithContext())
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, classOrObject.languageVersionSettings, EXACT) return IDELightClassConstructionContext(
bindingContext,
resolutionFacade.moduleDescriptor,
classOrObject.languageVersionSettings,
EXACT
)
} }
ForceResolveUtil.forceResolveAllContents(descriptor) ForceResolveUtil.forceResolveAllContents(descriptor)
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, classOrObject.languageVersionSettings, EXACT) return IDELightClassConstructionContext(
bindingContext,
resolutionFacade.moduleDescriptor,
classOrObject.languageVersionSettings,
EXACT
)
} }
@@ -135,7 +139,12 @@ internal object IDELightClassContexts {
val resolveSession = files.first().getResolutionFacade().getFrontendService(ResolveSession::class.java) val resolveSession = files.first().getResolutionFacade().getFrontendService(ResolveSession::class.java)
forceResolvePackageDeclarations(files, resolveSession) forceResolvePackageDeclarations(files, resolveSession)
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, files.first().languageVersionSettings, EXACT) return IDELightClassConstructionContext(
resolveSession.bindingContext,
resolveSession.moduleDescriptor,
files.first().languageVersionSettings,
EXACT
)
} }
fun contextForScript(script: KtScript): LightClassConstructionContext { fun contextForScript(script: KtScript): LightClassConstructionContext {
@@ -145,7 +154,12 @@ internal object IDELightClassContexts {
val descriptor = bindingContext[BindingContext.SCRIPT, script] val descriptor = bindingContext[BindingContext.SCRIPT, script]
if (descriptor == null) { if (descriptor == null) {
LOG.warn("No script descriptor in context for script: " + script.getElementTextWithContext()) LOG.warn("No script descriptor in context for script: " + script.getElementTextWithContext())
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, script.languageVersionSettings, EXACT) return IDELightClassConstructionContext(
bindingContext,
resolutionFacade.moduleDescriptor,
script.languageVersionSettings,
EXACT
)
} }
ForceResolveUtil.forceResolveAllContents(descriptor) ForceResolveUtil.forceResolveAllContents(descriptor)
@@ -167,7 +181,12 @@ internal object IDELightClassContexts {
ForceResolveUtil.forceResolveAllContents(descriptor) ForceResolveUtil.forceResolveAllContents(descriptor)
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, classOrObject.languageVersionSettings, LIGHT) return IDELightClassConstructionContext(
resolveSession.bindingContext,
resolveSession.moduleDescriptor,
classOrObject.languageVersionSettings,
LIGHT
)
} }
fun lightContextForFacade(files: List<KtFile>): LightClassConstructionContext { fun lightContextForFacade(files: List<KtFile>): LightClassConstructionContext {
@@ -176,7 +195,12 @@ internal object IDELightClassContexts {
forceResolvePackageDeclarations(files, resolveSession) forceResolvePackageDeclarations(files, resolveSession)
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, files.first().languageVersionSettings, LIGHT) return IDELightClassConstructionContext(
resolveSession.bindingContext,
resolveSession.moduleDescriptor,
files.first().languageVersionSettings,
LIGHT
)
} }
private fun isDummyResolveApplicable(classOrObject: KtClassOrObject): Boolean { private fun isDummyResolveApplicable(classOrObject: KtClassOrObject): Boolean {
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.caches.lightClasses package org.jetbrains.kotlin.idea.caches.lightClasses
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.caches.lightClasses package org.jetbrains.kotlin.idea.caches.lightClasses
@@ -40,7 +29,8 @@ class KtLightClassForDecompiledDeclaration(
override fun getOwnInnerClasses(): List<PsiClass> { override fun getOwnInnerClasses(): List<PsiClass> {
val nestedClasses = kotlinOrigin?.declarations?.filterIsInstance<KtClassOrObject>() ?: emptyList() val nestedClasses = kotlinOrigin?.declarations?.filterIsInstance<KtClassOrObject>() ?: emptyList()
return clsDelegate.ownInnerClasses.map { innerClsClass -> return clsDelegate.ownInnerClasses.map { innerClsClass ->
KtLightClassForDecompiledDeclaration(innerClsClass as ClsClassImpl, KtLightClassForDecompiledDeclaration(
innerClsClass as ClsClassImpl,
nestedClasses.firstOrNull { innerClsClass.name == it.name }, file nestedClasses.firstOrNull { innerClsClass.name == it.name }, file
) )
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2017 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -184,6 +184,7 @@ sealed class LazyLightClassDataHolder(
} }
private val PsiMember.debugName private val PsiMember.debugName
get() = "${this::class.java.simpleName}:${this.name} ${this.memberIndex}" + if (this is PsiMethod) " (with ${parameterList.parametersCount} parameters)" else "" get() = "${this::class.java
.simpleName}:${this.name} ${this.memberIndex}" + if (this is PsiMethod) " (with ${parameterList.parametersCount} parameters)" else ""
var KtClassOrObject.hasLightClassMatchingErrors: Boolean by NotNullableUserDataProperty(Key.create("LIGHT_CLASS_MATCHING_ERRORS"), false) var KtClassOrObject.hasLightClassMatchingErrors: Boolean by NotNullableUserDataProperty(Key.create("LIGHT_CLASS_MATCHING_ERRORS"), false)
@@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -233,8 +233,11 @@ fun Module.testSourceInfo(): ModuleTestSourceInfo? = if (hasTestRoots()) ModuleT
internal fun Module.correspondingModuleInfos(): List<ModuleSourceInfo> = listOf(testSourceInfo(), productionSourceInfo()).filterNotNull() internal fun Module.correspondingModuleInfos(): List<ModuleSourceInfo> = listOf(testSourceInfo(), productionSourceInfo()).filterNotNull()
private fun Module.hasProductionRoots() = hasRootsOfType(JavaSourceRootType.SOURCE) || hasRootsOfType(SourceKotlinRootType) || (isNewMPPModule && sourceType == SourceType.PRODUCTION) private fun Module.hasProductionRoots() =
private fun Module.hasTestRoots() = hasRootsOfType(JavaSourceRootType.TEST_SOURCE) || hasRootsOfType(TestSourceKotlinRootType) || (isNewMPPModule && sourceType == SourceType.TEST) hasRootsOfType(JavaSourceRootType.SOURCE) || hasRootsOfType(SourceKotlinRootType) || (isNewMPPModule && sourceType == SourceType.PRODUCTION)
private fun Module.hasTestRoots() =
hasRootsOfType(JavaSourceRootType.TEST_SOURCE) || hasRootsOfType(TestSourceKotlinRootType) || (isNewMPPModule && sourceType == SourceType.TEST)
private fun Module.hasRootsOfType(sourceRootType: JpsModuleSourceRootType<*>): Boolean = private fun Module.hasRootsOfType(sourceRootType: JpsModuleSourceRootType<*>): Boolean =
rootManager.contentEntries.any { it.getSourceFolders(sourceRootType).isNotEmpty() } rootManager.contentEntries.any { it.getSourceFolders(sourceRootType).isNotEmpty() }
@@ -322,7 +325,8 @@ open class LibraryInfo(val project: Project, val library: Library) : IdeaModuleI
override fun hashCode(): Int = 43 * library.hashCode() override fun hashCode(): Int = 43 * library.hashCode()
} }
data class LibrarySourceInfo(val project: Project, val library: Library, override val binariesModuleInfo: BinaryModuleInfo) : IdeaModuleInfo, SourceForBinaryModuleInfo { data class LibrarySourceInfo(val project: Project, val library: Library, override val binariesModuleInfo: BinaryModuleInfo) :
IdeaModuleInfo, SourceForBinaryModuleInfo {
override val name: Name = Name.special("<sources for library ${library.name}>") override val name: Name = Name.special("<sources for library ${library.name}>")
@@ -330,7 +334,8 @@ data class LibrarySourceInfo(val project: Project, val library: Library, overrid
LibrarySourceScope( LibrarySourceScope(
project, project,
library library
), project) ), project
)
override fun modulesWhoseInternalsAreVisible(): Collection<ModuleInfo> { override fun modulesWhoseInternalsAreVisible(): Collection<ModuleInfo> {
return createLibraryInfo(project, library) return createLibraryInfo(project, library)
@@ -105,10 +105,10 @@ private sealed class ModuleInfoCollector<out T>(
collectInfosByVirtualFile( collectInfosByVirtualFile(
project, project,
virtualFile, virtualFile,
isLibrarySource, isLibrarySource
{ ) {
return@processor it ?: NotUnderContentRootModuleInfo return@processor it ?: NotUnderContentRootModuleInfo
}) }
} }
) )
@@ -122,8 +122,8 @@ private sealed class ModuleInfoCollector<out T>(
collectInfosByVirtualFile( collectInfosByVirtualFile(
project, project,
virtualFile, virtualFile,
isLibrarySource, isLibrarySource
{ return@processor it }) ) { return@processor it }
} }
) )
@@ -138,8 +138,8 @@ private sealed class ModuleInfoCollector<out T>(
collectInfosByVirtualFile( collectInfosByVirtualFile(
project, project,
virtualFile, virtualFile,
isLibrarySource, isLibrarySource
{ yieldIfNotNull(it) }) ) { yieldIfNotNull(it) }
} }
} }
) )
@@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -103,7 +103,10 @@ val Module.implementedModules: List<Module>
KotlinMultiplatformVersion.M2 -> { KotlinMultiplatformVersion.M2 -> {
rootManager.dependencies.filter { rootManager.dependencies.filter {
// TODO: remove additional android check // TODO: remove additional android check
it.isNewMPPModule && it.platform.isCommon() && it.externalProjectId == externalProjectId && (isAndroidModule() || it.isTestModule == isTestModule) it.isNewMPPModule &&
it.platform.isCommon() &&
it.externalProjectId == externalProjectId &&
(isAndroidModule() || it.isTestModule == isTestModule)
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.caches.resolve package org.jetbrains.kotlin.idea.caches.resolve
@@ -224,7 +213,8 @@ internal class PerFileAnalysisCache(val file: KtFile, componentProvider: Compone
} }
} }
private class MergedDiagnostics(val diagnostics: Collection<Diagnostic>, override val modificationTracker: ModificationTracker) : Diagnostics { private class MergedDiagnostics(val diagnostics: Collection<Diagnostic>, override val modificationTracker: ModificationTracker) :
Diagnostics {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private val elementsCache = DiagnosticsElementsCache(this) { true } private val elementsCache = DiagnosticsElementsCache(this) { true }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.caches.resolve package org.jetbrains.kotlin.idea.caches.resolve
@@ -69,8 +58,9 @@ internal class ProjectResolutionFacade(
} }
} }
val allDependencies = val allDependencies = resolverForProjectDependencies + listOf(
resolverForProjectDependencies + listOf(KotlinCodeBlockModificationListener.getInstance(project).kotlinOutOfCodeBlockTracker) KotlinCodeBlockModificationListener.getInstance(project).kotlinOutOfCodeBlockTracker
)
CachedValueProvider.Result.create(results, allDependencies) CachedValueProvider.Result.create(results, allDependencies)
}, false }, false
) )
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -19,11 +19,11 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
@@ -205,7 +205,8 @@ private fun StringBuilder.appendElement(element: PsiElement) {
val moduleName = ifIndexReady { ModuleUtil.findModuleForFile(virtualFile, element.project)?.name ?: "null" }?.result val moduleName = ifIndexReady { ModuleUtil.findModuleForFile(virtualFile, element.project)?.name ?: "null" }?.result
info( info(
"ideaModule", "ideaModule",
moduleName ?: "<index not ready>") moduleName ?: "<index not ready>"
)
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -34,8 +34,13 @@ fun getResolveScope(file: KtFile): GlobalSearchScope {
} }
return when (file.getModuleInfo()) { return when (file.getModuleInfo()) {
is ModuleSourceInfo -> enlargedSearchScope(KotlinSourceFilterScope.projectSourceAndClassFiles(file.resolveScope, file.project), file) is ModuleSourceInfo -> enlargedSearchScope(
is ScriptModuleInfo -> file.getModuleInfo().dependencies().map { it.contentScope() }.let { GlobalSearchScope.union(it.toTypedArray()) } KotlinSourceFilterScope.projectSourceAndClassFiles(file.resolveScope, file.project),
file
)
is ScriptModuleInfo -> file.getModuleInfo().dependencies().map { it.contentScope() }.let {
GlobalSearchScope.union(it.toTypedArray())
}
else -> GlobalSearchScope.EMPTY_SCOPE else -> GlobalSearchScope.EMPTY_SCOPE
} }
} }
@@ -9,4 +9,5 @@ import com.intellij.psi.impl.PsiModificationTrackerImpl
// BUNCH: 191 // BUNCH: 191
@Suppress("unused") @Suppress("unused")
val PsiModificationTrackerImpl.isEnableLanguageTrackerCompat get() = true val PsiModificationTrackerImpl.isEnableLanguageTrackerCompat
get() = true
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.codeInsight package org.jetbrains.kotlin.idea.codeInsight
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.compiler.configuration package org.jetbrains.kotlin.idea.compiler.configuration
@@ -32,7 +21,8 @@ import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.idea.syncPublisherWithDisposeCheck import org.jetbrains.kotlin.idea.syncPublisherWithDisposeCheck
import kotlin.reflect.KClass import kotlin.reflect.KClass
abstract class BaseKotlinCompilerSettings<T : Freezable> protected constructor(private val project: Project) : PersistentStateComponent<Element>, Cloneable { abstract class BaseKotlinCompilerSettings<T : Freezable> protected constructor(private val project: Project) :
PersistentStateComponent<Element>, Cloneable {
// Based on com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters // Based on com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters
private object DefaultValuesFilter : SerializationFilterBase() { private object DefaultValuesFilter : SerializationFilterBase() {
private val defaultBeans = THashMap<Class<*>, Any>() private val defaultBeans = THashMap<Class<*>, Any>()
@@ -1,24 +1,14 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.compiler.configuration package org.jetbrains.kotlin.idea.compiler.configuration
import com.intellij.openapi.components.* import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.components.State
import com.intellij.openapi.components.Storage
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.util.text.VersionComparatorUtil
import org.jdom.Element import org.jdom.Element
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.setApiVersionToLanguageVersionIfNeeded import org.jetbrains.kotlin.cli.common.arguments.setApiVersionToLanguageVersionIfNeeded
@@ -1,22 +1,13 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.compiler.configuration package org.jetbrains.kotlin.idea.compiler.configuration
import com.intellij.openapi.components.* import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.components.State
import com.intellij.openapi.components.Storage
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.config.CompilerSettings import org.jetbrains.kotlin.config.CompilerSettings
import org.jetbrains.kotlin.config.SettingConstants import org.jetbrains.kotlin.config.SettingConstants
@@ -27,7 +18,6 @@ class KotlinCompilerSettings(project: Project) : BaseKotlinCompilerSettings<Comp
override fun createSettings() = CompilerSettings() override fun createSettings() = CompilerSettings()
companion object { companion object {
fun getInstance(project: Project) = ServiceManager.getService(project, KotlinCompilerSettings::class.java)!! fun getInstance(project: Project) = ServiceManager.getService(project, KotlinCompilerSettings::class.java)!!
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler package org.jetbrains.kotlin.idea.decompiler
@@ -41,8 +30,7 @@ class KotlinDecompiledFileViewProvider(
DebugUtil.startPsiModification("Invalidating throw-away copy of file that was used for getting text") DebugUtil.startPsiModification("Invalidating throw-away copy of file that was used for getting text")
try { try {
(psiFile as? PsiFileImpl)?.markInvalidated() (psiFile as? PsiFileImpl)?.markInvalidated()
} } finally {
finally {
DebugUtil.finishPsiModification() DebugUtil.finishPsiModification()
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler package org.jetbrains.kotlin.idea.decompiler
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.classFile package org.jetbrains.kotlin.idea.decompiler.classFile
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.classFile package org.jetbrains.kotlin.idea.decompiler.classFile
@@ -77,9 +66,10 @@ fun buildDecompiledTextForClassFile(
return createIncompatibleAbiVersionDecompiledText(JvmMetadataVersion.INSTANCE, classHeader.metadataVersion) return createIncompatibleAbiVersionDecompiledText(JvmMetadataVersion.INSTANCE, classHeader.metadataVersion)
} }
fun buildText(declarations: List<DeclarationDescriptor>) = fun buildText(declarations: List<DeclarationDescriptor>) = buildDecompiledText(
buildDecompiledText(classHeader.packageName?.let(::FqName) ?: classId.packageFqName, classHeader.packageName?.let(::FqName) ?: classId.packageFqName,
declarations, decompilerRendererForClassFiles, listOf(ByDescriptorIndexer, BySignatureIndexer)) declarations, decompilerRendererForClassFiles, listOf(ByDescriptorIndexer, BySignatureIndexer)
)
return when (classHeader.kind) { return when (classHeader.kind) {
KotlinClassHeader.Kind.FILE_FACADE -> KotlinClassHeader.Kind.FILE_FACADE ->
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.classFile package org.jetbrains.kotlin.idea.decompiler.classFile
@@ -142,8 +131,7 @@ class AnnotationLoaderForClassFileStubBuilder(
return null return null
} }
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId = override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId = nameResolver.getClassId(proto.id)
nameResolver.getClassId(proto.id)
override fun loadConstant(desc: String, initializer: Any) = null override fun loadConstant(desc: String, initializer: Any) = null
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.common package org.jetbrains.kotlin.idea.decompiler.common
@@ -90,5 +79,6 @@ class AnnotationLoaderForStubBuilderImpl(
container: ProtoContainer, container: ProtoContainer,
proto: ProtoBuf.Property, proto: ProtoBuf.Property,
expectedType: KotlinType expectedType: KotlinType
) {} ) {
}
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.common package org.jetbrains.kotlin.idea.decompiler.common
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.common package org.jetbrains.kotlin.idea.decompiler.common
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.common package org.jetbrains.kotlin.idea.decompiler.common
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.common package org.jetbrains.kotlin.idea.decompiler.common
@@ -20,21 +9,19 @@ import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledTextIndex import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledTextIndex
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
private val FILE_ABI_VERSION_MARKER: String = "FILE_ABI" private const val FILE_ABI_VERSION_MARKER: String = "FILE_ABI"
private val CURRENT_ABI_VERSION_MARKER: String = "CURRENT_ABI" private const val CURRENT_ABI_VERSION_MARKER: String = "CURRENT_ABI"
val INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT: String = "// This class file was compiled with different version of Kotlin compiler and can't be decompiled." val INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT: String =
private val INCOMPATIBLE_ABI_VERSION_COMMENT: String = "// This class file was compiled with different version of Kotlin compiler and can't be decompiled."
"$INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT\n" +
private val INCOMPATIBLE_ABI_VERSION_COMMENT: String = "$INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT\n" +
"//\n" + "//\n" +
"// Current compiler ABI version is $CURRENT_ABI_VERSION_MARKER\n" + "// Current compiler ABI version is $CURRENT_ABI_VERSION_MARKER\n" +
"// File ABI version is $FILE_ABI_VERSION_MARKER" "// File ABI version is $FILE_ABI_VERSION_MARKER"
fun <V : BinaryVersion> createIncompatibleAbiVersionDecompiledText(expectedVersion: V, actualVersion: V): DecompiledText { fun <V : BinaryVersion> createIncompatibleAbiVersionDecompiledText(expectedVersion: V, actualVersion: V): DecompiledText = DecompiledText(
return DecompiledText( INCOMPATIBLE_ABI_VERSION_COMMENT.replace(CURRENT_ABI_VERSION_MARKER, expectedVersion.toString())
INCOMPATIBLE_ABI_VERSION_COMMENT
.replace(CURRENT_ABI_VERSION_MARKER, expectedVersion.toString())
.replace(FILE_ABI_VERSION_MARKER, actualVersion.toString()), .replace(FILE_ABI_VERSION_MARKER, actualVersion.toString()),
DecompiledTextIndex.Empty DecompiledTextIndex.Empty
) )
}
@@ -1,29 +1,15 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.navigation package org.jetbrains.kotlin.idea.decompiler.navigation
import org.jetbrains.kotlin.psi.KotlinDeclarationNavigationPolicy import org.jetbrains.kotlin.psi.KotlinDeclarationNavigationPolicy
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import com.intellij.openapi.project.DumbService
class KotlinDeclarationNavigationPolicyImpl : KotlinDeclarationNavigationPolicy { class KotlinDeclarationNavigationPolicyImpl : KotlinDeclarationNavigationPolicy {
override fun getOriginalElement(declaration: KtDeclaration) = override fun getOriginalElement(declaration: KtDeclaration) = SourceNavigationHelper.getOriginalElement(declaration)
SourceNavigationHelper.getOriginalElement(declaration)
override fun getNavigationElement(declaration: KtDeclaration) = override fun getNavigationElement(declaration: KtDeclaration) = SourceNavigationHelper.getNavigationElement(declaration)
SourceNavigationHelper.getNavigationElement(declaration)
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.navigation package org.jetbrains.kotlin.idea.decompiler.navigation
@@ -78,20 +67,16 @@ private fun findInScope(referencedDescriptor: DeclarationDescriptor, scope: Glob
it?.containingFile as? KtDecompiledFile it?.containingFile as? KtDecompiledFile
} }
return decompiledFiles.asSequence().mapNotNull { return decompiledFiles.asSequence().mapNotNull { file ->
file ->
ByDescriptorIndexer.getDeclarationForDescriptor(referencedDescriptor, file) ByDescriptorIndexer.getDeclarationForDescriptor(referencedDescriptor, file)
}.firstOrNull() }.firstOrNull()
} }
private fun isLocal(descriptor: DeclarationDescriptor): Boolean { private fun isLocal(descriptor: DeclarationDescriptor): Boolean = if (descriptor is ParameterDescriptor) {
return if (descriptor is ParameterDescriptor) {
isLocal(descriptor.containingDeclaration) isLocal(descriptor.containingDeclaration)
} } else {
else {
DescriptorUtils.isLocal(descriptor) DescriptorUtils.isLocal(descriptor)
} }
}
private fun findCandidateDeclarationsInIndex( private fun findCandidateDeclarationsInIndex(
@@ -143,8 +128,10 @@ object ByDescriptorIndexer : DecompiledTextIndexer<String> {
val callable = original.containingDeclaration val callable = original.containingDeclaration
val callableDeclaration = getDeclarationForDescriptor(callable, file) as? KtCallableDeclaration ?: return null val callableDeclaration = getDeclarationForDescriptor(callable, file) as? KtCallableDeclaration ?: return null
if (original.index >= callableDeclaration.valueParameters.size) { if (original.index >= callableDeclaration.valueParameters.size) {
LOG.error("Parameter count mismatch for ${DescriptorRenderer.DEBUG_TEXT.render(callable)}[${original.index}] vs " + LOG.error(
callableDeclaration.valueParameterList?.text) "Parameter count mismatch for ${DescriptorRenderer.DEBUG_TEXT.render(callable)}[${original.index}] vs " +
callableDeclaration.valueParameterList?.text
)
return null return null
} }
return callableDeclaration.valueParameters[original.index] return callableDeclaration.valueParameters[original.index]
@@ -158,8 +145,12 @@ object ByDescriptorIndexer : DecompiledTextIndexer<String> {
val descriptorKey = original.toStringKey() val descriptorKey = original.toStringKey()
if (!file.isContentsLoaded && original is MemberDescriptor) { if (!file.isContentsLoaded && original is MemberDescriptor) {
val hasDeclarationByKey = file.hasDeclarationWithKey(this, descriptorKey) || val hasDeclarationByKey = file.hasDeclarationWithKey(this, descriptorKey) || (getBuiltinsDescriptorKey(descriptor)?.let {
(getBuiltinsDescriptorKey(descriptor)?.let { file.hasDeclarationWithKey(this, it) } ?: false) file.hasDeclarationWithKey(
this,
it
)
} ?: false)
if (hasDeclarationByKey) { if (hasDeclarationByKey) {
val declarationContainer: KtDeclarationContainer? = when { val declarationContainer: KtDeclarationContainer? = when {
DescriptorUtils.isTopLevelDeclaration(original) -> file DescriptorUtils.isTopLevelDeclaration(original) -> file
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.stubBuilder package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -44,7 +33,8 @@ fun createDeclarationsStubs(
packageProto: ProtoBuf.Package packageProto: ProtoBuf.Package
) { ) {
createDeclarationsStubs( createDeclarationsStubs(
parentStub, outerContext, protoContainer, packageProto.functionList, packageProto.propertyList, packageProto.typeAliasList) parentStub, outerContext, protoContainer, packageProto.functionList, packageProto.propertyList, packageProto.typeAliasList
)
} }
fun createDeclarationsStubs( fun createDeclarationsStubs(
@@ -198,11 +188,9 @@ private class PropertyClsStubBuilder(
get() = propertyProto.receiverType(c.typeTable) get() = propertyProto.receiverType(c.typeTable)
override val receiverAnnotations: List<ClassIdWithTarget> override val receiverAnnotations: List<ClassIdWithTarget>
get() { get() = c.components.annotationLoader
return c.components.annotationLoader
.loadExtensionReceiverParameterAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY_GETTER) .loadExtensionReceiverParameterAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY_GETTER)
.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) } .map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
}
override val returnType: ProtoBuf.Type? override val returnType: ProtoBuf.Type?
get() = propertyProto.returnType(c.typeTable) get() = propertyProto.returnType(c.typeTable)
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.stubBuilder package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -75,16 +64,17 @@ private class ClassClsStubBuilder(
private val supertypeIds = run { private val supertypeIds = run {
val supertypeIds = classProto.supertypes(c.typeTable).map { c.nameResolver.getClassId(it.className) } val supertypeIds = classProto.supertypes(c.typeTable).map { c.nameResolver.getClassId(it.className) }
//empty supertype list if single supertype is Any //empty supertype list if single supertype is Any
if (supertypeIds.singleOrNull()?.let { KotlinBuiltIns.FQ_NAMES.any == it.asSingleFqName().toUnsafe() } ?: false) { if (supertypeIds.singleOrNull()?.let { KotlinBuiltIns.FQ_NAMES.any == it.asSingleFqName().toUnsafe() } == true) {
listOf() listOf()
} } else {
else {
supertypeIds supertypeIds
} }
} }
private val companionObjectName = private val companionObjectName = if (classProto.hasCompanionObjectName())
if (classProto.hasCompanionObjectName()) c.nameResolver.getName(classProto.companionObjectName) else null c.nameResolver.getName(classProto.companionObjectName)
else
null
private val classOrObjectStub = createClassOrObjectStubAndModifierListStub() private val classOrObjectStub = createClassOrObjectStubAndModifierListStub()
@@ -169,8 +159,7 @@ private class ClassClsStubBuilder(
// if single supertype is any then no delegation specifier list is needed // if single supertype is any then no delegation specifier list is needed
if (supertypeIds.isEmpty()) return if (supertypeIds.isEmpty()) return
val delegationSpecifierListStub = val delegationSpecifierListStub = KotlinPlaceHolderStubImpl<KtSuperTypeList>(classOrObjectStub, KtStubElementTypes.SUPER_TYPE_LIST)
KotlinPlaceHolderStubImpl<KtSuperTypeList>(classOrObjectStub, KtStubElementTypes.SUPER_TYPE_LIST)
classProto.supertypes(c.typeTable).forEach { type -> classProto.supertypes(c.typeTable).forEach { type ->
val superClassStub = KotlinPlaceHolderStubImpl<KtSuperTypeEntry>( val superClassStub = KotlinPlaceHolderStubImpl<KtSuperTypeEntry>(
@@ -228,7 +217,8 @@ private class ClassClsStubBuilder(
} }
createDeclarationsStubs( createDeclarationsStubs(
classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList, classProto.typeAliasList) classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList, classProto.typeAliasList
)
} }
private fun isClass(): Boolean { private fun isClass(): Boolean {
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.stubBuilder package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -40,16 +29,15 @@ class ClsStubBuilderComponents(
nameResolver: NameResolver, nameResolver: NameResolver,
packageFqName: FqName, packageFqName: FqName,
typeTable: TypeTable typeTable: TypeTable
): ClsStubBuilderContext { ): ClsStubBuilderContext =
return ClsStubBuilderContext(this, nameResolver, packageFqName, EmptyTypeParameters, typeTable, protoContainer = null) ClsStubBuilderContext(this, nameResolver, packageFqName, EmptyTypeParameters, typeTable, protoContainer = null)
}
} }
interface TypeParameters { interface TypeParameters {
operator fun get(id: Int): Name operator fun get(id: Int): Name
fun child(nameResolver: NameResolver, innerTypeParameters: List<ProtoBuf.TypeParameter>) fun child(nameResolver: NameResolver, innerTypeParameters: List<ProtoBuf.TypeParameter>) =
= TypeParametersImpl(nameResolver, innerTypeParameters, parent = this) TypeParametersImpl(nameResolver, innerTypeParameters, parent = this)
} }
object EmptyTypeParameters : TypeParameters { object EmptyTypeParameters : TypeParameters {
@@ -81,8 +69,7 @@ internal fun ClsStubBuilderContext.child(
nameResolver: NameResolver = this.nameResolver, nameResolver: NameResolver = this.nameResolver,
typeTable: TypeTable = this.typeTable, typeTable: TypeTable = this.typeTable,
protoContainer: ProtoContainer.Class? = this.protoContainer protoContainer: ProtoContainer.Class? = this.protoContainer
): ClsStubBuilderContext { ): ClsStubBuilderContext = ClsStubBuilderContext(
return ClsStubBuilderContext(
this.components, this.components,
nameResolver, nameResolver,
if (name != null) this.containerFqName.child(name) else this.containerFqName, if (name != null) this.containerFqName.child(name) else this.containerFqName,
@@ -90,4 +77,3 @@ internal fun ClsStubBuilderContext.child(
typeTable, typeTable,
protoContainer protoContainer
) )
}
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -36,7 +36,11 @@ import java.util.*
private val ANNOTATIONS_NOT_LOADED_FOR_TYPES = setOf(KotlinBuiltIns.FQ_NAMES.parameterName) private val ANNOTATIONS_NOT_LOADED_FOR_TYPES = setOf(KotlinBuiltIns.FQ_NAMES.parameterName)
class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
fun createTypeReferenceStub(parent: StubElement<out PsiElement>, type: Type, additionalAnnotations: () -> List<ClassIdWithTarget> = { emptyList() }) { fun createTypeReferenceStub(
parent: StubElement<out PsiElement>,
type: Type,
additionalAnnotations: () -> List<ClassIdWithTarget> = { emptyList() }
) {
val abbreviatedType = type.abbreviatedType(c.typeTable) val abbreviatedType = type.abbreviatedType(c.typeTable)
if (abbreviatedType != null) { if (abbreviatedType != null) {
return createTypeReferenceStub(parent, abbreviatedType, additionalAnnotations) return createTypeReferenceStub(parent, abbreviatedType, additionalAnnotations)
@@ -64,9 +68,10 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
} }
} }
private fun nullableTypeParent(parent: KotlinStubBaseImpl<*>, type: Type): KotlinStubBaseImpl<*> = private fun nullableTypeParent(parent: KotlinStubBaseImpl<*>, type: Type): KotlinStubBaseImpl<*> = if (type.nullable)
if (type.nullable) KotlinPlaceHolderStubImpl<KtNullableType>(parent, KtStubElementTypes.NULLABLE_TYPE) KotlinPlaceHolderStubImpl<KtNullableType>(parent, KtStubElementTypes.NULLABLE_TYPE)
else parent else
parent
private fun createTypeParameterStub(parent: KotlinStubBaseImpl<*>, type: Type, name: Name, annotations: List<ClassIdWithTarget>) { private fun createTypeParameterStub(parent: KotlinStubBaseImpl<*>, type: Type, name: Name, annotations: List<ClassIdWithTarget>) {
createTypeAnnotationStubs(parent, type, annotations) createTypeAnnotationStubs(parent, type, annotations)
@@ -88,11 +93,11 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
} }
val classId = c.nameResolver.getClassId(if (type.hasClassName()) type.className else type.typeAliasName) val classId = c.nameResolver.getClassId(if (type.hasClassName()) type.className else type.typeAliasName)
val shouldBuildAsFunctionType = isBuiltinFunctionClass(classId) val shouldBuildAsFunctionType = isBuiltinFunctionClass(classId) && type.argumentList.none { it.projection == Projection.STAR }
&& type.argumentList.none { it.projection == Projection.STAR }
if (shouldBuildAsFunctionType) { if (shouldBuildAsFunctionType) {
val (extensionAnnotations, notExtensionAnnotations) = val (extensionAnnotations, notExtensionAnnotations) = annotations.partition {
annotations.partition { it.classId.asSingleFqName() == KotlinBuiltIns.FQ_NAMES.extensionFunctionType } it.classId.asSingleFqName() == KotlinBuiltIns.FQ_NAMES.extensionFunctionType
}
val isExtension = extensionAnnotations.isNotEmpty() val isExtension = extensionAnnotations.isNotEmpty()
val isSuspend = Flags.SUSPEND_TYPE.get(type.flags) val isSuspend = Flags.SUSPEND_TYPE.get(type.flags)
@@ -101,8 +106,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
val wrapper = nullableTypeParent(parent, type) val wrapper = nullableTypeParent(parent, type)
createTypeAnnotationStubs(wrapper, type, notExtensionAnnotations) createTypeAnnotationStubs(wrapper, type, notExtensionAnnotations)
wrapper wrapper
} } else {
else {
createTypeAnnotationStubs(parent, type, notExtensionAnnotations) createTypeAnnotationStubs(parent, type, notExtensionAnnotations)
nullableTypeParent(parent, type) nullableTypeParent(parent, type)
} }
@@ -116,8 +120,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
val outerTypeChain = generateSequence(type) { it.outerType(c.typeTable) }.toList() val outerTypeChain = generateSequence(type) { it.outerType(c.typeTable) }.toList()
createStubForTypeName(classId, nullableTypeParent(parent, type)) { createStubForTypeName(classId, nullableTypeParent(parent, type)) { userTypeStub, index ->
userTypeStub, index ->
outerTypeChain.getOrNull(index)?.let { createTypeArgumentListStub(userTypeStub, it.argumentList) } outerTypeChain.getOrNull(index)?.let { createTypeArgumentListStub(userTypeStub, it.argumentList) }
} }
} }
@@ -165,19 +168,24 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
Projection.STAR -> KtProjectionKind.STAR Projection.STAR -> KtProjectionKind.STAR
} }
private fun createFunctionTypeStub(parent: StubElement<out PsiElement>, type: Type, isExtensionFunctionType: Boolean, isSuspend: Boolean) { private fun createFunctionTypeStub(
parent: StubElement<out PsiElement>,
type: Type,
isExtensionFunctionType: Boolean,
isSuspend: Boolean
) {
val typeArgumentList = type.argumentList val typeArgumentList = type.argumentList
val functionType = KotlinPlaceHolderStubImpl<KtFunctionType>(parent, KtStubElementTypes.FUNCTION_TYPE) val functionType = KotlinPlaceHolderStubImpl<KtFunctionType>(parent, KtStubElementTypes.FUNCTION_TYPE)
if (isExtensionFunctionType) { if (isExtensionFunctionType) {
val functionTypeReceiverStub val functionTypeReceiverStub =
= KotlinPlaceHolderStubImpl<KtFunctionTypeReceiver>(functionType, KtStubElementTypes.FUNCTION_TYPE_RECEIVER) KotlinPlaceHolderStubImpl<KtFunctionTypeReceiver>(functionType, KtStubElementTypes.FUNCTION_TYPE_RECEIVER)
val receiverTypeProto = typeArgumentList.first().type(c.typeTable)!! val receiverTypeProto = typeArgumentList.first().type(c.typeTable)!!
createTypeReferenceStub(functionTypeReceiverStub, receiverTypeProto) createTypeReferenceStub(functionTypeReceiverStub, receiverTypeProto)
} }
val parameterList = KotlinPlaceHolderStubImpl<KtParameterList>(functionType, KtStubElementTypes.VALUE_PARAMETER_LIST) val parameterList = KotlinPlaceHolderStubImpl<KtParameterList>(functionType, KtStubElementTypes.VALUE_PARAMETER_LIST)
val typeArgumentsWithoutReceiverAndReturnType val typeArgumentsWithoutReceiverAndReturnType =
= typeArgumentList.subList(if (isExtensionFunctionType) 1 else 0, typeArgumentList.size - 1) typeArgumentList.subList(if (isExtensionFunctionType) 1 else 0, typeArgumentList.size - 1)
var suspendParameterType: Type? = null var suspendParameterType: Type? = null
for ((index, argument) in typeArgumentsWithoutReceiverAndReturnType.withIndex()) { for ((index, argument) in typeArgumentsWithoutReceiverAndReturnType.withIndex()) {
@@ -207,8 +215,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
if (suspendParameterType == null) { if (suspendParameterType == null) {
val returnType = typeArgumentList.last().type(c.typeTable)!! val returnType = typeArgumentList.last().type(c.typeTable)!!
createTypeReferenceStub(functionType, returnType) createTypeReferenceStub(functionType, returnType)
} } else {
else {
val continuationArgumentType = suspendParameterType.getArgument(0).type(c.typeTable)!! val continuationArgumentType = suspendParameterType.getArgument(0).type(c.typeTable)!!
createTypeReferenceStub(functionType, continuationArgumentType) createTypeReferenceStub(functionType, continuationArgumentType)
} }
@@ -235,9 +242,15 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
val typeProto = varargElementType ?: valueParameterProto.type(c.typeTable) val typeProto = varargElementType ?: valueParameterProto.type(c.typeTable)
val modifiers = arrayListOf<KtModifierKeywordToken>() val modifiers = arrayListOf<KtModifierKeywordToken>()
if (varargElementType != null) { modifiers.add(KtTokens.VARARG_KEYWORD) } if (varargElementType != null) {
if (Flags.IS_CROSSINLINE.get(valueParameterProto.flags)) { modifiers.add(KtTokens.CROSSINLINE_KEYWORD) } modifiers.add(KtTokens.VARARG_KEYWORD)
if (Flags.IS_NOINLINE.get(valueParameterProto.flags)) { modifiers.add(KtTokens.NOINLINE_KEYWORD) } }
if (Flags.IS_CROSSINLINE.get(valueParameterProto.flags)) {
modifiers.add(KtTokens.CROSSINLINE_KEYWORD)
}
if (Flags.IS_NOINLINE.get(valueParameterProto.flags)) {
modifiers.add(KtTokens.NOINLINE_KEYWORD)
}
val modifierList = createModifierListStub(parameterStub, modifiers) val modifierList = createModifierListStub(parameterStub, modifiers)
val parameterAnnotations = c.components.annotationLoader.loadValueParameterAnnotations( val parameterAnnotations = c.components.annotationLoader.loadValueParameterAnnotations(
@@ -303,8 +316,10 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
when (typeParameterProto.variance) { when (typeParameterProto.variance) {
Variance.IN -> modifiers.add(KtTokens.IN_KEYWORD) Variance.IN -> modifiers.add(KtTokens.IN_KEYWORD)
Variance.OUT -> modifiers.add(KtTokens.OUT_KEYWORD) Variance.OUT -> modifiers.add(KtTokens.OUT_KEYWORD)
Variance.INV -> { /* do nothing */ } Variance.INV -> { /* do nothing */
null -> { /* do nothing */ } }
null -> { /* do nothing */
}
} }
if (typeParameterProto.reified) { if (typeParameterProto.reified) {
modifiers.add(KtTokens.REIFIED_KEYWORD) modifiers.add(KtTokens.REIFIED_KEYWORD)
@@ -316,7 +331,8 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
if (annotations.isNotEmpty()) { if (annotations.isNotEmpty()) {
createAnnotationStubs( createAnnotationStubs(
annotations, annotations,
modifierList ?: createEmptyModifierListStub(typeParameterStub)) modifierList ?: createEmptyModifierListStub(typeParameterStub)
)
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.stubBuilder package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -62,7 +51,8 @@ fun createPackageFacadeStub(
val fileStub = KotlinFileStubForIde.forFile(packageFqName, isScript = false) val fileStub = KotlinFileStubForIde.forFile(packageFqName, isScript = false)
setupFileStub(fileStub, packageFqName) setupFileStub(fileStub, packageFqName)
createDeclarationsStubs( createDeclarationsStubs(
fileStub, c, ProtoContainer.Package(packageFqName, c.nameResolver, c.typeTable, source = null), packageProto) fileStub, c, ProtoContainer.Package(packageFqName, c.nameResolver, c.typeTable, source = null), packageProto
)
return fileStub return fileStub
} }
@@ -149,9 +139,9 @@ fun createStubForTypeName(
): KotlinUserTypeStub { ): KotlinUserTypeStub {
val substituteWithAny = typeClassId.isLocal val substituteWithAny = typeClassId.isLocal
val fqName = val fqName = if (substituteWithAny) KotlinBuiltIns.FQ_NAMES.any
if (substituteWithAny) KotlinBuiltIns.FQ_NAMES.any
else typeClassId.asSingleFqName().toUnsafe() else typeClassId.asSingleFqName().toUnsafe()
val segments = fqName.pathSegments().asReversed() val segments = fqName.pathSegments().asReversed()
assert(segments.isNotEmpty()) assert(segments.isNotEmpty())
@@ -225,20 +215,19 @@ fun createTargetedAnnotationStubs(
if (target != null) { if (target != null) {
KotlinAnnotationUseSiteTargetStubImpl(annotationEntryStubImpl, StringRef.fromString(target.name)!!) KotlinAnnotationUseSiteTargetStubImpl(annotationEntryStubImpl, StringRef.fromString(target.name)!!)
} }
val constructorCallee = KotlinPlaceHolderStubImpl<KtConstructorCalleeExpression>(annotationEntryStubImpl, KtStubElementTypes.CONSTRUCTOR_CALLEE) val constructorCallee =
KotlinPlaceHolderStubImpl<KtConstructorCalleeExpression>(annotationEntryStubImpl, KtStubElementTypes.CONSTRUCTOR_CALLEE)
val typeReference = KotlinPlaceHolderStubImpl<KtTypeReference>(constructorCallee, KtStubElementTypes.TYPE_REFERENCE) val typeReference = KotlinPlaceHolderStubImpl<KtTypeReference>(constructorCallee, KtStubElementTypes.TYPE_REFERENCE)
createStubForTypeName(annotationClassId, typeReference) createStubForTypeName(annotationClassId, typeReference)
} }
} }
val MessageLite.annotatedCallableKind: AnnotatedCallableKind val MessageLite.annotatedCallableKind: AnnotatedCallableKind
get() { get() = when (this) {
return when (this) {
is ProtoBuf.Property -> AnnotatedCallableKind.PROPERTY is ProtoBuf.Property -> AnnotatedCallableKind.PROPERTY
is ProtoBuf.Function, is ProtoBuf.Constructor -> AnnotatedCallableKind.FUNCTION is ProtoBuf.Function, is ProtoBuf.Constructor -> AnnotatedCallableKind.FUNCTION
else -> throw IllegalStateException("Unsupported message: $this") else -> throw IllegalStateException("Unsupported message: $this")
} }
}
fun Name.ref() = StringRef.fromString(this.asString())!! fun Name.ref() = StringRef.fromString(this.asString())!!
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags package org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.stubBuilder package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -21,12 +10,12 @@ import com.intellij.psi.stubs.StubElement
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags.VISIBILITY import org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags.VISIBILITY
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.deserialization.underlyingType
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.stubs.impl.KotlinTypeAliasStubImpl import org.jetbrains.kotlin.psi.stubs.impl.KotlinTypeAliasStubImpl
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.getClassId import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.deserialization.getName import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.metadata.deserialization.underlyingType
fun createTypeAliasStub( fun createTypeAliasStub(
parent: StubElement<out PsiElement>, parent: StubElement<out PsiElement>,
@@ -41,10 +30,10 @@ fun createTypeAliasStub(
is ProtoContainer.Package -> ClassId.topLevel(protoContainer.fqName.child(shortName)) is ProtoContainer.Package -> ClassId.topLevel(protoContainer.fqName.child(shortName))
} }
val typeAlias = val typeAlias = KotlinTypeAliasStubImpl(
KotlinTypeAliasStubImpl(
parent, classId.shortClassName.ref(), classId.asSingleFqName().ref(), parent, classId.shortClassName.ref(), classId.asSingleFqName().ref(),
isTopLevel = !classId.isNestedClass) isTopLevel = !classId.isNestedClass
)
val modifierList = createModifierListStubForDeclaration(typeAlias, typeAliasProto.flags, arrayListOf(VISIBILITY), listOf()) val modifierList = createModifierListStubForDeclaration(typeAlias, typeAliasProto.flags, arrayListOf(VISIBILITY), listOf())
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.textBuilder package org.jetbrains.kotlin.idea.decompiler.textBuilder
@@ -33,16 +22,14 @@ class DecompiledTextIndex(private val indexers: Collection<DecompiledTextIndexer
fun addToIndex(descriptor: DeclarationDescriptor, textRange: TextRange) { fun addToIndex(descriptor: DeclarationDescriptor, textRange: TextRange) {
indexers.forEach { mapper -> indexers.forEach { mapper ->
val correspondingMap = indexerToMap[mapper]!! val correspondingMap = indexerToMap.getValue(mapper)
mapper.indexDescriptor(descriptor).forEach { key -> mapper.indexDescriptor(descriptor).forEach { key ->
correspondingMap[key] = textRange correspondingMap[key] = textRange
} }
} }
} }
fun <T: Any> getRange(mapper: DecompiledTextIndexer<T>, key: T): TextRange? { fun <T : Any> getRange(mapper: DecompiledTextIndexer<T>, key: T): TextRange? = indexerToMap[mapper]?.get(key)
return indexerToMap[mapper]?.get(key)
}
companion object { companion object {
val Empty = DecompiledTextIndex(listOf()) val Empty = DecompiledTextIndex(listOf())
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.textBuilder package org.jetbrains.kotlin.idea.decompiler.textBuilder
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.textBuilder package org.jetbrains.kotlin.idea.decompiler.textBuilder
@@ -29,10 +18,10 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
import org.jetbrains.kotlin.types.isFlexible import org.jetbrains.kotlin.types.isFlexible
private val DECOMPILED_CODE_COMMENT = "/* compiled code */" private const val DECOMPILED_CODE_COMMENT = "/* compiled code */"
private val DECOMPILED_COMMENT_FOR_PARAMETER = "/* = compiled code */" private const val DECOMPILED_COMMENT_FOR_PARAMETER = "/* = compiled code */"
private val FLEXIBLE_TYPE_COMMENT = "/* platform type */" private const val FLEXIBLE_TYPE_COMMENT = "/* platform type */"
private val DECOMPILED_CONTRACT_STUB = "contract { /* compiled contract */ }" private const val DECOMPILED_CONTRACT_STUB = "contract { /* compiled contract */ }"
fun DescriptorRendererOptions.defaultDecompilerRendererOptions() { fun DescriptorRendererOptions.defaultDecompilerRendererOptions() {
withDefinedIn = false withDefinedIn = false
@@ -75,8 +64,7 @@ fun buildDecompiledText(
} }
builder.append(descriptor.name.asString()) builder.append(descriptor.name.asString())
builder.append(if (lastEnumEntry!!) ";" else ",") builder.append(if (lastEnumEntry!!) ";" else ",")
} } else {
else {
builder.append(descriptorRenderer.render(descriptor).replace("= ...", DECOMPILED_COMMENT_FOR_PARAMETER)) builder.append(descriptorRenderer.render(descriptor).replace("= ...", DECOMPILED_COMMENT_FOR_PARAMETER))
} }
var endOffset = builder.length var endOffset = builder.length
@@ -98,25 +86,22 @@ fun buildDecompiledText(
} }
append(DECOMPILED_CODE_COMMENT).append(" }") append(DECOMPILED_CODE_COMMENT).append(" }")
} }
} } else {
else {
// descriptor instanceof PropertyDescriptor // descriptor instanceof PropertyDescriptor
builder.append(" ").append(DECOMPILED_CODE_COMMENT) builder.append(" ").append(DECOMPILED_CODE_COMMENT)
} }
endOffset = builder.length endOffset = builder.length
} }
} } else if (descriptor is ClassDescriptor && !isEnumEntry(descriptor)) {
else if (descriptor is ClassDescriptor && !isEnumEntry(descriptor)) {
builder.append(" {\n") builder.append(" {\n")
val subindent = indent + " " val subindent = "$indent "
var firstPassed = false var firstPassed = false
fun newlineExceptFirst() { fun newlineExceptFirst() {
if (firstPassed) { if (firstPassed) {
builder.append("\n") builder.append("\n")
} } else {
else {
firstPassed = true firstPassed = true
} }
} }
@@ -147,7 +132,8 @@ fun buildDecompiledText(
if (member is CallableMemberDescriptor if (member is CallableMemberDescriptor
&& member.kind != CallableMemberDescriptor.Kind.DECLARATION && member.kind != CallableMemberDescriptor.Kind.DECLARATION
//TODO: not synthesized and component like //TODO: not synthesized and component like
&& !DataClassDescriptorResolver.isComponentLike(member.name)) { && !DataClassDescriptorResolver.isComponentLike(member.name)
) {
continue continue
} }
newlineExceptFirst() newlineExceptFirst()
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.facet package org.jetbrains.kotlin.idea.facet
@@ -20,11 +9,13 @@ import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.module.Module import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.ModuleRootModel import com.intellij.openapi.roots.ModuleRootModel
import com.intellij.util.text.VersionComparatorUtil import com.intellij.util.text.VersionComparatorUtil
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.platform.IdePlatformKind import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider
import org.jetbrains.kotlin.platform.orDefault import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.VersionView import org.jetbrains.kotlin.config.VersionView
import org.jetbrains.kotlin.platform.IdePlatformKind
import org.jetbrains.kotlin.platform.idePlatformKind import org.jetbrains.kotlin.platform.idePlatformKind
import org.jetbrains.kotlin.platform.orDefault
interface KotlinVersionInfoProvider { interface KotlinVersionInfoProvider {
companion object { companion object {
@@ -43,12 +34,10 @@ fun getRuntimeLibraryVersions(
module: Module, module: Module,
rootModel: ModuleRootModel?, rootModel: ModuleRootModel?,
platformKind: IdePlatformKind<*> platformKind: IdePlatformKind<*>
): Collection<String> { ): Collection<String> = KotlinVersionInfoProvider.EP_NAME
return KotlinVersionInfoProvider.EP_NAME
.extensions .extensions
.map { it.getLibraryVersions(module, platformKind, rootModel) } .map { it.getLibraryVersions(module, platformKind, rootModel) }
.firstOrNull { it.isNotEmpty() } ?: emptyList() .firstOrNull { it.isNotEmpty() } ?: emptyList()
}
fun getLibraryLanguageLevel( fun getLibraryLanguageLevel(
module: Module, module: Module,
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.findUsages package org.jetbrains.kotlin.idea.findUsages
@@ -44,15 +33,11 @@ object UsageTypeUtils {
val context = refExpr.analyze(BodyResolveMode.PARTIAL) val context = refExpr.analyze(BodyResolveMode.PARTIAL)
fun getCommonUsageType(): UsageTypeEnum? { fun getCommonUsageType(): UsageTypeEnum? = when {
return when { refExpr.getNonStrictParentOfType<KtImportDirective>() != null -> CLASS_IMPORT
refExpr.getNonStrictParentOfType<KtImportDirective>() != null -> refExpr.getParentOfTypeAndBranch<KtCallableReferenceExpression>() { callableReference } != null -> CALLABLE_REFERENCE
CLASS_IMPORT
refExpr.getParentOfTypeAndBranch<KtCallableReferenceExpression>(){ callableReference } != null ->
CALLABLE_REFERENCE
else -> null else -> null
} }
}
fun getClassUsageType(): UsageTypeEnum? { fun getClassUsageType(): UsageTypeEnum? {
if (refExpr.getNonStrictParentOfType<KtTypeProjection>() != null) return TYPE_PARAMETER if (refExpr.getNonStrictParentOfType<KtTypeProjection>() != null) return TYPE_PARAMETER
@@ -79,26 +64,18 @@ object UsageTypeUtils {
} }
return when { return when {
refExpr.getParentOfTypeAndBranch<KtTypeParameter>(){ extendsBound } != null refExpr.getParentOfTypeAndBranch<KtTypeParameter>() { extendsBound } != null || refExpr.getParentOfTypeAndBranch<KtTypeConstraint>() { boundTypeReference } != null -> TYPE_CONSTRAINT
|| refExpr.getParentOfTypeAndBranch<KtTypeConstraint>(){ boundTypeReference } != null ->
TYPE_CONSTRAINT
refExpr is KtSuperTypeListEntry refExpr is KtSuperTypeListEntry || refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>() { typeReference } != null -> SUPER_TYPE
|| refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>(){ typeReference } != null ->
SUPER_TYPE
refExpr.getParentOfTypeAndBranch<KtParameter>(){ typeReference } != null -> refExpr.getParentOfTypeAndBranch<KtParameter>() { typeReference } != null -> VALUE_PARAMETER_TYPE
VALUE_PARAMETER_TYPE
refExpr.getParentOfTypeAndBranch<KtIsExpression>(){ typeReference } != null refExpr.getParentOfTypeAndBranch<KtIsExpression>() { typeReference } != null || refExpr.getParentOfTypeAndBranch<KtWhenConditionIsPattern>() { typeReference } != null -> IS
|| refExpr.getParentOfTypeAndBranch<KtWhenConditionIsPattern>(){ typeReference } != null ->
IS
with(refExpr.getParentOfTypeAndBranch<KtBinaryExpressionWithTypeRHS>() { right }) { with(refExpr.getParentOfTypeAndBranch<KtBinaryExpressionWithTypeRHS>() { right }) {
val opType = this?.operationReference?.getReferencedNameElementType() val opType = this?.operationReference?.getReferencedNameElementType()
opType == KtTokens.AS_KEYWORD || opType == KtTokens.AS_SAFE opType == KtTokens.AS_KEYWORD || opType == KtTokens.AS_SAFE
} -> } -> CLASS_CAST_TO
CLASS_CAST_TO
with(refExpr.getNonStrictParentOfType<KtDotQualifiedExpression>()) { with(refExpr.getNonStrictParentOfType<KtDotQualifiedExpression>()) {
when { when {
@@ -113,23 +90,18 @@ object UsageTypeUtils {
&& getParentOfTypeAndBranch<KtDotQualifiedExpression>(strict = true) { receiverExpression } != null && getParentOfTypeAndBranch<KtDotQualifiedExpression>(strict = true) { receiverExpression } != null
} }
} }
} -> } -> CLASS_OBJECT_ACCESS
CLASS_OBJECT_ACCESS
refExpr.getParentOfTypeAndBranch<KtSuperExpression>(){ superTypeQualifier } != null -> refExpr.getParentOfTypeAndBranch<KtSuperExpression>() { superTypeQualifier } != null -> SUPER_TYPE_QUALIFIER
SUPER_TYPE_QUALIFIER
refExpr.getParentOfTypeAndBranch<KtTypeAlias> { getTypeReference() } != null -> refExpr.getParentOfTypeAndBranch<KtTypeAlias> { getTypeReference() } != null -> TYPE_ALIAS
TYPE_ALIAS
else -> null else -> null
} }
} }
fun getVariableUsageType(): UsageTypeEnum? { fun getVariableUsageType(): UsageTypeEnum? {
if (refExpr.getParentOfTypeAndBranch<KtDelegatedSuperTypeEntry>(){ delegateExpression } != null) { if (refExpr.getParentOfTypeAndBranch<KtDelegatedSuperTypeEntry>() { delegateExpression } != null) return DELEGATE
return DELEGATE
}
if (refExpr.parent is KtValueArgumentName) return NAMED_ARGUMENT if (refExpr.parent is KtValueArgumentName) return NAMED_ARGUMENT
@@ -165,41 +137,30 @@ object UsageTypeUtils {
} }
return when { return when {
refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>(){ typeReference } != null -> refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>() { typeReference } != null -> SUPER_TYPE
SUPER_TYPE
descriptor is ConstructorDescriptor descriptor is ConstructorDescriptor && refExpr.getParentOfTypeAndBranch<KtAnnotationEntry>() { typeReference } != null -> ANNOTATION
&& refExpr.getParentOfTypeAndBranch<KtAnnotationEntry>(){ typeReference } != null ->
ANNOTATION
with(refExpr.getParentOfTypeAndBranch<KtCallExpression>() { calleeExpression }) { with(refExpr.getParentOfTypeAndBranch<KtCallExpression>() { calleeExpression }) {
this?.calleeExpression is KtSimpleNameExpression this?.calleeExpression is KtSimpleNameExpression
} -> } -> if (descriptor is ConstructorDescriptor) CLASS_NEW_OPERATOR else FUNCTION_CALL
if (descriptor is ConstructorDescriptor) CLASS_NEW_OPERATOR else FUNCTION_CALL
refExpr.getParentOfTypeAndBranch<KtBinaryExpression>(){ operationReference } != null || refExpr.getParentOfTypeAndBranch<KtBinaryExpression>() { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtUnaryExpression>() { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtWhenConditionInRange>() { operationReference } != null -> FUNCTION_CALL
refExpr.getParentOfTypeAndBranch<KtUnaryExpression>(){ operationReference } != null ||
refExpr.getParentOfTypeAndBranch<KtWhenConditionInRange>(){ operationReference } != null ->
FUNCTION_CALL
else -> null else -> null
} }
} }
fun getPackageUsageType(): UsageTypeEnum? { fun getPackageUsageType(): UsageTypeEnum? = when {
return when {
refExpr.getNonStrictParentOfType<KtPackageDirective>() != null -> PACKAGE_DIRECTIVE refExpr.getNonStrictParentOfType<KtPackageDirective>() != null -> PACKAGE_DIRECTIVE
refExpr.getNonStrictParentOfType<KtQualifiedExpression>() != null -> PACKAGE_MEMBER_ACCESS refExpr.getNonStrictParentOfType<KtQualifiedExpression>() != null -> PACKAGE_MEMBER_ACCESS
else -> getClassUsageType() else -> getClassUsageType()
} }
}
val usageType = getCommonUsageType() val usageType = getCommonUsageType()
if (usageType != null) return usageType if (usageType != null) return usageType
val descriptor = context[BindingContext.REFERENCE_TARGET, refExpr] return when (val descriptor = context[BindingContext.REFERENCE_TARGET, refExpr]) {
return when (descriptor) {
is ClassifierDescriptor -> when { is ClassifierDescriptor -> when {
// Treat object accesses as variables to simulate the old behaviour (when variables were created for objects) // Treat object accesses as variables to simulate the old behaviour (when variables were created for objects)
DescriptorUtils.isNonCompanionObject(descriptor) || DescriptorUtils.isEnumEntry(descriptor) -> getVariableUsageType() DescriptorUtils.isNonCompanionObject(descriptor) || DescriptorUtils.isEnumEntry(descriptor) -> getVariableUsageType()
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -19,9 +19,11 @@ object CommonLibraryType : LibraryType<DummyLibraryProperties>(CommonLibraryKind
override fun getCreateActionName() = null override fun getCreateActionName() = null
override fun createNewLibrary(parentComponent: JComponent, override fun createNewLibrary(
parentComponent: JComponent,
contextDirectory: VirtualFile?, contextDirectory: VirtualFile?,
project: Project): NewLibraryConfiguration? = null project: Project
): NewLibraryConfiguration? = null
override fun getIcon(properties: DummyLibraryProperties?) = KotlinIcons.MPP override fun getIcon(properties: DummyLibraryProperties?) = KotlinIcons.MPP
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.framework package org.jetbrains.kotlin.idea.framework
@@ -28,7 +17,6 @@ import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.utils.LibraryUtils import org.jetbrains.kotlin.utils.LibraryUtils
import org.jetbrains.kotlin.utils.PathUtil import org.jetbrains.kotlin.utils.PathUtil
import java.io.File import java.io.File
import java.util.*
import java.util.jar.Attributes import java.util.jar.Attributes
object JsLibraryStdDetectionUtil { object JsLibraryStdDetectionUtil {
@@ -56,7 +44,8 @@ object JsLibraryStdDetectionUtil {
val name = root.url.substringBefore("!/").substringAfterLast('/') val name = root.url.substringBefore("!/").substringAfterLast('/')
if (name == PathUtil.JS_LIB_JAR_NAME || name == PathUtil.JS_LIB_10_JAR_NAME || if (name == PathUtil.JS_LIB_JAR_NAME || name == PathUtil.JS_LIB_10_JAR_NAME ||
PathUtil.KOTLIN_STDLIB_JS_JAR_PATTERN.matcher(name).matches() || PathUtil.KOTLIN_STDLIB_JS_JAR_PATTERN.matcher(name).matches() ||
PathUtil.KOTLIN_JS_LIBRARY_JAR_PATTERN.matcher(name).matches()) { PathUtil.KOTLIN_JS_LIBRARY_JAR_PATTERN.matcher(name).matches()
) {
val jar = VfsUtilCore.getVirtualFileForJar(root) ?: continue val jar = VfsUtilCore.getVirtualFileForJar(root) ?: continue
var isJSStdLib = jar.getUserData(IS_JS_LIBRARY_STD_LIB) var isJSStdLib = jar.getUserData(IS_JS_LIBRARY_STD_LIB)
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
@@ -82,7 +71,8 @@ internal class BeforeResolveHighlightingVisitor(holder: AnnotationHolder) : High
override fun visitArgument(argument: KtValueArgument) { override fun visitArgument(argument: KtValueArgument) {
val argumentName = argument.getArgumentName() ?: return val argumentName = argument.getArgumentName() ?: return
val eq = argument.equalsToken ?: return val eq = argument.equalsToken ?: return
createInfoAnnotation(TextRange(argumentName.startOffset, eq.endOffset), null).textAttributes = KotlinHighlightingColors.NAMED_ARGUMENT createInfoAnnotation(TextRange(argumentName.startOffset, eq.endOffset), null).textAttributes =
KotlinHighlightingColors.NAMED_ARGUMENT
} }
override fun visitExpressionWithLabel(expression: KtExpressionWithLabel) { override fun visitExpressionWithLabel(expression: KtExpressionWithLabel) {
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
@@ -56,9 +45,8 @@ class DebugInfoAnnotator : Annotator {
} }
override fun reportUnresolvedWithTarget(expression: KtReferenceExpression, target: String) { override fun reportUnresolvedWithTarget(expression: KtReferenceExpression, target: String) {
holder.createErrorAnnotation(expression, "[DEBUG] Reference marked as unresolved is actually resolved to " + target) holder.createErrorAnnotation(expression, "[DEBUG] Reference marked as unresolved is actually resolved to $target")
.textAttributes = .textAttributes = KotlinHighlightingColors.DEBUG_INFO
KotlinHighlightingColors.DEBUG_INFO
} }
}) })
} catch (e: ProcessCanceledException) { } catch (e: ProcessCanceledException) {
@@ -74,6 +62,7 @@ class DebugInfoAnnotator : Annotator {
companion object { companion object {
val isDebugInfoEnabled: Boolean val isDebugInfoEnabled: Boolean
get() = ApplicationManager.getApplication().isInternal && (KotlinPluginUtil.isSnapshotVersion() || KotlinPluginUtil.isDevVersion()) get() = ApplicationManager.getApplication()
.isInternal && (KotlinPluginUtil.isSnapshotVersion() || KotlinPluginUtil.isDevVersion())
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
@@ -25,8 +14,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
abstract class HighlighterExtension { abstract class HighlighterExtension {
abstract fun highlightDeclaration(elementToHighlight: PsiElement, descriptor: DeclarationDescriptor): TextAttributesKey? abstract fun highlightDeclaration(elementToHighlight: PsiElement, descriptor: DeclarationDescriptor): TextAttributesKey?
open fun highlightCall(elementToHighlight: PsiElement, resolvedCall: ResolvedCall<*>): TextAttributesKey? open fun highlightCall(elementToHighlight: PsiElement, resolvedCall: ResolvedCall<*>): TextAttributesKey? =
= highlightDeclaration(elementToHighlight, resolvedCall.resultingDescriptor) highlightDeclaration(elementToHighlight, resolvedCall.resultingDescriptor)
companion object { companion object {
val EP_NAME = ExtensionPointName.create<HighlighterExtension>("org.jetbrains.kotlin.highlighterExtension") val EP_NAME = ExtensionPointName.create<HighlighterExtension>("org.jetbrains.kotlin.highlighterExtension")
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
@@ -86,7 +75,8 @@ object IdeRenderers {
val context = RenderingContext.of(descriptors) val context = RenderingContext.of(descriptors)
val conflicts = descriptors.joinToString("") { "<li>" + HTML.render(it, context) + "</li>\n" } val conflicts = descriptors.joinToString("") { "<li>" + HTML.render(it, context) + "</li>\n" }
"The following declarations have the same JVM signature (<code>${data.signature.name}${data.signature.desc}</code>):<br/>\n<ul>\n$conflicts</ul>" "The following declarations have the same JVM signature (<code>${data.signature.name}${data.signature
.desc}</code>):<br/>\n<ul>\n$conflicts</ul>"
} }
@JvmField @JvmField
@@ -98,8 +88,12 @@ object IdeRenderers {
val HTML = DescriptorRenderer.HTML.withOptions { val HTML = DescriptorRenderer.HTML.withOptions {
modifiers = DescriptorRendererModifier.ALL_EXCEPT_ANNOTATIONS modifiers = DescriptorRendererModifier.ALL_EXCEPT_ANNOTATIONS
}.asRenderer() }.asRenderer()
@JvmField val HTML_WITH_ANNOTATIONS = DescriptorRenderer.HTML.withOptions {
@JvmField
val HTML_WITH_ANNOTATIONS = DescriptorRenderer.HTML.withOptions {
modifiers = DescriptorRendererModifier.ALL modifiers = DescriptorRendererModifier.ALL
}.asRenderer() }.asRenderer()
@JvmField val HTML_WITH_ANNOTATIONS_WHITELIST = DescriptorRenderer.HTML.withAnnotationsWhitelist()
@JvmField
val HTML_WITH_ANNOTATIONS_WHITELIST = DescriptorRenderer.HTML.withAnnotationsWhitelist()
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
@@ -39,7 +28,8 @@ class KotlinBeforeResolveHighlightingPass(
document: Document document: Document
) : TextEditorHighlightingPass(file.project, document), DumbAware { ) : TextEditorHighlightingPass(file.project, document), DumbAware {
@Volatile private var annotationHolder: AnnotationHolderImpl? = null @Volatile
private var annotationHolder: AnnotationHolderImpl? = null
override fun doCollectInformation(progress: ProgressIndicator) { override fun doCollectInformation(progress: ProgressIndicator) {
val annotationHolder = AnnotationHolderImpl(AnnotationSession(file)) val annotationHolder = AnnotationHolderImpl(AnnotationSession(file))
@@ -64,7 +54,13 @@ class KotlinBeforeResolveHighlightingPass(
class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, TextEditorHighlightingPassFactory { class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, TextEditorHighlightingPassFactory {
init { init {
registrar.registerTextEditorHighlightingPass(this, TextEditorHighlightingPassRegistrar.Anchor.BEFORE, Pass.UPDATE_FOLDING, false, false) registrar.registerTextEditorHighlightingPass(
this,
TextEditorHighlightingPassRegistrar.Anchor.BEFORE,
Pass.UPDATE_FOLDING,
false,
false
)
} }
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? { override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
@@ -71,15 +60,17 @@ fun createSuppressWarningActions(element: PsiElement, severity: Severity, suppre
// Add suppress action at first statement // Add suppress action at first statement
if (current.parent is KtBlockExpression || current.parent is KtDestructuringDeclaration) { if (current.parent is KtBlockExpression || current.parent is KtDestructuringDeclaration) {
val kind = if (current.parent is KtBlockExpression) "statement" else "initializer" val kind = if (current.parent is KtBlockExpression) "statement" else "initializer"
actions.add(KotlinSuppressIntentionAction(current, suppressionKey, actions.add(
AnnotationHostKind(kind, "", true))) KotlinSuppressIntentionAction(current, suppressionKey, AnnotationHostKind(kind, "", true))
)
suppressAtStatementAllowed = false suppressAtStatementAllowed = false
} }
} }
current is KtFile -> { current is KtFile -> {
actions.add(KotlinSuppressIntentionAction(current, suppressionKey, actions.add(
AnnotationHostKind("file", current.name, true))) KotlinSuppressIntentionAction(current, suppressionKey, AnnotationHostKind("file", current.name, true))
)
suppressAtStatementAllowed = false suppressAtStatementAllowed = false
} }
} }
@@ -101,8 +92,8 @@ private object DeclarationKindDetector : KtVisitor<AnnotationHostKind?, Unit?>()
override fun visitProperty(d: KtProperty, data: Unit?) = detect(d, d.valOrVarKeyword.text!!) override fun visitProperty(d: KtProperty, data: Unit?) = detect(d, d.valOrVarKeyword.text!!)
override fun visitDestructuringDeclaration(d: KtDestructuringDeclaration, data: Unit?) = detect(d, d.valOrVarKeyword?.text ?: "val", override fun visitDestructuringDeclaration(d: KtDestructuringDeclaration, data: Unit?) =
name = d.entries.joinToString(", ", "(", ")") { it.name!! }) detect(d, d.valOrVarKeyword?.text ?: "val", name = d.entries.joinToString(", ", "(", ")") { it.name!! })
override fun visitTypeParameter(d: KtTypeParameter, data: Unit?) = detect(d, "type parameter", newLineNeeded = false) override fun visitTypeParameter(d: KtTypeParameter, data: Unit?) = detect(d, "type parameter", newLineNeeded = false)
@@ -110,7 +101,8 @@ private object DeclarationKindDetector : KtVisitor<AnnotationHostKind?, Unit?>()
override fun visitParameter(d: KtParameter, data: Unit?) = detect(d, "parameter", newLineNeeded = false) override fun visitParameter(d: KtParameter, data: Unit?) = detect(d, "parameter", newLineNeeded = false)
override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: Unit?) = detect(constructor, "secondary constructor of") override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: Unit?) =
detect(constructor, "secondary constructor of")
override fun visitObjectDeclaration(d: KtObjectDeclaration, data: Unit?): AnnotationHostKind? { override fun visitObjectDeclaration(d: KtObjectDeclaration, data: Unit?): AnnotationHostKind? {
if (d.isCompanion()) return detect(d, "companion object", name = "${d.name} of ${d.getStrictParentOfType<KtClass>()?.name}") if (d.isCompanion()) return detect(d, "companion object", name = "${d.name} of ${d.getStrictParentOfType<KtClass>()?.name}")
@@ -118,6 +110,10 @@ private object DeclarationKindDetector : KtVisitor<AnnotationHostKind?, Unit?>()
return detect(d, "object") return detect(d, "object")
} }
private fun detect(declaration: KtDeclaration, kind: String, name: String = declaration.name ?: "<anonymous>", newLineNeeded: Boolean = true) private fun detect(
= AnnotationHostKind(kind, name, newLineNeeded) declaration: KtDeclaration,
kind: String,
name: String = declaration.name ?: "<anonymous>",
newLineNeeded: Boolean = true
) = AnnotationHostKind(kind, name, newLineNeeded)
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -91,8 +91,7 @@ internal class PropertiesHighlightingVisitor(holder: AnnotationHolder, bindingCo
} }
} }
private fun attributeKeyByPropertyType(descriptor: PropertyDescriptor): TextAttributesKey? { private fun attributeKeyByPropertyType(descriptor: PropertyDescriptor): TextAttributesKey? = when {
return when {
descriptor.isDynamic() -> descriptor.isDynamic() ->
// The property is set in VariablesHighlightingVisitor // The property is set in VariablesHighlightingVisitor
null null
@@ -113,4 +112,3 @@ internal class PropertiesHighlightingVisitor(holder: AnnotationHolder, bindingCo
INSTANCE_PROPERTY INSTANCE_PROPERTY
} }
} }
}
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter package org.jetbrains.kotlin.idea.highlighter
@@ -37,8 +26,8 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import org.jetbrains.kotlin.types.expressions.CaptureKind import org.jetbrains.kotlin.types.expressions.CaptureKind
internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) :
: AfterAnalysisHighlightingVisitor(holder, bindingContext) { AfterAnalysisHighlightingVisitor(holder, bindingContext) {
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
val target = bindingContext.get(REFERENCE_TARGET, expression) ?: return val target = bindingContext.get(REFERENCE_TARGET, expression) ?: return
@@ -91,31 +80,32 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
is ImplicitClassReceiver -> "Implicit receiver" is ImplicitClassReceiver -> "Implicit receiver"
else -> "Unknown receiver" else -> "Unknown receiver"
} }
createInfoAnnotation(expression, createInfoAnnotation(
"$receiverName smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)) expression,
.textAttributes = SMART_CAST_RECEIVER "$receiverName smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)
).textAttributes = SMART_CAST_RECEIVER
} }
} }
val nullSmartCast = bindingContext.get(SMARTCAST_NULL, expression) == true val nullSmartCast = bindingContext.get(SMARTCAST_NULL, expression) == true
if (nullSmartCast) { if (nullSmartCast) {
createInfoAnnotation(expression, "Always null") createInfoAnnotation(expression, "Always null").textAttributes = SMART_CONSTANT
.textAttributes = SMART_CONSTANT
} }
val smartCast = bindingContext.get(SMARTCAST, expression) val smartCast = bindingContext.get(SMARTCAST, expression)
if (smartCast != null) { if (smartCast != null) {
val defaultType = smartCast.defaultType val defaultType = smartCast.defaultType
if (defaultType != null) { if (defaultType != null) {
createInfoAnnotation(getSmartCastTarget(expression), createInfoAnnotation(
"Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(defaultType)) getSmartCastTarget(expression),
.textAttributes = SMART_CAST_VALUE "Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(defaultType)
} ).textAttributes = SMART_CAST_VALUE
else if (smartCast is MultipleSmartCasts) { } else if (smartCast is MultipleSmartCasts) {
for ((call, type) in smartCast.map) { for ((call, type) in smartCast.map) {
createInfoAnnotation(getSmartCastTarget(expression), createInfoAnnotation(
"Smart cast to ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)} (for $call call)") getSmartCastTarget(expression),
.textAttributes = SMART_CAST_VALUE "Smart cast to ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)} (for $call call)"
).textAttributes = SMART_CAST_VALUE
} }
} }
} }
@@ -166,11 +156,13 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
if (descriptor is PropertyDescriptor && KotlinHighlightingUtil.hasCustomPropertyDeclaration(descriptor)) { if (descriptor is PropertyDescriptor && KotlinHighlightingUtil.hasCustomPropertyDeclaration(descriptor)) {
val isStaticDeclaration = DescriptorUtils.isStaticDeclaration(descriptor) val isStaticDeclaration = DescriptorUtils.isStaticDeclaration(descriptor)
highlightName(elementToHighlight, highlightName(
elementToHighlight,
if (isStaticDeclaration) if (isStaticDeclaration)
PACKAGE_PROPERTY_CUSTOM_PROPERTY_DECLARATION PACKAGE_PROPERTY_CUSTOM_PROPERTY_DECLARATION
else else
INSTANCE_PROPERTY_CUSTOM_PROPERTY_DECLARATION) INSTANCE_PROPERTY_CUSTOM_PROPERTY_DECLARATION
)
} }
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.highlighter.renderersUtil package org.jetbrains.kotlin.idea.highlighter.renderersUtil
@@ -32,8 +21,8 @@ import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.ErrorUtils
private val RED_TEMPLATE = "<font color=red><b>%s</b></font>" private const val RED_TEMPLATE = "<font color=red><b>%s</b></font>"
private val STRONG_TEMPLATE = "<b>%s</b>" private const val STRONG_TEMPLATE = "<b>%s</b>"
fun renderStrong(o: Any): String = STRONG_TEMPLATE.format(o) fun renderStrong(o: Any): String = STRONG_TEMPLATE.format(o)
@@ -59,21 +48,19 @@ fun renderResolvedCall(resolvedCall: ResolvedCall<*>, context: RenderingContext)
fun renderParameter(parameter: ValueParameterDescriptor): String { fun renderParameter(parameter: ValueParameterDescriptor): String {
val varargElementType = parameter.varargElementType val varargElementType = parameter.varargElementType
val parameterType = varargElementType ?: parameter.type val parameterType = varargElementType ?: parameter.type
val renderedParameter = val renderedParameter = (if (varargElementType != null) "<b>vararg</b> " else "") +
(if (varargElementType != null) "<b>vararg</b> " else "") +
typeRenderer.render(parameterType, context) + typeRenderer.render(parameterType, context) +
if (parameter.hasDefaultValue()) " = ..." else "" if (parameter.hasDefaultValue()) " = ..." else ""
if (resolvedCall.hasTypeMismatchErrorOnParameter(parameter)) { return if (resolvedCall.hasTypeMismatchErrorOnParameter(parameter))
return renderError(renderedParameter) renderError(renderedParameter)
} else
return renderedParameter renderedParameter
} }
fun appendTypeParametersSubstitution() { fun appendTypeParametersSubstitution() {
val parametersToArgumentsMap = resolvedCall.typeArguments val parametersToArgumentsMap = resolvedCall.typeArguments
fun TypeParameterDescriptor.isInferred(): Boolean { fun TypeParameterDescriptor.isInferred(): Boolean {
val typeArgument = parametersToArgumentsMap[this] val typeArgument = parametersToArgumentsMap[this] ?: return false
if (typeArgument == null) return false
return !ErrorUtils.isUninferredParameter(typeArgument) return !ErrorUtils.isUninferredParameter(typeArgument)
} }
@@ -81,16 +68,16 @@ fun renderResolvedCall(resolvedCall: ResolvedCall<*>, context: RenderingContext)
val (inferredTypeParameters, notInferredTypeParameters) = typeParameters.partition(TypeParameterDescriptor::isInferred) val (inferredTypeParameters, notInferredTypeParameters) = typeParameters.partition(TypeParameterDescriptor::isInferred)
append("<br/>$indent<i>where</i> ") append("<br/>$indent<i>where</i> ")
if (!notInferredTypeParameters.isEmpty()) { if (notInferredTypeParameters.isNotEmpty()) {
append(notInferredTypeParameters.joinToString { typeParameter -> renderError(typeParameter.name) }) append(notInferredTypeParameters.joinToString { typeParameter -> renderError(typeParameter.name) })
append("<i> cannot be inferred</i>") append("<i> cannot be inferred</i>")
if (!inferredTypeParameters.isEmpty()) { if (inferredTypeParameters.isNotEmpty()) {
append("; ") append("; ")
} }
} }
val typeParameterToTypeArgumentMap = resolvedCall.typeArguments val typeParameterToTypeArgumentMap = resolvedCall.typeArguments
if (!inferredTypeParameters.isEmpty()) { if (inferredTypeParameters.isNotEmpty()) {
append(inferredTypeParameters.joinToString { typeParameter -> append(inferredTypeParameters.joinToString { typeParameter ->
"${typeParameter.name} = ${typeRenderer.render(typeParameterToTypeArgumentMap[typeParameter]!!, context)}" "${typeParameter.name} = ${typeRenderer.render(typeParameterToTypeArgumentMap[typeParameter]!!, context)}"
}) })
@@ -106,13 +93,12 @@ fun renderResolvedCall(resolvedCall: ResolvedCall<*>, context: RenderingContext)
append(resultingDescriptor.valueParameters.joinToString(transform = ::renderParameter)) append(resultingDescriptor.valueParameters.joinToString(transform = ::renderParameter))
append(if (resolvedCall.hasUnmappedArguments()) renderError(")") else ")") append(if (resolvedCall.hasUnmappedArguments()) renderError(")") else ")")
if (!resolvedCall.candidateDescriptor.typeParameters.isEmpty()) { if (resolvedCall.candidateDescriptor.typeParameters.isNotEmpty()) {
appendTypeParametersSubstitution() appendTypeParametersSubstitution()
append("<i> for </i><br/>$indent") append("<i> for </i><br/>$indent")
// candidate descriptor is not in context of the rest of the message // candidate descriptor is not in context of the rest of the message
append(descriptorRenderer.render(resolvedCall.candidateDescriptor, RenderingContext.of(resolvedCall.candidateDescriptor))) append(descriptorRenderer.render(resolvedCall.candidateDescriptor, RenderingContext.of(resolvedCall.candidateDescriptor)))
} } else {
else {
append(" <i>defined in</i> ") append(" <i>defined in</i> ")
val containingDeclaration = resultingDescriptor.containingDeclaration val containingDeclaration = resultingDescriptor.containingDeclaration
val fqName = DescriptorUtils.getFqName(containingDeclaration) val fqName = DescriptorUtils.getFqName(containingDeclaration)
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.inspections package org.jetbrains.kotlin.idea.inspections
@@ -71,8 +60,7 @@ abstract class IntentionBasedInspection<TElement : PsiElement> private construct
intention: KClass<out SelfTargetingRangeIntention<TElement>>, intention: KClass<out SelfTargetingRangeIntention<TElement>>,
additionalChecker: (TElement) -> Boolean, additionalChecker: (TElement) -> Boolean,
problemText: String? = null problemText: String? = null
) : this(IntentionData(intention, { element, _ -> additionalChecker(element) } ), problemText) ) : this(IntentionData(intention) { element, _ -> additionalChecker(element) }, problemText)
data class IntentionData<TElement : PsiElement>( data class IntentionData<TElement : PsiElement>(
@@ -147,13 +135,11 @@ abstract class IntentionBasedInspection<TElement : PsiElement> private construct
intention: SelfTargetingRangeIntention<TElement>, intention: SelfTargetingRangeIntention<TElement>,
additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean, additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
targetElement: TElement targetElement: TElement
): IntentionBasedQuickFix { ): IntentionBasedQuickFix = when (intention) {
return when (intention) {
is LowPriorityAction -> LowPriorityIntentionBasedQuickFix(intention, additionalChecker, targetElement) is LowPriorityAction -> LowPriorityIntentionBasedQuickFix(intention, additionalChecker, targetElement)
is HighPriorityAction -> HighPriorityIntentionBasedQuickFix(intention, additionalChecker, targetElement) is HighPriorityAction -> HighPriorityIntentionBasedQuickFix(intention, additionalChecker, targetElement)
else -> IntentionBasedQuickFix(intention, additionalChecker, targetElement) else -> IntentionBasedQuickFix(intention, additionalChecker, targetElement)
} }
}
/* we implement IntentionAction to provide isAvailable which will be used to hide outdated items and make sure we never call 'invoke' for such item */ /* we implement IntentionAction to provide isAvailable which will be used to hide outdated items and make sure we never call 'invoke' for such item */
internal open inner class IntentionBasedQuickFix( internal open inner class IntentionBasedQuickFix(
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.intentions package org.jetbrains.kotlin.idea.intentions
@@ -21,7 +10,8 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.* import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.references.ReferenceAccess import org.jetbrains.kotlin.idea.references.ReferenceAccess
import org.jetbrains.kotlin.idea.references.readWriteAccess import org.jetbrains.kotlin.idea.references.readWriteAccess
@@ -97,15 +87,15 @@ class OperatorToFunctionIntention :
val descriptor = resolvedCall?.resultingDescriptor val descriptor = resolvedCall?.resultingDescriptor
if (descriptor is FunctionDescriptor && descriptor.getName() == OperatorNameConventions.INVOKE) { if (descriptor is FunctionDescriptor && descriptor.getName() == OperatorNameConventions.INVOKE) {
if (element.parent is KtDotQualifiedExpression && if (element.parent is KtDotQualifiedExpression &&
element.calleeExpression?.text == OperatorNameConventions.INVOKE.asString()) return false element.calleeExpression?.text == OperatorNameConventions.INVOKE.asString()
) return false
return element.valueArgumentList != null || element.lambdaArguments.isNotEmpty() return element.valueArgumentList != null || element.lambdaArguments.isNotEmpty()
} }
return false return false
} }
private fun convertUnary(element: KtUnaryExpression): KtExpression { private fun convertUnary(element: KtUnaryExpression): KtExpression {
val op = element.operationReference.getReferencedNameElementType() val operatorName = when (element.operationReference.getReferencedNameElementType()) {
val operatorName = when (op) {
KtTokens.PLUSPLUS, KtTokens.MINUSMINUS -> return convertUnaryWithAssignFix(element) KtTokens.PLUSPLUS, KtTokens.MINUSMINUS -> return convertUnaryWithAssignFix(element)
KtTokens.PLUS -> OperatorNameConventions.UNARY_PLUS KtTokens.PLUS -> OperatorNameConventions.UNARY_PLUS
KtTokens.MINUS -> OperatorNameConventions.UNARY_MINUS KtTokens.MINUS -> OperatorNameConventions.UNARY_MINUS
@@ -118,8 +108,7 @@ class OperatorToFunctionIntention :
} }
private fun convertUnaryWithAssignFix(element: KtUnaryExpression): KtExpression { private fun convertUnaryWithAssignFix(element: KtUnaryExpression): KtExpression {
val op = element.operationReference.getReferencedNameElementType() val operatorName = when (element.operationReference.getReferencedNameElementType()) {
val operatorName = when (op) {
KtTokens.PLUSPLUS -> OperatorNameConventions.INC KtTokens.PLUSPLUS -> OperatorNameConventions.INC
KtTokens.MINUSMINUS -> OperatorNameConventions.DEC KtTokens.MINUSMINUS -> OperatorNameConventions.DEC
else -> return element else -> return element
@@ -208,7 +197,8 @@ class OperatorToFunctionIntention :
private fun isAssignmentLeftSide(element: KtArrayAccessExpression): Boolean { private fun isAssignmentLeftSide(element: KtArrayAccessExpression): Boolean {
val parent = element.parent val parent = element.parent
return parent is KtBinaryExpression && parent.operationReference.getReferencedNameElementType() == KtTokens.EQ && element == parent.left return parent is KtBinaryExpression &&
parent.operationReference.getReferencedNameElementType() == KtTokens.EQ && element == parent.left
} }
//TODO: don't use creation by plain text //TODO: don't use creation by plain text
@@ -218,8 +208,8 @@ class OperatorToFunctionIntention :
val argumentString = arguments?.text?.removeSurrounding("(", ")") val argumentString = arguments?.text?.removeSurrounding("(", ")")
val funcLitArgs = element.lambdaArguments val funcLitArgs = element.lambdaArguments
val calleeText = callee.text val calleeText = callee.text
val transformation = "$calleeText.${OperatorNameConventions.INVOKE.asString()}" + val transformation =
(if (argumentString == null) "()" else "($argumentString)") "$calleeText.${OperatorNameConventions.INVOKE.asString()}" + (if (argumentString == null) "()" else "($argumentString)")
val transformed = KtPsiFactory(element).createExpression(transformation) val transformed = KtPsiFactory(element).createExpression(transformation)
val callExpression = transformed.getCalleeExpressionIfAny()?.parent as? KtCallExpression val callExpression = transformed.getCalleeExpressionIfAny()?.parent as? KtCallExpression
if (callExpression != null) { if (callExpression != null) {
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.intentions package org.jetbrains.kotlin.idea.intentions
@@ -85,8 +74,7 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
return getTarget(offset, file) return getTarget(offset, file)
} }
protected open fun allowCaretInsideElement(element: PsiElement): Boolean = protected open fun allowCaretInsideElement(element: PsiElement): Boolean = element !is KtBlockExpression
element !is KtBlockExpression
final override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean { final override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean {
if (ApplicationManager.getApplication().isUnitTestMode) { if (ApplicationManager.getApplication().isUnitTestMode) {
@@ -94,8 +82,7 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
} }
try { try {
return getTarget(editor, file) != null return getTarget(editor, file) != null
} } finally {
finally {
CREATE_BY_PATTERN_MAY_NOT_REFORMAT = false CREATE_BY_PATTERN_MAY_NOT_REFORMAT = false
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.kdoc package org.jetbrains.kotlin.idea.kdoc
@@ -20,8 +9,8 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.stubindex.* import org.jetbrains.kotlin.idea.stubindex.*
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
@@ -37,7 +26,12 @@ import org.jetbrains.kotlin.utils.Printer
class IdeSampleResolutionService(val project: Project) : SampleResolutionService { class IdeSampleResolutionService(val project: Project) : SampleResolutionService {
override fun resolveSample(context: BindingContext, fromDescriptor: DeclarationDescriptor, resolutionFacade: ResolutionFacade, qualifiedName: List<String>): Collection<DeclarationDescriptor> { override fun resolveSample(
context: BindingContext,
fromDescriptor: DeclarationDescriptor,
resolutionFacade: ResolutionFacade,
qualifiedName: List<String>
): Collection<DeclarationDescriptor> {
val scope = KotlinSourceFilterScope.projectAndLibrariesSources(GlobalSearchScope.projectScope(project), project) val scope = KotlinSourceFilterScope.projectAndLibrariesSources(GlobalSearchScope.projectScope(project), project)
@@ -48,8 +42,7 @@ class IdeSampleResolutionService(val project: Project) : SampleResolutionService
val functions = KotlinFunctionShortNameIndex.getInstance().get(shortName, project, scope).asSequence() val functions = KotlinFunctionShortNameIndex.getInstance().get(shortName, project, scope).asSequence()
val classes = KotlinClassShortNameIndex.getInstance().get(shortName, project, scope).asSequence() val classes = KotlinClassShortNameIndex.getInstance().get(shortName, project, scope).asSequence()
val descriptors = (functions + classes) val descriptors = (functions + classes).filter { it.fqName == targetFqName }
.filter { it.fqName == targetFqName }
.map { it.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) } // TODO Filter out not visible due dependencies config descriptors .map { it.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) } // TODO Filter out not visible due dependencies config descriptors
.toList() .toList()
if (descriptors.isNotEmpty()) if (descriptors.isNotEmpty())
@@ -63,7 +56,11 @@ class IdeSampleResolutionService(val project: Project) : SampleResolutionService
private fun shouldNotBeCalled(): Nothing = throw UnsupportedOperationException("Synthetic PVD for KDoc link resolution") private fun shouldNotBeCalled(): Nothing = throw UnsupportedOperationException("Synthetic PVD for KDoc link resolution")
private class GlobalSyntheticPackageViewDescriptor(override val fqName: FqName, private val project: Project, private val scope: GlobalSearchScope) : PackageViewDescriptor { private class GlobalSyntheticPackageViewDescriptor(
override val fqName: FqName,
private val project: Project,
private val scope: GlobalSearchScope
) : PackageViewDescriptor {
override fun getContainingDeclaration(): PackageViewDescriptor? = override fun getContainingDeclaration(): PackageViewDescriptor? =
if (fqName.isOneSegmentFQN()) null else GlobalSyntheticPackageViewDescriptor(fqName.parent(), project, scope) if (fqName.isOneSegmentFQN()) null else GlobalSyntheticPackageViewDescriptor(fqName.parent(), project, scope)
@@ -72,7 +69,8 @@ private class GlobalSyntheticPackageViewDescriptor(override val fqName: FqName,
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> = shouldNotBeCalled() override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> = shouldNotBeCalled()
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> = shouldNotBeCalled() override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> =
shouldNotBeCalled()
override fun getFunctionNames(): Set<Name> = shouldNotBeCalled() override fun getFunctionNames(): Set<Name> = shouldNotBeCalled()
override fun getVariableNames(): Set<Name> = shouldNotBeCalled() override fun getVariableNames(): Set<Name> = shouldNotBeCalled()
@@ -106,14 +104,16 @@ private class GlobalSyntheticPackageViewDescriptor(override val fqName: FqName,
.flatMap { KotlinTopLevelFunctionFqnNameIndex.getInstance()[it.asString(), project, scope].asSequence() } .flatMap { KotlinTopLevelFunctionFqnNameIndex.getInstance()[it.asString(), project, scope].asSequence() }
.map { it.resolveToDescriptorIfAny() as? DeclarationDescriptor } .map { it.resolveToDescriptorIfAny() as? DeclarationDescriptor }
fun getSubpackages(nameFilter: (Name) -> Boolean) = fun getSubpackages(nameFilter: (Name) -> Boolean) = PackageIndexUtil.getSubPackageFqNames(fqName, scope, project, nameFilter)
PackageIndexUtil.getSubPackageFqNames(fqName, scope, project, nameFilter)
.map { GlobalSyntheticPackageViewDescriptor(it, project, scope) } .map { GlobalSyntheticPackageViewDescriptor(it, project, scope) }
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> override fun getContributedDescriptors(
= (getClassesByNameFilter(nameFilter) kindFilter: DescriptorKindFilter,
+ getFunctionsByNameFilter(nameFilter) nameFilter: (Name) -> Boolean
+ getSubpackages(nameFilter)).filterNotNull().toList() ): Collection<DeclarationDescriptor> = (getClassesByNameFilter(nameFilter) +
getFunctionsByNameFilter(nameFilter) +
getSubpackages(nameFilter)
).filterNotNull().toList()
} }
override val module: ModuleDescriptor override val module: ModuleDescriptor
@@ -1,25 +1,14 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.kdoc package org.jetbrains.kotlin.idea.kdoc
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.modules package org.jetbrains.kotlin.idea.modules
@@ -20,15 +9,12 @@ import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiJavaModule import com.intellij.psi.PsiJavaModule
import com.intellij.psi.PsiManager
import com.intellij.psi.impl.light.LightJavaModule import com.intellij.psi.impl.light.LightJavaModule
import org.jetbrains.annotations.NotNull
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
class IdeJavaModuleResolver(private val project: Project) : JavaModuleResolver { class IdeJavaModuleResolver(private val project: Project) : JavaModuleResolver {
private fun findJavaModule(file: VirtualFile): PsiJavaModule? = private fun findJavaModule(file: VirtualFile): PsiJavaModule? = ModuleHighlightUtil2.getModuleDescriptor(file, project)
ModuleHighlightUtil2.getModuleDescriptor(file, project)
override fun checkAccessibility( override fun checkAccessibility(
fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName? fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.project package org.jetbrains.kotlin.idea.project
@@ -20,9 +9,9 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.stubindex.resolve.PluginDeclarationProviderFactory import org.jetbrains.kotlin.idea.stubindex.resolve.PluginDeclarationProviderFactory
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.AbsentDescriptorHandler
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.LocalDescriptorResolver import org.jetbrains.kotlin.resolve.lazy.LocalDescriptorResolver
import org.jetbrains.kotlin.resolve.lazy.AbsentDescriptorHandler
import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
@@ -32,8 +21,9 @@ class IdeaLocalDescriptorResolver(
) : LocalDescriptorResolver { ) : LocalDescriptorResolver {
override fun resolveLocalDeclaration(declaration: KtDeclaration): DeclarationDescriptor { override fun resolveLocalDeclaration(declaration: KtDeclaration): DeclarationDescriptor {
val context = resolveElementCache.resolveToElements(listOf(declaration), BodyResolveMode.FULL) val context = resolveElementCache.resolveToElements(listOf(declaration), BodyResolveMode.FULL)
return context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) return context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) ?: absentDescriptorHandler.diagnoseDescriptorNotFound(
?: absentDescriptorHandler.diagnoseDescriptorNotFound(declaration) declaration
)
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.project package org.jetbrains.kotlin.idea.project
@@ -641,10 +630,7 @@ class ResolveElementCache(
val classDescriptor = resolveSession.resolveToDescriptor(klass) as ClassDescriptor val classDescriptor = resolveSession.resolveToDescriptor(klass) as ClassDescriptor
val constructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor val constructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor
?: error( ?: error("Can't get primary constructor for descriptor '$classDescriptor' in from class '${klass.getElementTextWithContext()}'")
"Can't get primary constructor for descriptor '$classDescriptor' " +
"in from class '${klass.getElementTextWithContext()}'"
)
ForceResolveUtil.forceResolveAllContents(constructorDescriptor) ForceResolveUtil.forceResolveAllContents(constructorDescriptor)
val primaryConstructor = klass.primaryConstructor val primaryConstructor = klass.primaryConstructor
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.quickfix package org.jetbrains.kotlin.idea.quickfix
@@ -26,10 +15,10 @@ abstract class KotlinIntentionActionsFactory {
protected abstract fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> protected abstract fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>
protected open fun doCreateActionsForAllProblems( protected open fun doCreateActionsForAllProblems(
sameTypeDiagnostics: Collection<Diagnostic>): List<IntentionAction> = emptyList() sameTypeDiagnostics: Collection<Diagnostic>
): List<IntentionAction> = emptyList()
fun createActions(diagnostic: Diagnostic): List<IntentionAction> = fun createActions(diagnostic: Diagnostic): List<IntentionAction> = createActions(listOfNotNull(diagnostic), false)
createActions(listOfNotNull(diagnostic), false)
fun createActionsForAllProblems(sameTypeDiagnostics: Collection<Diagnostic>): List<IntentionAction> = fun createActionsForAllProblems(sameTypeDiagnostics: Collection<Diagnostic>): List<IntentionAction> =
createActions(sameTypeDiagnostics, true) createActions(sameTypeDiagnostics, true)
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.quickfix package org.jetbrains.kotlin.idea.quickfix
@@ -25,7 +14,8 @@ import com.intellij.openapi.extensions.Extensions
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
class QuickFixes { class QuickFixes {
private val factories: Multimap<DiagnosticFactory<*>, KotlinIntentionActionsFactory> = HashMultimap.create<DiagnosticFactory<*>, KotlinIntentionActionsFactory>() private val factories: Multimap<DiagnosticFactory<*>, KotlinIntentionActionsFactory> =
HashMultimap.create<DiagnosticFactory<*>, KotlinIntentionActionsFactory>()
private val actions: Multimap<DiagnosticFactory<*>, IntentionAction> = HashMultimap.create<DiagnosticFactory<*>, IntentionAction>() private val actions: Multimap<DiagnosticFactory<*>, IntentionAction> = HashMultimap.create<DiagnosticFactory<*>, IntentionAction>()
init { init {
@@ -99,7 +99,8 @@ private tailrec fun DeclarationDescriptor.additionalClasses(existingClasses: Col
private fun DeclarationDescriptor.collectAllTypes(): Sequence<FqName?> { private fun DeclarationDescriptor.collectAllTypes(): Sequence<FqName?> {
return when (this) { return when (this) {
is ClassConstructorDescriptor -> valueParameters.asSequence().map(ValueParameterDescriptor::getType).flatMap(KotlinType::collectAllTypes) is ClassConstructorDescriptor -> valueParameters.asSequence().map(ValueParameterDescriptor::getType)
.flatMap(KotlinType::collectAllTypes)
is ClassDescriptor -> if (isInline) unsubstitutedPrimaryConstructor?.collectAllTypes().orEmpty() else { is ClassDescriptor -> if (isInline) unsubstitutedPrimaryConstructor?.collectAllTypes().orEmpty() else {
emptySequence() emptySequence()
} + declaredTypeParameters.asSequence().flatMap(DeclarationDescriptor::collectAllTypes) + sequenceOf(fqNameOrNull()) } + declaredTypeParameters.asSequence().flatMap(DeclarationDescriptor::collectAllTypes) + sequenceOf(fqNameOrNull())
@@ -70,8 +70,7 @@ internal class KotlinDefaultAnnotationMethodImplicitReferenceContributor : Kotli
override fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar) { override fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar) {
registrar.registerProvider<KtValueArgument> { registrar.registerProvider<KtValueArgument> {
if (it.isNamed()) return@registerProvider null if (it.isNamed()) return@registerProvider null
val annotationEntry = it.getParentOfTypeAndBranch<KtAnnotationEntry> { valueArgumentList } val annotationEntry = it.getParentOfTypeAndBranch<KtAnnotationEntry> { valueArgumentList } ?: return@registerProvider null
?: return@registerProvider null
if (annotationEntry.valueArguments.size != 1) return@registerProvider null if (annotationEntry.valueArguments.size != 1) return@registerProvider null
ReferenceImpl(it) ReferenceImpl(it)
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.references package org.jetbrains.kotlin.idea.references
@@ -26,7 +15,10 @@ import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.lexer.KtToken import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.KtArrayAccessExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.buildExpression
import org.jetbrains.kotlin.psi.psiUtil.getPossiblyQualifiedCallExpression import org.jetbrains.kotlin.psi.psiUtil.getPossiblyQualifiedCallExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_GET import org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_GET
@@ -63,8 +55,7 @@ class KtArrayAccessReference(
appendExpression(arrayExpression.receiverExpression) appendExpression(arrayExpression.receiverExpression)
appendFixedText(arrayExpression.operationSign.value) appendFixedText(arrayExpression.operationSign.value)
appendExpression(arrayExpression.selectorExpression) appendExpression(arrayExpression.selectorExpression)
} } else {
else {
appendExpression(arrayExpression) appendExpression(arrayExpression)
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.references package org.jetbrains.kotlin.idea.references
@@ -25,11 +14,11 @@ import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
class KtCollectionLiteralReference(expression: KtCollectionLiteralExpression) : KtSimpleReference<KtCollectionLiteralExpression>(expression), MultiRangeReference { class KtCollectionLiteralReference(expression: KtCollectionLiteralExpression) :
KtSimpleReference<KtCollectionLiteralExpression>(expression), MultiRangeReference {
companion object { companion object {
private val COLLECTION_LITERAL_CALL_NAMES = private val COLLECTION_LITERAL_CALL_NAMES =
CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY.values + CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY.values + CollectionLiteralResolver.ARRAY_OF_FUNCTION
CollectionLiteralResolver.ARRAY_OF_FUNCTION
} }
override fun getRangeInElement(): TextRange = element.normalizeRange() override fun getRangeInElement(): TextRange = element.normalizeRange()
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.references package org.jetbrains.kotlin.idea.references
@@ -27,7 +16,8 @@ import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
class KtDestructuringDeclarationReference(element: KtDestructuringDeclarationEntry) : AbstractKtReference<KtDestructuringDeclarationEntry>(element) { class KtDestructuringDeclarationReference(element: KtDestructuringDeclarationEntry) :
AbstractKtReference<KtDestructuringDeclarationEntry>(element) {
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> { override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
return listOfNotNull(context[BindingContext.COMPONENT_RESOLVED_CALL, element]?.candidateDescriptor) return listOfNotNull(context[BindingContext.COMPONENT_RESOLVED_CALL, element]?.candidateDescriptor)
} }
@@ -36,7 +26,9 @@ class KtDestructuringDeclarationReference(element: KtDestructuringDeclarationEnt
override fun canRename(): Boolean { override fun canRename(): Boolean {
val bindingContext = expression.analyze() //TODO: should it use full body resolve? val bindingContext = expression.analyze() //TODO: should it use full body resolve?
return resolveToDescriptors(bindingContext).all { it is CallableMemberDescriptor && it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED} return resolveToDescriptors(bindingContext).all {
it is CallableMemberDescriptor && it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED
}
} }
override fun handleElementRename(newElementName: String): PsiElement? { override fun handleElementRename(newElementName: String): PsiElement? {
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.references package org.jetbrains.kotlin.idea.references
@@ -98,9 +98,11 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
expression.replace(qualifiedElement.receiverExpression) expression.replace(qualifiedElement.receiverExpression)
qualifiedElement.replaced(qualifiedElement.selectorExpression!!) qualifiedElement.replaced(qualifiedElement.selectorExpression!!)
} }
is KtUserType -> { is KtUserType -> expression.replaced(
expression.replaced(KtPsiFactory(expression).createSimpleName(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.asString())) KtPsiFactory(expression).createSimpleName(
} SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.asString()
)
)
else -> expression else -> expression
} }
} }
@@ -296,7 +298,9 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
val importDirective = file.findImportByAlias(name) ?: return null val importDirective = file.findImportByAlias(name) ?: return null
val fqName = importDirective.importedFqName ?: return null val fqName = importDirective.importedFqName ?: return null
val importedDescriptors = file.resolveImportReference(fqName).map { it.unwrap() } val importedDescriptors = file.resolveImportReference(fqName).map { it.unwrap() }
if (getTargetDescriptors(element.analyze(BodyResolveMode.PARTIAL)).any { it.unwrap().getImportableDescriptor() in importedDescriptors }) { if (getTargetDescriptors(element.analyze(BodyResolveMode.PARTIAL)).any {
it.unwrap().getImportableDescriptor() in importedDescriptors
}) {
return importDirective.alias return importDirective.alias
} }
return null return null
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.references package org.jetbrains.kotlin.idea.references
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.references package org.jetbrains.kotlin.idea.references
@@ -89,9 +78,12 @@ fun DeclarationDescriptor.findPsiDeclarations(project: Project, resolveScope: Gl
fun Collection<KtNamedDeclaration>.fqNameFilter() = filter { it.fqName == fqName } fun Collection<KtNamedDeclaration>.fqNameFilter() = filter { it.fqName == fqName }
return when (this) { return when (this) {
is DeserializedClassDescriptor -> KotlinFullClassNameIndex.getInstance()[fqName.asString(), project, resolveScope] is DeserializedClassDescriptor -> KotlinFullClassNameIndex.getInstance()[fqName.asString(), project, resolveScope]
is DeserializedTypeAliasDescriptor -> KotlinTypeAliasShortNameIndex.getInstance()[fqName.shortName().asString(), project, resolveScope].fqNameFilter() is DeserializedTypeAliasDescriptor -> KotlinTypeAliasShortNameIndex.getInstance()[fqName.shortName()
is DeserializedSimpleFunctionDescriptor, is FunctionImportedFromObject -> KotlinFunctionShortNameIndex.getInstance()[fqName.shortName().asString(), project, resolveScope].fqNameFilter() .asString(), project, resolveScope].fqNameFilter()
is DeserializedPropertyDescriptor, is PropertyImportedFromObject -> KotlinPropertyShortNameIndex.getInstance()[fqName.shortName().asString(), project, resolveScope].fqNameFilter() is DeserializedSimpleFunctionDescriptor, is FunctionImportedFromObject -> KotlinFunctionShortNameIndex.getInstance()[fqName.shortName()
.asString(), project, resolveScope].fqNameFilter()
is DeserializedPropertyDescriptor, is PropertyImportedFromObject -> KotlinPropertyShortNameIndex.getInstance()[fqName.shortName()
.asString(), project, resolveScope].fqNameFilter()
is DeclarationDescriptorWithSource -> listOfNotNull(source.getPsi()) is DeclarationDescriptorWithSource -> listOfNotNull(source.getPsi())
else -> emptyList() else -> emptyList()
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.search package org.jetbrains.kotlin.idea.search
@@ -48,10 +37,12 @@ import java.util.concurrent.atomic.AtomicInteger
class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName: String) { class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName: String) {
private val targetShortName = targetClassFqName.substringAfterLast('.') private val targetShortName = targetClassFqName.substringAfterLast('.')
private val targetPackage = targetClassFqName.substringBeforeLast('.', "") private val targetPackage = targetClassFqName.substringBeforeLast('.', "")
/** /**
* Qualified names of packages which contain classes with the same short name as the target class. * Qualified names of packages which contain classes with the same short name as the target class.
*/ */
private val conflictingPackages = mutableListOf<String>() private val conflictingPackages = mutableListOf<String>()
/** /**
* Qualified names of packages which contain typealiases with the same short name as the target class * Qualified names of packages which contain typealiases with the same short name as the target class
* (which may or may not resolve to the target class). * (which may or may not resolve to the target class).
@@ -64,8 +55,10 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName:
companion object { companion object {
@get:TestOnly @get:TestOnly
val attempts = AtomicInteger() val attempts = AtomicInteger()
@get:TestOnly @get:TestOnly
val trueHits = AtomicInteger() val trueHits = AtomicInteger()
@get:TestOnly @get:TestOnly
val falseHits = AtomicInteger() val falseHits = AtomicInteger()

Some files were not shown because too many files have changed in this diff Show More