Using of enum entries as types is now forbidden #KT-5401 Fixed
This commit is contained in:
@@ -655,6 +655,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory0<KtSimpleNameExpression> CAST_NEVER_SUCCEEDS = DiagnosticFactory0.create(WARNING);
|
DiagnosticFactory0<KtSimpleNameExpression> CAST_NEVER_SUCCEEDS = DiagnosticFactory0.create(WARNING);
|
||||||
DiagnosticFactory0<KtTypeReference> DYNAMIC_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<KtTypeReference> DYNAMIC_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<KtTypeReference> IS_ENUM_ENTRY = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<KtTypeReference> IS_ENUM_ENTRY = DiagnosticFactory0.create(ERROR);
|
||||||
|
DiagnosticFactory0<KtTypeReference> ENUM_ENTRY_AS_TYPE = DiagnosticFactory0.create(ERROR);
|
||||||
|
|
||||||
DiagnosticFactory1<KtExpression, KotlinType> IMPLICIT_CAST_TO_UNIT_OR_ANY = DiagnosticFactory1.create(WARNING);
|
DiagnosticFactory1<KtExpression, KotlinType> IMPLICIT_CAST_TO_UNIT_OR_ANY = DiagnosticFactory1.create(WARNING);
|
||||||
|
|
||||||
|
|||||||
+1
@@ -320,6 +320,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(CAST_NEVER_SUCCEEDS, "This cast can never succeed");
|
MAP.put(CAST_NEVER_SUCCEEDS, "This cast can never succeed");
|
||||||
MAP.put(DYNAMIC_NOT_ALLOWED, "Dynamic types are not allowed in this position");
|
MAP.put(DYNAMIC_NOT_ALLOWED, "Dynamic types are not allowed in this position");
|
||||||
MAP.put(IS_ENUM_ENTRY, "'is' over enum entry is not allowed, use comparison instead");
|
MAP.put(IS_ENUM_ENTRY, "'is' over enum entry is not allowed, use comparison instead");
|
||||||
|
MAP.put(ENUM_ENTRY_AS_TYPE, "Use of enum entry names as types is not allowed, use enum type instead");
|
||||||
MAP.put(USELESS_NULLABLE_CHECK, "Non-null type is checked for instance of nullable type");
|
MAP.put(USELESS_NULLABLE_CHECK, "Non-null type is checked for instance of nullable type");
|
||||||
MAP.put(WRONG_SETTER_PARAMETER_TYPE, "Setter parameter type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
|
MAP.put(WRONG_SETTER_PARAMETER_TYPE, "Setter parameter type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
|
||||||
MAP.put(WRONG_GETTER_RETURN_TYPE, "Getter return type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
|
MAP.put(WRONG_GETTER_RETURN_TYPE, "Getter return type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
|
||||||
|
|||||||
@@ -141,7 +141,8 @@ public class BodyResolver {
|
|||||||
new Function1<LexicalScope, DataFlowInfo>() {
|
new Function1<LexicalScope, DataFlowInfo>() {
|
||||||
@Override
|
@Override
|
||||||
public DataFlowInfo invoke(@NotNull LexicalScope headerInnerScope) {
|
public DataFlowInfo invoke(@NotNull LexicalScope headerInnerScope) {
|
||||||
return resolveSecondaryConstructorDelegationCall(outerDataFlowInfo, trace, headerInnerScope, constructor, descriptor,
|
return resolveSecondaryConstructorDelegationCall(outerDataFlowInfo, trace, headerInnerScope,
|
||||||
|
constructor, descriptor,
|
||||||
callChecker);
|
callChecker);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -187,9 +188,9 @@ public class BodyResolver {
|
|||||||
|
|
||||||
// if next delegation call is super or primary constructor or already visited
|
// if next delegation call is super or primary constructor or already visited
|
||||||
if (!constructorDescriptor.getContainingDeclaration().equals(delegatedConstructorDescriptor.getContainingDeclaration()) ||
|
if (!constructorDescriptor.getContainingDeclaration().equals(delegatedConstructorDescriptor.getContainingDeclaration()) ||
|
||||||
delegatedConstructorDescriptor.isPrimary() ||
|
delegatedConstructorDescriptor.isPrimary() ||
|
||||||
visitedConstructors.contains(delegatedConstructorDescriptor)) {
|
visitedConstructors.contains(delegatedConstructorDescriptor)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (visitedInCurrentChain.contains(delegatedConstructorDescriptor)) {
|
if (visitedInCurrentChain.contains(delegatedConstructorDescriptor)) {
|
||||||
@@ -214,7 +215,8 @@ public class BodyResolver {
|
|||||||
|
|
||||||
currentConstructor = getDelegatedConstructor(currentConstructor);
|
currentConstructor = getDelegatedConstructor(currentConstructor);
|
||||||
assert currentConstructor != null : "Delegated constructor should not be null in cycle";
|
assert currentConstructor != null : "Delegated constructor should not be null in cycle";
|
||||||
} while (startConstructor != currentConstructor);
|
}
|
||||||
|
while (startConstructor != currentConstructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -251,7 +253,8 @@ public class BodyResolver {
|
|||||||
@NotNull LexicalScope scopeForSupertypeResolution,
|
@NotNull LexicalScope scopeForSupertypeResolution,
|
||||||
@NotNull final LexicalScope scopeForMemberResolution
|
@NotNull final LexicalScope scopeForMemberResolution
|
||||||
) {
|
) {
|
||||||
final LexicalScope scopeForConstructor = primaryConstructor == null
|
final LexicalScope scopeForConstructor =
|
||||||
|
primaryConstructor == null
|
||||||
? null
|
? null
|
||||||
: FunctionDescriptorUtil.getFunctionInnerScope(scopeForSupertypeResolution, primaryConstructor, trace);
|
: FunctionDescriptorUtil.getFunctionInnerScope(scopeForSupertypeResolution, primaryConstructor, trace);
|
||||||
final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow
|
final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow
|
||||||
@@ -477,7 +480,9 @@ public class BodyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (classDescriptor != null && classDescriptor.getKind().isSingleton()) {
|
if (classDescriptor != null && classDescriptor.getKind().isSingleton()) {
|
||||||
trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference));
|
if (!DescriptorUtils.isEnumEntry(classDescriptor)) {
|
||||||
|
trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) {
|
else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) {
|
||||||
if (classDescriptor.getModality() == Modality.SEALED) {
|
if (classDescriptor.getModality() == Modality.SEALED) {
|
||||||
@@ -565,7 +570,8 @@ public class BodyResolver {
|
|||||||
new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
|
new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
|
||||||
@Override
|
@Override
|
||||||
public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
|
public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
|
||||||
for (ValueParameterDescriptor valueParameterDescriptor : unsubstitutedPrimaryConstructor.getValueParameters()) {
|
for (ValueParameterDescriptor
|
||||||
|
valueParameterDescriptor : unsubstitutedPrimaryConstructor.getValueParameters()) {
|
||||||
handler.addVariableDescriptor(valueParameterDescriptor);
|
handler.addVariableDescriptor(valueParameterDescriptor);
|
||||||
}
|
}
|
||||||
return Unit.INSTANCE$;
|
return Unit.INSTANCE$;
|
||||||
@@ -662,11 +668,19 @@ public class BodyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ObservableBindingTrace createFieldTrackingTrace(final PropertyDescriptor propertyDescriptor) {
|
private ObservableBindingTrace createFieldTrackingTrace(final PropertyDescriptor propertyDescriptor) {
|
||||||
return new ObservableBindingTrace(trace).addHandler(BindingContext.REFERENCE_TARGET, new ObservableBindingTrace.RecordHandler<KtReferenceExpression, DeclarationDescriptor>() {
|
return new ObservableBindingTrace(trace).addHandler(
|
||||||
|
BindingContext.REFERENCE_TARGET,
|
||||||
|
new ObservableBindingTrace.RecordHandler<KtReferenceExpression, DeclarationDescriptor>() {
|
||||||
@Override
|
@Override
|
||||||
public void handleRecord(WritableSlice<KtReferenceExpression, DeclarationDescriptor> slice, KtReferenceExpression expression, DeclarationDescriptor descriptor) {
|
public void handleRecord(
|
||||||
if (expression instanceof KtSimpleNameExpression && descriptor instanceof SyntheticFieldDescriptor) {
|
WritableSlice<KtReferenceExpression, DeclarationDescriptor> slice,
|
||||||
trace.record(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
|
KtReferenceExpression expression,
|
||||||
|
DeclarationDescriptor descriptor
|
||||||
|
) {
|
||||||
|
if (expression instanceof KtSimpleNameExpression &&
|
||||||
|
descriptor instanceof SyntheticFieldDescriptor) {
|
||||||
|
trace.record(BindingContext.BACKING_FIELD_REQUIRED,
|
||||||
|
propertyDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -858,7 +872,11 @@ public class BodyResolver {
|
|||||||
final Queue<DeferredType> queue = new Queue<DeferredType>(deferredTypes.size() + 1);
|
final Queue<DeferredType> queue = new Queue<DeferredType>(deferredTypes.size() + 1);
|
||||||
trace.addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler<Box<DeferredType>, Boolean>() {
|
trace.addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler<Box<DeferredType>, Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void handleRecord(WritableSlice<Box<DeferredType>, Boolean> deferredTypeKeyDeferredTypeWritableSlice, Box<DeferredType> key, Boolean value) {
|
public void handleRecord(
|
||||||
|
WritableSlice<Box<DeferredType>, Boolean> deferredTypeKeyDeferredTypeWritableSlice,
|
||||||
|
Box<DeferredType> key,
|
||||||
|
Boolean value
|
||||||
|
) {
|
||||||
queue.addLast(key.getData());
|
queue.addLast(key.getData());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,6 +37,35 @@ import org.jetbrains.kotlin.resolve.BindingContext.TYPE_PARAMETER
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers
|
||||||
|
|
||||||
|
fun KtDeclaration.checkTypeReferences(trace: BindingTrace) {
|
||||||
|
if (this is KtCallableDeclaration) {
|
||||||
|
typeReference?.checkNotEnumEntry(trace)
|
||||||
|
receiverTypeReference?.checkNotEnumEntry(trace)
|
||||||
|
}
|
||||||
|
if (this is KtDeclarationWithBody) {
|
||||||
|
for (parameter in valueParameters) {
|
||||||
|
parameter.typeReference?.checkNotEnumEntry(trace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KtTypeReference.checkNotEnumEntry(trace: BindingTrace): Boolean {
|
||||||
|
var result = false
|
||||||
|
trace.bindingContext.get(TYPE, this)?.let {
|
||||||
|
val targetDescriptor = TypeUtils.getClassDescriptor(it)
|
||||||
|
if (targetDescriptor != null && DescriptorUtils.isEnumEntry(targetDescriptor)) {
|
||||||
|
trace.report(ENUM_ENTRY_AS_TYPE.on(this))
|
||||||
|
result = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typeElement?.let {
|
||||||
|
for (typeArgument in it.typeArgumentsAsTypes) {
|
||||||
|
typeArgument?.checkNotEnumEntry(trace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
class DeclarationsChecker(
|
class DeclarationsChecker(
|
||||||
private val descriptorResolver: DescriptorResolver,
|
private val descriptorResolver: DescriptorResolver,
|
||||||
modifiersChecker: ModifiersChecker,
|
modifiersChecker: ModifiersChecker,
|
||||||
@@ -46,6 +75,8 @@ class DeclarationsChecker(
|
|||||||
|
|
||||||
private val modifiersChecker = modifiersChecker.withTrace(trace)
|
private val modifiersChecker = modifiersChecker.withTrace(trace)
|
||||||
|
|
||||||
|
fun KtDeclaration.checkTypeReferences() = checkTypeReferences(trace)
|
||||||
|
|
||||||
fun process(bodiesResolveContext: BodiesResolveContext) {
|
fun process(bodiesResolveContext: BodiesResolveContext) {
|
||||||
for (file in bodiesResolveContext.files) {
|
for (file in bodiesResolveContext.files) {
|
||||||
checkModifiersAndAnnotationsInPackageDirective(file)
|
checkModifiersAndAnnotationsInPackageDirective(file)
|
||||||
@@ -69,6 +100,7 @@ class DeclarationsChecker(
|
|||||||
|
|
||||||
checkPrimaryConstructor(classOrObject, classDescriptor)
|
checkPrimaryConstructor(classOrObject, classDescriptor)
|
||||||
|
|
||||||
|
classOrObject.checkTypeReferences()
|
||||||
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor)
|
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor)
|
||||||
identifierChecker.checkDeclaration(classOrObject, trace)
|
identifierChecker.checkDeclaration(classOrObject, trace)
|
||||||
checkClassExposedType(classOrObject, classDescriptor)
|
checkClassExposedType(classOrObject, classDescriptor)
|
||||||
@@ -76,12 +108,14 @@ class DeclarationsChecker(
|
|||||||
|
|
||||||
for ((function, functionDescriptor) in bodiesResolveContext.functions.entries) {
|
for ((function, functionDescriptor) in bodiesResolveContext.functions.entries) {
|
||||||
checkFunction(function, functionDescriptor)
|
checkFunction(function, functionDescriptor)
|
||||||
|
function.checkTypeReferences()
|
||||||
modifiersChecker.checkModifiersForDeclaration(function, functionDescriptor)
|
modifiersChecker.checkModifiersForDeclaration(function, functionDescriptor)
|
||||||
identifierChecker.checkDeclaration(function, trace)
|
identifierChecker.checkDeclaration(function, trace)
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((property, propertyDescriptor) in bodiesResolveContext.properties.entries) {
|
for ((property, propertyDescriptor) in bodiesResolveContext.properties.entries) {
|
||||||
checkProperty(property, propertyDescriptor)
|
checkProperty(property, propertyDescriptor)
|
||||||
|
property.checkTypeReferences()
|
||||||
modifiersChecker.checkModifiersForDeclaration(property, propertyDescriptor)
|
modifiersChecker.checkModifiersForDeclaration(property, propertyDescriptor)
|
||||||
identifierChecker.checkDeclaration(property, trace)
|
identifierChecker.checkDeclaration(property, trace)
|
||||||
}
|
}
|
||||||
@@ -93,6 +127,7 @@ class DeclarationsChecker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkConstructorDeclaration(constructorDescriptor: ConstructorDescriptor, declaration: KtDeclaration) {
|
private fun checkConstructorDeclaration(constructorDescriptor: ConstructorDescriptor, declaration: KtDeclaration) {
|
||||||
|
declaration.checkTypeReferences()
|
||||||
modifiersChecker.checkModifiersForDeclaration(declaration, constructorDescriptor)
|
modifiersChecker.checkModifiersForDeclaration(declaration, constructorDescriptor)
|
||||||
identifierChecker.checkDeclaration(declaration, trace)
|
identifierChecker.checkDeclaration(declaration, trace)
|
||||||
}
|
}
|
||||||
@@ -113,19 +148,17 @@ class DeclarationsChecker(
|
|||||||
|
|
||||||
private fun checkTypesInClassHeader(classOrObject: KtClassOrObject) {
|
private fun checkTypesInClassHeader(classOrObject: KtClassOrObject) {
|
||||||
for (delegationSpecifier in classOrObject.getDelegationSpecifiers()) {
|
for (delegationSpecifier in classOrObject.getDelegationSpecifiers()) {
|
||||||
delegationSpecifier.typeReference?.checkBoundsForTypeInClassHeader()
|
delegationSpecifier.typeReference?.check(checkBoundsForTypeInClassHeader = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classOrObject !is KtClass) return
|
if (classOrObject !is KtClass) return
|
||||||
|
|
||||||
for (jetTypeParameter in classOrObject.typeParameters) {
|
for (jetTypeParameter in classOrObject.typeParameters) {
|
||||||
jetTypeParameter.extendsBound?.checkBoundsForTypeInClassHeader()
|
jetTypeParameter.extendsBound?.check(checkBoundsForTypeInClassHeader = true, checkFinalUpperBounds = true)
|
||||||
jetTypeParameter.extendsBound?.checkFinalUpperBounds()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (constraint in classOrObject.typeConstraints) {
|
for (constraint in classOrObject.typeConstraints) {
|
||||||
constraint.boundTypeReference?.checkBoundsForTypeInClassHeader()
|
constraint.boundTypeReference?.check(checkBoundsForTypeInClassHeader = true, checkFinalUpperBounds = true)
|
||||||
constraint.boundTypeReference?.checkFinalUpperBounds()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +170,18 @@ class DeclarationsChecker(
|
|||||||
trace.bindingContext.get(TYPE, this)?.let { DescriptorResolver.checkUpperBoundType(this, it, trace) }
|
trace.bindingContext.get(TYPE, this)?.let { DescriptorResolver.checkUpperBoundType(this, it, trace) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtTypeReference.check(checkBoundsForTypeInClassHeader: Boolean = false, checkFinalUpperBounds: Boolean = false) {
|
||||||
|
if (checkFinalUpperBounds) {
|
||||||
|
checkFinalUpperBounds()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
checkNotEnumEntry(trace)
|
||||||
|
}
|
||||||
|
if (checkBoundsForTypeInClassHeader) {
|
||||||
|
checkBoundsForTypeInClassHeader()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkSupertypesForConsistency(
|
private fun checkSupertypesForConsistency(
|
||||||
classifierDescriptor: ClassifierDescriptor,
|
classifierDescriptor: ClassifierDescriptor,
|
||||||
sourceElement: PsiElement) {
|
sourceElement: PsiElement) {
|
||||||
@@ -151,7 +196,7 @@ class DeclarationsChecker(
|
|||||||
removeDuplicateTypes(conflictingTypes)
|
removeDuplicateTypes(conflictingTypes)
|
||||||
if (conflictingTypes.size > 1) {
|
if (conflictingTypes.size > 1) {
|
||||||
val containingDeclaration = typeParameterDescriptor.containingDeclaration as? ClassDescriptor
|
val containingDeclaration = typeParameterDescriptor.containingDeclaration as? ClassDescriptor
|
||||||
?: throw AssertionError("Not a class descriptor : " + typeParameterDescriptor.containingDeclaration)
|
?: throw AssertionError("Not a class descriptor : " + typeParameterDescriptor.containingDeclaration)
|
||||||
if (sourceElement is KtClassOrObject) {
|
if (sourceElement is KtClassOrObject) {
|
||||||
val delegationSpecifierList = sourceElement.getDelegationSpecifierList() ?: continue
|
val delegationSpecifierList = sourceElement.getDelegationSpecifierList() ?: continue
|
||||||
trace.report(INCONSISTENT_TYPE_PARAMETER_VALUES.on(delegationSpecifierList,
|
trace.report(INCONSISTENT_TYPE_PARAMETER_VALUES.on(delegationSpecifierList,
|
||||||
@@ -593,6 +638,7 @@ class DeclarationsChecker(
|
|||||||
for (accessor in property.accessors) {
|
for (accessor in property.accessors) {
|
||||||
val propertyAccessorDescriptor = (if (accessor.isGetter) propertyDescriptor.getter else propertyDescriptor.setter)
|
val propertyAccessorDescriptor = (if (accessor.isGetter) propertyDescriptor.getter else propertyDescriptor.setter)
|
||||||
?: throw AssertionError("No property accessor descriptor for ${property.text}")
|
?: throw AssertionError("No property accessor descriptor for ${property.text}")
|
||||||
|
accessor.checkTypeReferences()
|
||||||
modifiersChecker.checkModifiersForDeclaration(accessor, propertyAccessorDescriptor)
|
modifiersChecker.checkModifiersForDeclaration(accessor, propertyAccessorDescriptor)
|
||||||
identifierChecker.checkDeclaration(accessor, trace)
|
identifierChecker.checkDeclaration(accessor, trace)
|
||||||
}
|
}
|
||||||
@@ -613,7 +659,7 @@ class DeclarationsChecker(
|
|||||||
if (accessor == null || accessorDescriptor == null) return
|
if (accessor == null || accessorDescriptor == null) return
|
||||||
val accessorModifierList = accessor.modifierList ?: return
|
val accessorModifierList = accessor.modifierList ?: return
|
||||||
val tokens = modifiersChecker.getTokensCorrespondingToModifiers(accessorModifierList,
|
val tokens = modifiersChecker.getTokensCorrespondingToModifiers(accessorModifierList,
|
||||||
Sets.newHashSet(KtTokens.PUBLIC_KEYWORD, KtTokens.PROTECTED_KEYWORD, KtTokens.PRIVATE_KEYWORD, KtTokens.INTERNAL_KEYWORD))
|
Sets.newHashSet(KtTokens.PUBLIC_KEYWORD, KtTokens.PROTECTED_KEYWORD, KtTokens.PRIVATE_KEYWORD, KtTokens.INTERNAL_KEYWORD))
|
||||||
if (accessor.isGetter) {
|
if (accessor.isGetter) {
|
||||||
if (accessorDescriptor.visibility != propertyDescriptor.visibility) {
|
if (accessorDescriptor.visibility != propertyDescriptor.visibility) {
|
||||||
reportVisibilityModifierDiagnostics(tokens.values, Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY)
|
reportVisibilityModifierDiagnostics(tokens.values, Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY)
|
||||||
|
|||||||
@@ -579,6 +579,7 @@ public class DescriptorResolver {
|
|||||||
@NotNull KotlinType upperBoundType,
|
@NotNull KotlinType upperBoundType,
|
||||||
BindingTrace trace
|
BindingTrace trace
|
||||||
) {
|
) {
|
||||||
|
if (DeclarationsCheckerKt.checkNotEnumEntry(upperBound, trace)) return;
|
||||||
if (!TypeUtils.canHaveSubtypes(KotlinTypeChecker.DEFAULT, upperBoundType)) {
|
if (!TypeUtils.canHaveSubtypes(KotlinTypeChecker.DEFAULT, upperBoundType)) {
|
||||||
ClassifierDescriptor descriptor = upperBoundType.getConstructor().getDeclarationDescriptor();
|
ClassifierDescriptor descriptor = upperBoundType.getConstructor().getDeclarationDescriptor();
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
|
|||||||
+2
@@ -237,6 +237,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
) {
|
) {
|
||||||
if (actualType == null || noExpectedType(targetType) || targetType.isError()) return;
|
if (actualType == null || noExpectedType(targetType) || targetType.isError()) return;
|
||||||
|
|
||||||
|
DeclarationsCheckerKt.checkNotEnumEntry(expression.getRight(), context.trace);
|
||||||
|
|
||||||
if (DynamicTypesKt.isDynamic(targetType)) {
|
if (DynamicTypesKt.isDynamic(targetType)) {
|
||||||
KtTypeReference right = expression.getRight();
|
KtTypeReference right = expression.getRight();
|
||||||
assert right != null : "We know target is dynamic, but RHS is missing";
|
assert right != null : "We know target is dynamic, but RHS is missing";
|
||||||
|
|||||||
+2
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.diagnostics.Errors;
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
|
import org.jetbrains.kotlin.resolve.DeclarationsCheckerKt;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
|
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache;
|
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache;
|
||||||
@@ -155,6 +156,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
ExpressionTypingUtils.checkVariableShadowing(context.scope, context.trace, propertyDescriptor);
|
ExpressionTypingUtils.checkVariableShadowing(context.scope, context.trace, propertyDescriptor);
|
||||||
|
|
||||||
scope.addVariableDescriptor(propertyDescriptor);
|
scope.addVariableDescriptor(propertyDescriptor);
|
||||||
|
DeclarationsCheckerKt.checkTypeReferences(property, context.trace);
|
||||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(property, propertyDescriptor);
|
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(property, propertyDescriptor);
|
||||||
components.identifierChecker.checkDeclaration(property, context.trace);
|
components.identifierChecker.checkDeclaration(property, context.trace);
|
||||||
return typeInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(property, context));
|
return typeInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(property, context));
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
|||||||
function.getValueParameters(), functionDescriptor.getValueParameters(), context.scope, context.dataFlowInfo, context.trace
|
function.getValueParameters(), functionDescriptor.getValueParameters(), context.scope, context.dataFlowInfo, context.trace
|
||||||
)
|
)
|
||||||
|
|
||||||
|
function.checkTypeReferences(context.trace)
|
||||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(function, functionDescriptor)
|
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(function, functionDescriptor)
|
||||||
components.identifierChecker.checkDeclaration(function, context.trace)
|
components.identifierChecker.checkDeclaration(function, context.trace)
|
||||||
if (!function.hasBody() && !function.hasModifier(KtTokens.EXTERNAL_KEYWORD)) {
|
if (!function.hasBody() && !function.hasModifier(KtTokens.EXTERNAL_KEYWORD)) {
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
enum class Color { RED }
|
||||||
|
|
||||||
|
class MyColor(val x: <!ENUM_ENTRY_AS_TYPE!>Color.RED<!>, y: <!ENUM_ENTRY_AS_TYPE!>Color.RED<!>) : <!ENUM_ENTRY_AS_TYPE!>Color.RED<!> {
|
||||||
|
|
||||||
|
var z: <!ENUM_ENTRY_AS_TYPE!>Color.RED<!> = <!TYPE_MISMATCH!>Color.RED<!>
|
||||||
|
set(arg: <!ENUM_ENTRY_AS_TYPE!>Color.RED<!>) { z = arg }
|
||||||
|
|
||||||
|
fun foo(arg: <!ENUM_ENTRY_AS_TYPE!>Color.RED<!>): <!ENUM_ENTRY_AS_TYPE!>Color.RED<!> = arg
|
||||||
|
|
||||||
|
fun bar(): <!ENUM_ENTRY_AS_TYPE!>Color.RED<!> {
|
||||||
|
class Local : <!ENUM_ENTRY_AS_TYPE!>Color.RED<!>
|
||||||
|
fun local(arg: <!ENUM_ENTRY_AS_TYPE!>Color.RED<!>): <!ENUM_ENTRY_AS_TYPE!>Color.RED<!> = arg
|
||||||
|
val temp: <!ENUM_ENTRY_AS_TYPE!>Color.RED<!> = <!TYPE_MISMATCH!>Color.RED<!>
|
||||||
|
temp <!USELESS_CAST!>as? <!ENUM_ENTRY_AS_TYPE!>Color.RED<!><!>
|
||||||
|
if (temp is <!IS_ENUM_ENTRY!>Color.RED<!>) {
|
||||||
|
return temp <!USELESS_CAST!>as <!ENUM_ENTRY_AS_TYPE!>Color.RED<!><!>
|
||||||
|
}
|
||||||
|
val obj = object : <!ENUM_ENTRY_AS_TYPE!>Color.RED<!> {}
|
||||||
|
if (obj is <!IS_ENUM_ENTRY!>Color.RED<!>) {
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
return <!TYPE_MISMATCH!>Color.RED<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(): Array<<!ENUM_ENTRY_AS_TYPE!>Color.RED<!>>? = null
|
||||||
|
|
||||||
|
interface Your<T : <!ENUM_ENTRY_AS_TYPE!>Color.RED<!>>
|
||||||
|
|
||||||
|
class His : Your<<!ENUM_ENTRY_AS_TYPE!>Color.RED<!>>
|
||||||
|
|
||||||
|
fun <T : <!ENUM_ENTRY_AS_TYPE!>Color.RED<!>> otherCreate(): Array<T>? = null
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun create(): kotlin.Array<Color.RED>?
|
||||||
|
public fun </*0*/ T : Color.RED> otherCreate(): kotlin.Array<T>?
|
||||||
|
|
||||||
|
public final enum class Color : kotlin.Enum<Color> {
|
||||||
|
enum entry RED
|
||||||
|
|
||||||
|
private constructor Color()
|
||||||
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Color): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
@kotlin.Deprecated(message = "Use 'values()' function instead", replaceWith = kotlin.ReplaceWith(expression = "this.values()", imports = {})) public final /*synthesized*/ val values: kotlin.Array<Color>
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Color
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<Color>
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class His : Your<Color.RED> {
|
||||||
|
public constructor His()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class MyColor : Color.RED {
|
||||||
|
public constructor MyColor(/*0*/ x: Color.RED, /*1*/ y: Color.RED)
|
||||||
|
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||||
|
public final val x: Color.RED
|
||||||
|
public final var z: Color.RED
|
||||||
|
public final fun bar(): Color.RED
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Color): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(/*0*/ arg: Color.RED): Color.RED
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Your</*0*/ T : Color.RED> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -2,4 +2,4 @@ enum class E {
|
|||||||
ENTRY
|
ENTRY
|
||||||
}
|
}
|
||||||
|
|
||||||
class A : <!SINGLETON_IN_SUPERTYPE!>E.ENTRY<!>
|
class A : <!ENUM_ENTRY_AS_TYPE!>E.ENTRY<!>
|
||||||
|
|||||||
@@ -235,6 +235,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("EnumEntryAsType.kt")
|
||||||
|
public void testEnumEntryAsType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/EnumEntryAsType.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("fileDependencyRecursion.kt")
|
@TestMetadata("fileDependencyRecursion.kt")
|
||||||
public void testFileDependencyRecursion() throws Exception {
|
public void testFileDependencyRecursion() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/fileDependencyRecursion.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/fileDependencyRecursion.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user