Refactoring of repeatable on retention SOURCE check (correct additional checker usage)

This commit is contained in:
Mikhail Glukhikh
2015-08-03 18:34:08 +03:00
parent 992c019c1e
commit 61fbe0d1e8
10 changed files with 95 additions and 78 deletions
@@ -185,7 +185,7 @@ public abstract class AnnotationCodegen {
private void generateTargetAnnotation(@NotNull ClassDescriptor classDescriptor, @NotNull Set<String> annotationDescriptorsAlreadyPresent) {
String descriptor = Type.getType(Target.class).getDescriptor();
if (!annotationDescriptorsAlreadyPresent.add(descriptor)) return;
Set<KotlinTarget> targets = AnnotationChecker.INSTANCE$.possibleTargetSet(classDescriptor);
Set<KotlinTarget> targets = AnnotationChecker.Companion.possibleTargetSet(classDescriptor);
Set<ElementType> javaTargets;
if (targets == null) {
javaTargets = getJavaTargetList(classDescriptor);
@@ -82,7 +82,7 @@ public object JvmPlatformConfigurator : PlatformConfigurator(
additionalSymbolUsageValidators = listOf(),
additionalAnnotationChecker = RepeatableAnnotationChecker
additionalAnnotationCheckers = listOf(RepeatableAnnotationChecker)
) {
override fun configure(container: StorageComponentContainer) {
@@ -29,9 +29,7 @@ import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.*
public object AnnotationChecker {
public var additionalChecker: AdditionalAnnotationChecker? = null
public class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnotationChecker>) {
public fun check(annotated: JetAnnotated, trace: BindingTrace, descriptor: ClassDescriptor? = null) {
if (annotated is JetTypeParameter) return // TODO: support type parameter annotations
@@ -71,25 +69,7 @@ public object AnnotationChecker {
trace.report(Errors.REPEATED_ANNOTATION.on(entry));
}
}
additionalChecker?.checkEntries(entries, actualTargets, trace)
}
public fun possibleTargetSet(classDescriptor: ClassDescriptor): Set<KotlinTarget>? {
val targetEntryDescriptor = classDescriptor.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.target)
?: return null
val valueArguments = targetEntryDescriptor.allValueArguments
val valueArgument = valueArguments.entrySet().firstOrNull()?.getValue() as? ArrayValue ?: return null
return valueArgument.value.filterIsInstance<EnumValue>().map {
KotlinTarget.valueOrNull(it.value.name.asString())
}.filterNotNull().toSet()
}
private fun possibleTargetSet(entry: JetAnnotationEntry, trace: BindingTrace): Set<KotlinTarget> {
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return KotlinTarget.DEFAULT_TARGET_SET
// For descriptor with error type, all targets are considered as possible
if (descriptor.type.isError) return KotlinTarget.ALL_TARGET_SET
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: return KotlinTarget.DEFAULT_TARGET_SET
return possibleTargetSet(classDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
additionalCheckers.forEach { it.checkEntries(entries, actualTargets, trace) }
}
private fun checkAnnotationEntry(entry: JetAnnotationEntry, actualTargets: List<KotlinTarget>, trace: BindingTrace) {
@@ -98,39 +78,60 @@ public object AnnotationChecker {
trace.report(Errors.WRONG_ANNOTATION_TARGET.on(entry, actualTargets.firstOrNull()?.description ?: "unidentified target"))
}
public fun getActualTargetList(annotated: JetElement, descriptor: ClassDescriptor?): List<KotlinTarget> {
return when (annotated) {
is JetClassOrObject -> descriptor?.let { KotlinTarget.classActualTargets(it) } ?: listOf(CLASSIFIER)
is JetProperty ->
if (annotated.isLocal) {
listOf(LOCAL_VARIABLE)
}
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody) {
listOf(MEMBER_PROPERTY, PROPERTY, FIELD)
}
else {
listOf(TOP_LEVEL_PROPERTY, PROPERTY, FIELD)
}
is JetParameter -> if (annotated.hasValOrVar()) listOf(PROPERTY_PARAMETER, MEMBER_PROPERTY, PROPERTY, FIELD) else listOf(VALUE_PARAMETER)
is JetConstructor<*> -> listOf(CONSTRUCTOR)
is JetFunction ->
if (annotated.isLocal) {
listOf(LOCAL_FUNCTION, FUNCTION)
}
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody) {
listOf(MEMBER_FUNCTION, FUNCTION)
}
else {
listOf(TOP_LEVEL_FUNCTION, FUNCTION)
}
is JetPropertyAccessor -> if (annotated.isGetter) listOf(PROPERTY_GETTER) else listOf(PROPERTY_SETTER)
is JetPackageDirective -> listOf(PACKAGE)
is JetTypeReference -> listOf(TYPE)
is JetFile -> listOf(FILE)
is JetTypeParameter -> listOf(TYPE_PARAMETER)
is JetTypeProjection -> if (annotated.projectionKind == JetProjectionKind.STAR) listOf(STAR_PROJECTION) else listOf(TYPE_PROJECTION)
is JetClassInitializer -> listOf(INITIALIZER)
else -> listOf()
companion object {
private fun possibleTargetSet(entry: JetAnnotationEntry, trace: BindingTrace): Set<KotlinTarget> {
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return KotlinTarget.DEFAULT_TARGET_SET
// For descriptor with error type, all targets are considered as possible
if (descriptor.type.isError) return KotlinTarget.ALL_TARGET_SET
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: return KotlinTarget.DEFAULT_TARGET_SET
return possibleTargetSet(classDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
}
public fun possibleTargetSet(classDescriptor: ClassDescriptor): Set<KotlinTarget>? {
val targetEntryDescriptor = classDescriptor.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.target)
?: return null
val valueArguments = targetEntryDescriptor.allValueArguments
val valueArgument = valueArguments.entrySet().firstOrNull()?.getValue() as? ArrayValue ?: return null
return valueArgument.value.filterIsInstance<EnumValue>().map {
KotlinTarget.valueOrNull(it.value.name.asString())
}.filterNotNull().toSet()
}
public fun getActualTargetList(annotated: JetElement, descriptor: ClassDescriptor?): List<KotlinTarget> {
return when (annotated) {
is JetClassOrObject -> descriptor?.let { KotlinTarget.classActualTargets(it) } ?: listOf(CLASSIFIER)
is JetProperty ->
if (annotated.isLocal) {
listOf(LOCAL_VARIABLE)
}
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody) {
listOf(MEMBER_PROPERTY, PROPERTY, FIELD)
}
else {
listOf(TOP_LEVEL_PROPERTY, PROPERTY, FIELD)
}
is JetParameter -> if (annotated.hasValOrVar()) listOf(PROPERTY_PARAMETER, MEMBER_PROPERTY, PROPERTY, FIELD) else listOf(VALUE_PARAMETER)
is JetConstructor<*> -> listOf(CONSTRUCTOR)
is JetFunction ->
if (annotated.isLocal) {
listOf(LOCAL_FUNCTION, FUNCTION)
}
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody) {
listOf(MEMBER_FUNCTION, FUNCTION)
}
else {
listOf(TOP_LEVEL_FUNCTION, FUNCTION)
}
is JetPropertyAccessor -> if (annotated.isGetter) listOf(PROPERTY_GETTER) else listOf(PROPERTY_SETTER)
is JetPackageDirective -> listOf(PACKAGE)
is JetTypeReference -> listOf(TYPE)
is JetFile -> listOf(FILE)
is JetTypeParameter -> listOf(TYPE_PARAMETER)
is JetTypeProjection -> if (annotated.projectionKind == JetProjectionKind.STAR) listOf(STAR_PROJECTION) else listOf(TYPE_PROJECTION)
is JetClassInitializer -> listOf(INITIALIZER)
else -> listOf()
}
}
}
}
@@ -54,7 +54,7 @@ import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
public class BodyResolver {
@NotNull private final ScriptBodyResolver scriptBodyResolverResolver;
@NotNull private final ModifiersChecker modifiersChecker;
@NotNull private final AnnotationChecker annotationChecker;
@NotNull private final ExpressionTypingServices expressionTypingServices;
@NotNull private final CallResolver callResolver;
@NotNull private final ObservableBindingTrace trace;
@@ -78,7 +78,7 @@ public class BodyResolver {
@NotNull ScriptBodyResolver scriptBodyResolverResolver,
@NotNull BindingTrace trace,
@NotNull ValueParameterResolver valueParameterResolver,
@NotNull ModifiersChecker modifiersChecker
@NotNull AnnotationChecker annotationChecker
) {
this.annotationResolver = annotationResolver;
this.bodyResolveCache = bodyResolveCache;
@@ -89,7 +89,7 @@ public class BodyResolver {
this.expressionTypingServices = expressionTypingServices;
this.functionAnalyzerExtension = functionAnalyzerExtension;
this.scriptBodyResolverResolver = scriptBodyResolverResolver;
this.modifiersChecker = modifiersChecker;
this.annotationChecker = annotationChecker;
this.trace = new ObservableBindingTrace(trace);
this.valueParameterResolver = valueParameterResolver;
}
@@ -507,7 +507,7 @@ public class BodyResolver {
}
private void processModifiersOnInitializer(@NotNull JetModifierListOwner owner, @NotNull JetScope scope) {
AnnotationChecker.INSTANCE$.check(owner, trace, null);
annotationChecker.check(owner, trace, null);
ModifierCheckerCore.INSTANCE$.check(owner, trace, null);
JetModifierList modifierList = owner.getModifierList();
if (modifierList == null) return;
@@ -47,21 +47,24 @@ public class DeclarationsChecker {
@NotNull private final BindingTrace trace;
@NotNull private final ModifiersChecker.ModifiersCheckingProcedure modifiersChecker;
@NotNull private final DescriptorResolver descriptorResolver;
@NotNull private final AnnotationChecker annotationChecker;
public DeclarationsChecker(
@NotNull DescriptorResolver descriptorResolver,
@NotNull ModifiersChecker modifiersChecker,
@NotNull AnnotationChecker annotationChecker,
@NotNull BindingTrace trace
) {
this.descriptorResolver = descriptorResolver;
this.modifiersChecker = modifiersChecker.withTrace(trace);
this.annotationChecker = annotationChecker;
this.trace = trace;
}
public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
for (JetFile file : bodiesResolveContext.getFiles()) {
checkModifiersAndAnnotationsInPackageDirective(file);
AnnotationChecker.INSTANCE$.check(file, trace, null);
annotationChecker.check(file, trace, null);
}
Map<JetClassOrObject, ClassDescriptorWithResolutionScopes> classes = bodiesResolveContext.getDeclaredClasses();
@@ -133,7 +136,7 @@ public class DeclarationsChecker {
}
}
}
AnnotationChecker.INSTANCE$.check(packageDirective, trace, null);
annotationChecker.check(packageDirective, trace, null);
ModifierCheckerCore.INSTANCE$.check(packageDirective, trace, null);
}
@@ -279,7 +282,7 @@ public class DeclarationsChecker {
if (typeParameter != null) {
DescriptorResolver.checkConflictingUpperBounds(trace, typeParameter, jetTypeParameter);
}
AnnotationChecker.INSTANCE$.check(jetTypeParameter, trace, null);
annotationChecker.check(jetTypeParameter, trace, null);
}
}
@@ -192,7 +192,7 @@ public class ModifiersChecker {
checkPlatformNameApplicability(descriptor);
runDeclarationCheckers(modifierListOwner, descriptor);
ClassDescriptor classDescriptor = descriptor instanceof ClassDescriptor ? (ClassDescriptor) descriptor : null;
AnnotationChecker.INSTANCE$.check(modifierListOwner, trace, classDescriptor);
annotationChecker.check(modifierListOwner, trace, classDescriptor);
}
public void checkModifiersForLocalDeclaration(
@@ -201,7 +201,7 @@ public class ModifiersChecker {
) {
checkPlatformNameApplicability(descriptor);
runDeclarationCheckers(modifierListOwner, descriptor);
AnnotationChecker.INSTANCE$.check(modifierListOwner, trace,
annotationChecker.check(modifierListOwner, trace,
descriptor instanceof ClassDescriptor ? (ClassDescriptor) descriptor : null);
ModifierCheckerCore.INSTANCE$.check(modifierListOwner, trace, descriptor);
}
@@ -285,10 +285,14 @@ public class ModifiersChecker {
}
}
@NotNull
private final AnnotationChecker annotationChecker;
@NotNull
private final Iterable<DeclarationChecker> declarationCheckers;
public ModifiersChecker(@NotNull Iterable<DeclarationChecker> declarationCheckers) {
public ModifiersChecker(@NotNull AnnotationChecker annotationChecker, @NotNull Iterable<DeclarationChecker> declarationCheckers) {
this.annotationChecker = annotationChecker;
this.declarationCheckers = declarationCheckers;
}
@@ -33,7 +33,7 @@ public abstract class TargetPlatform(
public abstract val platformConfigurator: PlatformConfigurator
public object Default : TargetPlatform("Default") {
override val platformConfigurator = PlatformConfigurator(DynamicTypesSettings(), listOf(), listOf(), listOf(), listOf())
override val platformConfigurator = PlatformConfigurator(DynamicTypesSettings(), listOf(), listOf(), listOf(), listOf(), listOf())
}
}
@@ -49,7 +49,7 @@ public open class PlatformConfigurator(
additionalCallCheckers: List<CallChecker>,
additionalTypeCheckers: List<AdditionalTypeChecker>,
additionalSymbolUsageValidators: List<SymbolUsageValidator>,
private val additionalAnnotationChecker: AdditionalAnnotationChecker? = null
private val additionalAnnotationCheckers: List<AdditionalAnnotationChecker>
) {
private val declarationCheckers: List<DeclarationChecker> = DEFAULT_DECLARATION_CHECKERS + additionalDeclarationCheckers
@@ -64,7 +64,7 @@ public open class PlatformConfigurator(
callCheckers.forEach { useInstance(it) }
typeCheckers.forEach { useInstance(it) }
useInstance(symbolUsageValidator)
additionalAnnotationCheckers.forEach { useInstance(it) }
}
AnnotationChecker.additionalChecker = additionalAnnotationChecker
}
}
@@ -49,14 +49,17 @@ public class ExpressionTypingServices {
private final ExpressionTypingFacade expressionTypingFacade;
private final ExpressionTypingComponents expressionTypingComponents;
@NotNull AnnotationChecker annotationChecker;
@NotNull private final StatementFilter statementFilter;
public ExpressionTypingServices(
@NotNull ExpressionTypingComponents components,
@NotNull AnnotationChecker annotationChecker,
@NotNull StatementFilter statementFilter,
@NotNull ExpressionTypingVisitorDispatcher.ForDeclarations facade
) {
this.expressionTypingComponents = components;
this.annotationChecker = annotationChecker;
this.statementFilter = statementFilter;
this.expressionTypingFacade = facade;
}
@@ -227,7 +230,8 @@ public class ExpressionTypingServices {
return TypeInfoFactoryPackage.createTypeInfo(expressionTypingComponents.builtIns.getUnitType(), context);
}
ExpressionTypingInternals blockLevelVisitor = new ExpressionTypingVisitorDispatcher.ForBlock(expressionTypingComponents, scope);
ExpressionTypingInternals blockLevelVisitor = new ExpressionTypingVisitorDispatcher.ForBlock(
expressionTypingComponents, annotationChecker, scope);
ExpressionTypingContext newContext = context.replaceScope(scope).replaceExpectedType(NO_EXPECTED_TYPE);
JetTypeInfo result = TypeInfoFactoryPackage.noTypeInfo(context);
@@ -260,7 +264,7 @@ public class ExpressionTypingServices {
newContext = newContext.replaceDataFlowInfo(newDataFlowInfo);
// We take current data flow info if jump there is not possible
}
blockLevelVisitor = new ExpressionTypingVisitorDispatcher.ForBlock(expressionTypingComponents, scope);
blockLevelVisitor = new ExpressionTypingVisitorDispatcher.ForBlock(expressionTypingComponents, annotationChecker, scope);
}
return result.replaceJumpOutPossible(jumpOutPossible).replaceJumpFlowInfo(beforeJumpInfo);
}
@@ -46,8 +46,8 @@ public abstract class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTy
private static final Logger LOG = Logger.getInstance(ExpressionTypingVisitor.class);
public static class ForDeclarations extends ExpressionTypingVisitorDispatcher {
public ForDeclarations(@NotNull ExpressionTypingComponents components) {
super(components);
public ForDeclarations(@NotNull ExpressionTypingComponents components, @NotNull AnnotationChecker annotationChecker) {
super(components, annotationChecker);
}
@Override
@@ -64,9 +64,10 @@ public abstract class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTy
public ForBlock(
@NotNull ExpressionTypingComponents components,
@NotNull AnnotationChecker annotationChecker,
@NotNull WritableScope writableScope
) {
super(components);
super(components, annotationChecker);
this.visitorForBlock = new ExpressionTypingVisitorForStatements(
this, writableScope, basic, controlStructures, patterns, functions
);
@@ -79,15 +80,18 @@ public abstract class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTy
}
private final ExpressionTypingComponents components;
@NotNull private final AnnotationChecker annotationChecker;
protected final BasicExpressionTypingVisitor basic;
protected final FunctionsTypingVisitor functions;
protected final ControlStructureTypingVisitor controlStructures;
protected final PatternMatchingTypingVisitor patterns;
private ExpressionTypingVisitorDispatcher(
@NotNull ExpressionTypingComponents components
@NotNull ExpressionTypingComponents components,
@NotNull AnnotationChecker annotationChecker
) {
this.components = components;
this.annotationChecker = annotationChecker;
this.basic = new BasicExpressionTypingVisitor(this);
this.controlStructures = new ControlStructureTypingVisitor(this);
this.patterns = new PatternMatchingTypingVisitor(this);
@@ -128,7 +132,7 @@ public abstract class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTy
@NotNull
public final JetTypeInfo getTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context) {
JetTypeInfo result = getTypeInfo(expression, context, this);
AnnotationChecker.INSTANCE$.checkExpression(expression, context.trace);
annotationChecker.checkExpression(expression, context.trace);
return result;
}
@@ -27,7 +27,8 @@ public object JsPlatformConfigurator : PlatformConfigurator(
additionalDeclarationCheckers = listOf(NativeInvokeChecker(), NativeGetterChecker(), NativeSetterChecker(), ClassDeclarationChecker()),
additionalCallCheckers = listOf(),
additionalTypeCheckers = listOf(),
additionalSymbolUsageValidators = listOf()
additionalSymbolUsageValidators = listOf(),
additionalAnnotationCheckers = listOf()
) {
override fun configure(container: StorageComponentContainer) {
super.configure(container)