Reuse package/class qualifier prefix resolution for qualified expression resolution.
This commit is contained in:
+173
-37
@@ -20,21 +20,27 @@ import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.calls.CallExpressionElement
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classObjectType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassObjectType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.containsFunctionOrVariable
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
import java.util.*
|
||||
|
||||
public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator) {
|
||||
|
||||
@@ -78,7 +84,8 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
val (qualifierPartList, hasError) = userType.asQualifierPartList()
|
||||
if (hasError) {
|
||||
val descriptor = resolveToPackageOrClass(
|
||||
qualifierPartList, module, trace, scope.ownerDescriptor, scope, inImport = false) as? ClassifierDescriptor
|
||||
qualifierPartList, module, trace, scope.ownerDescriptor, scope, position = QualifierPosition.TYPE
|
||||
) as? ClassifierDescriptor
|
||||
return TypeQualifierResolutionResult(qualifierPartList, descriptor)
|
||||
}
|
||||
assert(qualifierPartList.size() >= 1) {
|
||||
@@ -87,7 +94,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
|
||||
val qualifier = resolveToPackageOrClass(
|
||||
qualifierPartList.subList(0, qualifierPartList.size() - 1), module,
|
||||
trace, scope.ownerDescriptor, scope.check { !userType.startWithPackage }, inImport = false
|
||||
trace, scope.ownerDescriptor, scope.check { !userType.startWithPackage }, position = QualifierPosition.TYPE
|
||||
) ?: return TypeQualifierResolutionResult(qualifierPartList, null)
|
||||
|
||||
val lastPart = qualifierPartList.last()
|
||||
@@ -150,7 +157,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
return processSingleImport(moduleDescriptor, trace, importDirective, path, lastPart, packageFragmentForCheck)
|
||||
}
|
||||
val packageOrClassDescriptor = resolveToPackageOrClass(path, moduleDescriptor, trace, packageFragmentForCheck,
|
||||
scopeForFirstPart = null, inImport = true) ?: return null
|
||||
scopeForFirstPart = null, position = QualifierPosition.IMPORT) ?: return null
|
||||
if (packageOrClassDescriptor is ClassDescriptor && packageOrClassDescriptor.kind.isSingleton) {
|
||||
trace.report(Errors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON.on(lastPart.expression, packageOrClassDescriptor)) // todo report on star
|
||||
}
|
||||
@@ -164,13 +171,13 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
val aliasName = KtPsiUtil.getAliasName(importDirective)
|
||||
if (aliasName == null) {
|
||||
// import kotlin.
|
||||
resolveToPackageOrClass(path, moduleDescriptor, trace, packageFragmentForVisibilityCheck, scopeForFirstPart = null, inImport = true)
|
||||
resolveToPackageOrClass(path, moduleDescriptor, trace, packageFragmentForVisibilityCheck, scopeForFirstPart = null, position = QualifierPosition.IMPORT)
|
||||
return null
|
||||
}
|
||||
|
||||
val packageOrClassDescriptor = resolveToPackageOrClass(
|
||||
path.subList(0, path.size() - 1), moduleDescriptor, trace,
|
||||
packageFragmentForVisibilityCheck, scopeForFirstPart = null, inImport = true
|
||||
packageFragmentForVisibilityCheck, scopeForFirstPart = null, position = QualifierPosition.IMPORT
|
||||
) ?: return null
|
||||
|
||||
val candidates = collectCandidateDescriptors(lastPart, packageOrClassDescriptor)
|
||||
@@ -284,57 +291,184 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
val expression: KtSimpleNameExpression,
|
||||
val typeArguments: KtTypeArgumentList? = null
|
||||
) {
|
||||
constructor (expression: KtSimpleNameExpression) : this(expression.getReferencedNameAsName(), expression)
|
||||
|
||||
val location = KotlinLookupLocation(expression)
|
||||
}
|
||||
|
||||
private enum class QualifierPosition {
|
||||
IMPORT, TYPE, EXPRESSION
|
||||
}
|
||||
|
||||
private fun resolveToPackageOrClass(
|
||||
path: List<QualifierPart>,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
trace: BindingTrace,
|
||||
shouldBeVisibleFrom: DeclarationDescriptor?,
|
||||
scopeForFirstPart: LexicalScope?,
|
||||
inImport: Boolean
|
||||
position: QualifierPosition
|
||||
): DeclarationDescriptor? {
|
||||
val (packageOrClassDescriptor, endIndex) =
|
||||
resolveToPackageOrClassPrefix(path, moduleDescriptor, trace, shouldBeVisibleFrom, scopeForFirstPart, position)
|
||||
|
||||
if (endIndex != path.size) {
|
||||
return null
|
||||
}
|
||||
|
||||
return packageOrClassDescriptor
|
||||
}
|
||||
|
||||
private fun resolveToPackageOrClassPrefix(
|
||||
path: List<QualifierPart>,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
trace: BindingTrace,
|
||||
shouldBeVisibleFrom: DeclarationDescriptor?,
|
||||
scopeForFirstPart: LexicalScope?,
|
||||
position: QualifierPosition
|
||||
): Pair<DeclarationDescriptor?, Int> {
|
||||
if (path.isEmpty()) {
|
||||
return moduleDescriptor.getPackage(FqName.ROOT)
|
||||
return Pair(moduleDescriptor.getPackage(FqName.ROOT), 0)
|
||||
}
|
||||
|
||||
val firstDescriptor = scopeForFirstPart?.let {
|
||||
val firstPart = path.first()
|
||||
it.findClassifier(firstPart.name, firstPart.location)?.apply {
|
||||
storeResult(trace, firstPart.expression, this, shouldBeVisibleFrom, inImport)
|
||||
}
|
||||
val inImport = position == QualifierPosition.IMPORT
|
||||
|
||||
val firstPart = path.first()
|
||||
|
||||
if (position == QualifierPosition.EXPRESSION) {
|
||||
// In expression position, value wins against classifier (and package).
|
||||
// If we see a function or variable (possibly ambiguous),
|
||||
// tell resolver we have no qualifier and let it perform the context-dependent resolution.
|
||||
if (scopeForFirstPart != null && scopeForFirstPart.containsFunctionOrVariable(firstPart.name, firstPart.location)) {
|
||||
return Pair(null, 0)
|
||||
}
|
||||
}
|
||||
|
||||
val classifierDescriptor = scopeForFirstPart?.let {
|
||||
it.findClassifier(firstPart.name, firstPart.location)
|
||||
}
|
||||
|
||||
val (currentDescriptor, currentIndex) = firstDescriptor?.let { Pair(it, 1) } ?: moduleDescriptor.quickResolveToPackage(path, trace, inImport)
|
||||
if (classifierDescriptor != null) {
|
||||
storeResult(trace, firstPart.expression, classifierDescriptor, shouldBeVisibleFrom, inImport)
|
||||
}
|
||||
|
||||
return path.subList(currentIndex, path.size()).fold<QualifierPart, DeclarationDescriptor?>(currentDescriptor) {
|
||||
descriptor, qualifierPart ->
|
||||
// report unresolved reference only for first unresolved qualifier
|
||||
if (descriptor == null) return@fold null
|
||||
val (prefixDescriptor, nextIndexAfterPrefix) =
|
||||
if (classifierDescriptor != null)
|
||||
Pair(classifierDescriptor, 1)
|
||||
else
|
||||
moduleDescriptor.quickResolveToPackage(path, trace, inImport)
|
||||
|
||||
val nextDescriptor = when (descriptor) {
|
||||
// TODO: support inner classes which captured type parameter from outer class
|
||||
is ClassDescriptor ->
|
||||
descriptor.unsubstitutedInnerClassesScope.getContributedClassifier(qualifierPart.name, qualifierPart.location)
|
||||
is PackageViewDescriptor -> {
|
||||
val packageView = if (qualifierPart.typeArguments == null) {
|
||||
moduleDescriptor.getPackage(descriptor.fqName.child(qualifierPart.name))
|
||||
} else null
|
||||
var currentDescriptor: DeclarationDescriptor? = prefixDescriptor
|
||||
for (qualifierPartIndex in nextIndexAfterPrefix .. path.size - 1) {
|
||||
val qualifierPart = path[qualifierPartIndex]
|
||||
|
||||
|
||||
if (packageView != null && !packageView.isEmpty()) {
|
||||
packageView
|
||||
} else {
|
||||
descriptor.memberScope.getContributedClassifier(qualifierPart.name, qualifierPart.location)
|
||||
val nextPackageOrClassDescriptor =
|
||||
when (currentDescriptor) {
|
||||
is ClassDescriptor ->
|
||||
currentDescriptor.unsubstitutedInnerClassesScope.getContributedClassifier(qualifierPart.name, qualifierPart.location)
|
||||
is PackageViewDescriptor -> {
|
||||
val packageView =
|
||||
if (qualifierPart.typeArguments == null) {
|
||||
moduleDescriptor.getPackage(currentDescriptor.fqName.child(qualifierPart.name))
|
||||
}
|
||||
else null
|
||||
if (packageView != null && !packageView.isEmpty()) {
|
||||
packageView
|
||||
}
|
||||
else {
|
||||
currentDescriptor.memberScope.getContributedClassifier(qualifierPart.name, qualifierPart.location)
|
||||
}
|
||||
}
|
||||
else ->
|
||||
null
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
|
||||
// If we are in expression, this name can denote a value (not a package or class).
|
||||
if (!(position == QualifierPosition.EXPRESSION && nextPackageOrClassDescriptor == null)) {
|
||||
storeResult(trace, qualifierPart.expression, nextPackageOrClassDescriptor, shouldBeVisibleFrom, inImport)
|
||||
}
|
||||
storeResult(trace, qualifierPart.expression, nextDescriptor, shouldBeVisibleFrom, inImport)
|
||||
nextDescriptor
|
||||
|
||||
if (nextPackageOrClassDescriptor == null) {
|
||||
return Pair(currentDescriptor, qualifierPartIndex)
|
||||
}
|
||||
|
||||
currentDescriptor = nextPackageOrClassDescriptor
|
||||
}
|
||||
|
||||
return Pair(currentDescriptor, path.size)
|
||||
}
|
||||
|
||||
|
||||
public fun resolveQualifierInExpressionAndUnroll(
|
||||
expression: KtQualifiedExpression,
|
||||
context: ExpressionTypingContext
|
||||
): List<CallExpressionElement> {
|
||||
val qualifiedExpressions = unrollToLeftMostQualifiedExpression(expression)
|
||||
val maxPossibleQualifierPrefix = getMaxPossibleQualifierPrefix(qualifiedExpressions)
|
||||
|
||||
val (packageOrClassDescriptor, nextIndexAfterPrefix) = resolveToPackageOrClassPrefix(
|
||||
path = maxPossibleQualifierPrefix,
|
||||
moduleDescriptor = context.scope.ownerDescriptor.module,
|
||||
trace = context.trace,
|
||||
shouldBeVisibleFrom = context.scope.ownerDescriptor,
|
||||
scopeForFirstPart = context.scope,
|
||||
position = QualifierPosition.EXPRESSION
|
||||
)
|
||||
|
||||
if (nextIndexAfterPrefix > 0) {
|
||||
val qualifierReferenceExpression = maxPossibleQualifierPrefix[nextIndexAfterPrefix - 1].expression
|
||||
val qualifier =
|
||||
when (packageOrClassDescriptor) {
|
||||
is PackageViewDescriptor ->
|
||||
PackageQualifier(qualifierReferenceExpression, packageOrClassDescriptor)
|
||||
is ClassDescriptor ->
|
||||
ClassQualifier(qualifierReferenceExpression, packageOrClassDescriptor)
|
||||
else ->
|
||||
null
|
||||
}
|
||||
if (qualifier != null) {
|
||||
context.trace.record(BindingContext.QUALIFIER, qualifier.expression, qualifier)
|
||||
}
|
||||
}
|
||||
|
||||
return qualifiedExpressions.map { CallExpressionElement(it) }
|
||||
}
|
||||
|
||||
private fun unrollToLeftMostQualifiedExpression(expression: KtQualifiedExpression): List<KtQualifiedExpression> {
|
||||
val unrolled = arrayListOf<KtQualifiedExpression>()
|
||||
|
||||
var finger = expression
|
||||
while (true) {
|
||||
unrolled.add(finger)
|
||||
val receiver = finger.receiverExpression
|
||||
if (receiver !is KtQualifiedExpression) {
|
||||
break
|
||||
}
|
||||
finger = receiver
|
||||
}
|
||||
|
||||
Collections.reverse(unrolled)
|
||||
return unrolled
|
||||
}
|
||||
|
||||
private fun getMaxPossibleQualifierPrefix(qualifiedExpressions: List<KtQualifiedExpression>) : List<QualifierPart> {
|
||||
if (qualifiedExpressions.isEmpty()) return emptyList()
|
||||
|
||||
val first = qualifiedExpressions.first()
|
||||
if (first.operationSign != KtTokens.DOT) return emptyList()
|
||||
val firstReceiver = first.receiverExpression
|
||||
if (firstReceiver !is KtSimpleNameExpression) return emptyList()
|
||||
|
||||
val qualifierParts = arrayListOf<QualifierPart>()
|
||||
qualifierParts.add(QualifierPart(firstReceiver))
|
||||
|
||||
for (qualifiedExpression in qualifiedExpressions.dropLast(1)) {
|
||||
if (qualifiedExpression.operationSign != KtTokens.DOT) break
|
||||
val selector = qualifiedExpression.selectorExpression
|
||||
if (selector !is KtSimpleNameExpression) break
|
||||
qualifierParts.add(QualifierPart(selector))
|
||||
}
|
||||
|
||||
return qualifierParts
|
||||
}
|
||||
|
||||
private fun ModuleDescriptor.quickResolveToPackage(
|
||||
@@ -516,13 +650,15 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
context: ExpressionTypingContext,
|
||||
selector: DeclarationDescriptor?
|
||||
): DeclarationDescriptor {
|
||||
if (qualifier is ClassQualifier && qualifier.classifier is TypeParameterDescriptor) {
|
||||
if (qualifier is ClassifierQualifier && qualifier.classifier is TypeParameterDescriptor) {
|
||||
return qualifier.classifier
|
||||
}
|
||||
|
||||
val selectorContainer = when (selector) {
|
||||
is ConstructorDescriptor -> selector.containingDeclaration.containingDeclaration
|
||||
else -> selector?.containingDeclaration
|
||||
is ConstructorDescriptor ->
|
||||
selector.containingDeclaration.containingDeclaration
|
||||
else ->
|
||||
selector?.containingDeclaration
|
||||
}
|
||||
|
||||
if (qualifier is PackageQualifier &&
|
||||
|
||||
+7
-6
@@ -57,7 +57,6 @@ import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||
@@ -332,9 +331,12 @@ public class CallExpressionResolver {
|
||||
@NotNull KtQualifiedExpression expression, @NotNull ExpressionTypingContext context
|
||||
) {
|
||||
ExpressionTypingContext currentContext = context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
|
||||
Deque<CallExpressionElement> elementChain = CallExpressionUnrollerKt.unroll(expression);
|
||||
|
||||
KotlinTypeInfo receiverTypeInfo = expressionTypingServices.getTypeInfo(elementChain.getFirst().getReceiver(), currentContext);
|
||||
List<CallExpressionElement> elementChain =
|
||||
qualifiedExpressionResolver.resolveQualifierInExpressionAndUnroll(expression, context);
|
||||
|
||||
CallExpressionElement firstElement = elementChain.iterator().next();
|
||||
KotlinTypeInfo receiverTypeInfo = expressionTypingServices.getTypeInfo(firstElement.getReceiver(), currentContext);
|
||||
KotlinType receiverType = receiverTypeInfo.getType();
|
||||
DataFlowInfo receiverDataFlowInfo = receiverTypeInfo.getDataFlowInfo();
|
||||
KotlinTypeInfo resultTypeInfo = receiverTypeInfo;
|
||||
@@ -353,15 +355,14 @@ public class CallExpressionResolver {
|
||||
: qualifierReceiver;
|
||||
|
||||
boolean lastStage = element.getQualified() == expression;
|
||||
assert lastStage == (element == elementChain.getLast());
|
||||
// Drop NO_EXPECTED_TYPE / INDEPENDENT at last stage
|
||||
// But receiver data flow info changes should be always applied, while we are inside call chain
|
||||
ExpressionTypingContext baseContext = lastStage ? context : currentContext;
|
||||
currentContext = baseContext.replaceDataFlowInfo(receiverDataFlowInfo);
|
||||
|
||||
KtExpression selectorExpression = element.getSelector();
|
||||
KotlinTypeInfo selectorReturnTypeInfo = getSelectorReturnTypeInfo(
|
||||
receiver, element.getNode(), selectorExpression, currentContext);
|
||||
KotlinTypeInfo selectorReturnTypeInfo =
|
||||
getSelectorReturnTypeInfo(receiver, element.getNode(), selectorExpression, currentContext);
|
||||
KotlinType selectorReturnType = selectorReturnTypeInfo.getType();
|
||||
|
||||
resolveDeferredReceiverInQualifiedExpression(qualifierReceiver, element.getQualified(), currentContext);
|
||||
|
||||
@@ -32,7 +32,7 @@ internal fun unroll(root: KtQualifiedExpression): Deque<CallExpressionElement> {
|
||||
return result
|
||||
}
|
||||
|
||||
internal data class CallExpressionElement(val qualified: KtQualifiedExpression) {
|
||||
public data class CallExpressionElement internal constructor (val qualified: KtQualifiedExpression) {
|
||||
|
||||
val receiver: KtExpression
|
||||
get() = qualified.receiverExpression
|
||||
|
||||
@@ -69,7 +69,8 @@ public class TaskPrioritizer(
|
||||
when (explicitReceiver) {
|
||||
is QualifierReceiver -> {
|
||||
val qualifierReceiver: QualifierReceiver = explicitReceiver
|
||||
val receiverScope = qualifierReceiver.getNestedClassesAndPackageMembersScope().memberScopeAsImportingScope()
|
||||
val receiverScope = LexicalScope.empty(qualifierReceiver.getNestedClassesAndPackageMembersScope().memberScopeAsImportingScope(),
|
||||
qualifierReceiver.descriptor)
|
||||
doComputeTasks(NO_RECEIVER, taskPrioritizerContext.replaceScope(receiverScope))
|
||||
computeTasksForClassObjectReceiver(qualifierReceiver, taskPrioritizerContext)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.resolve.scopes.receivers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
@@ -36,8 +35,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findPackage
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
|
||||
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
@@ -102,9 +99,9 @@ class ClassifierQualifierWithEmptyScope(
|
||||
override val classifier: ClassifierDescriptor
|
||||
) : ClassifierQualifier(referenceExpression) {
|
||||
|
||||
override fun getNestedClassesAndPackageMembersScope(): MemberScope = scope
|
||||
override fun getNestedClassesAndPackageMembersScope(): MemberScope = MemberScope.Empty
|
||||
|
||||
override val scope: MemberScope = MemberScope.empty(classifier)
|
||||
override val scope: MemberScope = MemberScope.Empty
|
||||
}
|
||||
|
||||
class ClassQualifier(
|
||||
|
||||
@@ -98,6 +98,17 @@ public fun HierarchicalScope.findFunction(name: Name, location: LookupLocation,
|
||||
return null
|
||||
}
|
||||
|
||||
public fun HierarchicalScope.containsFunctionOrVariable(name: Name, location: LookupLocation): Boolean {
|
||||
processForMeAndParent {
|
||||
if (it.getContributedFunctions(name, location).isNotEmpty() ||
|
||||
it.getContributedVariables(name, location).isNotEmpty()
|
||||
) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public fun HierarchicalScope.collectSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation)
|
||||
= collectAllFromImportingScopes { it.getContributedSyntheticExtensionProperties(receiverTypes, name, location) }
|
||||
|
||||
|
||||
@@ -40,12 +40,12 @@ fun test() {
|
||||
f(<!INVISIBLE_MEMBER!>D<!>)
|
||||
|
||||
A.foo()
|
||||
B.<!INVISIBLE_MEMBER!>bar<!>()
|
||||
<!INVISIBLE_REFERENCE!>B<!>.<!INVISIBLE_MEMBER!>bar<!>()
|
||||
C.<!INVISIBLE_MEMBER!>baz<!>()
|
||||
D.<!INVISIBLE_MEMBER!>quux<!>()
|
||||
<!INVISIBLE_REFERENCE!>D<!>.<!INVISIBLE_MEMBER!>quux<!>()
|
||||
|
||||
a.A.foo()
|
||||
a.C.<!INVISIBLE_MEMBER!>baz<!>()
|
||||
}
|
||||
|
||||
fun f(<!UNUSED_PARAMETER!>unused<!>: Any) {}
|
||||
fun f(<!UNUSED_PARAMETER!>unused<!>: Any) {}
|
||||
+2
-2
@@ -10,6 +10,6 @@ class A {
|
||||
}
|
||||
}
|
||||
|
||||
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>f1<!>() = A.Companion.B.<!INVISIBLE_MEMBER!>C<!>
|
||||
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>f1<!>() = A.<!INVISIBLE_REFERENCE!>Companion<!>.<!INVISIBLE_REFERENCE!>B<!>.<!INVISIBLE_MEMBER!>C<!>
|
||||
|
||||
fun f2() = A.Companion.B.C.<!INVISIBLE_MEMBER!>foo<!>()
|
||||
fun f2() = A.<!INVISIBLE_REFERENCE!>Companion<!>.<!INVISIBLE_REFERENCE!>B<!>.<!INVISIBLE_REFERENCE!>C<!>.<!INVISIBLE_MEMBER!>foo<!>()
|
||||
@@ -12,7 +12,7 @@ class TopLevel {
|
||||
}
|
||||
|
||||
fun useNested() {
|
||||
val <!UNUSED_VARIABLE!>d<!> = TopLevel.<!DEPRECATION!>Nested<!>.use()
|
||||
TopLevel.<!DEPRECATION!>Nested<!>.Nested2()
|
||||
TopLevel.<!DEPRECATION!>Nested<!>.<!UNRESOLVED_REFERENCE!>CompanionNested2<!>()
|
||||
}
|
||||
val <!UNUSED_VARIABLE!>d<!> = TopLevel.<!DEPRECATION, DEPRECATION!>Nested<!>.use()
|
||||
TopLevel.<!DEPRECATION, DEPRECATION!>Nested<!>.Nested2()
|
||||
TopLevel.<!DEPRECATION, DEPRECATION!>Nested<!>.<!UNRESOLVED_REFERENCE!>CompanionNested2<!>()
|
||||
}
|
||||
@@ -15,13 +15,13 @@ fun first() {
|
||||
}
|
||||
|
||||
fun useObject() {
|
||||
<!DEPRECATION!>Obsolete<!>.use()
|
||||
<!DEPRECATION, DEPRECATION!>Obsolete<!>.use()
|
||||
val <!UNUSED_VARIABLE!>x<!> = <!DEPRECATION!>Obsolete<!>
|
||||
}
|
||||
|
||||
fun useCompanion() {
|
||||
val <!UNUSED_VARIABLE!>d<!> = <!DEPRECATION!>Another<!>
|
||||
val <!UNUSED_VARIABLE!>x<!> = Another.<!DEPRECATION!>Companion<!>
|
||||
Another.<!DEPRECATION!>Companion<!>.use()
|
||||
Another.<!DEPRECATION, DEPRECATION!>Companion<!>.use()
|
||||
<!DEPRECATION!>Another<!>.use()
|
||||
}
|
||||
}
|
||||
@@ -28,9 +28,9 @@ import a.<!INVISIBLE_REFERENCE!>MyJavaClass<!>
|
||||
|
||||
<!EXPOSED_PROPERTY_TYPE!>val mc1 = <!INVISIBLE_MEMBER!>MyJavaClass<!>()<!>
|
||||
|
||||
val x = MyJavaClass.<!INVISIBLE_MEMBER!>staticMethod<!>()
|
||||
val y = MyJavaClass.NestedClass.<!INVISIBLE_MEMBER!>staticMethodOfNested<!>()
|
||||
<!EXPOSED_PROPERTY_TYPE!>val z = MyJavaClass.<!INVISIBLE_MEMBER!>NestedClass<!>()<!>
|
||||
val x = <!INVISIBLE_REFERENCE!>MyJavaClass<!>.<!INVISIBLE_MEMBER!>staticMethod<!>()
|
||||
val y = <!INVISIBLE_REFERENCE!>MyJavaClass<!>.<!INVISIBLE_REFERENCE!>NestedClass<!>.<!INVISIBLE_MEMBER!>staticMethodOfNested<!>()
|
||||
<!EXPOSED_PROPERTY_TYPE!>val z = <!INVISIBLE_REFERENCE!>MyJavaClass<!>.<!INVISIBLE_MEMBER!>NestedClass<!>()<!>
|
||||
|
||||
//FILE: c.kt
|
||||
package a.c
|
||||
@@ -39,6 +39,6 @@ import a.<!INVISIBLE_REFERENCE!>MyJavaClass<!>
|
||||
|
||||
<!EXPOSED_PROPERTY_TYPE!>val mc1 = <!INVISIBLE_MEMBER!>MyJavaClass<!>()<!>
|
||||
|
||||
val x = MyJavaClass.<!INVISIBLE_MEMBER!>staticMethod<!>()
|
||||
val y = MyJavaClass.NestedClass.<!INVISIBLE_MEMBER!>staticMethodOfNested<!>()
|
||||
<!EXPOSED_PROPERTY_TYPE!>val z = MyJavaClass.<!INVISIBLE_MEMBER!>NestedClass<!>()<!>
|
||||
val x = <!INVISIBLE_REFERENCE!>MyJavaClass<!>.<!INVISIBLE_MEMBER!>staticMethod<!>()
|
||||
val y = <!INVISIBLE_REFERENCE!>MyJavaClass<!>.<!INVISIBLE_REFERENCE!>NestedClass<!>.<!INVISIBLE_MEMBER!>staticMethodOfNested<!>()
|
||||
<!EXPOSED_PROPERTY_TYPE!>val z = <!INVISIBLE_REFERENCE!>MyJavaClass<!>.<!INVISIBLE_MEMBER!>NestedClass<!>()<!>
|
||||
@@ -14,5 +14,5 @@ public class Foo {
|
||||
// FILE: 1.kt
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
javaPackage.Foo.Bar.<!INVISIBLE_MEMBER!>doSmth<!>()
|
||||
}
|
||||
javaPackage.Foo.<!INVISIBLE_REFERENCE!>Bar<!>.<!INVISIBLE_MEMBER!>doSmth<!>()
|
||||
}
|
||||
-19
@@ -133,23 +133,4 @@
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Type arguments are unnecessary</problem_class>
|
||||
<description>Remove explicit type arguments</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>platforrmType2.kt</file>
|
||||
<line>5</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="platforrmType2.kt" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Type arguments are unnecessary</problem_class>
|
||||
<description>Remove explicit type arguments</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>platforrmType1.kt</file>
|
||||
<line>5</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="platforrmType1.kt" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Type arguments are unnecessary</problem_class>
|
||||
<description>Remove explicit type arguments</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -19,8 +19,8 @@ import bar.*
|
||||
this./*c:foo.A*/a
|
||||
this./*c:foo.A*/foo()
|
||||
/*c:foo.A c:foo.A.Companion p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.io c:foo.A(getBaz) c:foo.A(getBAZ)*/baz()
|
||||
/*c:foo.A c:foo.A.Companion p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.io*/Companion./*c:foo.A.Companion*/a
|
||||
/*c:foo.A c:foo.A.Companion p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.io*/O./*c:foo.A.O*/v = "OK"
|
||||
/*p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.io c:foo.A c:foo.A.Companion*/Companion./*c:foo.A.Companion*/a
|
||||
/*p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.io c:foo.A c:foo.A.Companion*/O./*c:foo.A.O*/v = "OK"
|
||||
}
|
||||
|
||||
class B {
|
||||
@@ -64,8 +64,8 @@ import bar.*
|
||||
val a = 1
|
||||
fun foo() {
|
||||
/*c:foo.E*/a
|
||||
/*c:foo.E p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.io*/Y./*c:foo.E*/a
|
||||
/*p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.io c:foo.E*/Y./*c:foo.E*/a
|
||||
/*c:foo.E*/foo()
|
||||
/*c:foo.E p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.io*/X./*c:foo.E*/foo()
|
||||
/*p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.io c:foo.E*/X./*c:foo.E*/foo()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user