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.
*/
@@ -125,7 +125,6 @@ class FirExplorerToolWindow(private val project: Project, private val toolWindow
val psi = (data as? FirElement)?.psi
if (data is FirElement && psi != null) {
if (FileDocumentManager.getInstance().getFile(currentEditor.document) == psi.containingFile.virtualFile) {
rangeHighlightMarkers += currentEditor.markupModel.addRangeHighlighter(
psi.startOffset,
min(currentEditor.document.textLength, psi.endOffset),
@@ -288,8 +287,7 @@ private fun KType.renderSimple(): String {
}
return buildString {
val classifier = classifier
when (classifier) {
when (val classifier = classifier) {
is KClass<*> -> append(classifier.simpleName)
is KTypeParameter -> append(classifier.name)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.analysis
@@ -37,15 +26,16 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor
@JvmOverloads fun KtExpression.computeTypeInfoInContext(
scope: LexicalScope,
contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
expectedType: KotlinType = TypeUtils.NO_EXPECTED_TYPE,
isStatement: Boolean = false,
contextDependency: ContextDependency = ContextDependency.INDEPENDENT,
expressionTypingServices: ExpressionTypingServices = contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>()
@JvmOverloads
fun KtExpression.computeTypeInfoInContext(
scope: LexicalScope,
contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
expectedType: KotlinType = TypeUtils.NO_EXPECTED_TYPE,
isStatement: Boolean = false,
contextDependency: ContextDependency = ContextDependency.INDEPENDENT,
expressionTypingServices: ExpressionTypingServices = contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>()
): KotlinTypeInfo {
PreliminaryDeclarationVisitor.createForExpression(this, trace, expressionTypingServices.languageVersionSettings)
return expressionTypingServices.getTypeInfo(
@@ -53,52 +43,63 @@ import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor
)
}
@JvmOverloads fun KtExpression.analyzeInContext(
scope: LexicalScope,
contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
expectedType: KotlinType = TypeUtils.NO_EXPECTED_TYPE,
isStatement: Boolean = false,
contextDependency: ContextDependency = ContextDependency.INDEPENDENT,
expressionTypingServices: ExpressionTypingServices = contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>()
@JvmOverloads
fun KtExpression.analyzeInContext(
scope: LexicalScope,
contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
expectedType: KotlinType = TypeUtils.NO_EXPECTED_TYPE,
isStatement: Boolean = false,
contextDependency: ContextDependency = ContextDependency.INDEPENDENT,
expressionTypingServices: ExpressionTypingServices = contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>()
): BindingContext {
computeTypeInfoInContext(scope, contextExpression, trace, dataFlowInfo, expectedType, isStatement, contextDependency, expressionTypingServices)
computeTypeInfoInContext(
scope,
contextExpression,
trace,
dataFlowInfo,
expectedType,
isStatement,
contextDependency,
expressionTypingServices
)
return trace.bindingContext
}
@JvmOverloads fun KtExpression.computeTypeInContext(
scope: LexicalScope,
contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
expectedType: KotlinType = TypeUtils.NO_EXPECTED_TYPE
): KotlinType? {
return computeTypeInfoInContext(scope, contextExpression, trace, dataFlowInfo, expectedType).type
}
@JvmOverloads
fun KtExpression.computeTypeInContext(
scope: LexicalScope,
contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
expectedType: KotlinType = TypeUtils.NO_EXPECTED_TYPE
): KotlinType? = computeTypeInfoInContext(scope, contextExpression, trace, dataFlowInfo, expectedType).type
@JvmOverloads fun KtExpression.analyzeAsReplacement(
expressionToBeReplaced: KtExpression,
bindingContext: BindingContext,
scope: LexicalScope,
trace: BindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for analyzeAsReplacement()"),
contextDependency: ContextDependency = ContextDependency.INDEPENDENT
): BindingContext {
return analyzeInContext(scope,
expressionToBeReplaced,
dataFlowInfo = bindingContext.getDataFlowInfoBefore(expressionToBeReplaced),
expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, expressionToBeReplaced] ?: TypeUtils.NO_EXPECTED_TYPE,
isStatement = expressionToBeReplaced.isUsedAsStatement(bindingContext),
trace = trace,
contextDependency = contextDependency)
}
@JvmOverloads
fun KtExpression.analyzeAsReplacement(
expressionToBeReplaced: KtExpression,
bindingContext: BindingContext,
scope: LexicalScope,
trace: BindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for analyzeAsReplacement()"),
contextDependency: ContextDependency = ContextDependency.INDEPENDENT
): BindingContext = analyzeInContext(
scope,
expressionToBeReplaced,
dataFlowInfo = bindingContext.getDataFlowInfoBefore(expressionToBeReplaced),
expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, expressionToBeReplaced] ?: TypeUtils.NO_EXPECTED_TYPE,
isStatement = expressionToBeReplaced.isUsedAsStatement(bindingContext),
trace = trace,
contextDependency = contextDependency
)
@JvmOverloads fun KtExpression.analyzeAsReplacement(
expressionToBeReplaced: KtExpression,
bindingContext: BindingContext,
resolutionFacade: ResolutionFacade = expressionToBeReplaced.getResolutionFacade(),
trace: BindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for analyzeAsReplacement()"),
contextDependency: ContextDependency = ContextDependency.INDEPENDENT
@JvmOverloads
fun KtExpression.analyzeAsReplacement(
expressionToBeReplaced: KtExpression,
bindingContext: BindingContext,
resolutionFacade: ResolutionFacade = expressionToBeReplaced.getResolutionFacade(),
trace: BindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for analyzeAsReplacement()"),
contextDependency: ContextDependency = ContextDependency.INDEPENDENT
): BindingContext {
val scope = expressionToBeReplaced.getResolutionScope(bindingContext, resolutionFacade)
return analyzeAsReplacement(expressionToBeReplaced, bindingContext, scope, trace, contextDependency)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
@file:JvmName("ResolutionUtils")
@@ -20,7 +9,8 @@ package org.jetbrains.kotlin.idea.caches.resolve
import org.jetbrains.kotlin.analyzer.AnalysisResult
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.name.FqName
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]
*/
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,
@@ -187,13 +178,18 @@ fun KtElement.analyzeWithAllCompilerChecks(): AnalysisResult = getResolutionFaca
// this method don't check visibility and collect all descriptors with given fqName
fun ResolutionFacade.resolveImportReference(
moduleDescriptor: ModuleDescriptor,
fqName: FqName
moduleDescriptor: ModuleDescriptor,
fqName: FqName
): Collection<DeclarationDescriptor> {
val importDirective = KtPsiFactory(project).createImportDirective(ImportPath(fqName, false))
val qualifiedExpressionResolver = this.getFrontendService(moduleDescriptor, QualifiedExpressionResolver::class.java)
return qualifiedExpressionResolver.processImportReference(
importDirective, moduleDescriptor, BindingTraceContext(), excludedImportNames = emptyList(), packageFragmentForVisibilityCheck = null)?.getContributedDescriptors() ?: emptyList()
importDirective,
moduleDescriptor,
BindingTraceContext(),
excludedImportNames = emptyList(),
packageFragmentForVisibilityCheck = null
)?.getContributedDescriptors() ?: emptyList()
}
@Suppress("DEPRECATION")
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
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
return descriptors.flatMapTo(LinkedHashSet<DeclarationDescriptor>()) {
if (it is CallableMemberDescriptor && it.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) it.overriddenDescriptors else listOf(
it
)
if (it is CallableMemberDescriptor && it.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
it.overriddenDescriptors
else
listOf(it)
}
}
@@ -479,8 +469,9 @@ fun ResolutionScope.collectSyntheticStaticMembersAndConstructors(
nameFilter: (Name) -> Boolean
): List<FunctionDescriptor> {
val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java)
return (syntheticScopes.forceEnableSamAdapters().collectSyntheticStaticFunctions(this) + syntheticScopes.collectSyntheticConstructors(this))
.filter { kindFilter.accepts(it) && nameFilter(it.name) }
return (syntheticScopes.forceEnableSamAdapters().collectSyntheticStaticFunctions(this) + syntheticScopes.collectSyntheticConstructors(
this
)).filter { kindFilter.accepts(it) && nameFilter(it.name) }
}
// 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.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.kdoc
@@ -22,14 +11,24 @@ import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.resolve.BindingContext
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 {
/**
* 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)
return instance?.resolveSample(context, fromDescriptor, resolutionFacade, qualifiedName) ?: emptyList()
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.kdoc
@@ -46,17 +35,16 @@ import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addIfNotNull
fun resolveKDocLink(
context: BindingContext,
resolutionFacade: ResolutionFacade,
fromDescriptor: DeclarationDescriptor,
fromSubjectOfTag: KDocTag?,
qualifiedName: List<String>
): Collection<DeclarationDescriptor> =
when (fromSubjectOfTag?.knownTag) {
KDocKnownTag.PARAM -> resolveParamLink(fromDescriptor, qualifiedName)
KDocKnownTag.SAMPLE -> resolveKDocSampleLink(context, resolutionFacade, fromDescriptor, qualifiedName)
else -> resolveDefaultKDocLink(context, resolutionFacade, fromDescriptor, qualifiedName)
}
context: BindingContext,
resolutionFacade: ResolutionFacade,
fromDescriptor: DeclarationDescriptor,
fromSubjectOfTag: KDocTag?,
qualifiedName: List<String>
): Collection<DeclarationDescriptor> = when (fromSubjectOfTag?.knownTag) {
KDocKnownTag.PARAM -> resolveParamLink(fromDescriptor, qualifiedName)
KDocKnownTag.SAMPLE -> resolveKDocSampleLink(context, resolutionFacade, fromDescriptor, qualifiedName)
else -> resolveDefaultKDocLink(context, resolutionFacade, fromDescriptor, qualifiedName)
}
fun getParamDescriptors(fromDescriptor: DeclarationDescriptor): List<DeclarationDescriptor> {
@@ -89,10 +77,10 @@ private fun resolveParamLink(fromDescriptor: DeclarationDescriptor, qualifiedNam
}
fun resolveKDocSampleLink(
context: BindingContext,
resolutionFacade: ResolutionFacade,
fromDescriptor: DeclarationDescriptor,
qualifiedName: List<String>
context: BindingContext,
resolutionFacade: ResolutionFacade,
fromDescriptor: DeclarationDescriptor,
qualifiedName: List<String>
): Collection<DeclarationDescriptor> {
val resolvedViaService = SampleResolutionService.resolveSample(context, fromDescriptor, resolutionFacade, qualifiedName)
@@ -102,10 +90,10 @@ fun resolveKDocSampleLink(
}
private fun resolveDefaultKDocLink(
context: BindingContext,
resolutionFacade: ResolutionFacade,
fromDescriptor: DeclarationDescriptor,
qualifiedName: List<String>
context: BindingContext,
resolutionFacade: ResolutionFacade,
fromDescriptor: DeclarationDescriptor,
qualifiedName: List<String>
): Collection<DeclarationDescriptor> {
val contextScope = getKDocLinkResolutionScope(resolutionFacade, fromDescriptor)
@@ -137,14 +125,19 @@ private fun resolveDefaultKDocLink(
val factory = KtPsiFactory(resolutionFacade.project)
// TODO escape identifiers
val codeFragment = factory.createExpressionCodeFragment(qualifiedName.joinToString("."), contextElement)
val qualifiedExpression = codeFragment.findElementAt(codeFragment.textLength - 1)?.getStrictParentOfType<KtQualifiedExpression>() ?: return emptyList()
val (descriptor, memberName) = qualifiedExpressionResolver.resolveClassOrPackageInQualifiedExpression(qualifiedExpression, contextScope, context)
val qualifiedExpression =
codeFragment.findElementAt(codeFragment.textLength - 1)?.getStrictParentOfType<KtQualifiedExpression>() ?: return emptyList()
val (descriptor, memberName) = qualifiedExpressionResolver.resolveClassOrPackageInQualifiedExpression(
qualifiedExpression,
contextScope,
context
)
if (descriptor == null) return emptyList()
if (memberName != null) {
val memberScope = getKDocLinkMemberScope(descriptor, contextScope)
return memberScope.getContributedFunctions(memberName, NoLookupLocation.FROM_IDE) +
memberScope.getContributedVariables(memberName, NoLookupLocation.FROM_IDE) +
listOfNotNull(memberScope.getContributedClassifier(memberName, NoLookupLocation.FROM_IDE))
memberScope.getContributedVariables(memberName, NoLookupLocation.FROM_IDE) +
listOfNotNull(memberScope.getContributedClassifier(memberName, NoLookupLocation.FROM_IDE))
}
return listOf(descriptor)
}
@@ -155,16 +148,18 @@ private fun getPackageInnerScope(descriptor: PackageFragmentDescriptor): MemberS
private fun getClassInnerScope(outerScope: LexicalScope, descriptor: ClassDescriptor): LexicalScope {
val headerScope = LexicalScopeImpl(outerScope, descriptor, false, descriptor.thisAsReceiverParameter,
LexicalScopeKind.SYNTHETIC) {
val headerScope = LexicalScopeImpl(
outerScope, descriptor, false, descriptor.thisAsReceiverParameter,
LexicalScopeKind.SYNTHETIC
) {
descriptor.declaredTypeParameters.forEach { addClassifierDescriptor(it) }
descriptor.constructors.forEach { addFunctionDescriptor(it) }
}
val scopeChain = listOfNotNull(
descriptor.defaultType.memberScope,
descriptor.staticScope,
descriptor.companionObjectDescriptor?.defaultType?.memberScope
descriptor.defaultType.memberScope,
descriptor.staticScope,
descriptor.companionObjectDescriptor?.defaultType?.memberScope
)
return LexicalChainedScope(headerScope, descriptor, false, null, LexicalScopeKind.SYNTHETIC, scopeChain)
}
@@ -180,9 +175,10 @@ fun getKDocLinkResolutionScope(resolutionFacade: ResolutionFacade, contextDescri
is ClassDescriptor ->
getClassInnerScope(getOuterScope(contextDescriptor, resolutionFacade), contextDescriptor)
is FunctionDescriptor ->
FunctionDescriptorUtil.getFunctionInnerScope(getOuterScope(contextDescriptor, resolutionFacade),
contextDescriptor, LocalRedeclarationChecker.DO_NOTHING)
is FunctionDescriptor -> FunctionDescriptorUtil.getFunctionInnerScope(
getOuterScope(contextDescriptor, resolutionFacade),
contextDescriptor, LocalRedeclarationChecker.DO_NOTHING
)
is PropertyDescriptor ->
ScopeUtils.makeScopeForPropertyHeader(getOuterScope(contextDescriptor, resolutionFacade), contextDescriptor)
@@ -197,13 +193,14 @@ fun getKDocLinkResolutionScope(resolutionFacade: ResolutionFacade, contextDescri
private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, resolutionFacade: ResolutionFacade): LexicalScope {
val parent = descriptor.containingDeclaration!!
if (parent is PackageFragmentDescriptor) {
val containingFile = (descriptor.source as? PsiSourceElement)?.psi?.containingFile as? KtFile
?: return LexicalScope.Base(ImportingScope.Empty, parent)
val containingFile = (descriptor.source as? PsiSourceElement)?.psi?.containingFile as? KtFile ?: return LexicalScope.Base(
ImportingScope.Empty,
parent
)
val kotlinCacheService = ServiceManager.getService(containingFile.project, KotlinCacheService::class.java)
val facadeToUse = kotlinCacheService?.getResolutionFacade(listOf(containingFile)) ?: resolutionFacade
return facadeToUse.getFileResolutionScope(containingFile)
}
else {
} else {
return getKDocLinkResolutionScope(resolutionFacade, parent)
}
}
@@ -215,12 +212,14 @@ fun getKDocLinkMemberScope(descriptor: DeclarationDescriptor, contextScope: Lexi
is PackageViewDescriptor -> descriptor.memberScope
is ClassDescriptor -> {
ChainedMemberScope("Member scope for KDoc resolve", listOfNotNull(
ChainedMemberScope(
"Member scope for KDoc resolve", listOfNotNull(
descriptor.unsubstitutedMemberScope,
descriptor.staticScope,
descriptor.companionObjectDescriptor?.unsubstitutedMemberScope,
ExtensionsScope(descriptor, contextScope)
))
)
)
}
else -> MemberScope.Empty
@@ -228,40 +227,53 @@ fun getKDocLinkMemberScope(descriptor: DeclarationDescriptor, contextScope: Lexi
}
private class ExtensionsScope(
private val receiverClass: ClassDescriptor,
private val contextScope: LexicalScope
private val receiverClass: ClassDescriptor,
private val contextScope: LexicalScope
) : MemberScope {
private val receiverTypes = listOf(receiverClass.defaultType)
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
return contextScope.collectFunctions(name, location)
.flatMap { if (it is SimpleFunctionDescriptor && it.isExtension) it.substituteExtensionIfCallable(receiverTypes, CallType.DOT) else emptyList() }
return contextScope.collectFunctions(name, location).flatMap {
if (it is SimpleFunctionDescriptor && it.isExtension) it.substituteExtensionIfCallable(
receiverTypes,
CallType.DOT
) else emptyList()
}
}
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
return contextScope.collectVariables(name, location)
.flatMap { if (it is PropertyDescriptor && it.isExtension) it.substituteExtensionIfCallable(receiverTypes, CallType.DOT) else emptyList() }
return contextScope.collectVariables(name, location).flatMap {
if (it is PropertyDescriptor && it.isExtension) it.substituteExtensionIfCallable(
receiverTypes,
CallType.DOT
) else emptyList()
}
}
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()
return contextScope.collectDescriptorsFiltered(kindFilter exclude DescriptorKindExclude.NonExtensions, nameFilter, changeNamesForAliased = true)
.flatMap { if (it is CallableDescriptor && it.isExtension) it.substituteExtensionIfCallable(receiverTypes, CallType.DOT) else emptyList() }
return contextScope.collectDescriptorsFiltered(
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> {
return getContributedDescriptors(kindFilter = DescriptorKindFilter.FUNCTIONS)
.map { it.name }
.toSet()
}
override fun getFunctionNames(): Set<Name> =
getContributedDescriptors(kindFilter = DescriptorKindFilter.FUNCTIONS).map { it.name }.toSet()
override fun getVariableNames(): Set<Name> {
return getContributedDescriptors(kindFilter = DescriptorKindFilter.VARIABLES)
.map { it.name }
.toSet()
}
override fun getVariableNames(): Set<Name> =
getContributedDescriptors(kindFilter = DescriptorKindFilter.VARIABLES).map { it.name }.toSet()
override fun getClassifierNames() = null
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.refactoring.introduce
@@ -35,11 +24,11 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
class ExtractableSubstringInfo(
val startEntry: KtStringTemplateEntry,
val endEntry: KtStringTemplateEntry,
val prefix: String,
val suffix: String,
type: KotlinType? = null
val startEntry: KtStringTemplateEntry,
val endEntry: KtStringTemplateEntry,
val prefix: String,
val suffix: String,
type: KotlinType? = null
) {
private fun guessLiteralType(literal: String): KotlinType {
val facade = template.getResolutionFacade()
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.resolve
@@ -51,8 +40,6 @@ interface ResolutionFacade {
}
inline fun <reified T : Any> ResolutionFacade.frontendService(): T
= this.getFrontendService(T::class.java)
inline fun <reified T : Any> ResolutionFacade.frontendService(): T = this.getFrontendService(T::class.java)
inline fun <reified T : Any> ResolutionFacade.ideService(): T
= this.getIdeService(T::class.java)
inline fun <reified T : Any> ResolutionFacade.ideService(): T = this.getIdeService(T::class.java)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.util
@@ -146,7 +135,8 @@ sealed class CallTypeAndReceiver<TReceiver : KtElement?, out TCallType : CallTyp
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 DELEGATE(receiver: KtExpression?) : CallTypeAndReceiver<KtExpression?, CallType.DELEGATE>(CallType.DELEGATE, receiver)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
@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.checker.StrictEqualityTypeChecker
import org.jetbrains.kotlin.types.typeUtil.*
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.*
fun CallableDescriptor.fuzzyReturnType() = returnType?.toFuzzyType(typeParameters)
@@ -67,8 +55,8 @@ fun FuzzyType.presentationType(): KotlinType {
fun KotlinType.toFuzzyType(freeParameters: Collection<TypeParameterDescriptor>) = FuzzyType(this, freeParameters)
class FuzzyType(
val type: KotlinType,
freeParameters: Collection<TypeParameterDescriptor>
val type: KotlinType,
freeParameters: Collection<TypeParameterDescriptor>
) {
val freeParameters: Set<TypeParameterDescriptor>
@@ -79,12 +67,10 @@ class FuzzyType(
if (usedTypeParameters.isNotEmpty()) {
val originalFreeParameters = freeParameters.map { it.toOriginal() }.toSet()
this.freeParameters = usedTypeParameters.filter { it.toOriginal() in originalFreeParameters }.toSet()
}
else {
} else {
this.freeParameters = emptySet()
}
}
else {
} else {
this.freeParameters = emptySet()
}
}
@@ -115,17 +101,13 @@ class FuzzyType(
}
}
fun checkIsSubtypeOf(otherType: FuzzyType): TypeSubstitutor?
= matchedSubstitutor(otherType, MatchKind.IS_SUBTYPE)
fun checkIsSubtypeOf(otherType: FuzzyType): TypeSubstitutor? = matchedSubstitutor(otherType, MatchKind.IS_SUBTYPE)
fun checkIsSuperTypeOf(otherType: FuzzyType): TypeSubstitutor?
= matchedSubstitutor(otherType, MatchKind.IS_SUPERTYPE)
fun checkIsSuperTypeOf(otherType: FuzzyType): TypeSubstitutor? = matchedSubstitutor(otherType, MatchKind.IS_SUPERTYPE)
fun checkIsSubtypeOf(otherType: KotlinType): TypeSubstitutor?
= checkIsSubtypeOf(otherType.toFuzzyType(emptyList()))
fun checkIsSubtypeOf(otherType: KotlinType): TypeSubstitutor? = checkIsSubtypeOf(otherType.toFuzzyType(emptyList()))
fun checkIsSuperTypeOf(otherType: KotlinType): TypeSubstitutor?
= checkIsSuperTypeOf(otherType.toFuzzyType(emptyList()))
fun checkIsSuperTypeOf(otherType: KotlinType): TypeSubstitutor? = checkIsSuperTypeOf(otherType.toFuzzyType(emptyList()))
private enum class MatchKind {
IS_SUBTYPE,
@@ -181,14 +163,14 @@ class FuzzyType(
}.buildSubstitutor()
val substitutionMap: Map<TypeConstructor, TypeProjection> = constraintSystem.typeVariables
.map { it.originalTypeParameter }
.associateBy(
keySelector = { it.typeConstructor },
valueTransform = {
val typeProjection = TypeProjectionImpl(Variance.INVARIANT, it.defaultType)
val substitutedProjection = substitutorToKeepCapturedTypes.substitute(typeProjection)
substitutedProjection?.takeUnless { ErrorUtils.containsUninferredParameter(it.type) } ?: typeProjection
})
.map { it.originalTypeParameter }
.associateBy(
keySelector = { it.typeConstructor },
valueTransform = {
val typeProjection = TypeProjectionImpl(Variance.INVARIANT, it.defaultType)
val substitutedProjection = substitutorToKeepCapturedTypes.substitute(typeProjection)
substitutedProjection?.takeUnless { ErrorUtils.containsUninferredParameter(it.type) } ?: typeProjection
})
return TypeConstructorSubstitution.createByConstructorsMap(substitutionMap, approximateCapturedTypes = true).buildSubstitutor()
}
}
@@ -199,7 +181,10 @@ fun TypeSubstitution.hasConflictWith(other: TypeSubstitution, freeParameters: Co
val type = parameter.defaultType
val substituted1 = this[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.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.util
@@ -33,11 +22,16 @@ abstract class ImportInsertHelper {
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 {
@JvmStatic fun getInstance(project: Project): ImportInsertHelper
= ServiceManager.getService<ImportInsertHelper>(project, ImportInsertHelper::class.java)
@JvmStatic
fun getInstance(project: Project): ImportInsertHelper =
ServiceManager.getService<ImportInsertHelper>(project, ImportInsertHelper::class.java)
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.util
@@ -29,4 +18,4 @@ fun FunctionDescriptor.shouldNotConvertToProperty(notProperties: Set<FqNameUnsaf
}
fun SyntheticJavaPropertyDescriptor.suppressedByNotPropertyList(set: Set<FqNameUnsafe>) =
getMethod.shouldNotConvertToProperty(set) || setMethod?.shouldNotConvertToProperty(set) ?: false
getMethod.shouldNotConvertToProperty(set) || setMethod?.shouldNotConvertToProperty(set) ?: false
@@ -1,23 +1,11 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.util
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
@@ -40,17 +28,17 @@ import org.jetbrains.kotlin.util.descriptorsEqualWithSubstitution
import java.util.*
class ShadowedDeclarationsFilter(
private val bindingContext: BindingContext,
private val resolutionFacade: ResolutionFacade,
private val context: PsiElement,
private val explicitReceiverValue: ReceiverValue?
private val bindingContext: BindingContext,
private val resolutionFacade: ResolutionFacade,
private val context: PsiElement,
private val explicitReceiverValue: ReceiverValue?
) {
companion object {
fun create(
bindingContext: BindingContext,
resolutionFacade: ResolutionFacade,
context: PsiElement,
callTypeAndReceiver: CallTypeAndReceiver<*, *>
bindingContext: BindingContext,
resolutionFacade: ResolutionFacade,
context: PsiElement,
callTypeAndReceiver: CallTypeAndReceiver<*, *>
): ShadowedDeclarationsFilter? {
val receiverExpression = when (callTypeAndReceiver) {
is CallTypeAndReceiver.DEFAULT -> null
@@ -73,20 +61,16 @@ class ShadowedDeclarationsFilter(
private val psiFactory = KtPsiFactory(resolutionFacade.project)
private val dummyExpressionFactory = DummyExpressionFactory(psiFactory)
fun <TDescriptor : DeclarationDescriptor> filter(declarations: Collection<TDescriptor>): Collection<TDescriptor> {
return declarations
.groupBy { signature(it) }
.values
.flatMap { group -> filterEqualSignatureGroup(group) }
}
fun <TDescriptor : DeclarationDescriptor> filter(declarations: Collection<TDescriptor>): Collection<TDescriptor> =
declarations.groupBy { signature(it) }.values.flatMap { group -> filterEqualSignatureGroup(group) }
fun <TDescriptor : DeclarationDescriptor> createNonImportedDeclarationsFilter(
importedDeclarations: Collection<DeclarationDescriptor>
importedDeclarations: Collection<DeclarationDescriptor>
): (Collection<TDescriptor>) -> Collection<TDescriptor> {
val importedDeclarationsSet = importedDeclarations.toSet()
val importedDeclarationsBySignature = importedDeclarationsSet.groupBy { signature(it) }
return filter@ { declarations ->
return filter@{ declarations ->
// optimization
if (declarations.size == 1 && importedDeclarationsBySignature[signature(declarations.single())] == null) return@filter declarations
@@ -103,19 +87,18 @@ class ShadowedDeclarationsFilter(
}
}
private fun signature(descriptor: DeclarationDescriptor): Any =
when (descriptor) {
is SimpleFunctionDescriptor -> FunctionSignature(descriptor)
is VariableDescriptor -> descriptor.name
is ClassDescriptor -> descriptor.importableFqName ?: descriptor
else -> descriptor
}
private fun signature(descriptor: DeclarationDescriptor): Any = when (descriptor) {
is SimpleFunctionDescriptor -> FunctionSignature(descriptor)
is VariableDescriptor -> descriptor.name
is ClassDescriptor -> descriptor.importableFqName ?: descriptor
else -> descriptor
}
private fun packageName(descriptor: DeclarationDescriptor) = descriptor.importableFqName?.parent()
private fun <TDescriptor : DeclarationDescriptor> filterEqualSignatureGroup(
descriptors: Collection<TDescriptor>,
descriptorsToImport: Collection<TDescriptor> = emptyList()
descriptors: Collection<TDescriptor>,
descriptorsToImport: Collection<TDescriptor> = emptyList()
): Collection<TDescriptor> {
if (descriptors.size == 1) return descriptors
@@ -143,7 +126,8 @@ class ShadowedDeclarationsFilter(
}
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 {
private val expression = dummyArgumentExpressions[index]
@@ -153,8 +137,7 @@ class ShadowedDeclarationsFilter(
override val asName = parameters[index].name
override val referenceExpression = null
}
}
else {
} else {
null
}
@@ -206,17 +189,23 @@ class ShadowedDeclarationsFilter(
}
val dataFlowInfo = bindingContext.getDataFlowInfoBefore(context)
val context = BasicCallResolutionContext.create(bindingTrace, scope, newCall, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo,
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
false, /* languageVersionSettings */ resolutionFacade.frontendService(),
resolutionFacade.frontendService<DataFlowValueFactory>())
val context = BasicCallResolutionContext.create(
bindingTrace, scope, newCall, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo,
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
false, /* languageVersionSettings */ resolutionFacade.frontendService(),
resolutionFacade.frontendService<DataFlowValueFactory>()
)
val callResolver = resolutionFacade.frontendService<CallResolver>()
val results = if (isFunction) callResolver.resolveFunctionCall(context) else callResolver.resolveSimpleProperty(context)
val resultingDescriptors = results.resultingCalls.map { it.resultingDescriptor }
val resultingOriginals = resultingDescriptors.mapTo(HashSet<DeclarationDescriptor>()) { it.original }
val filtered = descriptors.filter { candidateDescriptor ->
candidateDescriptor.original in resultingOriginals /* optimization */
&& resultingDescriptors.any { descriptorsEqualWithSubstitution(it, candidateDescriptor) }
candidateDescriptor.original in resultingOriginals /* optimization */ && resultingDescriptors.any {
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 */
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
@file:JvmName("TypeUtils")
@@ -69,9 +58,8 @@ private fun KotlinType.approximateNonDynamicFlexibleTypes(
approximation = if (nullability() == TypeNullability.NOT_NULL) approximation.makeNullableAsSpecified(false) else approximation
if (approximation.isMarkedNullable && !flexible.lowerBound.isMarkedNullable && TypeUtils.isTypeParameter(approximation) && TypeUtils.hasNullableSuperType(
approximation
)
if (approximation.isMarkedNullable && !flexible.lowerBound
.isMarkedNullable && TypeUtils.isTypeParameter(approximation) && TypeUtils.hasNullableSuperType(approximation)
) {
approximation = approximation.makeNullableAsSpecified(false)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.util
@@ -56,14 +45,21 @@ fun KtFunctionLiteral.findLabelAndCall(): Pair<Name?, KtCallExpression?> {
}
fun SmartCastManager.getSmartCastVariantsWithLessSpecificExcluded(
receiverToCast: ReceiverValue,
bindingContext: BindingContext,
containingDeclarationOrModule: DeclarationDescriptor,
dataFlowInfo: DataFlowInfo,
languageVersionSettings: LanguageVersionSettings,
dataFlowValueFactory: DataFlowValueFactory
receiverToCast: ReceiverValue,
bindingContext: BindingContext,
containingDeclarationOrModule: DeclarationDescriptor,
dataFlowInfo: DataFlowInfo,
languageVersionSettings: LanguageVersionSettings,
dataFlowValueFactory: DataFlowValueFactory
): List<KotlinType> {
val variants = getSmartCastVariants(receiverToCast, bindingContext, containingDeclarationOrModule, dataFlowInfo, languageVersionSettings, dataFlowValueFactory)
val variants = getSmartCastVariants(
receiverToCast,
bindingContext,
containingDeclarationOrModule,
dataFlowInfo,
languageVersionSettings,
dataFlowValueFactory
)
return variants.filter { 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.
*
* 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.
* 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.
*/
@file:JvmName("ExtensionUtils")
@@ -33,8 +22,8 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.nullability
fun <TCallable : CallableDescriptor> TCallable.substituteExtensionIfCallable(
receiverTypes: Collection<KotlinType>,
callType: CallType<*>
receiverTypes: Collection<KotlinType>,
callType: CallType<*>
): Collection<TCallable> {
if (!callType.descriptorKindFilter.accepts(this)) return listOf()
@@ -44,22 +33,20 @@ fun <TCallable : CallableDescriptor> TCallable.substituteExtensionIfCallable(
}
val extensionReceiverType = fuzzyExtensionReceiverType()!!
val substitutors = types
.mapNotNull {
var substitutor = extensionReceiverType.checkIsSuperTypeOf(it)
// check if we may fail due to receiver expression being nullable
if (substitutor == null && it.nullability() == TypeNullability.NULLABLE && extensionReceiverType.nullability() == TypeNullability.NOT_NULL) {
substitutor = extensionReceiverType.checkIsSuperTypeOf(it.makeNotNullable())
}
substitutor
}
val substitutors = types.mapNotNull {
var substitutor = extensionReceiverType.checkIsSuperTypeOf(it)
// check if we may fail due to receiver expression being nullable
if (substitutor == null && it.nullability() == TypeNullability.NULLABLE && extensionReceiverType.nullability() == TypeNullability.NOT_NULL) {
substitutor = extensionReceiverType.checkIsSuperTypeOf(it.makeNotNullable())
}
substitutor
}
return if (typeParameters.isEmpty()) { // optimization for non-generic callables
if (substitutors.any()) listOf(this) else listOf()
}
else {
} else {
substitutors
.mapNotNull { @Suppress("UNCHECKED_CAST") (substitute(it) as TCallable?) }
.toList()
.mapNotNull { @Suppress("UNCHECKED_CAST") (substitute(it) as TCallable?) }
.toList()
}
}
@@ -76,20 +63,16 @@ fun ReceiverValue?.getThisReceiverOwner(bindingContext: BindingContext): Declara
}
}
fun ReceiverValue?.getReceiverTargetDescriptor(bindingContext: BindingContext): DeclarationDescriptor? {
return when (this) {
is ExpressionReceiver -> {
val expression = KtPsiUtil.deparenthesize(this.expression)
val refExpression = when (expression) {
is KtThisExpression -> expression.instanceReference
is KtReferenceExpression -> expression
else -> null
} ?: return null
bindingContext[BindingContext.REFERENCE_TARGET, refExpression]
}
is ImplicitReceiver -> this.declarationDescriptor
fun ReceiverValue?.getReceiverTargetDescriptor(bindingContext: BindingContext): DeclarationDescriptor? = when (this) {
is ExpressionReceiver -> when (val expression = KtPsiUtil.deparenthesize(this.expression)) {
is KtThisExpression -> expression.instanceReference
is KtReferenceExpression -> expression
else -> null
}?.let { referenceExpression ->
bindingContext[BindingContext.REFERENCE_TARGET, referenceExpression]
}
is ImplicitReceiver -> this.declarationDescriptor
else -> null
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.util
@@ -42,14 +31,10 @@ interface ReceiverExpressionFactory {
fun createExpression(psiFactory: KtPsiFactory, shortThis: Boolean = true): KtExpression
}
fun LexicalScope.getFactoryForImplicitReceiverWithSubtypeOf(receiverType: KotlinType): ReceiverExpressionFactory? {
return getImplicitReceiversWithInstanceToExpression()
.entries
.firstOrNull { (receiverDescriptor, _) ->
receiverDescriptor.type.isSubtypeOf(receiverType)
}
?.value
}
fun LexicalScope.getFactoryForImplicitReceiverWithSubtypeOf(receiverType: KotlinType): ReceiverExpressionFactory? =
getImplicitReceiversWithInstanceToExpression().entries.firstOrNull { (receiverDescriptor, _) ->
receiverDescriptor.type.isSubtypeOf(receiverType)
}?.value
fun LexicalScope.getImplicitReceiversWithInstanceToExpression(
excludeShadowedByDslMarkers: Boolean = false
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.util.psi.patternMatching
@@ -34,7 +23,7 @@ interface KotlinPsiRange {
override fun getTextRange(): TextRange = TextRange.EMPTY_RANGE
}
class ListRange(override val elements: List<PsiElement>): KotlinPsiRange {
class ListRange(override val elements: List<PsiElement>) : KotlinPsiRange {
val startElement: PsiElement = elements.first()
val endElement: PsiElement = elements.last()
@@ -63,29 +52,28 @@ interface KotlinPsiRange {
val matches = ArrayList<UnificationResult.Matched>()
scope.accept(
object: KtTreeVisitorVoid() {
override fun visitKtElement(element: KtElement) {
val range = element
.siblings()
.filter(SIGNIFICANT_FILTER)
.take(elements.size)
.toList()
.toRange()
object : KtTreeVisitorVoid() {
override fun visitKtElement(element: KtElement) {
val range = element
.siblings()
.filter(SIGNIFICANT_FILTER)
.take(elements.size)
.toList()
.toRange()
val result = unifier.unify(range, this@KotlinPsiRange)
val result = unifier.unify(range, this@KotlinPsiRange)
if (result is UnificationResult.StronglyMatched) {
if (result is UnificationResult.StronglyMatched) {
matches.add(result)
} else {
val matchCountSoFar = matches.size
super.visitKtElement(element)
if (result is UnificationResult.WeaklyMatched && matches.size == matchCountSoFar) {
matches.add(result)
}
else {
val matchCountSoFar = matches.size
super.visitKtElement(element)
if (result is UnificationResult.WeaklyMatched && matches.size == matchCountSoFar) {
matches.add(result)
}
}
}
}
}
)
return matches
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.util.psi.patternMatching
@@ -71,43 +60,43 @@ interface UnificationResult {
override val status: Status get() = UNMATCHED
}
interface Matched: UnificationResult {
interface Matched : UnificationResult {
val range: KotlinPsiRange
val substitution: Map<UnifierParameter, KtElement>
override val status: Status get() = MATCHED
}
class StronglyMatched(
override val range: KotlinPsiRange,
override val substitution: Map<UnifierParameter, KtElement>
): Matched
override val range: KotlinPsiRange,
override val substitution: Map<UnifierParameter, KtElement>
) : Matched
class WeaklyMatched(
override val range: KotlinPsiRange,
override val substitution: Map<UnifierParameter, KtElement>,
val weakMatches: Map<KtElement, KtElement>
): Matched
override val range: KotlinPsiRange,
override val substitution: Map<UnifierParameter, KtElement>,
val weakMatches: Map<KtElement, KtElement>
) : Matched
val status: Status
val matched: Boolean get() = status != UNMATCHED
}
class UnifierParameter(
val descriptor: DeclarationDescriptor,
val expectedType: KotlinType?
val descriptor: DeclarationDescriptor,
val expectedType: KotlinType?
)
class KotlinPsiUnifier(
parameters: Collection<UnifierParameter> = Collections.emptySet(),
val allowWeakMatches: Boolean = false
parameters: Collection<UnifierParameter> = Collections.emptySet(),
val allowWeakMatches: Boolean = false
) {
companion object {
val DEFAULT = KotlinPsiUnifier()
}
private inner class Context(
val originalTarget: KotlinPsiRange,
val originalPattern: KotlinPsiRange
val originalTarget: KotlinPsiRange,
val originalPattern: KotlinPsiRange
) {
val patternContext: BindingContext = originalPattern.getBindingContext()
val targetContext: BindingContext = originalTarget.getBindingContext()
@@ -155,7 +144,7 @@ class KotlinPsiUnifier(
private fun matchCalls(call1: Call, call2: Call): Boolean {
return matchReceivers(call1.explicitReceiver, call2.explicitReceiver) &&
matchReceivers(call1.dispatchReceiver, call2.dispatchReceiver)
matchReceivers(call1.dispatchReceiver, call2.dispatchReceiver)
}
private fun matchArguments(arg1: ValueArgument, arg2: ValueArgument): Status {
@@ -210,25 +199,23 @@ class KotlinPsiUnifier(
fun checkImplicitReceiver(implicitCall: ResolvedCall<*>, explicitCall: ResolvedCall<*>): Boolean {
val (implicitReceiver, explicitReceiver) =
when (explicitCall.explicitReceiverKind) {
ExplicitReceiverKind.EXTENSION_RECEIVER ->
(implicitCall.extensionReceiver as? ImplicitReceiver) to
(explicitCall.extensionReceiver as? ExpressionReceiver)
when (explicitCall.explicitReceiverKind) {
ExplicitReceiverKind.EXTENSION_RECEIVER ->
(implicitCall.extensionReceiver as? ImplicitReceiver) to (explicitCall.extensionReceiver as? ExpressionReceiver)
ExplicitReceiverKind.DISPATCH_RECEIVER ->
(implicitCall.dispatchReceiver as? ImplicitReceiver) to
(explicitCall.dispatchReceiver as? ExpressionReceiver)
ExplicitReceiverKind.DISPATCH_RECEIVER ->
(implicitCall.dispatchReceiver as? ImplicitReceiver) to (explicitCall.dispatchReceiver as? ExpressionReceiver)
else ->
null to null
}
else ->
null to null
}
val thisExpression = explicitReceiver?.expression as? KtThisExpression
if (implicitReceiver == null || thisExpression == null) return false
return matchDescriptors(
implicitReceiver.declarationDescriptor,
thisExpression.getAdjustedResolvedCall()?.candidateDescriptor?.containingDeclaration
implicitReceiver.declarationDescriptor,
thisExpression.getAdjustedResolvedCall()?.candidateDescriptor?.containingDeclaration
)
}
@@ -236,7 +223,10 @@ class KotlinPsiUnifier(
return when {
rc1.explicitReceiverKind == rc2.explicitReceiverKind -> {
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)
@@ -279,8 +269,7 @@ class KotlinPsiUnifier(
private fun KtElement.getAdjustedResolvedCall(): ResolvedCall<*>? {
val rc = if (this is KtArrayAccessExpression) {
bindingContext[BindingContext.INDEXED_LVALUE_GET, this]
}
else {
} else {
getResolvedCall(bindingContext)?.let {
when {
it !is VariableAsFunctionResolvedCall -> it
@@ -330,15 +319,20 @@ class KotlinPsiUnifier(
}
private fun matchTypes(
type1: KotlinType?,
type2: KotlinType?,
typeRef1: KtTypeReference? = null,
typeRef2: KtTypeReference? = null
type1: KotlinType?,
type2: KotlinType?,
typeRef1: KtTypeReference? = null,
typeRef2: KtTypeReference? = null
): Status? {
if (type1 != null && type2 != null) {
val unwrappedType1 = type1.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 is AbbreviatedType != type2 is AbbreviatedType) return UNMATCHED
@@ -348,16 +342,18 @@ class KotlinPsiUnifier(
if (type1.isMarkedNullable != type2.isMarkedNullable) return UNMATCHED
if (!matchDescriptors(
type1.constructor.declarationDescriptor,
type2.constructor.declarationDescriptor)) return UNMATCHED
type2.constructor.declarationDescriptor
)
) return UNMATCHED
val args1 = type1.arguments
val args2 = type2.arguments
if (args1.size != args2.size) return UNMATCHED
if (!args1.withIndex().all { p ->
val (i, arg1) = p
val arg2 = args2[i]
matchTypeArguments(i, arg1, arg2, typeRef1, typeRef2)
}) return UNMATCHED
val (i, arg1) = p
val arg2 = args2[i]
matchTypeArguments(i, arg1, arg2, typeRef1, typeRef2)
}) return UNMATCHED
return MATCHED
}
@@ -366,11 +362,11 @@ class KotlinPsiUnifier(
}
private fun matchTypeArguments(
argIndex: Int,
arg1: TypeProjection,
arg2: TypeProjection,
typeRef1: KtTypeReference?,
typeRef2: KtTypeReference?
argIndex: Int,
arg1: TypeProjection,
arg2: TypeProjection,
typeRef1: KtTypeReference?,
typeRef2: KtTypeReference?
): Boolean {
val typeArgRef1 = typeRef1?.typeElement?.typeArgumentsAsTypes?.getOrNull(argIndex)
val typeArgRef2 = typeRef2?.typeElement?.typeArgumentsAsTypes?.getOrNull(argIndex)
@@ -382,11 +378,10 @@ class KotlinPsiUnifier(
val status = if (!checkEquivalence && typeRef1 != null && typeRef2 != null) {
val typePsi1 = argType1.constructor.declarationDescriptor?.source?.getPsi()
val typePsi2 = argType2.constructor.declarationDescriptor?.source?.getPsi()
descriptorToParameter[typePsi1]?.let { substitute(it, typeArgRef2) } ?:
descriptorToParameter[typePsi2]?.let { substitute(it, typeArgRef1) } ?:
matchTypes(argType1, argType2, typeArgRef1, typeArgRef2)
}
else matchTypes(argType1, argType2, typeArgRef1, typeArgRef2)
descriptorToParameter[typePsi1]?.let { substitute(it, typeArgRef2) }
?: descriptorToParameter[typePsi2]?.let { substitute(it, typeArgRef1) }
?: matchTypes(argType1, argType2, typeArgRef1, typeArgRef2)
} else matchTypes(argType1, argType2, typeArgRef1, typeArgRef2)
return status == MATCHED
}
@@ -413,12 +408,11 @@ class KotlinPsiUnifier(
else -> false
}
private fun KtBinaryExpression.matchComplexAssignmentWithSimple(simple: KtBinaryExpression): Status? {
return when {
doUnify(left, simple.left) == UNMATCHED -> UNMATCHED
private fun KtBinaryExpression.matchComplexAssignmentWithSimple(simple: KtBinaryExpression): Status? =
when (doUnify(left, simple.left)) {
UNMATCHED -> UNMATCHED
else -> simple.right?.let { matchCalls(this, it) } ?: UNMATCHED
}
}
private fun KtBinaryExpression.matchAssignment(e: KtElement): Status? {
val operationType = operationReference.getReferencedNameElementType() as KtToken
@@ -435,11 +429,13 @@ class KotlinPsiUnifier(
val setResolvedCall = bindingContext[BindingContext.INDEXED_LVALUE_SET, lhs]
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()
if (assignResolvedCall == null) return UNMATCHED
val assignResolvedCall = getAdjustedResolvedCall() ?: return UNMATCHED
val operationName = OperatorConventions.getNameForOperationSymbol(operationType)
if (assignResolvedCall.resultingDescriptor?.name == operationName) return matchCalls(this, e)
@@ -456,13 +452,11 @@ class KotlinPsiUnifier(
private fun PsiElement.isIncrement(): Boolean {
val parent = parent
return parent is KtUnaryExpression
&& this == parent.operationReference
&& ((parent.operationToken as KtToken) in OperatorConventions.INCREMENT_OPERATIONS)
return parent is KtUnaryExpression && this == parent.operationReference && ((parent.operationToken as KtToken) in OperatorConventions.INCREMENT_OPERATIONS)
}
private fun KtCallableReferenceExpression.hasExpressionReceiver(): Boolean =
bindingContext[BindingContext.DOUBLE_COLON_LHS, receiverExpression] is DoubleColonLHS.Expression
bindingContext[BindingContext.DOUBLE_COLON_LHS, receiverExpression] is DoubleColonLHS.Expression
private fun matchCallableReferences(e1: KtCallableReferenceExpression, e2: KtCallableReferenceExpression): Status? {
if (e1.hasExpressionReceiver() || e2.hasExpressionReceiver()) return null
@@ -510,10 +504,11 @@ class KotlinPsiUnifier(
}
private fun matchCallables(
decl1: KtDeclaration,
decl2: KtDeclaration,
desc1: CallableDescriptor,
desc2: CallableDescriptor): Status? {
decl1: KtDeclaration,
decl2: KtDeclaration,
desc1: CallableDescriptor,
desc2: CallableDescriptor
): Status? {
fun needToCompareReturnTypes(): Boolean {
if (decl1 !is KtCallableDeclaration) return true
return decl1.typeReference != null || (decl2 as KtCallableDeclaration).typeReference != null
@@ -527,8 +522,11 @@ class KotlinPsiUnifier(
val type1 = desc1.returnType
val type2 = desc2.returnType
if (type1 != type2
&& (type1 == null || type2 == null || type1.isError || type2.isError || matchTypes(type1, type2) != MATCHED)) {
if (type1 != type2 && (type1 == null || type2 == null || type1.isError || type2.isError || matchTypes(
type1,
type2
) != MATCHED)
) {
return UNMATCHED
}
}
@@ -540,14 +538,14 @@ class KotlinPsiUnifier(
val params2 = desc2.valueParameters
val zippedParams = params1.zip(params2)
val parametersMatch =
(params1.size == params2.size) && zippedParams.all { matchTypes(it.first.type, it.second.type) == MATCHED }
(params1.size == params2.size) && zippedParams.all { matchTypes(it.first.type, it.second.type) == MATCHED }
if (!parametersMatch) return UNMATCHED
zippedParams.forEach { declarationPatternsToTargets.putValue(it.first, it.second) }
return doUnify(
(decl1 as? KtTypeParameterListOwner)?.typeParameters?.toRange() ?: Empty,
(decl2 as? KtTypeParameterListOwner)?.typeParameters?.toRange() ?: Empty
(decl1 as? KtTypeParameterListOwner)?.typeParameters?.toRange() ?: Empty,
(decl2 as? KtTypeParameterListOwner)?.typeParameters?.toRange() ?: Empty
) and when (decl1) {
is KtDeclarationWithBody ->
doUnify(decl1.bodyExpression, (decl2 as KtDeclarationWithBody).bodyExpression)
@@ -570,14 +568,19 @@ class KotlinPsiUnifier(
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
}
private fun <T: DeclarationDescriptor> matchContainedDescriptors(
declarations1: List<T>,
declarations2: List<T>,
matchPair: (Pair<T, T>) -> Boolean
private fun <T : DeclarationDescriptor> matchContainedDescriptors(
declarations1: List<T>,
declarations2: List<T>,
matchPair: (Pair<T, T>) -> Boolean
): Boolean {
val zippedParams = declarations1.zip(declarations2)
if (declarations1.size != declarations2.size || !zippedParams.all { matchPair(it) }) return false
@@ -587,13 +590,14 @@ class KotlinPsiUnifier(
}
private fun matchClasses(
decl1: KtClassOrObject,
decl2: KtClassOrObject,
desc1: ClassDescriptor,
desc2: ClassDescriptor): Status? {
decl1: KtClassOrObject,
decl2: KtClassOrObject,
desc1: ClassDescriptor,
desc2: ClassDescriptor
): Status? {
class OrderInfo<out T>(
val orderSensitive: List<T>,
val orderInsensitive: List<T>
val orderSensitive: List<T>,
val orderInsensitive: List<T>
)
fun getMemberOrderInfo(cls: KtClassOrObject): OrderInfo<KtDeclaration> {
@@ -610,9 +614,8 @@ class KotlinPsiUnifier(
}
fun resolveAndSortDeclarationsByDescriptor(declarations: List<KtDeclaration>): List<Pair<KtDeclaration, DeclarationDescriptor?>> {
return declarations
.map { it to it.bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, it] }
.sortedBy { it.second?.let { IdeDescriptorRenderers.SOURCE_CODE.render(it) } ?: "" }
return declarations.map { it to it.bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, it] }
.sortedBy { it.second?.let { descriptor -> IdeDescriptorRenderers.SOURCE_CODE.render(descriptor) } ?: "" }
}
fun sortDeclarationsByElementType(declarations: List<KtDeclaration>): List<KtDeclaration> {
@@ -642,7 +645,10 @@ class KotlinPsiUnifier(
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(delegationInfo1.orderSensitive.toRange(), delegationInfo2.orderSensitive.toRange())
if (status == UNMATCHED) return UNMATCHED
@@ -654,19 +660,20 @@ class KotlinPsiUnifier(
val sortedMembers2 = resolveAndSortDeclarationsByDescriptor(membersInfo2.orderInsensitive)
if ((sortedMembers1.size != sortedMembers2.size)) return UNMATCHED
if (sortedMembers1.zip(sortedMembers2).any {
val (d1, d2) = it
(matchDeclarations(d1.first, d2.first, d1.second, d2.second) ?: doUnify(d1.first, d2.first)) == UNMATCHED
}) return UNMATCHED
val (d1, d2) = it
(matchDeclarations(d1.first, d2.first, d1.second, d2.second) ?: doUnify(d1.first, d2.first)) == UNMATCHED
}
) return UNMATCHED
return doUnify(
sortDeclarationsByElementType(membersInfo1.orderSensitive).toRange(),
sortDeclarationsByElementType(membersInfo2.orderSensitive).toRange()
sortDeclarationsByElementType(membersInfo1.orderSensitive).toRange(),
sortDeclarationsByElementType(membersInfo2.orderSensitive).toRange()
)
}
private fun matchTypeParameters(
desc1: TypeParameterDescriptor,
desc2: TypeParameterDescriptor
desc1: TypeParameterDescriptor,
desc2: TypeParameterDescriptor
): Status {
if (desc1.variance != desc2.variance) return UNMATCHED
if (!matchTypes(desc1.upperBounds, desc2.upperBounds)) return UNMATCHED
@@ -682,18 +689,22 @@ class KotlinPsiUnifier(
}
private fun matchDeclarations(
decl1: KtDeclaration,
decl2: KtDeclaration,
desc1: DeclarationDescriptor?,
desc2: DeclarationDescriptor?): Status? {
decl1: KtDeclaration,
decl2: KtDeclaration,
desc1: DeclarationDescriptor?,
desc2: DeclarationDescriptor?
): Status? {
if (decl1::class.java != decl2::class.java) return UNMATCHED
if (desc1 == null || desc2 == null) {
if (decl1 is KtParameter
return if (decl1 is KtParameter
&& decl2 is KtParameter
&& decl1.getStrictParentOfType<KtTypeElement>() != null
&& decl2.getStrictParentOfType<KtTypeElement>() != null) return null
return UNMATCHED
&& decl2.getStrictParentOfType<KtTypeElement>() != null
)
null
else
UNMATCHED
}
if (ErrorUtils.isError(desc1) || ErrorUtils.isError(desc2)) return UNMATCHED
if (desc1::class.java != desc2::class.java) return UNMATCHED
@@ -801,8 +812,7 @@ class KotlinPsiUnifier(
val patternText = pattern.startEntry.text.substring(prefixLength)
if (!targetEntryText.endsWith(patternText)) continue
targetEntryText.substring(0, targetEntryText.length - patternText.length)
}
else ""
} else ""
val lastTargetEntry = targetEntries[index + patternEntries.lastIndex]
@@ -813,8 +823,7 @@ class KotlinPsiUnifier(
val lastTargetEntryText = lastTargetEntry.text
if (!lastTargetEntryText.startsWith(patternText)) continue
lastTargetEntryText.substring(patternText.length)
}
else ""
} else ""
val fromIndex = if (matchStartByText) 1 else 0
val toIndex = if (matchEndByText) patternEntries.lastIndex - 1 else patternEntries.lastIndex
@@ -846,8 +855,7 @@ class KotlinPsiUnifier(
}
}
private fun ASTNode.getChildrenRange(): KotlinPsiRange =
getChildren(null).mapNotNull { it.psi }.toRange()
private fun ASTNode.getChildrenRange(): KotlinPsiRange = getChildren(null).mapNotNull { it.psi }.toRange()
private fun PsiElement.unwrapWeakly(): KtElement? {
return when {
@@ -860,8 +868,8 @@ class KotlinPsiUnifier(
}
private fun doUnifyWeakly(
targetElement: KtElement,
patternElement: KtElement
targetElement: KtElement,
patternElement: KtElement
): Status {
if (!allowWeakMatches) return UNMATCHED
@@ -878,10 +886,9 @@ class KotlinPsiUnifier(
return status
}
private fun substitute(parameter: UnifierParameter, targetElement: PsiElement?): Status {
val existingArgument = substitution[parameter]
return when {
existingArgument == null -> {
private fun substitute(parameter: UnifierParameter, targetElement: PsiElement?): Status =
when (val existingArgument = substitution[parameter]) {
null -> {
substitution[parameter] = targetElement as KtElement
MATCHED
}
@@ -893,11 +900,10 @@ class KotlinPsiUnifier(
status
}
}
}
fun doUnify(
targetElement: PsiElement?,
patternElement: PsiElement?
targetElement: PsiElement?,
patternElement: PsiElement?
): Status {
val targetElementUnwrapped = targetElement?.unwrap()
val patternElementUnwrapped = patternElement?.unwrap()
@@ -922,8 +928,7 @@ class KotlinPsiUnifier(
if (referencedPatternDeclaration != null && parameter != null) {
if (targetElementUnwrapped is KtExpression) {
if (!targetElementUnwrapped.checkType(parameter)) return UNMATCHED
}
else if (targetElementUnwrapped !is KtUserType) return UNMATCHED
} else if (targetElementUnwrapped !is KtUserType) return UNMATCHED
return substitute(parameter, targetElementUnwrapped)
}
@@ -958,12 +963,10 @@ class KotlinPsiUnifier(
private val descriptorToParameter = parameters.associateBy { (it.descriptor as? DeclarationDescriptorWithSource)?.source?.getPsi() }
private fun PsiElement.unwrap(): PsiElement? {
return when (this) {
is KtExpression -> KtPsiUtil.deparenthesize(this)
is KtStringTemplateEntryWithExpression -> KtPsiUtil.deparenthesize(expression)
else -> this
}
private fun PsiElement.unwrap(): PsiElement? = when (this) {
is KtExpression -> KtPsiUtil.deparenthesize(this)
is KtStringTemplateEntryWithExpression -> KtPsiUtil.deparenthesize(expression)
else -> this
}
private fun PsiElement.unquotedText(): String {
@@ -975,8 +978,7 @@ class KotlinPsiUnifier(
return with(Context(target, pattern)) {
val status = doUnify(target, pattern)
when {
substitution.size != descriptorToParameter.size ->
Unmatched
substitution.size != descriptorToParameter.size -> Unmatched
status == MATCHED -> {
val targetRange = targetSubstringInfo?.createExpression()?.toRange() ?: target
if (weakMatches.isEmpty()) {
@@ -985,14 +987,13 @@ class KotlinPsiUnifier(
WeaklyMatched(targetRange, substitution, weakMatches)
}
}
else ->
Unmatched
else -> Unmatched
}
}
}
fun unify(targetElement: PsiElement?, patternElement: PsiElement?): UnificationResult =
unify(targetElement.toRange(), patternElement.toRange())
unify(targetElement.toRange(), patternElement.toRange())
}
fun PsiElement?.matches(e: PsiElement?): Boolean = KotlinPsiUnifier.DEFAULT.unify(this, e).matched
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
@file:JvmName("ScopeUtils")
@@ -44,13 +33,15 @@ fun LexicalScope.getAllAccessibleVariables(name: Name): Collection<VariableDescr
}
fun LexicalScope.getAllAccessibleFunctions(name: Name): Collection<FunctionDescriptor> {
return getImplicitReceiversWithInstance().flatMap { it.type.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_IDE) } +
collectFunctions(name, NoLookupLocation.FROM_IDE)
return getImplicitReceiversWithInstance().flatMap {
it.type.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_IDE)
} + collectFunctions(name, NoLookupLocation.FROM_IDE)
}
fun LexicalScope.getVariablesFromImplicitReceivers(name: Name): Collection<VariableDescriptor> = getImplicitReceiversWithInstance().flatMap {
it.type.memberScope.getContributedVariables(name, NoLookupLocation.FROM_IDE)
}
fun LexicalScope.getVariablesFromImplicitReceivers(name: Name): Collection<VariableDescriptor> =
getImplicitReceiversWithInstance().flatMap {
it.type.memberScope.getContributedVariables(name, NoLookupLocation.FROM_IDE)
}
fun LexicalScope.getVariableFromImplicitReceivers(name: Name): VariableDescriptor? {
getImplicitReceiversWithInstance().forEach {
@@ -80,12 +71,12 @@ fun PsiElement.getResolutionScope(bindingContext: BindingContext): LexicalScope?
return null
}
fun PsiElement.getResolutionScope(bindingContext: BindingContext, resolutionFacade: ResolutionFacade/*TODO: get rid of this parameter*/): LexicalScope {
return getResolutionScope(bindingContext) ?:
when (containingFile) {
is KtFile -> resolutionFacade.getFileResolutionScope(containingFile as KtFile)
else -> error("Not in KtFile")
}
fun PsiElement.getResolutionScope(
bindingContext: BindingContext,
resolutionFacade: ResolutionFacade/*TODO: get rid of this parameter*/
): LexicalScope = getResolutionScope(bindingContext) ?: when (containingFile) {
is KtFile -> resolutionFacade.getFileResolutionScope(containingFile as KtFile)
else -> error("Not in KtFile")
}
fun KtElement.getResolutionScope(): LexicalScope {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
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) {
// All body statements are analyzed, diagnostics included
FULL(BindingTraceFilter.ACCEPT_ALL, doControlFlowAnalysis = true),
// Analyzes only dependent statements, including all declaration statements (difference from PARTIAL_WITH_CFA)
PARTIAL_FOR_COMPLETION(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = true),
// Analyzes only dependent statements, diagnostics included
PARTIAL_WITH_DIAGNOSTICS(BindingTraceFilter.ACCEPT_ALL, doControlFlowAnalysis = true),
// Analyzes only dependent statements, performs control flow analysis (mostly needed for isUsedAsExpression / AsStatement)
PARTIAL_WITH_CFA(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = true),
// Analyzes only dependent statements, including only used declaration statements, does not perform control flow analysis
PARTIAL(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = false)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.resolve.lazy
@@ -31,9 +20,9 @@ import java.util.*
//TODO: do resolve anonymous object's body
class PartialBodyResolveFilter(
elementsToResolve: Collection<KtElement>,
private val declaration: KtDeclaration,
forCompletion: Boolean
elementsToResolve: Collection<KtElement>,
private val declaration: KtDeclaration,
forCompletion: Boolean
) : StatementFilter() {
private val statementMarks = StatementMarks()
@@ -59,8 +48,7 @@ class PartialBodyResolveFilter(
if (name != null) {
if (declaration is KtNamedFunction) {
contextNothingFunctionNames.add(name)
}
else {
} else {
contextNothingVariableNames.add(name)
}
}
@@ -91,12 +79,11 @@ class PartialBodyResolveFilter(
if (name != null && nameFilter(name)) {
statementMarks.mark(statement, MarkLevel.NEED_REFERENCE_RESOLVE)
}
}
else if (statement is KtDestructuringDeclaration) {
} else if (statement is KtDestructuringDeclaration) {
if (statement.entries.any {
val name = it.name
name != null && nameFilter(name)
}) {
val name = it.name
name != null && nameFilter(name)
}) {
statementMarks.mark(statement, MarkLevel.NEED_REFERENCE_RESOLVE)
}
}
@@ -116,8 +103,8 @@ class PartialBodyResolveFilter(
if (!smartCastPlaces.isEmpty()) {
//TODO: do we really need correct resolve for ALL smart cast places?
smartCastPlaces.values
.flatten()
.forEach { statementMarks.mark(it, MarkLevel.NEED_REFERENCE_RESOLVE) }
.flatten()
.forEach { statementMarks.mark(it, MarkLevel.NEED_REFERENCE_RESOLVE) }
updateNameFilter()
}
}
@@ -140,8 +127,8 @@ class PartialBodyResolveFilter(
* Returns map from smart-cast expression names (variable name or qualified variable name) to places.
*/
private fun potentialSmartCastPlaces(
statement: KtExpression,
filter: (SmartCastName) -> Boolean = { true }
statement: KtExpression,
filter: (SmartCastName) -> Boolean = { true }
): Map<SmartCastName, List<KtExpression>> {
val map = HashMap<SmartCastName, ArrayList<KtExpression>>(0)
@@ -235,9 +222,9 @@ class PartialBodyResolveFilter(
if (thenBranch != null && elseBranch != null) {
val thenCasts = potentialSmartCastPlaces(thenBranch, filter)
if (!thenCasts.isEmpty()) {
if (thenCasts.isNotEmpty()) {
val elseCasts = potentialSmartCastPlaces(elseBranch) { filter(it) && thenCasts.containsKey(it) }
if (!elseCasts.isEmpty()) {
if (elseCasts.isNotEmpty()) {
for ((name, places) in thenCasts) {
if (elseCasts.containsKey(name)) { // need filtering by cast names in else-branch
addPlaces(name, places)
@@ -262,8 +249,7 @@ class PartialBodyResolveFilter(
// we need to enter the body only for "while(true)"
if (condition.isTrueConstant()) {
expression.acceptChildren(this)
}
else {
} else {
condition?.accept(this)
}
}
@@ -406,8 +392,7 @@ class PartialBodyResolveFilter(
insideLoopLevel++
loop.body?.accept(this)
insideLoopLevel--
}
else {
} else {
// do not make sense to search exits inside while-loop as not necessary enter it at all
condition.accept(this)
}
@@ -451,8 +436,7 @@ class PartialBodyResolveFilter(
if (expression.operationToken == KtTokens.ELVIS) {
// do not search exits after "?:"
expression.left?.accept(this)
}
else {
} else {
super.visitBinaryExpression(expression)
}
}
@@ -473,8 +457,8 @@ class PartialBodyResolveFilter(
}
private data class SmartCastName(
private val receiverName: SmartCastName?,
private val selectorName: String? /* null means "this" (and receiverName should be null */
private val receiverName: SmartCastName?,
private val selectorName: String? /* null means "this" (and receiverName should be null */
) {
init {
if (selectorName == null) {
@@ -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 {
if (selectorName == null) return true
@@ -533,8 +517,7 @@ class PartialBodyResolveFilter(
if (names == null) return
if (filter.names == null) {
names = null
}
else {
} else {
names!!.addAll(filter.names!!)
}
}
@@ -562,42 +545,38 @@ class PartialBodyResolveFilter(
private fun KtExpression?.isNullLiteral() = this?.node?.elementType == KtNodeTypes.NULL
private fun KtExpression?.isTrueConstant()
= this != null && node?.elementType == KtNodeTypes.BOOLEAN_CONSTANT && text == "true"
private fun KtExpression?.isTrueConstant() = this != null && node?.elementType == KtNodeTypes.BOOLEAN_CONSTANT && text == "true"
private fun <T : Any> T?.singletonOrEmptySet(): Set<T> = if (this != null) setOf(this) else setOf()
//TODO: review logic
private fun isValueNeeded(expression: KtExpression): Boolean {
val parent = expression.parent
return when (parent) {
is KtBlockExpression -> expression == parent.lastStatement() && isValueNeeded(parent)
private fun isValueNeeded(expression: KtExpression): Boolean = when (val parent = expression.parent) {
is KtBlockExpression -> expression == parent.lastStatement() && isValueNeeded(parent)
is KtContainerNode -> { //TODO - not quite correct
val pparent = parent.parent as? KtExpression
pparent != null && isValueNeeded(pparent)
}
is KtDeclarationWithBody -> {
if (expression == parent.bodyExpression)
!parent.hasBlockBody() && !parent.hasDeclaredReturnType()
else
true
}
is KtAnonymousInitializer -> false
else -> true
is KtContainerNode -> { //TODO - not quite correct
val pparent = parent.parent as? KtExpression
pparent != null && isValueNeeded(pparent)
}
is KtDeclarationWithBody -> {
if (expression == parent.bodyExpression)
!parent.hasBlockBody() && !parent.hasDeclaredReturnType()
else
true
}
is KtAnonymousInitializer -> false
else -> true
}
private fun KtBlockExpression.lastStatement(): KtExpression?
= lastChild?.siblings(forward = false)?.firstIsInstanceOrNull<KtExpression>()
private fun KtBlockExpression.lastStatement(): KtExpression? =
lastChild?.siblings(forward = false)?.firstIsInstanceOrNull<KtExpression>()
private fun PsiElement.isStatement() = this is KtExpression && parent is KtBlockExpression
private fun KtTypeReference?.containsProbablyNothing()
= this?.typeElement?.anyDescendantOfType<KtUserType> { it.isProbablyNothing() } ?: false
private fun KtTypeReference?.containsProbablyNothing() =
this?.typeElement?.anyDescendantOfType<KtUserType> { it.isProbablyNothing() } ?: false
}
private inner class StatementMarks {
@@ -627,18 +606,16 @@ class PartialBodyResolveFilter(
}
}
fun statementMark(statement: KtExpression): MarkLevel
= statementMarks[statement] ?: MarkLevel.NONE
fun statementMark(statement: KtExpression): MarkLevel = statementMarks[statement] ?: MarkLevel.NONE
fun allMarkedStatements(): Collection<KtExpression>
= statementMarks.keys
fun allMarkedStatements(): Collection<KtExpression> = statementMarks.keys
fun lastMarkedStatement(block: KtBlockExpression, minLevel: MarkLevel): KtExpression? {
val level = blockLevels[block] ?: MarkLevel.NONE
if (level < minLevel) return null // optimization
return block.lastChild.siblings(forward = false)
.filterIsInstance<KtExpression>()
.first { statementMark(it) >= minLevel }
.filterIsInstance<KtExpression>()
.first { statementMark(it) >= minLevel }
}
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.resolve.scopes
@@ -23,20 +12,22 @@ import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
class ExplicitImportsScope(private val descriptors: Collection<DeclarationDescriptor>) : BaseImportingScope(null) {
override fun getContributedClassifier(name: Name, location: LookupLocation)
= descriptors.filter { it.name == name }.firstIsInstanceOrNull<ClassifierDescriptor>()
override fun getContributedClassifier(name: Name, location: LookupLocation) =
descriptors.filter { it.name == name }.firstIsInstanceOrNull<ClassifierDescriptor>()
override fun getContributedPackage(name: Name)
= descriptors.filter { it.name == name }.firstIsInstanceOrNull<PackageViewDescriptor>()
override fun getContributedPackage(name: Name) = descriptors.filter { it.name == name }.firstIsInstanceOrNull<PackageViewDescriptor>()
override fun getContributedVariables(name: Name, location: LookupLocation)
= descriptors.filter { it.name == name }.filterIsInstance<VariableDescriptor>()
override fun getContributedVariables(name: Name, location: LookupLocation) =
descriptors.filter { it.name == name }.filterIsInstance<VariableDescriptor>()
override fun getContributedFunctions(name: Name, location: LookupLocation)
= descriptors.filter { it.name == name }.filterIsInstance<FunctionDescriptor>()
override fun getContributedFunctions(name: Name, location: LookupLocation) =
descriptors.filter { it.name == name }.filterIsInstance<FunctionDescriptor>()
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, changeNamesForAliased: Boolean)
= descriptors
override fun getContributedDescriptors(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean,
changeNamesForAliased: Boolean
) = descriptors
override fun computeImportedNames() = descriptors.mapTo(hashSetOf()) { it.name }
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.util
@@ -31,9 +20,9 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeCheckerImpl
import org.jetbrains.kotlin.types.typeUtil.equalTypesOrNulls
fun descriptorsEqualWithSubstitution(
descriptor1: DeclarationDescriptor?,
descriptor2: DeclarationDescriptor?,
checkOriginals: Boolean = true
descriptor1: DeclarationDescriptor?,
descriptor2: DeclarationDescriptor?,
checkOriginals: Boolean = true
): Boolean {
if (descriptor1 == descriptor2) return true
if (descriptor1 == null || descriptor2 == null) return false
@@ -41,14 +30,15 @@ fun descriptorsEqualWithSubstitution(
if (descriptor1 !is CallableDescriptor) return true
descriptor2 as CallableDescriptor
val typeChecker = KotlinTypeCheckerImpl.withAxioms(object: KotlinTypeChecker.TypeConstructorEquality {
val typeChecker = KotlinTypeCheckerImpl.withAxioms(object : KotlinTypeChecker.TypeConstructorEquality {
override fun equals(a: TypeConstructor, b: TypeConstructor): Boolean {
val typeParam1 = a.declarationDescriptor as? TypeParameterDescriptor
val typeParam2 = b.declarationDescriptor as? TypeParameterDescriptor
if (typeParam1 != null
&& typeParam2 != null
&& typeParam1.containingDeclaration == descriptor1
&& typeParam2.containingDeclaration == descriptor2) {
&& typeParam2.containingDeclaration == descriptor2
) {
return typeParam1.index == typeParam2.index
}
@@ -68,25 +58,25 @@ fun descriptorsEqualWithSubstitution(
}
fun ClassDescriptor.findCallableMemberBySignature(
signature: CallableMemberDescriptor,
allowOverridabilityConflicts: Boolean = false
signature: CallableMemberDescriptor,
allowOverridabilityConflicts: Boolean = false
): CallableMemberDescriptor? {
val descriptorKind = if (signature is FunctionDescriptor) DescriptorKindFilter.FUNCTIONS else DescriptorKindFilter.VARIABLES
return defaultType.memberScope
.getContributedDescriptors(descriptorKind)
.filterIsInstance<CallableMemberDescriptor>()
.firstOrNull {
if (it.containingDeclaration != this) return@firstOrNull false
val overridability = OverridingUtil.DEFAULT.isOverridableBy(it as CallableDescriptor, signature, null).result
overridability == OVERRIDABLE || (allowOverridabilityConflicts && overridability == CONFLICT)
}
.getContributedDescriptors(descriptorKind)
.filterIsInstance<CallableMemberDescriptor>()
.firstOrNull {
if (it.containingDeclaration != this) return@firstOrNull false
val overridability = OverridingUtil.DEFAULT.isOverridableBy(it as CallableDescriptor, signature, null).result
overridability == OVERRIDABLE || (allowOverridabilityConflicts && overridability == CONFLICT)
}
}
fun TypeConstructor.supertypesWithAny(): Collection<KotlinType> {
val supertypes = supertypes
val noSuperClass = supertypes
.map { it.constructor.declarationDescriptor as? ClassDescriptor }
.all { it == null || it.kind == ClassKind.INTERFACE }
val noSuperClass = supertypes.map { it.constructor.declarationDescriptor as? ClassDescriptor }.all {
it == null || it.kind == ClassKind.INTERFACE
}
return if (noSuperClass) supertypes + builtIns.anyType else supertypes
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.types.*
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
import java.util.LinkedHashMap
import java.util.*
fun getTypeSubstitution(baseType: KotlinType, derivedType: KotlinType): LinkedHashMap<TypeConstructor, TypeProjection>? {
val substitutedType = TypeCheckingProcedure.findCorrespondingSupertype(derivedType, baseType) ?: return null
@@ -34,8 +23,8 @@ fun getTypeSubstitution(baseType: KotlinType, derivedType: KotlinType): LinkedHa
}
fun getCallableSubstitution(
baseCallable: CallableDescriptor,
derivedCallable: CallableDescriptor
baseCallable: CallableDescriptor,
derivedCallable: CallableDescriptor
): MutableMap<TypeConstructor, TypeProjection>? {
val baseClass = baseCallable.containingDeclaration as? ClassDescriptor ?: return null
val derivedClass = derivedCallable.containingDeclaration as? ClassDescriptor ?: return null
@@ -49,8 +38,8 @@ fun getCallableSubstitution(
}
fun getCallableSubstitutor(
baseCallable: CallableDescriptor,
derivedCallable: CallableDescriptor
baseCallable: CallableDescriptor,
derivedCallable: CallableDescriptor
): TypeSubstitutor? {
return getCallableSubstitution(baseCallable, derivedCallable)?.let { TypeSubstitutor.create(it) }
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea
@@ -107,7 +96,7 @@ class KotlinIconProvider : IconProvider(), DumbAware {
return PlatformIcons.PUBLIC_ICON
}
fun PsiElement.getBaseIcon(): Icon? = when(this) {
fun PsiElement.getBaseIcon(): Icon? = when (this) {
is KtPackageDirective -> PlatformIcons.PACKAGE_ICON
is KtLightClassForFacade -> KotlinIcons.FILE
is KtLightClassForDecompiledDeclaration -> {
@@ -136,8 +125,7 @@ class KotlinIconProvider : IconProvider(), DumbAware {
is KtParameter -> {
if (KtPsiUtil.getClassIfParameterIsProperty(this) != null) {
if (isMutable) KotlinIcons.FIELD_VAR else KotlinIcons.FIELD_VAL
}
else
} else
KotlinIcons.PARAMETER
}
is KtProperty -> if (isVar) KotlinIcons.FIELD_VAR else KotlinIcons.FIELD_VAL
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.caches
@@ -97,7 +86,8 @@ class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache()
LOG.error(
"A declaration obtained from index has non-matching name:" +
"\nin index: $name" +
"\ndeclared: ${fqName.shortName()}($fqName)")
"\ndeclared: ${fqName.shortName()}($fqName)"
)
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.
*/
@@ -47,7 +47,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
class KotlinPackageContentModificationListener(private val project: Project): Disposable {
class KotlinPackageContentModificationListener(private val project: Project) : Disposable {
val connection = project.messageBus.connect()
init {
@@ -63,8 +63,7 @@ class KotlinPackageContentModificationListener(private val project: Project): Di
if (events.size >= FULL_DROP_THRESHOLD) {
service.onTooComplexChange()
} else {
events
.asSequence()
events.asSequence()
.filter(::isRelevant)
.filter { (it.isValid || it !is VFileCreateEvent) && it.file != null }
.filter {
@@ -303,7 +302,9 @@ class PerModulePackageCacheService(private val project: Project) : Disposable {
pendingKtFileChanges.processPending { file ->
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
}
val nullableModuleInfo = file.getNullableModuleInfo()
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.caches.lightClasses
@@ -111,7 +100,12 @@ internal object IDELightClassContexts {
"Class descriptor was not found for ${classOrObject.getElementTextWithContext()}"
}
ForceResolveUtil.forceResolveAllContents(classDescriptor)
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, classOrObject.languageVersionSettings, EXACT)
return IDELightClassConstructionContext(
bindingContext,
resolutionFacade.moduleDescriptor,
classOrObject.languageVersionSettings,
EXACT
)
}
fun contextForLocalClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext {
@@ -122,12 +116,22 @@ internal object IDELightClassContexts {
if (descriptor == null) {
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)
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)
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 {
@@ -145,7 +154,12 @@ internal object IDELightClassContexts {
val descriptor = bindingContext[BindingContext.SCRIPT, script]
if (descriptor == null) {
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)
@@ -167,7 +181,12 @@ internal object IDELightClassContexts {
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 {
@@ -176,7 +195,12 @@ internal object IDELightClassContexts {
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 {
@@ -384,7 +408,7 @@ internal object IDELightClassContexts {
private val codegenAffectingAnnotations: CodegenAffectingAnnotations,
private val callResolver: CallResolver,
private val languageVersionSettings: LanguageVersionSettings,
private val dataFlowValueFactory: DataFlowValueFactory,constantExpressionEvaluator: ConstantExpressionEvaluator,
private val dataFlowValueFactory: DataFlowValueFactory, constantExpressionEvaluator: ConstantExpressionEvaluator,
storageManager: StorageManager
) : AnnotationResolverImpl(callResolver, constantExpressionEvaluator, storageManager) {
@@ -404,7 +428,7 @@ internal object IDELightClassContexts {
trace: BindingTrace
): OverloadResolutionResults<FunctionDescriptor> {
val annotationConstructor = annotationClassByEntry(annotationEntry)?.constructors?.singleOrNull()
?: return super.resolveAnnotationCall(annotationEntry, scope, trace)
?: return super.resolveAnnotationCall(annotationEntry, scope, trace)
@Suppress("UNCHECKED_CAST")
return callResolver.resolveConstructorCall(
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.caches.lightClasses
@@ -108,10 +97,10 @@ private object DummyJavaPsiFactory {
val canonicalText = GenericsUtil.getVariableTypeByExpressionType(returnType).getCanonicalText(true)
val file = createDummyJavaFile(project, "class _Dummy_ { public $canonicalText $name() {\n} }")
val klass = file.classes.singleOrNull()
?: throw IncorrectOperationException("Class was not created. Method name: $name; return type: $canonicalText")
?: throw IncorrectOperationException("Class was not created. Method name: $name; return type: $canonicalText")
return klass.methods.singleOrNull()
?: throw IncorrectOperationException("Method was not created. Method name: $name; return type: $canonicalText")
?: throw IncorrectOperationException("Method was not created. Method name: $name; return type: $canonicalText")
}
fun createDummyClass(project: Project): PsiClass = PsiElementFactory.SERVICE.getInstance(project).createClass("dummy")
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.caches.lightClasses
@@ -40,8 +29,9 @@ class KtLightClassForDecompiledDeclaration(
override fun getOwnInnerClasses(): List<PsiClass> {
val nestedClasses = kotlinOrigin?.declarations?.filterIsInstance<KtClassOrObject>() ?: emptyList()
return clsDelegate.ownInnerClasses.map { innerClsClass ->
KtLightClassForDecompiledDeclaration(innerClsClass as ClsClassImpl,
nestedClasses.firstOrNull { innerClsClass.name == it.name }, file
KtLightClassForDecompiledDeclaration(
innerClsClass as ClsClassImpl,
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.
*/
@@ -184,6 +184,7 @@ sealed class LazyLightClassDataHolder(
}
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)
@@ -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.
*/
@@ -233,8 +233,11 @@ fun Module.testSourceInfo(): ModuleTestSourceInfo? = if (hasTestRoots()) ModuleT
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.hasTestRoots() = hasRootsOfType(JavaSourceRootType.TEST_SOURCE) || hasRootsOfType(TestSourceKotlinRootType) || (isNewMPPModule && sourceType == SourceType.TEST)
private fun Module.hasProductionRoots() =
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 =
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()
}
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}>")
@@ -330,7 +334,8 @@ data class LibrarySourceInfo(val project: Project, val library: Library, overrid
LibrarySourceScope(
project,
library
), project)
), project
)
override fun modulesWhoseInternalsAreVisible(): Collection<ModuleInfo> {
return createLibraryInfo(project, library)
@@ -101,14 +101,14 @@ private sealed class ModuleInfoCollector<out T>(
LOG.error("Could not find correct module information.\nReason: $reason")
NotUnderContentRootModuleInfo
},
virtualFileProcessor = processor@ { project, virtualFile, isLibrarySource ->
virtualFileProcessor = processor@{ project, virtualFile, isLibrarySource ->
collectInfosByVirtualFile(
project,
virtualFile,
isLibrarySource,
{
return@processor it ?: NotUnderContentRootModuleInfo
})
isLibrarySource
) {
return@processor it ?: NotUnderContentRootModuleInfo
}
}
)
@@ -118,12 +118,12 @@ private sealed class ModuleInfoCollector<out T>(
LOG.warn("Could not find correct module information.\nReason: $reason")
null
},
virtualFileProcessor = processor@ { project, virtualFile, isLibrarySource ->
virtualFileProcessor = processor@{ project, virtualFile, isLibrarySource ->
collectInfosByVirtualFile(
project,
virtualFile,
isLibrarySource,
{ return@processor it })
isLibrarySource
) { return@processor it }
}
)
@@ -138,8 +138,8 @@ private sealed class ModuleInfoCollector<out T>(
collectInfosByVirtualFile(
project,
virtualFile,
isLibrarySource,
{ yieldIfNotNull(it) })
isLibrarySource
) { 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.
*/
@@ -103,7 +103,10 @@ val Module.implementedModules: List<Module>
KotlinMultiplatformVersion.M2 -> {
rootManager.dependencies.filter {
// 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.
*
* 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.
* 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.
*/
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")
private val elementsCache = DiagnosticsElementsCache(this) { true }
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.caches.resolve
@@ -69,8 +58,9 @@ internal class ProjectResolutionFacade(
}
}
val allDependencies =
resolverForProjectDependencies + listOf(KotlinCodeBlockModificationListener.getInstance(project).kotlinOutOfCodeBlockTracker)
val allDependencies = resolverForProjectDependencies + listOf(
KotlinCodeBlockModificationListener.getInstance(project).kotlinOutOfCodeBlockTracker
)
CachedValueProvider.Result.create(results, allDependencies)
}, false
)
@@ -114,8 +104,8 @@ internal class ProjectResolutionFacade(
internal fun resolverForElement(element: PsiElement): ResolverForModule {
val infos = element.getModuleInfos()
return infos.asIterable().firstNotNullResult { cachedResolverForProject.tryGetResolverForModule(it) }
?: cachedResolverForProject.tryGetResolverForModule(NotUnderContentRootModuleInfo)
?: cachedResolverForProject.diagnoseUnknownModuleInfo(infos.toList())
?: cachedResolverForProject.tryGetResolverForModule(NotUnderContentRootModuleInfo)
?: cachedResolverForProject.diagnoseUnknownModuleInfo(infos.toList())
}
internal fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) =
@@ -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.
*/
@@ -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.getNullableModuleInfo
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
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
info(
"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.
*/
@@ -34,8 +34,13 @@ fun getResolveScope(file: KtFile): GlobalSearchScope {
}
return when (file.getModuleInfo()) {
is ModuleSourceInfo -> enlargedSearchScope(KotlinSourceFilterScope.projectSourceAndClassFiles(file.resolveScope, file.project), file)
is ScriptModuleInfo -> file.getModuleInfo().dependencies().map { it.contentScope() }.let { GlobalSearchScope.union(it.toTypedArray()) }
is ModuleSourceInfo -> enlargedSearchScope(
KotlinSourceFilterScope.projectSourceAndClassFiles(file.resolveScope, file.project),
file
)
is ScriptModuleInfo -> file.getModuleInfo().dependencies().map { it.contentScope() }.let {
GlobalSearchScope.union(it.toTypedArray())
}
else -> GlobalSearchScope.EMPTY_SCOPE
}
}
@@ -9,4 +9,5 @@ import com.intellij.psi.impl.PsiModificationTrackerImpl
// BUNCH: 191
@Suppress("unused")
val PsiModificationTrackerImpl.isEnableLanguageTrackerCompat get() = true
val PsiModificationTrackerImpl.isEnableLanguageTrackerCompat
get() = true
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.codeInsight
@@ -33,9 +22,9 @@ object DescriptorToSourceUtilsIde {
// Returns all PSI elements for descriptor. It can find declarations in builtins or decompiled code.
fun getAllDeclarations(
project: Project,
targetDescriptor: DeclarationDescriptor,
builtInsSearchScope: GlobalSearchScope? = null
project: Project,
targetDescriptor: DeclarationDescriptor,
builtInsSearchScope: GlobalSearchScope? = null
): Collection<PsiElement> {
val result = getDeclarationsStream(project, targetDescriptor, builtInsSearchScope).toHashSet()
// filter out elements which are navigate to some other element of the result
@@ -44,15 +33,15 @@ object DescriptorToSourceUtilsIde {
}
private fun getDeclarationsStream(
project: Project, targetDescriptor: DeclarationDescriptor, builtInsSearchScope: GlobalSearchScope? = null
project: Project, targetDescriptor: DeclarationDescriptor, builtInsSearchScope: GlobalSearchScope? = null
): Sequence<PsiElement> {
val effectiveReferencedDescriptors = DescriptorToSourceUtils.getEffectiveReferencedDescriptors(targetDescriptor).asSequence()
return effectiveReferencedDescriptors.flatMap { effectiveReferenced ->
// References in library sources should be resolved to corresponding decompiled declarations,
// therefore we put both source declaration and decompiled declaration to stream, and afterwards we filter it in getAllDeclarations
sequenceOfLazyValues(
{ DescriptorToSourceUtils.getSourceFromDescriptor(effectiveReferenced) },
{ findDecompiledDeclaration(project, effectiveReferenced, builtInsSearchScope) }
{ DescriptorToSourceUtils.getSourceFromDescriptor(effectiveReferenced) },
{ findDecompiledDeclaration(project, effectiveReferenced, builtInsSearchScope) }
)
}.filterNotNull()
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
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 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
private object DefaultValuesFilter : SerializationFilterBase() {
private val defaultBeans = THashMap<Class<*>, Any>()
@@ -1,24 +1,14 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.util.text.VersionComparatorUtil
import org.jdom.Element
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.setApiVersionToLanguageVersionIfNeeded
@@ -49,6 +39,6 @@ class KotlinCommonCompilerArgumentsHolder(project: Project) : BaseKotlinCompiler
companion object {
fun getInstance(project: Project) =
ServiceManager.getService<KotlinCommonCompilerArgumentsHolder>(project, KotlinCommonCompilerArgumentsHolder::class.java)!!
ServiceManager.getService<KotlinCommonCompilerArgumentsHolder>(project, KotlinCommonCompilerArgumentsHolder::class.java)!!
}
}
@@ -1,22 +1,13 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
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 org.jetbrains.kotlin.config.CompilerSettings
import org.jetbrains.kotlin.config.SettingConstants
@@ -27,7 +18,6 @@ class KotlinCompilerSettings(project: Project) : BaseKotlinCompilerSettings<Comp
override fun createSettings() = CompilerSettings()
companion object {
fun getInstance(project: Project) = ServiceManager.getService(project, KotlinCompilerSettings::class.java)!!
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler
@@ -29,20 +18,19 @@ import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
class KotlinDecompiledFileViewProvider(
manager: PsiManager,
file: VirtualFile,
physical: Boolean,
private val factory: (KotlinDecompiledFileViewProvider) -> KtDecompiledFile?
manager: PsiManager,
file: VirtualFile,
physical: Boolean,
private val factory: (KotlinDecompiledFileViewProvider) -> KtDecompiledFile?
) : SingleRootFileViewProvider(manager, file, physical, KotlinLanguage.INSTANCE) {
val content : LockedClearableLazyValue<String> = LockedClearableLazyValue(Any()) {
val content: LockedClearableLazyValue<String> = LockedClearableLazyValue(Any()) {
val psiFile = createFile(manager.project, file, KotlinFileType.INSTANCE)
val text = psiFile?.text ?: ""
DebugUtil.startPsiModification("Invalidating throw-away copy of file that was used for getting text")
try {
(psiFile as? PsiFileImpl)?.markInvalidated()
}
finally {
} finally {
DebugUtil.finishPsiModification()
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler
@@ -25,8 +14,8 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
open class KtDecompiledFile(
private val provider: KotlinDecompiledFileViewProvider,
buildDecompiledText: (VirtualFile) -> DecompiledText
private val provider: KotlinDecompiledFileViewProvider,
buildDecompiledText: (VirtualFile) -> DecompiledText
) : KtFile(provider, true) {
private val decompiledText = LockedClearableLazyValue(Any()) {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.classFile
@@ -51,8 +40,8 @@ fun DeserializerForClassfileDecompiler(classFile: VirtualFile): DeserializerForC
}
class DeserializerForClassfileDecompiler(
packageDirectory: VirtualFile,
directoryPackageFqName: FqName
packageDirectory: VirtualFile,
directoryPackageFqName: FqName
) : DeserializerForDecompilerBase(directoryPackageFqName) {
override val builtIns: KotlinBuiltIns get() = DefaultBuiltIns.Instance
@@ -64,7 +53,7 @@ class DeserializerForClassfileDecompiler(
val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG)
val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor)
val annotationAndConstantLoader =
BinaryClassAnnotationAndConstantLoaderImpl(moduleDescriptor, notFoundClasses, storageManager, classFinder)
BinaryClassAnnotationAndConstantLoaderImpl(moduleDescriptor, notFoundClasses, storageManager, classFinder)
val configuration = object : DeserializationConfiguration {
override val readDeserializedContracts: Boolean
@@ -72,11 +61,11 @@ class DeserializerForClassfileDecompiler(
}
deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, configuration, classDataFinder, annotationAndConstantLoader,
packageFragmentProvider, ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, JavaFlexibleTypeDeserializer, emptyList(), notFoundClasses,
ContractDeserializerImpl(configuration, storageManager),
extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY
storageManager, moduleDescriptor, configuration, classDataFinder, annotationAndConstantLoader,
packageFragmentProvider, ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, JavaFlexibleTypeDeserializer, emptyList(), notFoundClasses,
ContractDeserializerImpl(configuration, storageManager),
extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY
)
}
@@ -108,8 +97,8 @@ class DeserializerForClassfileDecompiler(
}
class DirectoryBasedClassFinder(
val packageDirectory: VirtualFile,
val directoryPackageFqName: FqName
val packageDirectory: VirtualFile,
val directoryPackageFqName: FqName
) : KotlinClassFinder {
override fun findKotlinClassOrContent(javaClass: JavaClass) = findKotlinClassOrContent(javaClass.classId!!)
@@ -136,8 +125,8 @@ class DirectoryBasedClassFinder(
}
class DirectoryBasedDataFinder(
val classFinder: DirectoryBasedClassFinder,
val log: Logger
val classFinder: DirectoryBasedClassFinder,
val log: Logger
) : ClassDataFinder {
override fun findClassData(classId: ClassId): ClassData? {
val binaryClass = classFinder.findKotlinClass(classId) ?: return null
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.classFile
@@ -64,8 +53,8 @@ private val decompilerRendererForClassFiles = DescriptorRenderer.withOptions {
}
fun buildDecompiledTextForClassFile(
classFile: VirtualFile,
resolver: ResolverForDecompiler = DeserializerForClassfileDecompiler(classFile)
classFile: VirtualFile,
resolver: ResolverForDecompiler = DeserializerForClassfileDecompiler(classFile)
): DecompiledText {
val classHeader =
IDEKotlinBinaryClassCache.getInstance().getKotlinBinaryClassHeaderData(classFile)
@@ -77,9 +66,10 @@ fun buildDecompiledTextForClassFile(
return createIncompatibleAbiVersionDecompiledText(JvmMetadataVersion.INSTANCE, classHeader.metadataVersion)
}
fun buildText(declarations: List<DeclarationDescriptor>) =
buildDecompiledText(classHeader.packageName?.let(::FqName) ?: classId.packageFqName,
declarations, decompilerRendererForClassFiles, listOf(ByDescriptorIndexer, BySignatureIndexer))
fun buildText(declarations: List<DeclarationDescriptor>) = buildDecompiledText(
classHeader.packageName?.let(::FqName) ?: classId.packageFqName,
declarations, decompilerRendererForClassFiles, listOf(ByDescriptorIndexer, BySignatureIndexer)
)
return when (classHeader.kind) {
KotlinClassHeader.Kind.FILE_FACADE ->
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.classFile
@@ -103,7 +92,7 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(annotationData, strings)
val context = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable))
val fqName = header.packageName?.let { ClassId(FqName(it), classId.relativeClassName, classId.isLocal).asSingleFqName() }
?: classId.asSingleFqName()
?: classId.asSingleFqName()
createFileFacadeStub(packageProto, fqName, context)
}
else -> throw IllegalStateException("Should have processed " + file.path + " with header $header")
@@ -130,9 +119,9 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
}
class AnnotationLoaderForClassFileStubBuilder(
kotlinClassFinder: KotlinClassFinder,
private val cachedFile: VirtualFile,
private val cachedFileContent: ByteArray
kotlinClassFinder: KotlinClassFinder,
private val cachedFile: VirtualFile,
private val cachedFileContent: ByteArray
) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit>(LockBasedStorageManager.NO_LOCKS, kotlinClassFinder) {
override fun getCachedFileContent(kotlinClass: KotlinJvmBinaryClass): ByteArray? {
@@ -142,15 +131,14 @@ class AnnotationLoaderForClassFileStubBuilder(
return null
}
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId =
nameResolver.getClassId(proto.id)
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId = nameResolver.getClassId(proto.id)
override fun loadConstant(desc: String, initializer: Any) = null
override fun transformToUnsignedConstant(constant: Unit) = null
override fun loadAnnotation(
annotationClassId: ClassId, source: SourceElement, result: MutableList<ClassId>
annotationClassId: ClassId, source: SourceElement, result: MutableList<ClassId>
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
result.add(annotationClassId)
return null
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.common
@@ -28,16 +17,16 @@ import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.types.KotlinType
class AnnotationLoaderForStubBuilderImpl(
private val protocol: SerializerExtensionProtocol
private val protocol: SerializerExtensionProtocol
) : AnnotationAndConstantLoader<ClassId, Unit> {
override fun loadClassAnnotations(container: ProtoContainer.Class): List<ClassId> =
container.classProto.getExtension(protocol.classAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
container.classProto.getExtension(protocol.classAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
override fun loadCallableAnnotations(
container: ProtoContainer,
proto: MessageLite,
kind: AnnotatedCallableKind
container: ProtoContainer,
proto: MessageLite,
kind: AnnotatedCallableKind
): List<ClassId> {
val annotations = when (proto) {
is ProtoBuf.Constructor -> proto.getExtension(protocol.constructorAnnotation)
@@ -60,35 +49,36 @@ class AnnotationLoaderForStubBuilderImpl(
emptyList()
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<ClassId> =
proto.getExtension(protocol.enumEntryAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
proto.getExtension(protocol.enumEntryAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
override fun loadValueParameterAnnotations(
container: ProtoContainer,
callableProto: MessageLite,
kind: AnnotatedCallableKind,
parameterIndex: Int,
proto: ProtoBuf.ValueParameter
container: ProtoContainer,
callableProto: MessageLite,
kind: AnnotatedCallableKind,
parameterIndex: Int,
proto: ProtoBuf.ValueParameter
): List<ClassId> =
proto.getExtension(protocol.parameterAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
proto.getExtension(protocol.parameterAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
override fun loadExtensionReceiverParameterAnnotations(
container: ProtoContainer,
proto: MessageLite,
kind: AnnotatedCallableKind
container: ProtoContainer,
proto: MessageLite,
kind: AnnotatedCallableKind
): List<ClassId> = emptyList()
override fun loadTypeAnnotations(
proto: ProtoBuf.Type,
nameResolver: NameResolver
proto: ProtoBuf.Type,
nameResolver: NameResolver
): List<ClassId> =
proto.getExtension(protocol.typeAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
proto.getExtension(protocol.typeAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
override fun loadTypeParameterAnnotations(proto: ProtoBuf.TypeParameter, nameResolver: NameResolver): List<ClassId> =
proto.getExtension(protocol.typeParameterAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
override fun loadPropertyConstant(
container: ProtoContainer,
proto: ProtoBuf.Property,
expectedType: KotlinType
) {}
container: ProtoContainer,
proto: ProtoBuf.Property,
expectedType: KotlinType
) {
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.common
@@ -101,8 +90,8 @@ abstract class KotlinMetadataDecompiler<out V : BinaryVersion>(
is FileWithMetadata.Compatible -> {
val packageFqName = file.packageFqName
val resolver = KotlinMetadataDeserializerForDecompiler(
packageFqName, file.proto, file.nameResolver, file.version,
serializerProtocol(), flexibleTypeDeserializer
packageFqName, file.proto, file.nameResolver, file.version,
serializerProtocol(), flexibleTypeDeserializer
)
val declarations = arrayListOf<DeclarationDescriptor>()
declarations.addAll(resolver.resolveDeclarationsInFacade(packageFqName))
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.common
@@ -34,12 +23,12 @@ import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
class KotlinMetadataDeserializerForDecompiler(
packageFqName: FqName,
private val proto: ProtoBuf.PackageFragment,
private val nameResolver: NameResolver,
private val metadataVersion: BinaryVersion,
serializerProtocol: SerializerExtensionProtocol,
flexibleTypeDeserializer: FlexibleTypeDeserializer
packageFqName: FqName,
private val proto: ProtoBuf.PackageFragment,
private val nameResolver: NameResolver,
private val metadataVersion: BinaryVersion,
serializerProtocol: SerializerExtensionProtocol,
flexibleTypeDeserializer: FlexibleTypeDeserializer
) : DeserializerForDecompilerBase(packageFqName) {
override val builtIns: KotlinBuiltIns get() = DefaultBuiltIns.Instance
@@ -49,13 +38,13 @@ class KotlinMetadataDeserializerForDecompiler(
val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor)
deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, DeserializationConfiguration.Default,
ProtoBasedClassDataFinder(proto, nameResolver, metadataVersion),
AnnotationAndConstantLoaderImpl(moduleDescriptor, notFoundClasses, serializerProtocol), packageFragmentProvider,
ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, flexibleTypeDeserializer, emptyList(), notFoundClasses,
ContractDeserializer.DEFAULT,
extensionRegistryLite = serializerProtocol.extensionRegistry
storageManager, moduleDescriptor, DeserializationConfiguration.Default,
ProtoBasedClassDataFinder(proto, nameResolver, metadataVersion),
AnnotationAndConstantLoaderImpl(moduleDescriptor, notFoundClasses, serializerProtocol), packageFragmentProvider,
ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, flexibleTypeDeserializer, emptyList(), notFoundClasses,
ContractDeserializer.DEFAULT,
extensionRegistryLite = serializerProtocol.extensionRegistry
)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.common
@@ -30,10 +19,10 @@ import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.getClassId
open class KotlinMetadataStubBuilder(
private val version: Int,
private val fileType: FileType,
private val serializerProtocol: () -> SerializerExtensionProtocol,
private val readFile: (VirtualFile, ByteArray) -> FileWithMetadata?
private val version: Int,
private val fileType: FileType,
private val serializerProtocol: () -> SerializerExtensionProtocol,
private val readFile: (VirtualFile, ByteArray) -> FileWithMetadata?
) : ClsStubBuilder() {
override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + version
@@ -51,21 +40,21 @@ open class KotlinMetadataStubBuilder(
val packageFqName = file.packageFqName
val nameResolver = file.nameResolver
val components = ClsStubBuilderComponents(
ProtoBasedClassDataFinder(file.proto, nameResolver, file.version),
AnnotationLoaderForStubBuilderImpl(serializerProtocol()),
virtualFile
ProtoBasedClassDataFinder(file.proto, nameResolver, file.version),
AnnotationLoaderForStubBuilderImpl(serializerProtocol()),
virtualFile
)
val context = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable))
val fileStub = createFileStub(packageFqName, isScript = false)
createDeclarationsStubs(
fileStub, context,
ProtoContainer.Package(packageFqName, context.nameResolver, context.typeTable, source = null),
packageProto
fileStub, context,
ProtoContainer.Package(packageFqName, context.nameResolver, context.typeTable, source = null),
packageProto
)
for (classProto in file.classesToDecompile) {
createClassStub(
fileStub, classProto, nameResolver, nameResolver.getClassId(classProto.fqName), source = null, context = context
fileStub, classProto, nameResolver, nameResolver.getClassId(classProto.fqName), source = null, context = context
)
}
return fileStub
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.metadata.deserialization.BinaryVersion
private val FILE_ABI_VERSION_MARKER: String = "FILE_ABI"
private val CURRENT_ABI_VERSION_MARKER: String = "CURRENT_ABI"
private const val FILE_ABI_VERSION_MARKER: String = "FILE_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."
private val INCOMPATIBLE_ABI_VERSION_COMMENT: String =
"$INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT\n" +
val INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT: String =
"// This class file was compiled with different version of Kotlin compiler and can't be decompiled."
private val INCOMPATIBLE_ABI_VERSION_COMMENT: String = "$INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT\n" +
"//\n" +
"// Current compiler ABI version is $CURRENT_ABI_VERSION_MARKER\n" +
"// File ABI version is $FILE_ABI_VERSION_MARKER"
fun <V : BinaryVersion> createIncompatibleAbiVersionDecompiledText(expectedVersion: V, actualVersion: V): DecompiledText {
return DecompiledText(
INCOMPATIBLE_ABI_VERSION_COMMENT
.replace(CURRENT_ABI_VERSION_MARKER, expectedVersion.toString())
.replace(FILE_ABI_VERSION_MARKER, actualVersion.toString()),
DecompiledTextIndex.Empty
)
}
fun <V : BinaryVersion> createIncompatibleAbiVersionDecompiledText(expectedVersion: V, actualVersion: V): DecompiledText = DecompiledText(
INCOMPATIBLE_ABI_VERSION_COMMENT.replace(CURRENT_ABI_VERSION_MARKER, expectedVersion.toString())
.replace(FILE_ABI_VERSION_MARKER, actualVersion.toString()),
DecompiledTextIndex.Empty
)
@@ -1,29 +1,15 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.navigation
import org.jetbrains.kotlin.psi.KotlinDeclarationNavigationPolicy
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtDeclaration
import com.intellij.openapi.project.DumbService
class KotlinDeclarationNavigationPolicyImpl : KotlinDeclarationNavigationPolicy {
override fun getOriginalElement(declaration: KtDeclaration) =
SourceNavigationHelper.getOriginalElement(declaration)
override fun getNavigationElement(declaration: KtDeclaration) =
SourceNavigationHelper.getNavigationElement(declaration)
override fun getOriginalElement(declaration: KtDeclaration) = SourceNavigationHelper.getOriginalElement(declaration)
override fun getNavigationElement(declaration: KtDeclaration) = SourceNavigationHelper.getNavigationElement(declaration)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.navigation
@@ -46,10 +35,10 @@ import org.jetbrains.kotlin.types.ErrorUtils
import java.util.*
fun findDecompiledDeclaration(
project: Project,
referencedDescriptor: DeclarationDescriptor,
// TODO: should not require explicitly specified scope to search for builtIns, use SourceElement to provide such information
builtInsSearchScope: GlobalSearchScope?
project: Project,
referencedDescriptor: DeclarationDescriptor,
// TODO: should not require explicitly specified scope to search for builtIns, use SourceElement to provide such information
builtInsSearchScope: GlobalSearchScope?
): KtDeclaration? {
if (ErrorUtils.isError(referencedDescriptor)) return null
if (isLocal(referencedDescriptor)) return null
@@ -63,9 +52,9 @@ fun findDecompiledDeclaration(
if (KotlinBuiltIns.isBuiltIn(referencedDescriptor)) {
// builtin module does not contain information about it's origin
return builtInsSearchScope?.let { findInScope(referencedDescriptor, it) }
// fallback on searching everywhere since builtIns are accessible from any context
?: findInScope(referencedDescriptor, GlobalSearchScope.allScope(project))
?: findInScope(referencedDescriptor, EverythingGlobalScope(project))
// fallback on searching everywhere since builtIns are accessible from any context
?: findInScope(referencedDescriptor, GlobalSearchScope.allScope(project))
?: findInScope(referencedDescriptor, EverythingGlobalScope(project))
}
return null
}
@@ -73,31 +62,27 @@ fun findDecompiledDeclaration(
private fun findInScope(referencedDescriptor: DeclarationDescriptor, scope: GlobalSearchScope): KtDeclaration? {
val project = scope.project ?: return null
val decompiledFiles = findCandidateDeclarationsInIndex(
referencedDescriptor, KotlinSourceFilterScope.libraryClassFiles(scope, project), project
referencedDescriptor, KotlinSourceFilterScope.libraryClassFiles(scope, project), project
).mapNotNullTo(LinkedHashSet()) {
it?.containingFile as? KtDecompiledFile
}
return decompiledFiles.asSequence().mapNotNull {
file ->
return decompiledFiles.asSequence().mapNotNull { file ->
ByDescriptorIndexer.getDeclarationForDescriptor(referencedDescriptor, file)
}.firstOrNull()
}
private fun isLocal(descriptor: DeclarationDescriptor): Boolean {
return if (descriptor is ParameterDescriptor) {
isLocal(descriptor.containingDeclaration)
}
else {
DescriptorUtils.isLocal(descriptor)
}
private fun isLocal(descriptor: DeclarationDescriptor): Boolean = if (descriptor is ParameterDescriptor) {
isLocal(descriptor.containingDeclaration)
} else {
DescriptorUtils.isLocal(descriptor)
}
private fun findCandidateDeclarationsInIndex(
referencedDescriptor: DeclarationDescriptor,
scope: GlobalSearchScope,
project: Project
referencedDescriptor: DeclarationDescriptor,
scope: GlobalSearchScope,
project: Project
): Collection<KtDeclaration?> {
val containingClass = DescriptorUtils.getParentOfType(referencedDescriptor, ClassDescriptor::class.java, false)
if (containingClass != null) {
@@ -105,7 +90,7 @@ private fun findCandidateDeclarationsInIndex(
}
val topLevelDeclaration =
DescriptorUtils.getParentOfType(referencedDescriptor, PropertyDescriptor::class.java, false) as DeclarationDescriptor?
DescriptorUtils.getParentOfType(referencedDescriptor, PropertyDescriptor::class.java, false) as DeclarationDescriptor?
?: DescriptorUtils.getParentOfType(referencedDescriptor, TypeAliasConstructorDescriptor::class.java, false)?.typeAliasDescriptor
?: DescriptorUtils.getParentOfType(referencedDescriptor, FunctionDescriptor::class.java, false)
?: DescriptorUtils.getParentOfType(referencedDescriptor, TypeAliasDescriptor::class.java, false)
@@ -143,8 +128,10 @@ object ByDescriptorIndexer : DecompiledTextIndexer<String> {
val callable = original.containingDeclaration
val callableDeclaration = getDeclarationForDescriptor(callable, file) as? KtCallableDeclaration ?: return null
if (original.index >= callableDeclaration.valueParameters.size) {
LOG.error("Parameter count mismatch for ${DescriptorRenderer.DEBUG_TEXT.render(callable)}[${original.index}] vs " +
callableDeclaration.valueParameterList?.text)
LOG.error(
"Parameter count mismatch for ${DescriptorRenderer.DEBUG_TEXT.render(callable)}[${original.index}] vs " +
callableDeclaration.valueParameterList?.text
)
return null
}
return callableDeclaration.valueParameters[original.index]
@@ -158,8 +145,12 @@ object ByDescriptorIndexer : DecompiledTextIndexer<String> {
val descriptorKey = original.toStringKey()
if (!file.isContentsLoaded && original is MemberDescriptor) {
val hasDeclarationByKey = file.hasDeclarationWithKey(this, descriptorKey) ||
(getBuiltinsDescriptorKey(descriptor)?.let { file.hasDeclarationWithKey(this, it) } ?: false)
val hasDeclarationByKey = file.hasDeclarationWithKey(this, descriptorKey) || (getBuiltinsDescriptorKey(descriptor)?.let {
file.hasDeclarationWithKey(
this,
it
)
} ?: false)
if (hasDeclarationByKey) {
val declarationContainer: KtDeclarationContainer? = when {
DescriptorUtils.isTopLevelDeclaration(original) -> file
@@ -190,7 +181,7 @@ object ByDescriptorIndexer : DecompiledTextIndexer<String> {
if (!JvmBuiltInsSettings.isSerializableInJava(classFqName)) return null
val builtInDescriptor =
DefaultBuiltIns.Instance.builtInsModule.resolveTopLevelClass(classFqName.toSafe(), NoLookupLocation.FROM_IDE)
DefaultBuiltIns.Instance.builtInsModule.resolveTopLevelClass(classFqName.toSafe(), NoLookupLocation.FROM_IDE)
return builtInDescriptor?.toStringKey()
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -38,22 +27,23 @@ import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.getName
fun createDeclarationsStubs(
parentStub: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
packageProto: ProtoBuf.Package
parentStub: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
packageProto: ProtoBuf.Package
) {
createDeclarationsStubs(
parentStub, outerContext, protoContainer, packageProto.functionList, packageProto.propertyList, packageProto.typeAliasList)
parentStub, outerContext, protoContainer, packageProto.functionList, packageProto.propertyList, packageProto.typeAliasList
)
}
fun createDeclarationsStubs(
parentStub: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
functionProtos: List<ProtoBuf.Function>,
propertyProtos: List<ProtoBuf.Property>,
typeAliasesProtos: List<ProtoBuf.TypeAlias>
parentStub: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
functionProtos: List<ProtoBuf.Function>,
propertyProtos: List<ProtoBuf.Property>,
typeAliasesProtos: List<ProtoBuf.TypeAlias>
) {
for (propertyProto in propertyProtos) {
if (!shouldSkip(propertyProto.flags, outerContext.nameResolver.getName(propertyProto.name))) {
@@ -72,10 +62,10 @@ fun createDeclarationsStubs(
}
fun createConstructorStub(
parentStub: StubElement<out PsiElement>,
constructorProto: ProtoBuf.Constructor,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer
parentStub: StubElement<out PsiElement>,
constructorProto: ProtoBuf.Constructor,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer
) {
ConstructorClsStubBuilder(parentStub, outerContext, protoContainer, constructorProto).build()
}
@@ -90,10 +80,10 @@ private fun shouldSkip(flags: Int, name: Name): Boolean {
}
abstract class CallableClsStubBuilder(
parent: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protected val protoContainer: ProtoContainer,
private val typeParameters: List<ProtoBuf.TypeParameter>
parent: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protected val protoContainer: ProtoContainer,
private val typeParameters: List<ProtoBuf.TypeParameter>
) {
protected val c = outerContext.child(typeParameters)
protected val typeStubBuilder = TypeClsStubBuilder(c)
@@ -134,10 +124,10 @@ abstract class CallableClsStubBuilder(
}
private class FunctionClsStubBuilder(
parent: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
private val functionProto: ProtoBuf.Function
parent: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
private val functionProto: ProtoBuf.Function
) : CallableClsStubBuilder(parent, outerContext, protoContainer, functionProto.typeParameterList) {
override val receiverType: ProtoBuf.Type?
get() = functionProto.receiverType(c.typeTable)
@@ -145,8 +135,8 @@ private class FunctionClsStubBuilder(
override val receiverAnnotations: List<ClassIdWithTarget>
get() {
return c.components.annotationLoader
.loadExtensionReceiverParameterAnnotations(protoContainer, functionProto, AnnotatedCallableKind.FUNCTION)
.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
.loadExtensionReceiverParameterAnnotations(protoContainer, functionProto, AnnotatedCallableKind.FUNCTION)
.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
}
override val returnType: ProtoBuf.Type?
@@ -159,12 +149,12 @@ private class FunctionClsStubBuilder(
override fun createModifierListStub() {
val modalityModifier = if (isTopLevel) listOf() else listOf(MODALITY)
val modifierListStubImpl = createModifierListStubForDeclaration(
callableStub, functionProto.flags,
listOf(VISIBILITY, OPERATOR, INFIX, EXTERNAL_FUN, INLINE, TAILREC, SUSPEND) + modalityModifier
callableStub, functionProto.flags,
listOf(VISIBILITY, OPERATOR, INFIX, EXTERNAL_FUN, INLINE, TAILREC, SUSPEND) + modalityModifier
)
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
protoContainer, functionProto, AnnotatedCallableKind.FUNCTION
protoContainer, functionProto, AnnotatedCallableKind.FUNCTION
)
createAnnotationStubs(annotationIds, modifierListStubImpl)
}
@@ -173,24 +163,24 @@ private class FunctionClsStubBuilder(
val callableName = c.nameResolver.getName(functionProto.name)
return KotlinFunctionStubImpl(
parent,
callableName.ref(),
isTopLevel,
c.containerFqName.child(callableName),
isExtension = functionProto.hasReceiver(),
hasBlockBody = true,
hasBody = Flags.MODALITY.get(functionProto.flags) != Modality.ABSTRACT,
hasTypeParameterListBeforeFunctionName = functionProto.typeParameterList.isNotEmpty(),
mayHaveContract = functionProto.hasContract()
parent,
callableName.ref(),
isTopLevel,
c.containerFqName.child(callableName),
isExtension = functionProto.hasReceiver(),
hasBlockBody = true,
hasBody = Flags.MODALITY.get(functionProto.flags) != Modality.ABSTRACT,
hasTypeParameterListBeforeFunctionName = functionProto.typeParameterList.isNotEmpty(),
mayHaveContract = functionProto.hasContract()
)
}
}
private class PropertyClsStubBuilder(
parent: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
private val propertyProto: ProtoBuf.Property
parent: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
private val propertyProto: ProtoBuf.Property
) : CallableClsStubBuilder(parent, outerContext, protoContainer, propertyProto.typeParameterList) {
private val isVar = Flags.IS_VAR.get(propertyProto.flags)
@@ -198,11 +188,9 @@ private class PropertyClsStubBuilder(
get() = propertyProto.receiverType(c.typeTable)
override val receiverAnnotations: List<ClassIdWithTarget>
get() {
return c.components.annotationLoader
.loadExtensionReceiverParameterAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY_GETTER)
.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
}
get() = c.components.annotationLoader
.loadExtensionReceiverParameterAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY_GETTER)
.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
override val returnType: ProtoBuf.Type?
get() = propertyProto.returnType(c.typeTable)
@@ -215,8 +203,8 @@ private class PropertyClsStubBuilder(
val modalityModifier = if (isTopLevel) listOf() else listOf(MODALITY)
val modifierListStubImpl = createModifierListStubForDeclaration(
callableStub, propertyProto.flags,
listOf(VISIBILITY, LATEINIT, EXTERNAL_PROPERTY) + constModifier + modalityModifier
callableStub, propertyProto.flags,
listOf(VISIBILITY, LATEINIT, EXTERNAL_PROPERTY) + constModifier + modalityModifier
)
val propertyAnnotations =
@@ -236,25 +224,25 @@ private class PropertyClsStubBuilder(
val callableName = c.nameResolver.getName(propertyProto.name)
return KotlinPropertyStubImpl(
parent,
callableName.ref(),
isVar,
isTopLevel,
hasDelegate = false,
hasDelegateExpression = false,
hasInitializer = false,
isExtension = propertyProto.hasReceiver(),
hasReturnTypeRef = true,
fqName = c.containerFqName.child(callableName)
parent,
callableName.ref(),
isVar,
isTopLevel,
hasDelegate = false,
hasDelegateExpression = false,
hasInitializer = false,
isExtension = propertyProto.hasReceiver(),
hasReturnTypeRef = true,
fqName = c.containerFqName.child(callableName)
)
}
}
private class ConstructorClsStubBuilder(
parent: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
private val constructorProto: ProtoBuf.Constructor
parent: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
private val constructorProto: ProtoBuf.Constructor
) : CallableClsStubBuilder(parent, outerContext, protoContainer, emptyList()) {
override val receiverType: ProtoBuf.Type?
get() = null
@@ -273,7 +261,7 @@ private class ConstructorClsStubBuilder(
val modifierListStubImpl = createModifierListStubForDeclaration(callableStub, constructorProto.flags, listOf(VISIBILITY))
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
protoContainer, constructorProto, AnnotatedCallableKind.FUNCTION
protoContainer, constructorProto, AnnotatedCallableKind.FUNCTION
)
createAnnotationStubs(annotationIds, modifierListStubImpl)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -45,46 +34,47 @@ import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.deserialization.getName
fun createClassStub(
parent: StubElement<out PsiElement>,
classProto: ProtoBuf.Class,
nameResolver: NameResolver,
classId: ClassId,
source: SourceElement?,
context: ClsStubBuilderContext
parent: StubElement<out PsiElement>,
classProto: ProtoBuf.Class,
nameResolver: NameResolver,
classId: ClassId,
source: SourceElement?,
context: ClsStubBuilderContext
) {
ClassClsStubBuilder(parent, classProto, nameResolver, classId, source, context).build()
}
private class ClassClsStubBuilder(
private val parentStub: StubElement<out PsiElement>,
private val classProto: ProtoBuf.Class,
nameResolver: NameResolver,
private val classId: ClassId,
source: SourceElement?,
outerContext: ClsStubBuilderContext
private val parentStub: StubElement<out PsiElement>,
private val classProto: ProtoBuf.Class,
nameResolver: NameResolver,
private val classId: ClassId,
source: SourceElement?,
outerContext: ClsStubBuilderContext
) {
private val thisAsProtoContainer = ProtoContainer.Class(
classProto, nameResolver, TypeTable(classProto.typeTable), source, outerContext.protoContainer
classProto, nameResolver, TypeTable(classProto.typeTable), source, outerContext.protoContainer
)
private val classKind = thisAsProtoContainer.kind
private val c = outerContext.child(
classProto.typeParameterList, classId.shortClassName, nameResolver, thisAsProtoContainer.typeTable, thisAsProtoContainer
classProto.typeParameterList, classId.shortClassName, nameResolver, thisAsProtoContainer.typeTable, thisAsProtoContainer
)
private val typeStubBuilder = TypeClsStubBuilder(c)
private val supertypeIds = run {
val supertypeIds = classProto.supertypes(c.typeTable).map { c.nameResolver.getClassId(it.className) }
//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()
}
else {
} else {
supertypeIds
}
}
private val companionObjectName =
if (classProto.hasCompanionObjectName()) c.nameResolver.getName(classProto.companionObjectName) else null
private val companionObjectName = if (classProto.hasCompanionObjectName())
c.nameResolver.getName(classProto.companionObjectName)
else
null
private val classOrObjectStub = createClassOrObjectStubAndModifierListStub()
@@ -134,24 +124,24 @@ private class ClassClsStubBuilder(
return when (classKind) {
ProtoBuf.Class.Kind.OBJECT, ProtoBuf.Class.Kind.COMPANION_OBJECT -> {
KotlinObjectStubImpl(
parentStub, shortName, fqName, superTypeRefs,
isTopLevel = !classId.isNestedClass,
isDefault = isCompanionObject,
isLocal = false,
isObjectLiteral = false
parentStub, shortName, fqName, superTypeRefs,
isTopLevel = !classId.isNestedClass,
isDefault = isCompanionObject,
isLocal = false,
isObjectLiteral = false
)
}
else -> {
KotlinClassStubImpl(
KtClassElementType.getStubType(classKind == ProtoBuf.Class.Kind.ENUM_ENTRY),
parentStub,
fqName.ref(),
shortName,
superTypeRefs,
isInterface = classKind == ProtoBuf.Class.Kind.INTERFACE,
isEnumEntry = classKind == ProtoBuf.Class.Kind.ENUM_ENTRY,
isLocal = false,
isTopLevel = !classId.isNestedClass
KtClassElementType.getStubType(classKind == ProtoBuf.Class.Kind.ENUM_ENTRY),
parentStub,
fqName.ref(),
shortName,
superTypeRefs,
isInterface = classKind == ProtoBuf.Class.Kind.INTERFACE,
isEnumEntry = classKind == ProtoBuf.Class.Kind.ENUM_ENTRY,
isLocal = false,
isTopLevel = !classId.isNestedClass
)
}
}
@@ -169,12 +159,11 @@ private class ClassClsStubBuilder(
// if single supertype is any then no delegation specifier list is needed
if (supertypeIds.isEmpty()) return
val delegationSpecifierListStub =
KotlinPlaceHolderStubImpl<KtSuperTypeList>(classOrObjectStub, KtStubElementTypes.SUPER_TYPE_LIST)
val delegationSpecifierListStub = KotlinPlaceHolderStubImpl<KtSuperTypeList>(classOrObjectStub, KtStubElementTypes.SUPER_TYPE_LIST)
classProto.supertypes(c.typeTable).forEach { type ->
val superClassStub = KotlinPlaceHolderStubImpl<KtSuperTypeEntry>(
delegationSpecifierListStub, KtStubElementTypes.SUPER_TYPE_ENTRY
delegationSpecifierListStub, KtStubElementTypes.SUPER_TYPE_ENTRY
)
typeStubBuilder.createTypeReferenceStub(superClassStub, type)
}
@@ -204,15 +193,15 @@ private class ClassClsStubBuilder(
val name = c.nameResolver.getName(entry.name)
val annotations = c.components.annotationLoader.loadEnumEntryAnnotations(thisAsProtoContainer, entry)
val enumEntryStub = KotlinClassStubImpl(
KtStubElementTypes.ENUM_ENTRY,
classBody,
qualifiedName = c.containerFqName.child(name).ref(),
name = name.ref(),
superNames = arrayOf(),
isInterface = false,
isEnumEntry = true,
isLocal = false,
isTopLevel = false
KtStubElementTypes.ENUM_ENTRY,
classBody,
qualifiedName = c.containerFqName.child(name).ref(),
name = name.ref(),
superNames = arrayOf(),
isInterface = false,
isEnumEntry = true,
isLocal = false,
isTopLevel = false
)
if (annotations.isNotEmpty()) {
createAnnotationStubs(annotations, createEmptyModifierListStub(enumEntryStub))
@@ -228,13 +217,14 @@ private class ClassClsStubBuilder(
}
createDeclarationsStubs(
classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList, classProto.typeAliasList)
classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList, classProto.typeAliasList
)
}
private fun isClass(): Boolean {
return classKind == ProtoBuf.Class.Kind.CLASS ||
classKind == ProtoBuf.Class.Kind.ENUM_CLASS ||
classKind == ProtoBuf.Class.Kind.ANNOTATION_CLASS
classKind == ProtoBuf.Class.Kind.ENUM_CLASS ||
classKind == ProtoBuf.Class.Kind.ANNOTATION_CLASS
}
private fun createInnerAndNestedClasses(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -32,24 +21,23 @@ import org.jetbrains.kotlin.serialization.deserialization.getName
data class ClassIdWithTarget(val classId: ClassId, val target: AnnotationUseSiteTarget?)
class ClsStubBuilderComponents(
val classDataFinder: ClassDataFinder,
val annotationLoader: AnnotationAndConstantLoader<ClassId, Unit>,
val virtualFileForDebug: VirtualFile
val classDataFinder: ClassDataFinder,
val annotationLoader: AnnotationAndConstantLoader<ClassId, Unit>,
val virtualFileForDebug: VirtualFile
) {
fun createContext(
nameResolver: NameResolver,
packageFqName: FqName,
typeTable: TypeTable
): ClsStubBuilderContext {
return ClsStubBuilderContext(this, nameResolver, packageFqName, EmptyTypeParameters, typeTable, protoContainer = null)
}
nameResolver: NameResolver,
packageFqName: FqName,
typeTable: TypeTable
): ClsStubBuilderContext =
ClsStubBuilderContext(this, nameResolver, packageFqName, EmptyTypeParameters, typeTable, protoContainer = null)
}
interface TypeParameters {
operator fun get(id: Int): Name
fun child(nameResolver: NameResolver, innerTypeParameters: List<ProtoBuf.TypeParameter>)
= TypeParametersImpl(nameResolver, innerTypeParameters, parent = this)
fun child(nameResolver: NameResolver, innerTypeParameters: List<ProtoBuf.TypeParameter>) =
TypeParametersImpl(nameResolver, innerTypeParameters, parent = this)
}
object EmptyTypeParameters : TypeParameters {
@@ -57,9 +45,9 @@ object EmptyTypeParameters : TypeParameters {
}
class TypeParametersImpl(
nameResolver: NameResolver,
typeParameterProtos: Collection<ProtoBuf.TypeParameter>,
private val parent: TypeParameters
nameResolver: NameResolver,
typeParameterProtos: Collection<ProtoBuf.TypeParameter>,
private val parent: TypeParameters
) : TypeParameters {
private val typeParametersById = typeParameterProtos.map { Pair(it.id, nameResolver.getName(it.name)) }.toMap()
@@ -67,27 +55,25 @@ class TypeParametersImpl(
}
class ClsStubBuilderContext(
val components: ClsStubBuilderComponents,
val nameResolver: NameResolver,
val containerFqName: FqName,
val typeParameters: TypeParameters,
val typeTable: TypeTable,
val protoContainer: ProtoContainer.Class?
val components: ClsStubBuilderComponents,
val nameResolver: NameResolver,
val containerFqName: FqName,
val typeParameters: TypeParameters,
val typeTable: TypeTable,
val protoContainer: ProtoContainer.Class?
)
internal fun ClsStubBuilderContext.child(
typeParameterList: List<ProtoBuf.TypeParameter>,
name: Name? = null,
nameResolver: NameResolver = this.nameResolver,
typeTable: TypeTable = this.typeTable,
protoContainer: ProtoContainer.Class? = this.protoContainer
): ClsStubBuilderContext {
return ClsStubBuilderContext(
this.components,
nameResolver,
if (name != null) this.containerFqName.child(name) else this.containerFqName,
this.typeParameters.child(nameResolver, typeParameterList),
typeTable,
protoContainer
)
}
typeParameterList: List<ProtoBuf.TypeParameter>,
name: Name? = null,
nameResolver: NameResolver = this.nameResolver,
typeTable: TypeTable = this.typeTable,
protoContainer: ProtoContainer.Class? = this.protoContainer
): ClsStubBuilderContext = ClsStubBuilderContext(
this.components,
nameResolver,
if (name != null) this.containerFqName.child(name) else this.containerFqName,
this.typeParameters.child(nameResolver, typeParameterList),
typeTable,
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.
*/
@@ -36,7 +36,11 @@ import java.util.*
private val ANNOTATIONS_NOT_LOADED_FOR_TYPES = setOf(KotlinBuiltIns.FQ_NAMES.parameterName)
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)
if (abbreviatedType != null) {
return createTypeReferenceStub(parent, abbreviatedType, additionalAnnotations)
@@ -64,9 +68,10 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
}
}
private fun nullableTypeParent(parent: KotlinStubBaseImpl<*>, type: Type): KotlinStubBaseImpl<*> =
if (type.nullable) KotlinPlaceHolderStubImpl<KtNullableType>(parent, KtStubElementTypes.NULLABLE_TYPE)
else parent
private fun nullableTypeParent(parent: KotlinStubBaseImpl<*>, type: Type): KotlinStubBaseImpl<*> = if (type.nullable)
KotlinPlaceHolderStubImpl<KtNullableType>(parent, KtStubElementTypes.NULLABLE_TYPE)
else
parent
private fun createTypeParameterStub(parent: KotlinStubBaseImpl<*>, type: Type, name: Name, annotations: List<ClassIdWithTarget>) {
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 shouldBuildAsFunctionType = isBuiltinFunctionClass(classId)
&& type.argumentList.none { it.projection == Projection.STAR }
val shouldBuildAsFunctionType = isBuiltinFunctionClass(classId) && type.argumentList.none { it.projection == Projection.STAR }
if (shouldBuildAsFunctionType) {
val (extensionAnnotations, notExtensionAnnotations) =
annotations.partition { it.classId.asSingleFqName() == KotlinBuiltIns.FQ_NAMES.extensionFunctionType }
val (extensionAnnotations, notExtensionAnnotations) = annotations.partition {
it.classId.asSingleFqName() == KotlinBuiltIns.FQ_NAMES.extensionFunctionType
}
val isExtension = extensionAnnotations.isNotEmpty()
val isSuspend = Flags.SUSPEND_TYPE.get(type.flags)
@@ -101,8 +106,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
val wrapper = nullableTypeParent(parent, type)
createTypeAnnotationStubs(wrapper, type, notExtensionAnnotations)
wrapper
}
else {
} else {
createTypeAnnotationStubs(parent, type, notExtensionAnnotations)
nullableTypeParent(parent, type)
}
@@ -116,8 +120,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
val outerTypeChain = generateSequence(type) { it.outerType(c.typeTable) }.toList()
createStubForTypeName(classId, nullableTypeParent(parent, type)) {
userTypeStub, index ->
createStubForTypeName(classId, nullableTypeParent(parent, type)) { userTypeStub, index ->
outerTypeChain.getOrNull(index)?.let { createTypeArgumentListStub(userTypeStub, it.argumentList) }
}
}
@@ -165,19 +168,24 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
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 functionType = KotlinPlaceHolderStubImpl<KtFunctionType>(parent, KtStubElementTypes.FUNCTION_TYPE)
if (isExtensionFunctionType) {
val functionTypeReceiverStub
= KotlinPlaceHolderStubImpl<KtFunctionTypeReceiver>(functionType, KtStubElementTypes.FUNCTION_TYPE_RECEIVER)
val functionTypeReceiverStub =
KotlinPlaceHolderStubImpl<KtFunctionTypeReceiver>(functionType, KtStubElementTypes.FUNCTION_TYPE_RECEIVER)
val receiverTypeProto = typeArgumentList.first().type(c.typeTable)!!
createTypeReferenceStub(functionTypeReceiverStub, receiverTypeProto)
}
val parameterList = KotlinPlaceHolderStubImpl<KtParameterList>(functionType, KtStubElementTypes.VALUE_PARAMETER_LIST)
val typeArgumentsWithoutReceiverAndReturnType
= typeArgumentList.subList(if (isExtensionFunctionType) 1 else 0, typeArgumentList.size - 1)
val typeArgumentsWithoutReceiverAndReturnType =
typeArgumentList.subList(if (isExtensionFunctionType) 1 else 0, typeArgumentList.size - 1)
var suspendParameterType: Type? = null
for ((index, argument) in typeArgumentsWithoutReceiverAndReturnType.withIndex()) {
@@ -197,7 +205,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
}
}
val parameter = KotlinParameterStubImpl(
parameterList, fqName = null, name = null, isMutable = false, hasValOrVar = false, hasDefaultValue = false
parameterList, fqName = null, name = null, isMutable = false, hasValOrVar = false, hasDefaultValue = false
)
createTypeReferenceStub(parameter, argument.type(c.typeTable)!!)
@@ -207,41 +215,46 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
if (suspendParameterType == null) {
val returnType = typeArgumentList.last().type(c.typeTable)!!
createTypeReferenceStub(functionType, returnType)
}
else {
} else {
val continuationArgumentType = suspendParameterType.getArgument(0).type(c.typeTable)!!
createTypeReferenceStub(functionType, continuationArgumentType)
}
}
fun createValueParameterListStub(
parent: StubElement<out PsiElement>,
callableProto: MessageLite,
parameters: List<ProtoBuf.ValueParameter>,
container: ProtoContainer
parent: StubElement<out PsiElement>,
callableProto: MessageLite,
parameters: List<ProtoBuf.ValueParameter>,
container: ProtoContainer
) {
val parameterListStub = KotlinPlaceHolderStubImpl<KtParameterList>(parent, KtStubElementTypes.VALUE_PARAMETER_LIST)
for ((index, valueParameterProto) in parameters.withIndex()) {
val name = c.nameResolver.getName(valueParameterProto.name)
val parameterStub = KotlinParameterStubImpl(
parameterListStub,
name = name.ref(),
fqName = null,
hasDefaultValue = false,
hasValOrVar = false,
isMutable = false
parameterListStub,
name = name.ref(),
fqName = null,
hasDefaultValue = false,
hasValOrVar = false,
isMutable = false
)
val varargElementType = valueParameterProto.varargElementType(c.typeTable)
val typeProto = varargElementType ?: valueParameterProto.type(c.typeTable)
val modifiers = arrayListOf<KtModifierKeywordToken>()
if (varargElementType != null) { modifiers.add(KtTokens.VARARG_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) }
if (varargElementType != null) {
modifiers.add(KtTokens.VARARG_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 parameterAnnotations = c.components.annotationLoader.loadValueParameterAnnotations(
container, callableProto, callableProto.annotatedCallableKind, index, valueParameterProto
container, callableProto, callableProto.annotatedCallableKind, index, valueParameterProto
)
if (parameterAnnotations.isNotEmpty()) {
createAnnotationStubs(parameterAnnotations, modifierList ?: createEmptyModifierListStub(parameterStub))
@@ -252,8 +265,8 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
}
fun createTypeParameterListStub(
parent: StubElement<out PsiElement>,
typeParameterProtoList: List<ProtoBuf.TypeParameter>
parent: StubElement<out PsiElement>,
typeParameterProtoList: List<ProtoBuf.TypeParameter>
): List<Pair<Name, Type>> {
if (typeParameterProtoList.isEmpty()) return listOf()
@@ -262,10 +275,10 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
for (proto in typeParameterProtoList) {
val name = c.nameResolver.getName(proto.name)
val typeParameterStub = KotlinTypeParameterStubImpl(
typeParameterListStub,
name = name.ref(),
isInVariance = proto.variance == Variance.IN,
isOutVariance = proto.variance == Variance.OUT
typeParameterListStub,
name = name.ref(),
isInVariance = proto.variance == Variance.IN,
isOutVariance = proto.variance == Variance.OUT
)
createTypeParameterModifierListStub(typeParameterStub, proto)
val upperBoundProtos = proto.upperBounds(c.typeTable)
@@ -281,8 +294,8 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
}
fun createTypeConstraintListStub(
parent: StubElement<out PsiElement>,
protosForTypeConstraintList: List<Pair<Name, Type>>
parent: StubElement<out PsiElement>,
protosForTypeConstraintList: List<Pair<Name, Type>>
) {
if (protosForTypeConstraintList.isEmpty()) {
return
@@ -296,15 +309,17 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
}
private fun createTypeParameterModifierListStub(
typeParameterStub: KotlinTypeParameterStubImpl,
typeParameterProto: ProtoBuf.TypeParameter
typeParameterStub: KotlinTypeParameterStubImpl,
typeParameterProto: ProtoBuf.TypeParameter
) {
val modifiers = ArrayList<KtModifierKeywordToken>()
when (typeParameterProto.variance) {
Variance.IN -> modifiers.add(KtTokens.IN_KEYWORD)
Variance.OUT -> modifiers.add(KtTokens.OUT_KEYWORD)
Variance.INV -> { /* do nothing */ }
null -> { /* do nothing */ }
Variance.INV -> { /* do nothing */
}
null -> { /* do nothing */
}
}
if (typeParameterProto.reified) {
modifiers.add(KtTokens.REIFIED_KEYWORD)
@@ -315,14 +330,15 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
val annotations = c.components.annotationLoader.loadTypeParameterAnnotations(typeParameterProto, c.nameResolver)
if (annotations.isNotEmpty()) {
createAnnotationStubs(
annotations,
modifierList ?: createEmptyModifierListStub(typeParameterStub))
annotations,
modifierList ?: createEmptyModifierListStub(typeParameterStub)
)
}
}
private fun Type.isDefaultUpperBound(): Boolean {
return this.hasClassName() &&
c.nameResolver.getClassId(className).let { KotlinBuiltIns.FQ_NAMES.any == it.asSingleFqName().toUnsafe() } &&
this.nullable
c.nameResolver.getClassId(className).let { KotlinBuiltIns.FQ_NAMES.any == it.asSingleFqName().toUnsafe() } &&
this.nullable
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -43,11 +32,11 @@ import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
fun createTopLevelClassStub(
classId: ClassId,
classProto: ProtoBuf.Class,
source: SourceElement?,
context: ClsStubBuilderContext,
isScript: Boolean
classId: ClassId,
classProto: ProtoBuf.Class,
source: SourceElement?,
context: ClsStubBuilderContext,
isScript: Boolean
): KotlinFileStubImpl {
val fileStub = createFileStub(classId.packageFqName, isScript)
createClassStub(fileStub, classProto, context.nameResolver, classId, source, context)
@@ -55,21 +44,22 @@ fun createTopLevelClassStub(
}
fun createPackageFacadeStub(
packageProto: ProtoBuf.Package,
packageFqName: FqName,
c: ClsStubBuilderContext
packageProto: ProtoBuf.Package,
packageFqName: FqName,
c: ClsStubBuilderContext
): KotlinFileStubImpl {
val fileStub = KotlinFileStubForIde.forFile(packageFqName, isScript = false)
setupFileStub(fileStub, packageFqName)
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
}
fun createFileFacadeStub(
packageProto: ProtoBuf.Package,
facadeFqName: FqName,
c: ClsStubBuilderContext
packageProto: ProtoBuf.Package,
facadeFqName: FqName,
c: ClsStubBuilderContext
): KotlinFileStubImpl {
val packageFqName = facadeFqName.parent()
val fileStub = KotlinFileStubForIde.forFileFacadeStub(facadeFqName)
@@ -83,10 +73,10 @@ fun createFileFacadeStub(
}
fun createMultifileClassStub(
header: KotlinClassHeader,
partFiles: List<KotlinJvmBinaryClass>,
facadeFqName: FqName,
components: ClsStubBuilderComponents
header: KotlinClassHeader,
partFiles: List<KotlinJvmBinaryClass>,
facadeFqName: FqName,
components: ClsStubBuilderComponents
): KotlinFileStubImpl {
val packageFqName = facadeFqName.parent()
val partNames = header.data?.asList()?.map { it.substringAfterLast('/') }
@@ -143,15 +133,15 @@ fun createStubForPackageName(packageDirectiveStub: KotlinPlaceHolderStubImpl<KtP
}
fun createStubForTypeName(
typeClassId: ClassId,
parent: StubElement<out PsiElement>,
bindTypeArguments: (KotlinUserTypeStub, Int) -> Unit = { _, _ -> }
typeClassId: ClassId,
parent: StubElement<out PsiElement>,
bindTypeArguments: (KotlinUserTypeStub, Int) -> Unit = { _, _ -> }
): KotlinUserTypeStub {
val substituteWithAny = typeClassId.isLocal
val fqName =
if (substituteWithAny) KotlinBuiltIns.FQ_NAMES.any
else typeClassId.asSingleFqName().toUnsafe()
val fqName = if (substituteWithAny) KotlinBuiltIns.FQ_NAMES.any
else typeClassId.asSingleFqName().toUnsafe()
val segments = fqName.pathSegments().asReversed()
assert(segments.isNotEmpty())
@@ -172,10 +162,10 @@ fun createStubForTypeName(
}
fun createModifierListStubForDeclaration(
parent: StubElement<out PsiElement>,
flags: Int,
flagsToTranslate: List<FlagsToModifiers> = listOf(),
additionalModifiers: List<KtModifierKeywordToken> = listOf()
parent: StubElement<out PsiElement>,
flags: Int,
flagsToTranslate: List<FlagsToModifiers> = listOf(),
additionalModifiers: List<KtModifierKeywordToken> = listOf()
): KotlinModifierListStubImpl {
assert(flagsToTranslate.isNotEmpty())
@@ -184,24 +174,24 @@ fun createModifierListStubForDeclaration(
}
fun createModifierListStub(
parent: StubElement<out PsiElement>,
modifiers: Collection<KtModifierKeywordToken>
parent: StubElement<out PsiElement>,
modifiers: Collection<KtModifierKeywordToken>
): KotlinModifierListStubImpl? {
if (modifiers.isEmpty()) {
return null
}
return KotlinModifierListStubImpl(
parent,
ModifierMaskUtils.computeMask { it in modifiers },
KtStubElementTypes.MODIFIER_LIST
parent,
ModifierMaskUtils.computeMask { it in modifiers },
KtStubElementTypes.MODIFIER_LIST
)
}
fun createEmptyModifierListStub(parent: KotlinStubBaseImpl<*>): KotlinModifierListStubImpl {
return KotlinModifierListStubImpl(
parent,
ModifierMaskUtils.computeMask { false },
KtStubElementTypes.MODIFIER_LIST
parent,
ModifierMaskUtils.computeMask { false },
KtStubElementTypes.MODIFIER_LIST
)
}
@@ -210,34 +200,33 @@ fun createAnnotationStubs(annotationIds: List<ClassId>, parent: KotlinStubBaseIm
}
fun createTargetedAnnotationStubs(
annotationIds: List<ClassIdWithTarget>,
parent: KotlinStubBaseImpl<*>
annotationIds: List<ClassIdWithTarget>,
parent: KotlinStubBaseImpl<*>
) {
if (annotationIds.isEmpty()) return
annotationIds.forEach { annotation ->
val (annotationClassId, target) = annotation
val annotationEntryStubImpl = KotlinAnnotationEntryStubImpl(
parent,
shortName = annotationClassId.shortClassName.ref(),
hasValueArguments = false
parent,
shortName = annotationClassId.shortClassName.ref(),
hasValueArguments = false
)
if (target != null) {
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)
createStubForTypeName(annotationClassId, typeReference)
}
}
val MessageLite.annotatedCallableKind: AnnotatedCallableKind
get() {
return when (this) {
is ProtoBuf.Property -> AnnotatedCallableKind.PROPERTY
is ProtoBuf.Function, is ProtoBuf.Constructor -> AnnotatedCallableKind.FUNCTION
else -> throw IllegalStateException("Unsupported message: $this")
}
get() = when (this) {
is ProtoBuf.Property -> AnnotatedCallableKind.PROPERTY
is ProtoBuf.Function, is ProtoBuf.Constructor -> AnnotatedCallableKind.FUNCTION
else -> throw IllegalStateException("Unsupported message: $this")
}
fun Name.ref() = StringRef.fromString(this.asString())!!
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags
@@ -66,12 +55,12 @@ val TAILREC = createBooleanFlagToModifier(Flags.IS_TAILREC, KtTokens.TAILREC_KEY
val SUSPEND = createBooleanFlagToModifier(Flags.IS_SUSPEND, KtTokens.SUSPEND_KEYWORD)
private fun createBooleanFlagToModifier(
flagField: Flags.BooleanFlagField, ktModifierKeywordToken: KtModifierKeywordToken
flagField: Flags.BooleanFlagField, ktModifierKeywordToken: KtModifierKeywordToken
): FlagsToModifiers = BooleanFlagToModifier(flagField, ktModifierKeywordToken)
private class BooleanFlagToModifier(
private val flagField: Flags.BooleanFlagField,
private val ktModifierKeywordToken: KtModifierKeywordToken
private val flagField: Flags.BooleanFlagField,
private val ktModifierKeywordToken: KtModifierKeywordToken
) : FlagsToModifiers() {
override fun getModifiers(flags: Int): KtModifierKeywordToken? = if (flagField.get(flags)) ktModifierKeywordToken else null
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
@@ -21,18 +10,18 @@ import com.intellij.psi.stubs.StubElement
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags.VISIBILITY
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.deserialization.underlyingType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.stubs.impl.KotlinTypeAliasStubImpl
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.metadata.deserialization.underlyingType
fun createTypeAliasStub(
parent: StubElement<out PsiElement>,
typeAliasProto: ProtoBuf.TypeAlias,
protoContainer: ProtoContainer,
context: ClsStubBuilderContext
parent: StubElement<out PsiElement>,
typeAliasProto: ProtoBuf.TypeAlias,
protoContainer: ProtoContainer,
context: ClsStubBuilderContext
) {
val shortName = context.nameResolver.getName(typeAliasProto.name)
@@ -41,10 +30,10 @@ fun createTypeAliasStub(
is ProtoContainer.Package -> ClassId.topLevel(protoContainer.fqName.child(shortName))
}
val typeAlias =
KotlinTypeAliasStubImpl(
parent, classId.shortClassName.ref(), classId.asSingleFqName().ref(),
isTopLevel = !classId.isNestedClass)
val typeAlias = KotlinTypeAliasStubImpl(
parent, classId.shortClassName.ref(), classId.asSingleFqName().ref(),
isTopLevel = !classId.isNestedClass
)
val modifierList = createModifierListStubForDeclaration(typeAlias, typeAliasProto.flags, arrayListOf(VISIBILITY), listOf())
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.textBuilder
@@ -22,7 +11,7 @@ import org.jetbrains.kotlin.utils.keysToMap
data class DecompiledText(val text: String, val index: DecompiledTextIndex)
interface DecompiledTextIndexer<out T: Any> {
interface DecompiledTextIndexer<out T : Any> {
fun indexDescriptor(descriptor: DeclarationDescriptor): Collection<T>
}
@@ -33,16 +22,14 @@ class DecompiledTextIndex(private val indexers: Collection<DecompiledTextIndexer
fun addToIndex(descriptor: DeclarationDescriptor, textRange: TextRange) {
indexers.forEach { mapper ->
val correspondingMap = indexerToMap[mapper]!!
val correspondingMap = indexerToMap.getValue(mapper)
mapper.indexDescriptor(descriptor).forEach { key ->
correspondingMap[key] = textRange
}
}
}
fun <T: Any> getRange(mapper: DecompiledTextIndexer<T>, key: T): TextRange? {
return indexerToMap[mapper]?.get(key)
}
fun <T : Any> getRange(mapper: DecompiledTextIndexer<T>, key: T): TextRange? = indexerToMap[mapper]?.get(key)
companion object {
val Empty = DecompiledTextIndex(listOf())
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.decompiler.textBuilder
@@ -52,7 +41,7 @@ abstract class DeserializerForDecompilerBase(val directoryPackageFqName: FqName)
override fun resolveTopLevelClass(classId: ClassId) = deserializationComponents.deserializeClass(classId)
protected fun createDummyPackageFragment(fqName: FqName): MutablePackageFragmentDescriptor =
MutablePackageFragmentDescriptor(moduleDescriptor, fqName)
MutablePackageFragmentDescriptor(moduleDescriptor, fqName)
private fun createDummyModule(name: String) = ModuleDescriptorImpl(Name.special("<$name>"), storageManager, builtIns)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.types.isFlexible
private val DECOMPILED_CODE_COMMENT = "/* compiled code */"
private val DECOMPILED_COMMENT_FOR_PARAMETER = "/* = compiled code */"
private val FLEXIBLE_TYPE_COMMENT = "/* platform type */"
private val DECOMPILED_CONTRACT_STUB = "contract { /* compiled contract */ }"
private const val DECOMPILED_CODE_COMMENT = "/* compiled code */"
private const val DECOMPILED_COMMENT_FOR_PARAMETER = "/* = compiled code */"
private const val FLEXIBLE_TYPE_COMMENT = "/* platform type */"
private const val DECOMPILED_CONTRACT_STUB = "contract { /* compiled contract */ }"
fun DescriptorRendererOptions.defaultDecompilerRendererOptions() {
withDefinedIn = false
@@ -45,10 +34,10 @@ fun DescriptorRendererOptions.defaultDecompilerRendererOptions() {
}
fun buildDecompiledText(
packageFqName: FqName,
descriptors: List<DeclarationDescriptor>,
descriptorRenderer: DescriptorRenderer,
indexers: Collection<DecompiledTextIndexer<*>> = listOf(ByDescriptorIndexer)
packageFqName: FqName,
descriptors: List<DeclarationDescriptor>,
descriptorRenderer: DescriptorRenderer,
indexers: Collection<DecompiledTextIndexer<*>> = listOf(ByDescriptorIndexer)
): DecompiledText {
val builder = StringBuilder()
@@ -75,8 +64,7 @@ fun buildDecompiledText(
}
builder.append(descriptor.name.asString())
builder.append(if (lastEnumEntry!!) ";" else ",")
}
else {
} else {
builder.append(descriptorRenderer.render(descriptor).replace("= ...", DECOMPILED_COMMENT_FOR_PARAMETER))
}
var endOffset = builder.length
@@ -98,25 +86,22 @@ fun buildDecompiledText(
}
append(DECOMPILED_CODE_COMMENT).append(" }")
}
}
else {
} else {
// descriptor instanceof PropertyDescriptor
builder.append(" ").append(DECOMPILED_CODE_COMMENT)
}
endOffset = builder.length
}
}
else if (descriptor is ClassDescriptor && !isEnumEntry(descriptor)) {
} else if (descriptor is ClassDescriptor && !isEnumEntry(descriptor)) {
builder.append(" {\n")
val subindent = indent + " "
val subindent = "$indent "
var firstPassed = false
fun newlineExceptFirst() {
if (firstPassed) {
builder.append("\n")
}
else {
} else {
firstPassed = true
}
}
@@ -147,7 +132,8 @@ fun buildDecompiledText(
if (member is CallableMemberDescriptor
&& member.kind != CallableMemberDescriptor.Kind.DECLARATION
//TODO: not synthesized and component like
&& !DataClassDescriptorResolver.isComponentLike(member.name)) {
&& !DataClassDescriptorResolver.isComponentLike(member.name)
) {
continue
}
newlineExceptFirst()
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.roots.ModuleRootModel
import com.intellij.util.text.VersionComparatorUtil
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.platform.IdePlatformKind
import org.jetbrains.kotlin.platform.orDefault
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.VersionView
import org.jetbrains.kotlin.platform.IdePlatformKind
import org.jetbrains.kotlin.platform.idePlatformKind
import org.jetbrains.kotlin.platform.orDefault
interface KotlinVersionInfoProvider {
companion object {
@@ -43,18 +34,16 @@ fun getRuntimeLibraryVersions(
module: Module,
rootModel: ModuleRootModel?,
platformKind: IdePlatformKind<*>
): Collection<String> {
return KotlinVersionInfoProvider.EP_NAME
.extensions
.map { it.getLibraryVersions(module, platformKind, rootModel) }
.firstOrNull { it.isNotEmpty() } ?: emptyList()
}
): Collection<String> = KotlinVersionInfoProvider.EP_NAME
.extensions
.map { it.getLibraryVersions(module, platformKind, rootModel) }
.firstOrNull { it.isNotEmpty() } ?: emptyList()
fun getLibraryLanguageLevel(
module: Module,
rootModel: ModuleRootModel?,
platformKind: IdePlatformKind<*>?,
coerceRuntimeLibraryVersionToReleased: Boolean = true
module: Module,
rootModel: ModuleRootModel?,
platformKind: IdePlatformKind<*>?,
coerceRuntimeLibraryVersionToReleased: Boolean = true
): LanguageVersion {
val minVersion = getRuntimeLibraryVersions(module, rootModel, platformKind.orDefault())
.addReleaseVersionIfNecessary(coerceRuntimeLibraryVersionToReleased)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.findUsages
@@ -44,14 +33,10 @@ object UsageTypeUtils {
val context = refExpr.analyze(BodyResolveMode.PARTIAL)
fun getCommonUsageType(): UsageTypeEnum? {
return when {
refExpr.getNonStrictParentOfType<KtImportDirective>() != null ->
CLASS_IMPORT
refExpr.getParentOfTypeAndBranch<KtCallableReferenceExpression>(){ callableReference } != null ->
CALLABLE_REFERENCE
else -> null
}
fun getCommonUsageType(): UsageTypeEnum? = when {
refExpr.getNonStrictParentOfType<KtImportDirective>() != null -> CLASS_IMPORT
refExpr.getParentOfTypeAndBranch<KtCallableReferenceExpression>() { callableReference } != null -> CALLABLE_REFERENCE
else -> null
}
fun getClassUsageType(): UsageTypeEnum? {
@@ -79,26 +64,18 @@ object UsageTypeUtils {
}
return when {
refExpr.getParentOfTypeAndBranch<KtTypeParameter>(){ extendsBound } != null
|| refExpr.getParentOfTypeAndBranch<KtTypeConstraint>(){ boundTypeReference } != null ->
TYPE_CONSTRAINT
refExpr.getParentOfTypeAndBranch<KtTypeParameter>() { extendsBound } != null || refExpr.getParentOfTypeAndBranch<KtTypeConstraint>() { boundTypeReference } != null -> TYPE_CONSTRAINT
refExpr is KtSuperTypeListEntry
|| refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>(){ typeReference } != null ->
SUPER_TYPE
refExpr is KtSuperTypeListEntry || refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>() { typeReference } != null -> SUPER_TYPE
refExpr.getParentOfTypeAndBranch<KtParameter>(){ typeReference } != null ->
VALUE_PARAMETER_TYPE
refExpr.getParentOfTypeAndBranch<KtParameter>() { typeReference } != null -> VALUE_PARAMETER_TYPE
refExpr.getParentOfTypeAndBranch<KtIsExpression>(){ typeReference } != null
|| refExpr.getParentOfTypeAndBranch<KtWhenConditionIsPattern>(){ typeReference } != null ->
IS
refExpr.getParentOfTypeAndBranch<KtIsExpression>() { typeReference } != null || refExpr.getParentOfTypeAndBranch<KtWhenConditionIsPattern>() { typeReference } != null -> IS
with(refExpr.getParentOfTypeAndBranch<KtBinaryExpressionWithTypeRHS>(){ right }) {
with(refExpr.getParentOfTypeAndBranch<KtBinaryExpressionWithTypeRHS>() { right }) {
val opType = this?.operationReference?.getReferencedNameElementType()
opType == KtTokens.AS_KEYWORD || opType == KtTokens.AS_SAFE
} ->
CLASS_CAST_TO
} -> CLASS_CAST_TO
with(refExpr.getNonStrictParentOfType<KtDotQualifiedExpression>()) {
when {
@@ -110,26 +87,21 @@ object UsageTypeUtils {
}
else -> {
selectorExpression == refExpr
&& getParentOfTypeAndBranch<KtDotQualifiedExpression>(strict = true) { receiverExpression } != null
&& getParentOfTypeAndBranch<KtDotQualifiedExpression>(strict = true) { receiverExpression } != null
}
}
} ->
CLASS_OBJECT_ACCESS
} -> CLASS_OBJECT_ACCESS
refExpr.getParentOfTypeAndBranch<KtSuperExpression>(){ superTypeQualifier } != null ->
SUPER_TYPE_QUALIFIER
refExpr.getParentOfTypeAndBranch<KtSuperExpression>() { superTypeQualifier } != null -> SUPER_TYPE_QUALIFIER
refExpr.getParentOfTypeAndBranch<KtTypeAlias> { getTypeReference() } != null ->
TYPE_ALIAS
refExpr.getParentOfTypeAndBranch<KtTypeAlias> { getTypeReference() } != null -> TYPE_ALIAS
else -> null
}
}
fun getVariableUsageType(): UsageTypeEnum? {
if (refExpr.getParentOfTypeAndBranch<KtDelegatedSuperTypeEntry>(){ delegateExpression } != null) {
return DELEGATE
}
if (refExpr.getParentOfTypeAndBranch<KtDelegatedSuperTypeEntry>() { delegateExpression } != null) return DELEGATE
if (refExpr.parent is KtValueArgumentName) return NAMED_ARGUMENT
@@ -165,43 +137,32 @@ object UsageTypeUtils {
}
return when {
refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>(){ typeReference } != null ->
SUPER_TYPE
refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>() { typeReference } != null -> SUPER_TYPE
descriptor is ConstructorDescriptor
&& refExpr.getParentOfTypeAndBranch<KtAnnotationEntry>(){ typeReference } != null ->
ANNOTATION
descriptor is ConstructorDescriptor && refExpr.getParentOfTypeAndBranch<KtAnnotationEntry>() { typeReference } != null -> ANNOTATION
with(refExpr.getParentOfTypeAndBranch<KtCallExpression>(){ calleeExpression }) {
with(refExpr.getParentOfTypeAndBranch<KtCallExpression>() { calleeExpression }) {
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<KtUnaryExpression>(){ operationReference } != null ||
refExpr.getParentOfTypeAndBranch<KtWhenConditionInRange>(){ operationReference } != null ->
FUNCTION_CALL
refExpr.getParentOfTypeAndBranch<KtBinaryExpression>() { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtUnaryExpression>() { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtWhenConditionInRange>() { operationReference } != null -> FUNCTION_CALL
else -> null
}
}
fun getPackageUsageType(): UsageTypeEnum? {
return when {
refExpr.getNonStrictParentOfType<KtPackageDirective>() != null -> PACKAGE_DIRECTIVE
refExpr.getNonStrictParentOfType<KtQualifiedExpression>() != null -> PACKAGE_MEMBER_ACCESS
else -> getClassUsageType()
}
fun getPackageUsageType(): UsageTypeEnum? = when {
refExpr.getNonStrictParentOfType<KtPackageDirective>() != null -> PACKAGE_DIRECTIVE
refExpr.getNonStrictParentOfType<KtQualifiedExpression>() != null -> PACKAGE_MEMBER_ACCESS
else -> getClassUsageType()
}
val usageType = getCommonUsageType()
if (usageType != null) return usageType
val descriptor = context[BindingContext.REFERENCE_TARGET, refExpr]
return when (descriptor) {
return when (val descriptor = context[BindingContext.REFERENCE_TARGET, refExpr]) {
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.isCompanionObject(descriptor) -> COMPANION_OBJECT_ACCESS
else -> getClassUsageType()
@@ -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.
*/
@@ -19,9 +19,11 @@ object CommonLibraryType : LibraryType<DummyLibraryProperties>(CommonLibraryKind
override fun getCreateActionName() = null
override fun createNewLibrary(parentComponent: JComponent,
contextDirectory: VirtualFile?,
project: Project): NewLibraryConfiguration? = null
override fun createNewLibrary(
parentComponent: JComponent,
contextDirectory: VirtualFile?,
project: Project
): NewLibraryConfiguration? = null
override fun getIcon(properties: DummyLibraryProperties?) = KotlinIcons.MPP
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.PathUtil
import java.io.File
import java.util.*
import java.util.jar.Attributes
object JsLibraryStdDetectionUtil {
@@ -56,7 +44,8 @@ object JsLibraryStdDetectionUtil {
val name = root.url.substringBefore("!/").substringAfterLast('/')
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_JS_LIBRARY_JAR_PATTERN.matcher(name).matches()) {
PathUtil.KOTLIN_JS_LIBRARY_JAR_PATTERN.matcher(name).matches()
) {
val jar = VfsUtilCore.getVirtualFileForJar(root) ?: continue
var isJSStdLib = jar.getUserData(IS_JS_LIBRARY_STD_LIB)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.highlighter
@@ -82,7 +71,8 @@ internal class BeforeResolveHighlightingVisitor(holder: AnnotationHolder) : High
override fun visitArgument(argument: KtValueArgument) {
val argumentName = argument.getArgumentName() ?: 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) {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.highlighter
@@ -45,7 +34,7 @@ class DebugInfoAnnotator : Annotator {
DebugInfoUtil.markDebugAnnotations(element, bindingContext, object : DebugInfoUtil.DebugInfoReporter() {
override fun reportElementWithErrorType(expression: KtReferenceExpression) {
holder.createErrorAnnotation(expression, "[DEBUG] Resolved to error element").textAttributes =
KotlinHighlightingColors.RESOLVED_TO_ERROR
KotlinHighlightingColors.RESOLVED_TO_ERROR
}
override fun reportMissingUnresolved(expression: KtReferenceExpression) {
@@ -56,9 +45,8 @@ class DebugInfoAnnotator : Annotator {
}
override fun reportUnresolvedWithTarget(expression: KtReferenceExpression, target: String) {
holder.createErrorAnnotation(expression, "[DEBUG] Reference marked as unresolved is actually resolved to " + target)
.textAttributes =
KotlinHighlightingColors.DEBUG_INFO
holder.createErrorAnnotation(expression, "[DEBUG] Reference marked as unresolved is actually resolved to $target")
.textAttributes = KotlinHighlightingColors.DEBUG_INFO
}
})
} catch (e: ProcessCanceledException) {
@@ -74,6 +62,7 @@ class DebugInfoAnnotator : Annotator {
companion object {
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.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.highlighter
@@ -37,7 +26,7 @@ import org.jetbrains.kotlin.serialization.deserialization.KOTLIN_SUSPEND_BUILT_I
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
internal class FunctionsHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) :
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
override fun visitNamedFunction(function: KtNamedFunction) {
function.nameIdentifier?.let { highlightName(it, FUNCTION_DECLARATION) }
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.highlighter
@@ -25,8 +14,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
abstract class HighlighterExtension {
abstract fun highlightDeclaration(elementToHighlight: PsiElement, descriptor: DeclarationDescriptor): TextAttributesKey?
open fun highlightCall(elementToHighlight: PsiElement, resolvedCall: ResolvedCall<*>): TextAttributesKey?
= highlightDeclaration(elementToHighlight, resolvedCall.resultingDescriptor)
open fun highlightCall(elementToHighlight: PsiElement, resolvedCall: ResolvedCall<*>): TextAttributesKey? =
highlightDeclaration(elementToHighlight, resolvedCall.resultingDescriptor)
companion object {
val EP_NAME = ExtensionPointName.create<HighlighterExtension>("org.jetbrains.kotlin.highlighterExtension")
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.highlighter
@@ -40,7 +29,7 @@ object IdeRenderers {
@JvmField
val HTML_RENDER_TYPE = SmartTypeRenderer(DescriptorRenderer.HTML.withOptions {
parameterNamesInFunctionalTypes = false
modifiers = DescriptorRendererModifier.ALL_EXCEPT_ANNOTATIONS
modifiers = DescriptorRendererModifier.ALL_EXCEPT_ANNOTATIONS
})
@JvmField
@@ -86,7 +75,8 @@ object IdeRenderers {
val context = RenderingContext.of(descriptors)
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
@@ -98,8 +88,12 @@ object IdeRenderers {
val HTML = DescriptorRenderer.HTML.withOptions {
modifiers = DescriptorRendererModifier.ALL_EXCEPT_ANNOTATIONS
}.asRenderer()
@JvmField val HTML_WITH_ANNOTATIONS = DescriptorRenderer.HTML.withOptions {
@JvmField
val HTML_WITH_ANNOTATIONS = DescriptorRenderer.HTML.withOptions {
modifiers = DescriptorRendererModifier.ALL
}.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.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.highlighter
@@ -35,16 +24,17 @@ import com.intellij.psi.PsiRecursiveElementVisitor
import org.jetbrains.kotlin.psi.KtFile
class KotlinBeforeResolveHighlightingPass(
private val file: KtFile,
document: Document
private val file: KtFile,
document: Document
) : TextEditorHighlightingPass(file.project, document), DumbAware {
@Volatile private var annotationHolder: AnnotationHolderImpl? = null
@Volatile
private var annotationHolder: AnnotationHolderImpl? = null
override fun doCollectInformation(progress: ProgressIndicator) {
val annotationHolder = AnnotationHolderImpl(AnnotationSession(file))
val visitor = BeforeResolveHighlightingVisitor(annotationHolder)
file.accept(object : PsiRecursiveElementVisitor(){
file.accept(object : PsiRecursiveElementVisitor() {
override fun visitElement(element: PsiElement) {
super.visitElement(element)
element.accept(visitor)
@@ -64,7 +54,13 @@ class KotlinBeforeResolveHighlightingPass(
class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent, TextEditorHighlightingPassFactory {
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? {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.highlighter
@@ -28,11 +17,11 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import java.util.*
class KotlinSuppressableWarningProblemGroup(
private val diagnosticFactory: DiagnosticFactory<*>
private val diagnosticFactory: DiagnosticFactory<*>
) : SuppressableProblemGroup {
init {
assert (diagnosticFactory.severity == Severity.WARNING)
assert(diagnosticFactory.severity == Severity.WARNING)
}
override fun getProblemName() = diagnosticFactory.name
@@ -47,7 +36,7 @@ class KotlinSuppressableWarningProblemGroup(
}
fun createSuppressWarningActions(element: PsiElement, diagnosticFactory: DiagnosticFactory<*>): List<SuppressIntentionAction> =
createSuppressWarningActions(element, diagnosticFactory.severity, diagnosticFactory.name)
createSuppressWarningActions(element, diagnosticFactory.severity, diagnosticFactory.name)
fun createSuppressWarningActions(element: PsiElement, severity: Severity, suppressionKey: String): List<SuppressIntentionAction> {
@@ -71,15 +60,17 @@ fun createSuppressWarningActions(element: PsiElement, severity: Severity, suppre
// Add suppress action at first statement
if (current.parent is KtBlockExpression || current.parent is KtDestructuringDeclaration) {
val kind = if (current.parent is KtBlockExpression) "statement" else "initializer"
actions.add(KotlinSuppressIntentionAction(current, suppressionKey,
AnnotationHostKind(kind, "", true)))
actions.add(
KotlinSuppressIntentionAction(current, suppressionKey, AnnotationHostKind(kind, "", true))
)
suppressAtStatementAllowed = false
}
}
current is KtFile -> {
actions.add(KotlinSuppressIntentionAction(current, suppressionKey,
AnnotationHostKind("file", current.name, true)))
actions.add(
KotlinSuppressIntentionAction(current, suppressionKey, AnnotationHostKind("file", current.name, true))
)
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 visitDestructuringDeclaration(d: KtDestructuringDeclaration, data: Unit?) = detect(d, d.valOrVarKeyword?.text ?: "val",
name = d.entries.joinToString(", ", "(", ")") { it.name!! })
override fun visitDestructuringDeclaration(d: KtDestructuringDeclaration, data: Unit?) =
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)
@@ -110,7 +101,8 @@ private object DeclarationKindDetector : KtVisitor<AnnotationHostKind?, Unit?>()
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? {
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")
}
private fun detect(declaration: KtDeclaration, kind: String, name: String = declaration.name ?: "<anonymous>", newLineNeeded: Boolean = true)
= AnnotationHostKind(kind, name, newLineNeeded)
private fun detect(
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.
*/
@@ -91,26 +91,24 @@ internal class PropertiesHighlightingVisitor(holder: AnnotationHolder, bindingCo
}
}
private fun attributeKeyByPropertyType(descriptor: PropertyDescriptor): TextAttributesKey? {
return when {
descriptor.isDynamic() ->
// The property is set in VariablesHighlightingVisitor
null
private fun attributeKeyByPropertyType(descriptor: PropertyDescriptor): TextAttributesKey? = when {
descriptor.isDynamic() ->
// The property is set in VariablesHighlightingVisitor
null
KotlinHighlightingUtil.hasExtensionReceiverParameter(descriptor) ->
if (descriptor.isSynthesized) SYNTHETIC_EXTENSION_PROPERTY else EXTENSION_PROPERTY
KotlinHighlightingUtil.hasExtensionReceiverParameter(descriptor) ->
if (descriptor.isSynthesized) SYNTHETIC_EXTENSION_PROPERTY else EXTENSION_PROPERTY
DescriptorUtils.isStaticDeclaration(descriptor) ->
if(KotlinHighlightingUtil.hasCustomPropertyDeclaration(descriptor))
PACKAGE_PROPERTY_CUSTOM_PROPERTY_DECLARATION
else
PACKAGE_PROPERTY
DescriptorUtils.isStaticDeclaration(descriptor) ->
if (KotlinHighlightingUtil.hasCustomPropertyDeclaration(descriptor))
PACKAGE_PROPERTY_CUSTOM_PROPERTY_DECLARATION
else
PACKAGE_PROPERTY
else ->
if (KotlinHighlightingUtil.hasCustomPropertyDeclaration(descriptor))
INSTANCE_PROPERTY_CUSTOM_PROPERTY_DECLARATION
else
INSTANCE_PROPERTY
}
else ->
if (KotlinHighlightingUtil.hasCustomPropertyDeclaration(descriptor))
INSTANCE_PROPERTY_CUSTOM_PROPERTY_DECLARATION
else
INSTANCE_PROPERTY
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.types.expressions.CaptureKind
internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext)
: AfterAnalysisHighlightingVisitor(holder, bindingContext) {
internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingContext: BindingContext) :
AfterAnalysisHighlightingVisitor(holder, bindingContext) {
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
val target = bindingContext.get(REFERENCE_TARGET, expression) ?: return
@@ -91,31 +80,32 @@ internal class VariablesHighlightingVisitor(holder: AnnotationHolder, bindingCon
is ImplicitClassReceiver -> "Implicit receiver"
else -> "Unknown receiver"
}
createInfoAnnotation(expression,
"$receiverName smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type))
.textAttributes = SMART_CAST_RECEIVER
createInfoAnnotation(
expression,
"$receiverName smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)
).textAttributes = SMART_CAST_RECEIVER
}
}
val nullSmartCast = bindingContext.get(SMARTCAST_NULL, expression) == true
if (nullSmartCast) {
createInfoAnnotation(expression, "Always null")
.textAttributes = SMART_CONSTANT
createInfoAnnotation(expression, "Always null").textAttributes = SMART_CONSTANT
}
val smartCast = bindingContext.get(SMARTCAST, expression)
if (smartCast != null) {
val defaultType = smartCast.defaultType
if (defaultType != null) {
createInfoAnnotation(getSmartCastTarget(expression),
"Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(defaultType))
.textAttributes = SMART_CAST_VALUE
}
else if (smartCast is MultipleSmartCasts) {
createInfoAnnotation(
getSmartCastTarget(expression),
"Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(defaultType)
).textAttributes = SMART_CAST_VALUE
} else if (smartCast is MultipleSmartCasts) {
for ((call, type) in smartCast.map) {
createInfoAnnotation(getSmartCastTarget(expression),
"Smart cast to ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)} (for $call call)")
.textAttributes = SMART_CAST_VALUE
createInfoAnnotation(
getSmartCastTarget(expression),
"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)) {
val isStaticDeclaration = DescriptorUtils.isStaticDeclaration(descriptor)
highlightName(elementToHighlight,
if (isStaticDeclaration)
PACKAGE_PROPERTY_CUSTOM_PROPERTY_DECLARATION
else
INSTANCE_PROPERTY_CUSTOM_PROPERTY_DECLARATION)
highlightName(
elementToHighlight,
if (isStaticDeclaration)
PACKAGE_PROPERTY_CUSTOM_PROPERTY_DECLARATION
else
INSTANCE_PROPERTY_CUSTOM_PROPERTY_DECLARATION
)
}
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.types.ErrorUtils
private val RED_TEMPLATE = "<font color=red><b>%s</b></font>"
private val STRONG_TEMPLATE = "<b>%s</b>"
private const val RED_TEMPLATE = "<font color=red><b>%s</b></font>"
private const val STRONG_TEMPLATE = "<b>%s</b>"
fun renderStrong(o: Any): String = STRONG_TEMPLATE.format(o)
@@ -59,21 +48,19 @@ fun renderResolvedCall(resolvedCall: ResolvedCall<*>, context: RenderingContext)
fun renderParameter(parameter: ValueParameterDescriptor): String {
val varargElementType = parameter.varargElementType
val parameterType = varargElementType ?: parameter.type
val renderedParameter =
(if (varargElementType != null) "<b>vararg</b> " else "") +
val renderedParameter = (if (varargElementType != null) "<b>vararg</b> " else "") +
typeRenderer.render(parameterType, context) +
if (parameter.hasDefaultValue()) " = ..." else ""
if (resolvedCall.hasTypeMismatchErrorOnParameter(parameter)) {
return renderError(renderedParameter)
}
return renderedParameter
return if (resolvedCall.hasTypeMismatchErrorOnParameter(parameter))
renderError(renderedParameter)
else
renderedParameter
}
fun appendTypeParametersSubstitution() {
val parametersToArgumentsMap = resolvedCall.typeArguments
fun TypeParameterDescriptor.isInferred(): Boolean {
val typeArgument = parametersToArgumentsMap[this]
if (typeArgument == null) return false
val typeArgument = parametersToArgumentsMap[this] ?: return false
return !ErrorUtils.isUninferredParameter(typeArgument)
}
@@ -81,16 +68,16 @@ fun renderResolvedCall(resolvedCall: ResolvedCall<*>, context: RenderingContext)
val (inferredTypeParameters, notInferredTypeParameters) = typeParameters.partition(TypeParameterDescriptor::isInferred)
append("<br/>$indent<i>where</i> ")
if (!notInferredTypeParameters.isEmpty()) {
if (notInferredTypeParameters.isNotEmpty()) {
append(notInferredTypeParameters.joinToString { typeParameter -> renderError(typeParameter.name) })
append("<i> cannot be inferred</i>")
if (!inferredTypeParameters.isEmpty()) {
if (inferredTypeParameters.isNotEmpty()) {
append("; ")
}
}
val typeParameterToTypeArgumentMap = resolvedCall.typeArguments
if (!inferredTypeParameters.isEmpty()) {
if (inferredTypeParameters.isNotEmpty()) {
append(inferredTypeParameters.joinToString { typeParameter ->
"${typeParameter.name} = ${typeRenderer.render(typeParameterToTypeArgumentMap[typeParameter]!!, context)}"
})
@@ -106,13 +93,12 @@ fun renderResolvedCall(resolvedCall: ResolvedCall<*>, context: RenderingContext)
append(resultingDescriptor.valueParameters.joinToString(transform = ::renderParameter))
append(if (resolvedCall.hasUnmappedArguments()) renderError(")") else ")")
if (!resolvedCall.candidateDescriptor.typeParameters.isEmpty()) {
if (resolvedCall.candidateDescriptor.typeParameters.isNotEmpty()) {
appendTypeParametersSubstitution()
append("<i> for </i><br/>$indent")
// candidate descriptor is not in context of the rest of the message
append(descriptorRenderer.render(resolvedCall.candidateDescriptor, RenderingContext.of(resolvedCall.candidateDescriptor)))
}
else {
} else {
append(" <i>defined in</i> ")
val containingDeclaration = resultingDescriptor.containingDeclaration
val fqName = DescriptorUtils.getFqName(containingDeclaration)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.inspections
@@ -43,8 +32,8 @@ import kotlin.reflect.KClass
// thus making the original purpose useless.
// The class still can be used, if you want to create a pair for existing intention with additional checker
abstract class IntentionBasedInspection<TElement : PsiElement> private constructor(
private val intentionInfo: IntentionData<TElement>,
protected open val problemText: String?
private val intentionInfo: IntentionData<TElement>,
protected open val problemText: String?
) : AbstractKotlinInspection() {
val intention: SelfTargetingRangeIntention<TElement> by lazy {
@@ -57,33 +46,32 @@ abstract class IntentionBasedInspection<TElement : PsiElement> private construct
@Suppress("DEPRECATION")
@Deprecated("Please do not use for new inspections. Use AbstractKotlinInspection as base class for them")
constructor(
intention: KClass<out SelfTargetingRangeIntention<TElement>>,
problemText: String? = null
intention: KClass<out SelfTargetingRangeIntention<TElement>>,
problemText: String? = null
) : this(IntentionData(intention), problemText)
constructor(
intention: KClass<out SelfTargetingRangeIntention<TElement>>,
additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
problemText: String? = null
intention: KClass<out SelfTargetingRangeIntention<TElement>>,
additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
problemText: String? = null
) : this(IntentionData(intention, additionalChecker), problemText)
constructor(
intention: KClass<out SelfTargetingRangeIntention<TElement>>,
additionalChecker: (TElement) -> Boolean,
problemText: String? = null
) : this(IntentionData(intention, { element, _ -> additionalChecker(element) } ), problemText)
intention: KClass<out SelfTargetingRangeIntention<TElement>>,
additionalChecker: (TElement) -> Boolean,
problemText: String? = null
) : this(IntentionData(intention) { element, _ -> additionalChecker(element) }, problemText)
data class IntentionData<TElement : PsiElement>(
val intention: KClass<out SelfTargetingRangeIntention<TElement>>,
val additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean = { _, _ -> true }
val intention: KClass<out SelfTargetingRangeIntention<TElement>>,
val additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean = { _, _ -> true }
)
open fun additionalFixes(element: TElement): List<LocalQuickFix>? = null
open fun inspectionTarget(element: TElement): PsiElement? = null
open fun inspectionProblemText(element: TElement): String? = null
private fun PsiElement.toRange(baseElement: PsiElement): TextRange {
@@ -127,12 +115,12 @@ abstract class IntentionBasedInspection<TElement : PsiElement> private construct
additionalFixes(targetElement)?.let { allFixes.addAll(it) }
if (!allFixes.isEmpty()) {
holder.registerProblemWithoutOfflineInformation(
targetElement,
inspectionProblemText(element) ?: problemText ?: allFixes.first().name,
isOnTheFly,
problemHighlightType(targetElement),
range,
*allFixes.toTypedArray()
targetElement,
inspectionProblemText(element) ?: problemText ?: allFixes.first().name,
isOnTheFly,
problemHighlightType(targetElement),
range,
*allFixes.toTypedArray()
)
}
}
@@ -141,25 +129,23 @@ abstract class IntentionBasedInspection<TElement : PsiElement> private construct
}
protected open fun problemHighlightType(element: TElement): ProblemHighlightType =
ProblemHighlightType.GENERIC_ERROR_OR_WARNING
ProblemHighlightType.GENERIC_ERROR_OR_WARNING
private fun createQuickFix(
intention: SelfTargetingRangeIntention<TElement>,
additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
targetElement: TElement
): IntentionBasedQuickFix {
return when (intention) {
is LowPriorityAction -> LowPriorityIntentionBasedQuickFix(intention, additionalChecker, targetElement)
is HighPriorityAction -> HighPriorityIntentionBasedQuickFix(intention, additionalChecker, targetElement)
else -> IntentionBasedQuickFix(intention, additionalChecker, targetElement)
}
intention: SelfTargetingRangeIntention<TElement>,
additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
targetElement: TElement
): IntentionBasedQuickFix = when (intention) {
is LowPriorityAction -> LowPriorityIntentionBasedQuickFix(intention, additionalChecker, targetElement)
is HighPriorityAction -> HighPriorityIntentionBasedQuickFix(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 */
internal open inner class IntentionBasedQuickFix(
val intention: SelfTargetingRangeIntention<TElement>,
private val additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
targetElement: TElement
val intention: SelfTargetingRangeIntention<TElement>,
private val additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
targetElement: TElement
) : LocalQuickFixOnPsiElement(targetElement), IntentionAction {
private val text = intention.text
@@ -200,15 +186,15 @@ abstract class IntentionBasedInspection<TElement : PsiElement> private construct
}
private inner class LowPriorityIntentionBasedQuickFix(
intention: SelfTargetingRangeIntention<TElement>,
additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
targetElement: TElement
intention: SelfTargetingRangeIntention<TElement>,
additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
targetElement: TElement
) : IntentionBasedQuickFix(intention, additionalChecker, targetElement), LowPriorityAction
private inner class HighPriorityIntentionBasedQuickFix(
intention: SelfTargetingRangeIntention<TElement>,
additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
targetElement: TElement
intention: SelfTargetingRangeIntention<TElement>,
additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
targetElement: TElement
) : IntentionBasedQuickFix(intention, additionalChecker, targetElement), HighPriorityAction
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -21,7 +10,8 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.config.LanguageFeature
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.references.ReferenceAccess
import org.jetbrains.kotlin.idea.references.readWriteAccess
@@ -89,23 +79,23 @@ class OperatorToFunctionIntention :
private fun isApplicableCall(element: KtCallExpression, caretOffset: Int): Boolean {
val lbrace = (element.valueArgumentList?.leftParenthesis
?: element.lambdaArguments.firstOrNull()?.getLambdaExpression()?.leftCurlyBrace
?: return false) as PsiElement
?: element.lambdaArguments.firstOrNull()?.getLambdaExpression()?.leftCurlyBrace
?: return false) as PsiElement
if (!lbrace.textRange.containsOffset(caretOffset)) return false
val resolvedCall = element.resolveToCall(BodyResolveMode.FULL)
val descriptor = resolvedCall?.resultingDescriptor
if (descriptor is FunctionDescriptor && descriptor.getName() == OperatorNameConventions.INVOKE) {
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 false
}
private fun convertUnary(element: KtUnaryExpression): KtExpression {
val op = element.operationReference.getReferencedNameElementType()
val operatorName = when (op) {
val operatorName = when (element.operationReference.getReferencedNameElementType()) {
KtTokens.PLUSPLUS, KtTokens.MINUSMINUS -> return convertUnaryWithAssignFix(element)
KtTokens.PLUS -> OperatorNameConventions.UNARY_PLUS
KtTokens.MINUS -> OperatorNameConventions.UNARY_MINUS
@@ -118,8 +108,7 @@ class OperatorToFunctionIntention :
}
private fun convertUnaryWithAssignFix(element: KtUnaryExpression): KtExpression {
val op = element.operationReference.getReferencedNameElementType()
val operatorName = when (op) {
val operatorName = when (element.operationReference.getReferencedNameElementType()) {
KtTokens.PLUSPLUS -> OperatorNameConventions.INC
KtTokens.MINUSMINUS -> OperatorNameConventions.DEC
else -> return element
@@ -208,7 +197,8 @@ class OperatorToFunctionIntention :
private fun isAssignmentLeftSide(element: KtArrayAccessExpression): Boolean {
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
@@ -218,8 +208,8 @@ class OperatorToFunctionIntention :
val argumentString = arguments?.text?.removeSurrounding("(", ")")
val funcLitArgs = element.lambdaArguments
val calleeText = callee.text
val transformation = "$calleeText.${OperatorNameConventions.INVOKE.asString()}" +
(if (argumentString == null) "()" else "($argumentString)")
val transformation =
"$calleeText.${OperatorNameConventions.INVOKE.asString()}" + (if (argumentString == null) "()" else "($argumentString)")
val transformed = KtPsiFactory(element).createExpression(transformation)
val callExpression = transformed.getCalleeExpressionIfAny()?.parent as? KtCallExpression
if (callExpression != null) {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -36,9 +25,9 @@ import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
@Suppress("EqualsOrHashCode")
abstract class SelfTargetingIntention<TElement : PsiElement>(
val elementType: Class<TElement>,
private var text: String,
private val familyName: String = text
val elementType: Class<TElement>,
private var text: String,
private val familyName: String = text
) : IntentionAction {
protected val defaultText: String = text
@@ -85,8 +74,7 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
return getTarget(offset, file)
}
protected open fun allowCaretInsideElement(element: PsiElement): Boolean =
element !is KtBlockExpression
protected open fun allowCaretInsideElement(element: PsiElement): Boolean = element !is KtBlockExpression
final override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean {
if (ApplicationManager.getApplication().isUnitTestMode) {
@@ -94,8 +82,7 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
}
try {
return getTarget(editor, file) != null
}
finally {
} finally {
CREATE_BY_PATTERN_MAY_NOT_REFORMAT = false
}
}
@@ -126,9 +113,9 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
}
abstract class SelfTargetingRangeIntention<TElement : PsiElement>(
elementType: Class<TElement>,
text: String,
familyName: String = text
elementType: Class<TElement>,
text: String,
familyName: String = text
) : SelfTargetingIntention<TElement>(elementType, text, familyName) {
abstract fun applicabilityRange(element: TElement): TextRange?
@@ -140,9 +127,9 @@ abstract class SelfTargetingRangeIntention<TElement : PsiElement>(
}
abstract class SelfTargetingOffsetIndependentIntention<TElement : KtElement>(
elementType: Class<TElement>,
text: String,
familyName: String = text
elementType: Class<TElement>,
text: String,
familyName: String = text
) : SelfTargetingRangeIntention<TElement>(elementType, text, familyName) {
abstract fun isApplicableTo(element: TElement): Boolean
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.kdoc
@@ -20,8 +9,8 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.descriptors.*
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.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.stubindex.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
@@ -37,7 +26,12 @@ import org.jetbrains.kotlin.utils.Printer
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)
@@ -48,10 +42,9 @@ class IdeSampleResolutionService(val project: Project) : SampleResolutionService
val functions = KotlinFunctionShortNameIndex.getInstance().get(shortName, project, scope).asSequence()
val classes = KotlinClassShortNameIndex.getInstance().get(shortName, project, scope).asSequence()
val descriptors = (functions + classes)
.filter { it.fqName == targetFqName }
.map { it.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) } // TODO Filter out not visible due dependencies config descriptors
.toList()
val descriptors = (functions + classes).filter { it.fqName == targetFqName }
.map { it.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) } // TODO Filter out not visible due dependencies config descriptors
.toList()
if (descriptors.isNotEmpty())
return descriptors
@@ -63,16 +56,21 @@ class IdeSampleResolutionService(val project: Project) : SampleResolutionService
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? =
if (fqName.isOneSegmentFQN()) null else GlobalSyntheticPackageViewDescriptor(fqName.parent(), project, scope)
if (fqName.isOneSegmentFQN()) null else GlobalSyntheticPackageViewDescriptor(fqName.parent(), project, scope)
override val memberScope: MemberScope = object : MemberScope {
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 getVariableNames(): Set<Name> = shouldNotBeCalled()
@@ -87,33 +85,35 @@ private class GlobalSyntheticPackageViewDescriptor(override val fqName: FqName,
fun getClassesByNameFilter(nameFilter: (Name) -> Boolean) = KotlinFullClassNameIndex.getInstance()
.getAllKeys(project)
.asSequence()
.filter { it.startsWith(fqName.asString()) }
.map(::FqName)
.filter { it.isChildOf(fqName) }
.filter { nameFilter(it.shortName()) }
.flatMap { KotlinFullClassNameIndex.getInstance()[it.asString(), project, scope].asSequence() }
.map { it.resolveToDescriptorIfAny() }
.getAllKeys(project)
.asSequence()
.filter { it.startsWith(fqName.asString()) }
.map(::FqName)
.filter { it.isChildOf(fqName) }
.filter { nameFilter(it.shortName()) }
.flatMap { KotlinFullClassNameIndex.getInstance()[it.asString(), project, scope].asSequence() }
.map { it.resolveToDescriptorIfAny() }
fun getFunctionsByNameFilter(nameFilter: (Name) -> Boolean) = KotlinTopLevelFunctionFqnNameIndex.getInstance()
.getAllKeys(project)
.asSequence()
.filter { it.startsWith(fqName.asString()) }
.map(::FqName)
.filter { it.isChildOf(fqName) }
.filter { nameFilter(it.shortName()) }
.flatMap { KotlinTopLevelFunctionFqnNameIndex.getInstance()[it.asString(), project, scope].asSequence() }
.map { it.resolveToDescriptorIfAny() as? DeclarationDescriptor }
.getAllKeys(project)
.asSequence()
.filter { it.startsWith(fqName.asString()) }
.map(::FqName)
.filter { it.isChildOf(fqName) }
.filter { nameFilter(it.shortName()) }
.flatMap { KotlinTopLevelFunctionFqnNameIndex.getInstance()[it.asString(), project, scope].asSequence() }
.map { it.resolveToDescriptorIfAny() as? DeclarationDescriptor }
fun getSubpackages(nameFilter: (Name) -> Boolean) =
PackageIndexUtil.getSubPackageFqNames(fqName, scope, project, nameFilter)
.map { GlobalSyntheticPackageViewDescriptor(it, project, scope) }
fun getSubpackages(nameFilter: (Name) -> Boolean) = PackageIndexUtil.getSubPackageFqNames(fqName, scope, project, nameFilter)
.map { GlobalSyntheticPackageViewDescriptor(it, project, scope) }
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor>
= (getClassesByNameFilter(nameFilter)
+ getFunctionsByNameFilter(nameFilter)
+ getSubpackages(nameFilter)).filterNotNull().toList()
override fun getContributedDescriptors(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> = (getClassesByNameFilter(nameFilter) +
getFunctionsByNameFilter(nameFilter) +
getSubpackages(nameFilter)
).filterNotNull().toList()
}
override val module: ModuleDescriptor
@@ -1,33 +1,22 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.kdoc
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
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.kdoc.psi.impl.KDocName
class KDocUnresolvedReferenceInspection(): AbstractKotlinInspection() {
class KDocUnresolvedReferenceInspection() : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
KDocUnresolvedReferenceVisitor(holder)
private class KDocUnresolvedReferenceVisitor(private val holder: ProblemsHolder): PsiElementVisitor() {
private class KDocUnresolvedReferenceVisitor(private val holder: ProblemsHolder) : PsiElementVisitor() {
override fun visitElement(element: PsiElement) {
if (element is KDocName) {
val ref = element.mainReference
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.modules
@@ -20,18 +9,15 @@ import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiJavaModule
import com.intellij.psi.PsiManager
import com.intellij.psi.impl.light.LightJavaModule
import org.jetbrains.annotations.NotNull
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
class IdeJavaModuleResolver(private val project: Project) : JavaModuleResolver {
private fun findJavaModule(file: VirtualFile): PsiJavaModule? =
ModuleHighlightUtil2.getModuleDescriptor(file, project)
private fun findJavaModule(file: VirtualFile): PsiJavaModule? = ModuleHighlightUtil2.getModuleDescriptor(file, project)
override fun checkAccessibility(
fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?
fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?
): JavaModuleResolver.AccessError? {
val ourModule = fileFromOurModule?.let(this::findJavaModule)
val theirModule = findJavaModule(referencedFile)
@@ -64,5 +50,5 @@ class IdeJavaModuleResolver(private val project: Project) : JavaModuleResolver {
// Returns whether or not [source] exports [packageName] to [target]
private fun exports(source: PsiJavaModule, packageName: String, target: PsiJavaModule): Boolean =
source is LightJavaModule || JavaModuleGraphUtil.exports(source, packageName, target)
source is LightJavaModule || JavaModuleGraphUtil.exports(source, packageName, target)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.project
@@ -20,30 +9,31 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.stubindex.resolve.PluginDeclarationProviderFactory
import org.jetbrains.kotlin.psi.KtDeclaration
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.LocalDescriptorResolver
import org.jetbrains.kotlin.resolve.lazy.AbsentDescriptorHandler
import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
class IdeaLocalDescriptorResolver(
private val resolveElementCache: ResolveElementCache,
private val absentDescriptorHandler: AbsentDescriptorHandler
private val resolveElementCache: ResolveElementCache,
private val absentDescriptorHandler: AbsentDescriptorHandler
) : LocalDescriptorResolver {
override fun resolveLocalDeclaration(declaration: KtDeclaration): DeclarationDescriptor {
val context = resolveElementCache.resolveToElements(listOf(declaration), BodyResolveMode.FULL)
return context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
?: absentDescriptorHandler.diagnoseDescriptorNotFound(declaration)
return context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) ?: absentDescriptorHandler.diagnoseDescriptorNotFound(
declaration
)
}
}
class IdeaAbsentDescriptorHandler(
private val declarationProviderFactory: DeclarationProviderFactory
private val declarationProviderFactory: DeclarationProviderFactory
) : AbsentDescriptorHandler {
override fun diagnoseDescriptorNotFound(declaration: KtDeclaration): DeclarationDescriptor {
throw NoDescriptorForDeclarationException(
declaration,
(declarationProviderFactory as? PluginDeclarationProviderFactory)?.debugToString()
declaration,
(declarationProviderFactory as? PluginDeclarationProviderFactory)?.debugToString()
)
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.project
@@ -61,8 +50,8 @@ class ResolveElementCache(
private fun modificationStamp(resolveElement: KtElement): Long? {
val file = resolveElement.containingFile
return when {
// for non-physical file we don't get OUT_OF_CODE_BLOCK_MODIFICATION_COUNT increased and must reset
// data on any modification of the file
// for non-physical file we don't get OUT_OF_CODE_BLOCK_MODIFICATION_COUNT increased and must reset
// data on any modification of the file
!file.isPhysical -> file.modificationStamp
resolveElement is KtDeclaration && KotlinCodeBlockModificationListener.isBlockDeclaration(resolveElement) -> resolveElement.getModificationStamp()
@@ -493,7 +482,7 @@ class ResolveElementCache(
if (declaration is KtClass) {
if (modifierList == declaration.primaryConstructorModifierList) {
descriptor = (descriptor as ClassDescriptor).unsubstitutedPrimaryConstructor
?: error("No constructor found: ${declaration.getText()}")
?: error("No constructor found: ${declaration.getText()}")
}
}
@@ -641,10 +630,7 @@ class ResolveElementCache(
val classDescriptor = resolveSession.resolveToDescriptor(klass) as ClassDescriptor
val constructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor
?: error(
"Can't get primary constructor for descriptor '$classDescriptor' " +
"in from class '${klass.getElementTextWithContext()}'"
)
?: error("Can't get primary constructor for descriptor '$classDescriptor' in from class '${klass.getElementTextWithContext()}'")
ForceResolveUtil.forceResolveAllContents(constructorDescriptor)
val primaryConstructor = klass.primaryConstructor
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.quickfix
@@ -26,13 +15,13 @@ abstract class KotlinIntentionActionsFactory {
protected abstract fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>
protected open fun doCreateActionsForAllProblems(
sameTypeDiagnostics: Collection<Diagnostic>): List<IntentionAction> = emptyList()
sameTypeDiagnostics: Collection<Diagnostic>
): List<IntentionAction> = emptyList()
fun createActions(diagnostic: Diagnostic): List<IntentionAction> =
createActions(listOfNotNull(diagnostic), false)
fun createActions(diagnostic: Diagnostic): List<IntentionAction> = createActions(listOfNotNull(diagnostic), false)
fun createActionsForAllProblems(sameTypeDiagnostics: Collection<Diagnostic>): List<IntentionAction> =
createActions(sameTypeDiagnostics, true)
createActions(sameTypeDiagnostics, true)
private fun createActions(sameTypeDiagnostics: Collection<Diagnostic>, createForAll: Boolean): List<IntentionAction> {
if (sameTypeDiagnostics.isEmpty()) return emptyList()
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.quickfix
@@ -25,7 +14,8 @@ import com.intellij.openapi.extensions.Extensions
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
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>()
init {
@@ -99,7 +99,8 @@ private tailrec fun DeclarationDescriptor.additionalClasses(existingClasses: Col
private fun DeclarationDescriptor.collectAllTypes(): Sequence<FqName?> {
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 {
emptySequence()
} + declaredTypeParameters.asSequence().flatMap(DeclarationDescriptor::collectAllTypes) + sequenceOf(fqNameOrNull())
@@ -70,8 +70,7 @@ internal class KotlinDefaultAnnotationMethodImplicitReferenceContributor : Kotli
override fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar) {
registrar.registerProvider<KtValueArgument> {
if (it.isNamed()) return@registerProvider null
val annotationEntry = it.getParentOfTypeAndBranch<KtAnnotationEntry> { valueArgumentList }
?: return@registerProvider null
val annotationEntry = it.getParentOfTypeAndBranch<KtAnnotationEntry> { valueArgumentList } ?: return@registerProvider null
if (annotationEntry.valueArguments.size != 1) return@registerProvider null
ReferenceImpl(it)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.KtTokens
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.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_GET
@@ -63,8 +55,7 @@ class KtArrayAccessReference(
appendExpression(arrayExpression.receiverExpression)
appendFixedText(arrayExpression.operationSign.value)
appendExpression(arrayExpression.selectorExpression)
}
else {
} else {
appendExpression(arrayExpression)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.CollectionLiteralResolver
class KtCollectionLiteralReference(expression: KtCollectionLiteralExpression) : KtSimpleReference<KtCollectionLiteralExpression>(expression), MultiRangeReference {
class KtCollectionLiteralReference(expression: KtCollectionLiteralExpression) :
KtSimpleReference<KtCollectionLiteralExpression>(expression), MultiRangeReference {
companion object {
private val COLLECTION_LITERAL_CALL_NAMES =
CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY.values +
CollectionLiteralResolver.ARRAY_OF_FUNCTION
CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY.values + CollectionLiteralResolver.ARRAY_OF_FUNCTION
}
override fun getRangeInElement(): TextRange = element.normalizeRange()
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
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.resolve.BindingContext
class KtDestructuringDeclarationReference(element: KtDestructuringDeclarationEntry) : AbstractKtReference<KtDestructuringDeclarationEntry>(element) {
class KtDestructuringDeclarationReference(element: KtDestructuringDeclarationEntry) :
AbstractKtReference<KtDestructuringDeclarationEntry>(element) {
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
return listOfNotNull(context[BindingContext.COMPONENT_RESOLVED_CALL, element]?.candidateDescriptor)
}
@@ -36,7 +26,9 @@ class KtDestructuringDeclarationReference(element: KtDestructuringDeclarationEnt
override fun canRename(): Boolean {
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? {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.references
@@ -42,15 +31,15 @@ class KtForLoopInReference(element: KtForExpression) : KtMultiReference<KtForExp
companion object {
private val LOOP_RANGE_KEYS = arrayOf(
BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL,
BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL,
BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL
BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL,
BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL,
BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL
)
private val NAMES = listOf(
OperatorNameConventions.ITERATOR,
OperatorNameConventions.NEXT,
OperatorNameConventions.HAS_NEXT
OperatorNameConventions.ITERATOR,
OperatorNameConventions.NEXT,
OperatorNameConventions.HAS_NEXT
)
}
}
@@ -98,9 +98,11 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
expression.replace(qualifiedElement.receiverExpression)
qualifiedElement.replaced(qualifiedElement.selectorExpression!!)
}
is KtUserType -> {
expression.replaced(KtPsiFactory(expression).createSimpleName(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.asString()))
}
is KtUserType -> expression.replaced(
KtPsiFactory(expression).createSimpleName(
SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.asString()
)
)
else -> expression
}
}
@@ -296,7 +298,9 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere
val importDirective = file.findImportByAlias(name) ?: return null
val fqName = importDirective.importedFqName ?: return null
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 null
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.references
@@ -38,7 +27,7 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.utils.addIfNotNull
sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpression, private val getter: Boolean) :
KtSimpleReference<KtNameReferenceExpression>(expression) {
KtSimpleReference<KtNameReferenceExpression>(expression) {
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
val descriptors = super.getTargetDescriptors(context)
if (descriptors.none { it is SyntheticJavaPropertyDescriptor }) return emptyList()
@@ -115,10 +104,10 @@ sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpre
//TODO: it's not correct
//TODO: setIsY -> setIsIsY bug
SyntheticJavaPropertyDescriptor.propertyNameBySetMethodName(
newNameAsName,
withIsPrefix = expression.getReferencedNameAsName().asString().startsWith(
"is"
)
newNameAsName,
withIsPrefix = expression.getReferencedNameAsName().asString().startsWith(
"is"
)
)
}
// get/set becomes ordinary method
@@ -162,16 +151,16 @@ sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpre
} else {
val anchor = parent.parentsWithSelf.firstOrNull { it.parent == context }
val validator = NewDeclarationNameValidator(
context,
anchor,
NewDeclarationNameValidator.Target.VARIABLES
context,
anchor,
NewDeclarationNameValidator.Target.VARIABLES
)
val varName = KotlinNameSuggester.suggestNamesByExpressionAndType(
unaryExpr,
null,
unaryExpr.analyze(),
validator,
"p"
unaryExpr,
null,
unaryExpr.analyze(),
validator,
"p"
).first()
val isPrefix = unaryExpr is KtPrefixExpression
val varInitializer = if (isPrefix) incDecValue else originalValue
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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.
* 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.
*/
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 }
return when (this) {
is DeserializedClassDescriptor -> KotlinFullClassNameIndex.getInstance()[fqName.asString(), project, resolveScope]
is DeserializedTypeAliasDescriptor -> KotlinTypeAliasShortNameIndex.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 DeserializedTypeAliasDescriptor -> KotlinTypeAliasShortNameIndex.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())
else -> emptyList()
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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.
* 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.
*/
package org.jetbrains.kotlin.idea.search
@@ -48,10 +37,12 @@ import java.util.concurrent.atomic.AtomicInteger
class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName: String) {
private val targetShortName = targetClassFqName.substringAfterLast('.')
private val targetPackage = targetClassFqName.substringBeforeLast('.', "")
/**
* Qualified names of packages which contain classes with the same short name as the target class.
*/
private val conflictingPackages = mutableListOf<String>()
/**
* 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).
@@ -64,8 +55,10 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName:
companion object {
@get:TestOnly
val attempts = AtomicInteger()
@get:TestOnly
val trueHits = AtomicInteger()
@get:TestOnly
val falseHits = AtomicInteger()

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