Drop SymbolUsageValidator.Composite, use validators similarly to call checkers

Also fix warnings in DeprecatedSymbolValidator, DelegatedPropertyResolver and
elsewhere
This commit is contained in:
Alexander Udalov
2016-06-24 18:47:51 +03:00
parent e94fd8f777
commit d7d2780666
12 changed files with 76 additions and 95 deletions
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
import org.jetbrains.kotlin.types.expressions.FakeCallResolver;
import org.jetbrains.kotlin.util.OperatorNameConventions;
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
import java.util.Collections;
@@ -60,26 +61,23 @@ import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.createFakeExpressionOfType;
public class DelegatedPropertyResolver {
public static final Name PROPERTY_DELEGATED_FUNCTION_NAME = Name.identifier("propertyDelegated");
public static final Name GETTER_NAME = Name.identifier("getValue");
public static final Name SETTER_NAME = Name.identifier("setValue");
public static final Name OLD_GETTER_NAME = Name.identifier("get");
public static final Name OLD_SETTER_NAME = Name.identifier("set");
private static final Name OLD_GETTER_NAME = Name.identifier("get");
private static final Name OLD_SETTER_NAME = Name.identifier("set");
@NotNull private final ExpressionTypingServices expressionTypingServices;
@NotNull private final FakeCallResolver fakeCallResolver;
@NotNull private final KotlinBuiltIns builtIns;
@NotNull private final SymbolUsageValidator symbolUsageValidator;
private final ExpressionTypingServices expressionTypingServices;
private final FakeCallResolver fakeCallResolver;
private final KotlinBuiltIns builtIns;
private final Iterable<SymbolUsageValidator> symbolUsageValidators;
public DelegatedPropertyResolver(
@NotNull SymbolUsageValidator symbolUsageValidator,
@NotNull Iterable<SymbolUsageValidator> symbolUsageValidators,
@NotNull KotlinBuiltIns builtIns,
@NotNull FakeCallResolver fakeCallResolver,
@NotNull ExpressionTypingServices expressionTypingServices
) {
this.symbolUsageValidator = symbolUsageValidator;
this.symbolUsageValidators = symbolUsageValidators;
this.builtIns = builtIns;
this.fakeCallResolver = fakeCallResolver;
this.expressionTypingServices = expressionTypingServices;
@@ -266,7 +264,9 @@ public class DelegatedPropertyResolver {
OperatorCallChecker.Companion.report(byKeyword, resultingDescriptor, trace);
}
symbolUsageValidator.validateCall(resultingCall, resultingCall.getResultingDescriptor(), trace, byKeyword);
for (SymbolUsageValidator validator : symbolUsageValidators) {
validator.validateCall(resultingCall, resultingCall.getResultingDescriptor(), trace, byKeyword);
}
}
}
trace.record(DELEGATED_PROPERTY_RESOLVED_CALL, accessor, resultingCall);
@@ -308,7 +308,7 @@ public class DelegatedPropertyResolver {
trace.record(REFERENCE_TARGET, fakeArgument, valueParameters.get(0));
}
Name functionName = isGet ? GETTER_NAME : SETTER_NAME;
Name functionName = isGet ? OperatorNameConventions.GET_VALUE : OperatorNameConventions.SET_VALUE;
ExpressionReceiver receiver = ExpressionReceiver.Companion.create(delegateExpression, delegateType, trace.getBindingContext());
Pair<Call, OverloadResolutionResults<FunctionDescriptor>> resolutionResult =
@@ -29,9 +29,9 @@ fun resolveQualifierAsReceiverInExpression(
qualifier: Qualifier,
selector: DeclarationDescriptor?,
context: ExpressionTypingContext,
symbolUsageValidator: SymbolUsageValidator
symbolUsageValidators: Iterable<SymbolUsageValidator>
): DeclarationDescriptor {
val referenceTarget = resolveQualifierReferenceTarget(qualifier, selector, context, symbolUsageValidator)
val referenceTarget = resolveQualifierReferenceTarget(qualifier, selector, context, symbolUsageValidators)
if (referenceTarget is TypeParameterDescriptor) {
context.trace.report(Errors.TYPE_PARAMETER_ON_LHS_OF_DOT.on(qualifier.referenceExpression, referenceTarget))
@@ -43,9 +43,9 @@ fun resolveQualifierAsReceiverInExpression(
fun resolveQualifierAsStandaloneExpression(
qualifier: Qualifier,
context: ExpressionTypingContext,
symbolUsageValidator: SymbolUsageValidator
symbolUsageValidators: Iterable<SymbolUsageValidator>
): DeclarationDescriptor {
val referenceTarget = resolveQualifierReferenceTarget(qualifier, null, context, symbolUsageValidator)
val referenceTarget = resolveQualifierReferenceTarget(qualifier, null, context, symbolUsageValidators)
when (referenceTarget) {
is TypeParameterDescriptor -> {
@@ -68,7 +68,7 @@ private fun resolveQualifierReferenceTarget(
qualifier: Qualifier,
selector: DeclarationDescriptor?,
context: ExpressionTypingContext,
symbolUsageValidator: SymbolUsageValidator
symbolUsageValidators: Iterable<SymbolUsageValidator>
): DeclarationDescriptor {
if (qualifier is TypeParameterQualifier) {
return qualifier.descriptor
@@ -104,7 +104,9 @@ private fun resolveQualifierReferenceTarget(
context.trace.recordType(qualifier.expression, classValueTypeDescriptor.defaultType)
if (classifier.hasCompanionObject) {
context.trace.record(BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, qualifier.referenceExpression, classifier)
symbolUsageValidator.validateTypeUsage(classValueDescriptor, context.trace, qualifier.referenceExpression)
for (validator in symbolUsageValidators) {
validator.validateTypeUsage(classValueDescriptor, context.trace, qualifier.referenceExpression)
}
}
return classValueTypeDescriptor
}
@@ -40,9 +40,7 @@ import org.jetbrains.kotlin.types.expressions.isWithoutValueArguments
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.check
class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator) {
class QualifiedExpressionResolver(val symbolUsageValidators: Iterable<SymbolUsageValidator>) {
fun resolvePackageHeader(
packageDirective: KtPackageDirective,
module: ModuleDescriptor,
@@ -598,7 +596,9 @@ class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptor)
if (descriptor is ClassifierDescriptor) {
symbolUsageValidator.validateTypeUsage(descriptor, trace, referenceExpression)
for (validator in symbolUsageValidators) {
validator.validateTypeUsage(descriptor, trace, referenceExpression)
}
}
if (descriptor is DeclarationDescriptorWithVisibility) {
@@ -84,11 +84,10 @@ abstract class PlatformConfigurator(
private val identifierChecker: IdentifierChecker,
private val overloadFilter: OverloadFilter
) {
private val declarationCheckers: List<DeclarationChecker> = DEFAULT_DECLARATION_CHECKERS + additionalDeclarationCheckers
private val callCheckers: List<CallChecker> = DEFAULT_CALL_CHECKERS + additionalCallCheckers
private val typeCheckers: List<AdditionalTypeChecker> = DEFAULT_TYPE_CHECKERS + additionalTypeCheckers
private val symbolUsageValidator: SymbolUsageValidator = SymbolUsageValidator.Composite(DEFAULT_VALIDATORS + additionalSymbolUsageValidators)
private val symbolUsageValidators: List<SymbolUsageValidator> = DEFAULT_VALIDATORS + additionalSymbolUsageValidators
open fun configure(container: StorageComponentContainer) {
with (container) {
@@ -96,7 +95,7 @@ abstract class PlatformConfigurator(
declarationCheckers.forEach { useInstance(it) }
callCheckers.forEach { useInstance(it) }
typeCheckers.forEach { useInstance(it) }
useInstance(symbolUsageValidator)
symbolUsageValidators.forEach { useInstance(it) }
additionalAnnotationCheckers.forEach { useInstance(it) }
useInstance(identifierChecker)
useInstance(overloadFilter)
@@ -55,9 +55,9 @@ import java.util.*
class CallCompleter(
private val argumentTypeResolver: ArgumentTypeResolver,
private val candidateResolver: CandidateResolver,
private val symbolUsageValidator: SymbolUsageValidator,
private val dataFlowAnalyzer: DataFlowAnalyzer,
private val callCheckers: Iterable<CallChecker>,
private val symbolUsageValidators: Iterable<SymbolUsageValidator>,
private val builtIns: KotlinBuiltIns,
private val fakeCallResolver: FakeCallResolver,
private val languageFeatureSettings: LanguageFeatureSettings
@@ -91,7 +91,10 @@ class CallCompleter(
resolvedCall.variableCall.call.calleeExpression
else
resolvedCall.call.calleeExpression
symbolUsageValidator.validateCall(resolvedCall, resolvedCall.resultingDescriptor, context.trace, element!!)
for (validator in symbolUsageValidators) {
validator.validateCall(resolvedCall, resolvedCall.resultingDescriptor, context.trace, element!!)
}
resolveHandleResultCallForCoroutineLambdaExpressions(context, resolvedCall)
}
@@ -72,9 +72,8 @@ class CallExpressionResolver(
private val dataFlowAnalyzer: DataFlowAnalyzer,
private val builtIns: KotlinBuiltIns,
private val qualifiedExpressionResolver: QualifiedExpressionResolver,
private val symbolUsageValidator: SymbolUsageValidator
private val symbolUsageValidators: Iterable<SymbolUsageValidator>
) {
private lateinit var expressionTypingServices: ExpressionTypingServices
// component dependency cycle
@@ -164,7 +163,7 @@ class CallExpressionResolver(
val temporaryForQualifier = TemporaryTraceAndCache.create(context, "trace to resolve as qualifier", nameExpression)
val contextForQualifier = context.replaceTraceAndCache(temporaryForQualifier)
qualifiedExpressionResolver.resolveNameExpressionAsQualifierForDiagnostics(nameExpression, receiver, contextForQualifier)?.let {
resolveQualifierAsStandaloneExpression(it, contextForQualifier, symbolUsageValidator)
resolveQualifierAsStandaloneExpression(it, contextForQualifier, symbolUsageValidators)
temporaryForQualifier.commit()
} ?: temporaryForVariable.commit()
return noTypeInfo(context)
@@ -451,7 +450,7 @@ class CallExpressionResolver(
context.trace.get(BindingContext.REFERENCE_TARGET, it)
}
resolveQualifierAsReceiverInExpression(qualifier, selectorDescriptor, context, symbolUsageValidator)
resolveQualifierAsReceiverInExpression(qualifier, selectorDescriptor, context, symbolUsageValidators)
}
companion object {
@@ -52,13 +52,11 @@ class DeprecatedSymbolValidator : SymbolUsageValidator {
override fun validateTypeUsage(targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement) {
// Do not check types in annotation entries to prevent cycles in resolve, rely on call message
val annotationEntry = KtStubbedPsiUtil.getPsiOrStubParent(element, KtAnnotationEntry::class.java, true)
if (annotationEntry != null && annotationEntry.getCalleeExpression()!!.getConstructorReferenceExpression() == element)
return
if (annotationEntry != null && annotationEntry.calleeExpression!!.constructorReferenceExpression == element) return
// Do not check types in calls to super constructor in extends list, rely on call message
val superExpression = KtStubbedPsiUtil.getPsiOrStubParent(element, KtSuperTypeCallEntry::class.java, true)
if (superExpression != null && superExpression.getCalleeExpression().getConstructorReferenceExpression() == element)
return
if (superExpression != null && superExpression.calleeExpression.constructorReferenceExpression == element) return
val deprecation = targetDescriptor.getDeprecation()
if (deprecation != null) {
@@ -88,37 +86,25 @@ class DeprecatedSymbolValidator : SymbolUsageValidator {
val binaryExpression = PsiTreeUtil.getParentOfType<KtBinaryExpression>(expression, KtBinaryExpression::class.java)
if (binaryExpression != null) {
val left = binaryExpression.left
if (left == expression) {
val operation = binaryExpression.operationToken
if (operation != null && operation in PROPERTY_SET_OPERATIONS)
return
}
if (left == expression && binaryExpression.operationToken in PROPERTY_SET_OPERATIONS) return
val jetReferenceExpressions = PsiTreeUtil.getChildrenOfType<KtReferenceExpression>(left, KtReferenceExpression::class.java)
if (jetReferenceExpressions != null) {
for (expr in jetReferenceExpressions) {
if (expr == expression) {
val operation = binaryExpression.operationToken
if (operation != null && operation in PROPERTY_SET_OPERATIONS)
return // skip binary set operations
}
val referenceExpressions = PsiTreeUtil.getChildrenOfType<KtReferenceExpression>(left, KtReferenceExpression::class.java)
if (referenceExpressions != null) {
for (expr in referenceExpressions) {
// skip binary set operations
if (expr == expression && binaryExpression.operationToken in PROPERTY_SET_OPERATIONS) return
}
}
}
val unaryExpression = PsiTreeUtil.getParentOfType(expression, KtUnaryExpression::class.java)
if (unaryExpression != null) {
val operation = unaryExpression.operationReference.getReferencedNameElementType()
if (operation != null && operation in PROPERTY_SET_OPERATIONS)
return // skip unary set operations
}
// skip unary set operations
if (unaryExpression?.operationReference?.getReferencedNameElementType() in PROPERTY_SET_OPERATIONS) return
val callableExpression = PsiTreeUtil.getParentOfType(expression, KtCallableReferenceExpression::class.java)
if (callableExpression != null && callableExpression.getCallableReference() == expression) {
return // skip Type::property
}
// skip Type::property
if (callableExpression != null && callableExpression.callableReference == expression) return
propertyDescriptor.getter?.let { validateCall(resolvedCall, it, trace, expression) }
}
}
}
@@ -23,22 +23,7 @@ import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
interface SymbolUsageValidator {
fun validateTypeUsage(targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement)
fun validateTypeUsage(targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement) { }
fun validateCall(resolvedCall: ResolvedCall<*>?, targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement) { }
open class Composite(val validators: List<SymbolUsageValidator>) : SymbolUsageValidator {
override fun validateCall(resolvedCall: ResolvedCall<*>?, targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement) {
validators.forEach { it.validateCall(resolvedCall, targetDescriptor, trace, element) }
}
override fun validateTypeUsage(targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement) {
validators.forEach { it.validateTypeUsage(targetDescriptor, trace, element) }
}
}
companion object {
val Empty: SymbolUsageValidator = Composite(listOf())
}
}
fun validateCall(resolvedCall: ResolvedCall<*>?, targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement)
}
@@ -61,6 +61,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct;
@@ -590,8 +591,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
for (CallChecker checker : components.callCheckers) {
checker.check(resolvedCall, resolutionContext, components.languageFeatureSettings);
}
components.symbolUsageValidator.validateCall(resolvedCall, descriptor, trace, expression);
for (SymbolUsageValidator validator : components.symbolUsageValidators) {
validator.validateCall(resolvedCall, descriptor, trace, expression);
}
}
private static boolean isDeclaredInClass(ReceiverParameterDescriptor receiver) {
@@ -921,9 +923,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
trace.report(SETTER_PROJECTED_OUT.on(reportOn, propertyDescriptor));
result = false;
}
else {
if (setter != null) {
components.symbolUsageValidator.validateCall(null, setter, trace, reportOn);
else if (setter != null) {
for (SymbolUsageValidator validator : components.symbolUsageValidators) {
validator.validateCall(null, setter, trace, reportOn);
}
}
}
@@ -37,7 +37,7 @@ class DestructuringDeclarationResolver(
private val fakeCallResolver: FakeCallResolver,
private val localVariableResolver: LocalVariableResolver,
private val typeResolver: TypeResolver,
private val symbolUsageValidator: SymbolUsageValidator
private val symbolUsageValidators: Iterable<SymbolUsageValidator>
) {
fun defineLocalVariablesFromMultiDeclaration(
writableScope: LexicalWritableScope,
@@ -82,7 +82,9 @@ class DestructuringDeclarationResolver(
context.trace.record(BindingContext.COMPONENT_RESOLVED_CALL, entry, results.resultingCall)
val functionDescriptor = results.resultingDescriptor
symbolUsageValidator.validateCall(null, functionDescriptor, context.trace, entry)
for (validator in symbolUsageValidators) {
validator.validateCall(null, functionDescriptor, context.trace, entry)
}
val functionReturnType = functionDescriptor.returnType
if (functionReturnType != null && !TypeUtils.noExpectedType(expectedType)
@@ -42,7 +42,6 @@ public class ExpressionTypingComponents {
/*package*/ ForLoopConventionsChecker forLoopConventionsChecker;
/*package*/ FakeCallResolver fakeCallResolver;
/*package*/ ReflectionTypes reflectionTypes;
/*package*/ SymbolUsageValidator symbolUsageValidator;
/*package*/ DynamicTypesSettings dynamicTypesSettings;
/*package*/ KotlinBuiltIns builtIns;
/*package*/ LocalClassifierAnalyzer localClassifierAnalyzer;
@@ -58,6 +57,7 @@ public class ExpressionTypingComponents {
/*package*/ ModifiersChecker modifiersChecker;
/*package*/ DataFlowAnalyzer dataFlowAnalyzer;
/*package*/ Iterable<CallChecker> callCheckers;
/*package*/ Iterable<SymbolUsageValidator> symbolUsageValidators;
/*package*/ IdentifierChecker identifierChecker;
/*package*/ DeclarationsCheckerBuilder declarationsCheckerBuilder;
/*package*/ LocalVariableResolver localVariableResolver;
@@ -106,8 +106,8 @@ public class ExpressionTypingComponents {
}
@Inject
public void setSymbolUsageValidator(SymbolUsageValidator symbolUsageValidator) {
this.symbolUsageValidator = symbolUsageValidator;
public void setSymbolUsageValidators(@NotNull Iterable<SymbolUsageValidator> symbolUsageValidators) {
this.symbolUsageValidators = symbolUsageValidators;
}
@Inject
@@ -44,19 +44,18 @@ import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
public class ForLoopConventionsChecker {
@NotNull private final KotlinBuiltIns builtIns;
@NotNull private final SymbolUsageValidator symbolUsageValidator;
@NotNull private final FakeCallResolver fakeCallResolver;
private final KotlinBuiltIns builtIns;
private final Iterable<SymbolUsageValidator> symbolUsageValidators;
private final FakeCallResolver fakeCallResolver;
public ForLoopConventionsChecker(
@NotNull KotlinBuiltIns builtIns,
@NotNull FakeCallResolver fakeCallResolver,
@NotNull SymbolUsageValidator symbolUsageValidator
@NotNull Iterable<SymbolUsageValidator> symbolUsageValidators
) {
this.builtIns = builtIns;
this.fakeCallResolver = fakeCallResolver;
this.symbolUsageValidator = symbolUsageValidator;
this.symbolUsageValidators = symbolUsageValidators;
}
@Nullable
@@ -77,7 +76,9 @@ public class ForLoopConventionsChecker {
checkIfOperatorModifierPresent(loopRangeExpression, iteratorFunction, context.trace);
symbolUsageValidator.validateCall(iteratorResolvedCall, iteratorFunction, context.trace, loopRangeExpression);
for (SymbolUsageValidator validator : symbolUsageValidators) {
validator.validateCall(iteratorResolvedCall, iteratorFunction, context.trace, loopRangeExpression);
}
KotlinType iteratorType = iteratorFunction.getReturnType();
KotlinType hasNextType = checkConventionForIterator(context, loopRangeExpression, iteratorType, "hasNext",
@@ -130,7 +131,9 @@ public class ForLoopConventionsChecker {
ResolvedCall<FunctionDescriptor> resolvedCall = nextResolutionResults.getResultingCall();
context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall);
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
symbolUsageValidator.validateCall(resolvedCall, functionDescriptor, context.trace, loopRangeExpression);
for (SymbolUsageValidator validator : symbolUsageValidators) {
validator.validateCall(resolvedCall, functionDescriptor, context.trace, loopRangeExpression);
}
checkIfOperatorModifierPresent(loopRangeExpression, functionDescriptor, context.trace);