Refactor ModifiersChecker to be more component-like
A couple of minor prettifications
This commit is contained in:
@@ -54,6 +54,7 @@ import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
|
|||||||
|
|
||||||
public class BodyResolver {
|
public class BodyResolver {
|
||||||
@NotNull private final ScriptBodyResolver scriptBodyResolverResolver;
|
@NotNull private final ScriptBodyResolver scriptBodyResolverResolver;
|
||||||
|
@NotNull private final ModifiersChecker modifiersChecker;
|
||||||
@NotNull private final ExpressionTypingServices expressionTypingServices;
|
@NotNull private final ExpressionTypingServices expressionTypingServices;
|
||||||
@NotNull private final CallResolver callResolver;
|
@NotNull private final CallResolver callResolver;
|
||||||
@NotNull private final ObservableBindingTrace trace;
|
@NotNull private final ObservableBindingTrace trace;
|
||||||
@@ -78,7 +79,8 @@ public class BodyResolver {
|
|||||||
@NotNull FunctionAnalyzerExtension functionAnalyzerExtension,
|
@NotNull FunctionAnalyzerExtension functionAnalyzerExtension,
|
||||||
@NotNull ScriptBodyResolver scriptBodyResolverResolver,
|
@NotNull ScriptBodyResolver scriptBodyResolverResolver,
|
||||||
@NotNull BindingTrace trace,
|
@NotNull BindingTrace trace,
|
||||||
@NotNull ValueParameterResolver valueParameterResolver
|
@NotNull ValueParameterResolver valueParameterResolver,
|
||||||
|
@NotNull ModifiersChecker modifiersChecker
|
||||||
) {
|
) {
|
||||||
this.additionalCheckerProvider = additionalCheckerProvider;
|
this.additionalCheckerProvider = additionalCheckerProvider;
|
||||||
this.annotationResolver = annotationResolver;
|
this.annotationResolver = annotationResolver;
|
||||||
@@ -90,6 +92,7 @@ public class BodyResolver {
|
|||||||
this.expressionTypingServices = expressionTypingServices;
|
this.expressionTypingServices = expressionTypingServices;
|
||||||
this.functionAnalyzerExtension = functionAnalyzerExtension;
|
this.functionAnalyzerExtension = functionAnalyzerExtension;
|
||||||
this.scriptBodyResolverResolver = scriptBodyResolverResolver;
|
this.scriptBodyResolverResolver = scriptBodyResolverResolver;
|
||||||
|
this.modifiersChecker = modifiersChecker;
|
||||||
this.trace = new ObservableBindingTrace(trace);
|
this.trace = new ObservableBindingTrace(trace);
|
||||||
this.valueParameterResolver = valueParameterResolver;
|
this.valueParameterResolver = valueParameterResolver;
|
||||||
}
|
}
|
||||||
@@ -512,7 +515,7 @@ public class BodyResolver {
|
|||||||
|
|
||||||
annotationResolver.resolveAnnotationsWithArguments(scope, modifierList, trace);
|
annotationResolver.resolveAnnotationsWithArguments(scope, modifierList, trace);
|
||||||
|
|
||||||
ModifiersChecker.reportIllegalModifiers(modifierList, Arrays.asList(JetTokens.MODIFIER_KEYWORDS_ARRAY), trace);
|
modifiersChecker.withTrace(trace).reportIllegalModifiers(modifierList, Arrays.asList(JetTokens.MODIFIER_KEYWORDS_ARRAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolvePrimaryConstructorParameters(@NotNull BodiesResolveContext c) {
|
private void resolvePrimaryConstructorParameters(@NotNull BodiesResolveContext c) {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembe
|
|||||||
|
|
||||||
public class DeclarationsChecker {
|
public class DeclarationsChecker {
|
||||||
@NotNull private final BindingTrace trace;
|
@NotNull private final BindingTrace trace;
|
||||||
@NotNull private final ModifiersChecker modifiersChecker;
|
@NotNull private final ModifiersChecker.ModifiersCheckingProcedure modifiersChecker;
|
||||||
@NotNull private final DescriptorResolver descriptorResolver;
|
@NotNull private final DescriptorResolver descriptorResolver;
|
||||||
|
|
||||||
public DeclarationsChecker(
|
public DeclarationsChecker(
|
||||||
@@ -54,7 +54,7 @@ public class DeclarationsChecker {
|
|||||||
@NotNull BindingTrace trace
|
@NotNull BindingTrace trace
|
||||||
) {
|
) {
|
||||||
this.descriptorResolver = descriptorResolver;
|
this.descriptorResolver = descriptorResolver;
|
||||||
this.modifiersChecker = modifiersChecker;
|
this.modifiersChecker = modifiersChecker.withTrace(trace);
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ public class DeclarationsChecker {
|
|||||||
}
|
}
|
||||||
AnnotationTargetChecker.INSTANCE$.check(packageDirective, trace, null);
|
AnnotationTargetChecker.INSTANCE$.check(packageDirective, trace, null);
|
||||||
|
|
||||||
ModifiersChecker.reportIllegalModifiers(modifierList, Arrays.asList(JetTokens.MODIFIER_KEYWORDS_ARRAY), trace);
|
modifiersChecker.reportIllegalModifiers(modifierList, Arrays.asList(JetTokens.MODIFIER_KEYWORDS_ARRAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkTypesInClassHeader(@NotNull JetClassOrObject classOrObject) {
|
private void checkTypesInClassHeader(@NotNull JetClassOrObject classOrObject) {
|
||||||
@@ -532,7 +532,7 @@ public class DeclarationsChecker {
|
|||||||
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
|
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
|
||||||
JetModifierList getterModifierList = getter != null ? getter.getModifierList() : null;
|
JetModifierList getterModifierList = getter != null ? getter.getModifierList() : null;
|
||||||
if (getterModifierList != null && getterDescriptor != null) {
|
if (getterModifierList != null && getterDescriptor != null) {
|
||||||
Map<JetModifierKeywordToken, ASTNode> nodes = ModifiersChecker.getNodesCorrespondingToModifiers(getterModifierList, Sets
|
Map<JetModifierKeywordToken, ASTNode> nodes = modifiersChecker.getNodesCorrespondingToModifiers(getterModifierList, Sets
|
||||||
.newHashSet(JetTokens.PUBLIC_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PRIVATE_KEYWORD,
|
.newHashSet(JetTokens.PUBLIC_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PRIVATE_KEYWORD,
|
||||||
JetTokens.INTERNAL_KEYWORD));
|
JetTokens.INTERNAL_KEYWORD));
|
||||||
if (getterDescriptor.getVisibility() != propertyDescriptor.getVisibility()) {
|
if (getterDescriptor.getVisibility() != propertyDescriptor.getVisibility()) {
|
||||||
|
|||||||
@@ -61,12 +61,6 @@ import static org.jetbrains.kotlin.resolve.source.SourcePackage.toSourceElement;
|
|||||||
|
|
||||||
public class DescriptorResolver {
|
public class DescriptorResolver {
|
||||||
public static final Name COPY_METHOD_NAME = Name.identifier("copy");
|
public static final Name COPY_METHOD_NAME = Name.identifier("copy");
|
||||||
private static final Set<JetModifierKeywordToken> MODIFIERS_ILLEGAL_ON_PARAMETERS;
|
|
||||||
static {
|
|
||||||
MODIFIERS_ILLEGAL_ON_PARAMETERS = Sets.newHashSet();
|
|
||||||
MODIFIERS_ILLEGAL_ON_PARAMETERS.addAll(Arrays.asList(JetTokens.MODIFIER_KEYWORDS_ARRAY));
|
|
||||||
MODIFIERS_ILLEGAL_ON_PARAMETERS.remove(JetTokens.VARARG_KEYWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull private final TypeResolver typeResolver;
|
@NotNull private final TypeResolver typeResolver;
|
||||||
@NotNull private final AnnotationResolver annotationResolver;
|
@NotNull private final AnnotationResolver annotationResolver;
|
||||||
@@ -1165,24 +1159,6 @@ public class DescriptorResolver {
|
|||||||
return getParentOfType(scope.getContainingDeclaration(), ClassDescriptor.class, false);
|
return getParentOfType(scope.getContainingDeclaration(), ClassDescriptor.class, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkParameterHasNoValOrVar(
|
|
||||||
@NotNull BindingTrace trace,
|
|
||||||
@NotNull JetParameter parameter,
|
|
||||||
@NotNull DiagnosticFactory1<PsiElement, JetKeywordToken> diagnosticFactory
|
|
||||||
) {
|
|
||||||
PsiElement valOrVar = parameter.getValOrVarKeyword();
|
|
||||||
if (valOrVar != null) {
|
|
||||||
trace.report(diagnosticFactory.on(valOrVar, ((JetKeywordToken) valOrVar.getNode().getElementType())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void checkParameterHasNoModifier(
|
|
||||||
@NotNull BindingTrace trace,
|
|
||||||
@NotNull JetParameter parameter
|
|
||||||
) {
|
|
||||||
ModifiersChecker.reportIllegalModifiers(parameter.getModifierList(), MODIFIERS_ILLEGAL_ON_PARAMETERS, trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void resolvePackageHeader(
|
public static void resolvePackageHeader(
|
||||||
@NotNull JetPackageDirective packageDirective,
|
@NotNull JetPackageDirective packageDirective,
|
||||||
@NotNull ModuleDescriptor module,
|
@NotNull ModuleDescriptor module,
|
||||||
|
|||||||
@@ -16,13 +16,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve
|
package org.jetbrains.kotlin.resolve
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import org.jetbrains.kotlin.builtins
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.*
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.*
|
import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.FunctionExpressionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl.create
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -33,6 +34,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.*
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorResolver.*
|
import org.jetbrains.kotlin.resolve.DescriptorResolver.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.WritableScope
|
import org.jetbrains.kotlin.resolve.scopes.WritableScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl
|
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl
|
||||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||||
@@ -47,12 +49,13 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
class FunctionDescriptorResolver(
|
class FunctionDescriptorResolver(
|
||||||
val typeResolver: TypeResolver,
|
private val typeResolver: TypeResolver,
|
||||||
val descriptorResolver: DescriptorResolver,
|
private val descriptorResolver: DescriptorResolver,
|
||||||
val annotationResolver: AnnotationResolver,
|
private val annotationResolver: AnnotationResolver,
|
||||||
val storageManager: StorageManager,
|
private val storageManager: StorageManager,
|
||||||
val expressionTypingServices: ExpressionTypingServices,
|
private val expressionTypingServices: ExpressionTypingServices,
|
||||||
val builtIns: KotlinBuiltIns
|
private val builtIns: KotlinBuiltIns,
|
||||||
|
private val modifiersChecker: ModifiersChecker
|
||||||
) {
|
) {
|
||||||
public fun resolveFunctionDescriptor(
|
public fun resolveFunctionDescriptor(
|
||||||
containingDescriptor: DeclarationDescriptor,
|
containingDescriptor: DeclarationDescriptor,
|
||||||
@@ -336,11 +339,13 @@ class FunctionDescriptorResolver(
|
|||||||
|
|
||||||
if (functionDescriptor !is ConstructorDescriptor || !functionDescriptor.isPrimary()) {
|
if (functionDescriptor !is ConstructorDescriptor || !functionDescriptor.isPrimary()) {
|
||||||
val isConstructor = functionDescriptor is ConstructorDescriptor
|
val isConstructor = functionDescriptor is ConstructorDescriptor
|
||||||
DescriptorResolver.checkParameterHasNoValOrVar(
|
with (modifiersChecker.withTrace(trace)) {
|
||||||
trace, valueParameter,
|
checkParameterHasNoValOrVar(
|
||||||
|
valueParameter,
|
||||||
if (isConstructor) VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER else VAL_OR_VAR_ON_FUN_PARAMETER
|
if (isConstructor) VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER else VAL_OR_VAR_ON_FUN_PARAMETER
|
||||||
)
|
)
|
||||||
DescriptorResolver.checkParameterHasNoModifier(trace, valueParameter)
|
checkParameterHasNoModifier(valueParameter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
checkConstructorParameterHasNoModifier(trace, valueParameter)
|
checkConstructorParameterHasNoModifier(trace, valueParameter)
|
||||||
@@ -357,7 +362,7 @@ class FunctionDescriptorResolver(
|
|||||||
private fun checkConstructorParameterHasNoModifier(trace: BindingTrace, parameter: JetParameter) {
|
private fun checkConstructorParameterHasNoModifier(trace: BindingTrace, parameter: JetParameter) {
|
||||||
// If is not a property, then it must have no modifier
|
// If is not a property, then it must have no modifier
|
||||||
if (!parameter.hasValOrVar()) {
|
if (!parameter.hasValOrVar()) {
|
||||||
DescriptorResolver.checkParameterHasNoModifier(trace, parameter)
|
modifiersChecker.withTrace(trace).checkParameterHasNoModifier(parameter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
|
import org.jetbrains.kotlin.lexer.JetKeywordToken;
|
||||||
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
|
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
@@ -50,10 +52,156 @@ public class ModifiersChecker {
|
|||||||
private static final Collection<JetModifierKeywordToken> VISIBILITY_MODIFIERS =
|
private static final Collection<JetModifierKeywordToken> VISIBILITY_MODIFIERS =
|
||||||
Lists.newArrayList(PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD);
|
Lists.newArrayList(PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD);
|
||||||
|
|
||||||
public static void reportIllegalModifiers(
|
private static final Set<JetModifierKeywordToken> MODIFIERS_ILLEGAL_ON_PARAMETERS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
MODIFIERS_ILLEGAL_ON_PARAMETERS = Sets.newHashSet();
|
||||||
|
MODIFIERS_ILLEGAL_ON_PARAMETERS.addAll(Arrays.asList(JetTokens.MODIFIER_KEYWORDS_ARRAY));
|
||||||
|
MODIFIERS_ILLEGAL_ON_PARAMETERS.remove(JetTokens.VARARG_KEYWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isIllegalInner(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
return checkIllegalInner(descriptor) != InnerModifierCheckResult.ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum InnerModifierCheckResult {
|
||||||
|
ALLOWED,
|
||||||
|
ILLEGAL_POSITION,
|
||||||
|
IN_TRAIT,
|
||||||
|
IN_OBJECT,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: just checks if this is legal context for companion modifier (Companion object descriptor can be created)
|
||||||
|
// COMPANION_OBJECT_NOT_ALLOWED can be reported later
|
||||||
|
public static boolean isCompanionModifierAllowed(@NotNull JetDeclaration declaration) {
|
||||||
|
if (declaration instanceof JetObjectDeclaration) {
|
||||||
|
JetDeclaration containingDeclaration = getContainingDeclaration(declaration);
|
||||||
|
if (containingDeclaration instanceof JetClassOrObject) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static InnerModifierCheckResult checkIllegalInner(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (!(descriptor instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
||||||
|
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||||
|
|
||||||
|
if (classDescriptor.getKind() != ClassKind.CLASS) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
||||||
|
|
||||||
|
DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration();
|
||||||
|
if (!(containingDeclaration instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
||||||
|
|
||||||
|
if (DescriptorUtils.isTrait(containingDeclaration)) {
|
||||||
|
return InnerModifierCheckResult.IN_TRAIT;
|
||||||
|
}
|
||||||
|
else if (DescriptorUtils.isObject(containingDeclaration)) {
|
||||||
|
return InnerModifierCheckResult.IN_OBJECT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return InnerModifierCheckResult.ALLOWED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isIllegalNestedClass(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (!(descriptor instanceof ClassDescriptor)) return false;
|
||||||
|
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||||
|
if (!(containingDeclaration instanceof ClassDescriptor)) return false;
|
||||||
|
ClassDescriptor containingClass = (ClassDescriptor) containingDeclaration;
|
||||||
|
return containingClass.isInner() || containingClass.getContainingDeclaration() instanceof FunctionDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Modality resolveModalityFromModifiers(
|
||||||
|
@NotNull JetModifierListOwner modifierListOwner,
|
||||||
|
@NotNull Modality defaultModality
|
||||||
|
) {
|
||||||
|
return resolveModalityFromModifiers(modifierListOwner.getModifierList(), defaultModality);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Modality resolveModalityFromModifiers(@Nullable JetModifierList modifierList, @NotNull Modality defaultModality) {
|
||||||
|
if (modifierList == null) return defaultModality;
|
||||||
|
boolean hasAbstractModifier = modifierList.hasModifier(ABSTRACT_KEYWORD);
|
||||||
|
boolean hasOverrideModifier = modifierList.hasModifier(OVERRIDE_KEYWORD);
|
||||||
|
|
||||||
|
if (modifierList.hasModifier(SEALED_KEYWORD)) {
|
||||||
|
return Modality.SEALED;
|
||||||
|
}
|
||||||
|
if (modifierList.hasModifier(OPEN_KEYWORD)) {
|
||||||
|
if (hasAbstractModifier || defaultModality == Modality.ABSTRACT) {
|
||||||
|
return Modality.ABSTRACT;
|
||||||
|
}
|
||||||
|
return Modality.OPEN;
|
||||||
|
}
|
||||||
|
if (hasAbstractModifier) {
|
||||||
|
return Modality.ABSTRACT;
|
||||||
|
}
|
||||||
|
boolean hasFinalModifier = modifierList.hasModifier(FINAL_KEYWORD);
|
||||||
|
if (hasOverrideModifier && !hasFinalModifier && !(defaultModality == Modality.ABSTRACT)) {
|
||||||
|
return Modality.OPEN;
|
||||||
|
}
|
||||||
|
if (hasFinalModifier) {
|
||||||
|
return Modality.FINAL;
|
||||||
|
}
|
||||||
|
return defaultModality;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Visibility resolveVisibilityFromModifiers(
|
||||||
|
@NotNull JetModifierListOwner modifierListOwner,
|
||||||
|
@NotNull Visibility defaultVisibility
|
||||||
|
) {
|
||||||
|
return resolveVisibilityFromModifiers(modifierListOwner.getModifierList(), defaultVisibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Visibility resolveVisibilityFromModifiers(@Nullable JetModifierList modifierList, @NotNull Visibility defaultVisibility) {
|
||||||
|
if (modifierList == null) return defaultVisibility;
|
||||||
|
if (modifierList.hasModifier(PRIVATE_KEYWORD)) return Visibilities.PRIVATE;
|
||||||
|
if (modifierList.hasModifier(PUBLIC_KEYWORD)) return Visibilities.PUBLIC;
|
||||||
|
if (modifierList.hasModifier(PROTECTED_KEYWORD)) return Visibilities.PROTECTED;
|
||||||
|
if (modifierList.hasModifier(INTERNAL_KEYWORD)) return Visibilities.INTERNAL;
|
||||||
|
return defaultVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isInnerClass(@Nullable JetModifierList modifierList) {
|
||||||
|
return modifierList != null && modifierList.hasModifier(INNER_KEYWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Visibility getDefaultClassVisibility(@NotNull ClassDescriptor descriptor) {
|
||||||
|
if (isEnumEntry(descriptor) || isCompanionObject(descriptor)) {
|
||||||
|
// should be be accessible where containing class is accessible by default
|
||||||
|
return Visibilities.PUBLIC;
|
||||||
|
}
|
||||||
|
return Visibilities.INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ModifiersCheckingProcedure {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final BindingTrace trace;
|
||||||
|
|
||||||
|
private ModifiersCheckingProcedure(@NotNull BindingTrace trace) {
|
||||||
|
this.trace = trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkParameterHasNoValOrVar(
|
||||||
|
@NotNull JetParameter parameter,
|
||||||
|
@NotNull DiagnosticFactory1<PsiElement, JetKeywordToken> diagnosticFactory
|
||||||
|
) {
|
||||||
|
PsiElement valOrVar = parameter.getValOrVarKeyword();
|
||||||
|
if (valOrVar != null) {
|
||||||
|
trace.report(diagnosticFactory.on(valOrVar, ((JetKeywordToken) valOrVar.getNode().getElementType())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reportIllegalModifiers(
|
||||||
@Nullable JetModifierList modifierList,
|
@Nullable JetModifierList modifierList,
|
||||||
@NotNull Collection<JetModifierKeywordToken> illegalModifiers,
|
@NotNull Collection<JetModifierKeywordToken> illegalModifiers
|
||||||
@NotNull BindingTrace trace
|
|
||||||
) {
|
) {
|
||||||
if (modifierList == null) return;
|
if (modifierList == null) return;
|
||||||
|
|
||||||
@@ -66,9 +214,15 @@ public class ModifiersChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkIncompatibleModifiers(
|
public void reportIllegalModifiers(
|
||||||
|
@NotNull JetModifierListOwner modifierListOwner,
|
||||||
|
@NotNull Collection<JetModifierKeywordToken> illegalModifiers
|
||||||
|
) {
|
||||||
|
reportIllegalModifiers(modifierListOwner.getModifierList(), illegalModifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkIncompatibleModifiers(
|
||||||
@Nullable JetModifierList modifierList,
|
@Nullable JetModifierList modifierList,
|
||||||
@NotNull BindingTrace trace,
|
|
||||||
@NotNull Collection<JetModifierKeywordToken> availableModifiers,
|
@NotNull Collection<JetModifierKeywordToken> availableModifiers,
|
||||||
@NotNull Collection<JetModifierKeywordToken>... availableCombinations
|
@NotNull Collection<JetModifierKeywordToken>... availableCombinations
|
||||||
) {
|
) {
|
||||||
@@ -79,7 +233,7 @@ public class ModifiersChecker {
|
|||||||
presentModifiers.add(modifier);
|
presentModifiers.add(modifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkRepeatedModifiers(modifierList, trace, availableModifiers);
|
checkRepeatedModifiers(modifierList, availableModifiers);
|
||||||
|
|
||||||
if (presentModifiers.size() == 1) {
|
if (presentModifiers.size() == 1) {
|
||||||
return;
|
return;
|
||||||
@@ -94,9 +248,8 @@ public class ModifiersChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkRepeatedModifiers(
|
private void checkRepeatedModifiers(
|
||||||
@NotNull JetModifierList modifierList,
|
@NotNull JetModifierList modifierList,
|
||||||
@NotNull BindingTrace trace,
|
|
||||||
@NotNull Collection<JetModifierKeywordToken> availableModifiers
|
@NotNull Collection<JetModifierKeywordToken> availableModifiers
|
||||||
) {
|
) {
|
||||||
for (JetModifierKeywordToken token : availableModifiers) {
|
for (JetModifierKeywordToken token : availableModifiers) {
|
||||||
@@ -118,31 +271,18 @@ public class ModifiersChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkIncompatibleVarianceModifiers(@Nullable JetModifierList modifierList, @NotNull BindingTrace trace) {
|
public void checkIncompatibleVarianceModifiers(@Nullable JetModifierList modifierList) {
|
||||||
checkIncompatibleModifiers(modifierList, trace, Arrays.asList(JetTokens.IN_KEYWORD, JetTokens.OUT_KEYWORD));
|
checkIncompatibleModifiers(modifierList, Arrays.asList(JetTokens.IN_KEYWORD, JetTokens.OUT_KEYWORD));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final BindingTrace trace;
|
|
||||||
@NotNull
|
|
||||||
private final AdditionalCheckerProvider additionalCheckerProvider;
|
|
||||||
|
|
||||||
public ModifiersChecker(@NotNull BindingTrace trace, @NotNull AdditionalCheckerProvider additionalCheckerProvider) {
|
|
||||||
this.trace = trace;
|
|
||||||
this.additionalCheckerProvider = additionalCheckerProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ModifiersChecker create(@NotNull BindingTrace trace, @NotNull AdditionalCheckerProvider provider) {
|
|
||||||
return new ModifiersChecker(trace, provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkModifiersForDeclaration(@NotNull JetDeclaration modifierListOwner, @NotNull MemberDescriptor descriptor) {
|
public void checkModifiersForDeclaration(@NotNull JetDeclaration modifierListOwner, @NotNull MemberDescriptor descriptor) {
|
||||||
if (modifierListOwner instanceof JetEnumEntry) {
|
if (modifierListOwner instanceof JetEnumEntry) {
|
||||||
reportIllegalModifiers(modifierListOwner, Arrays.asList(MODIFIER_KEYWORDS_ARRAY));
|
reportIllegalModifiers(modifierListOwner.getModifierList(), Arrays.asList(MODIFIER_KEYWORDS_ARRAY));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
checkInnerModifier(modifierListOwner, descriptor);
|
checkInnerModifier(modifierListOwner, descriptor);
|
||||||
checkDefaultModifier(modifierListOwner);
|
checkCompanionModifier(modifierListOwner);
|
||||||
checkModalityModifiers(modifierListOwner);
|
checkModalityModifiers(modifierListOwner);
|
||||||
checkVisibilityModifiers(modifierListOwner, descriptor);
|
checkVisibilityModifiers(modifierListOwner, descriptor);
|
||||||
checkVarianceModifiers(modifierListOwner);
|
checkVarianceModifiers(modifierListOwner);
|
||||||
@@ -156,11 +296,14 @@ public class ModifiersChecker {
|
|||||||
|
|
||||||
private void checkVarargsModifiers(@NotNull JetDeclaration owner, @NotNull MemberDescriptor descriptor) {
|
private void checkVarargsModifiers(@NotNull JetDeclaration owner, @NotNull MemberDescriptor descriptor) {
|
||||||
if (!(owner instanceof JetParameter)) {
|
if (!(owner instanceof JetParameter)) {
|
||||||
reportIllegalModifiers(owner, Collections.singleton(VARARG_KEYWORD));
|
reportIllegalModifiers(owner.getModifierList(), Collections.singleton(VARARG_KEYWORD));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkModifiersForLocalDeclaration(@NotNull JetDeclaration modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
|
public void checkModifiersForLocalDeclaration(
|
||||||
|
@NotNull JetDeclaration modifierListOwner,
|
||||||
|
@NotNull DeclarationDescriptor descriptor
|
||||||
|
) {
|
||||||
reportIllegalModalityModifiers(modifierListOwner);
|
reportIllegalModalityModifiers(modifierListOwner);
|
||||||
reportIllegalVisibilityModifiers(modifierListOwner);
|
reportIllegalVisibilityModifiers(modifierListOwner);
|
||||||
checkPlatformNameApplicability(descriptor);
|
checkPlatformNameApplicability(descriptor);
|
||||||
@@ -234,64 +377,12 @@ public class ModifiersChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isIllegalInner(@NotNull DeclarationDescriptor descriptor) {
|
private void checkCompanionModifier(@NotNull JetDeclaration declaration) {
|
||||||
return checkIllegalInner(descriptor) != InnerModifierCheckResult.ALLOWED;
|
if (declaration.hasModifier(COMPANION_KEYWORD) && !isCompanionModifierAllowed(declaration)) {
|
||||||
}
|
|
||||||
|
|
||||||
private enum InnerModifierCheckResult {
|
|
||||||
ALLOWED,
|
|
||||||
ILLEGAL_POSITION,
|
|
||||||
IN_TRAIT,
|
|
||||||
IN_OBJECT,
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkDefaultModifier(@NotNull JetDeclaration declaration) {
|
|
||||||
if (declaration.hasModifier(COMPANION_KEYWORD) && !isDefaultModifierAllowed(declaration)) {
|
|
||||||
reportIllegalModifiers(declaration, Collections.singletonList(COMPANION_KEYWORD));
|
reportIllegalModifiers(declaration, Collections.singletonList(COMPANION_KEYWORD));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: just checks if this is legal context for companion modifier (Companion object descriptor can be created)
|
|
||||||
// COMPANION_OBJECT_NOT_ALLOWED can be reported later
|
|
||||||
public static boolean isDefaultModifierAllowed(@NotNull JetDeclaration declaration) {
|
|
||||||
if (declaration instanceof JetObjectDeclaration) {
|
|
||||||
JetDeclaration containingDeclaration = getContainingDeclaration(declaration);
|
|
||||||
if (containingDeclaration instanceof JetClassOrObject) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static InnerModifierCheckResult checkIllegalInner(DeclarationDescriptor descriptor) {
|
|
||||||
if (!(descriptor instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
|
||||||
|
|
||||||
if (classDescriptor.getKind() != ClassKind.CLASS) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
|
||||||
|
|
||||||
DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration();
|
|
||||||
if (!(containingDeclaration instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
|
||||||
|
|
||||||
if (DescriptorUtils.isTrait(containingDeclaration)) {
|
|
||||||
return InnerModifierCheckResult.IN_TRAIT;
|
|
||||||
}
|
|
||||||
else if (DescriptorUtils.isObject(containingDeclaration)) {
|
|
||||||
return InnerModifierCheckResult.IN_OBJECT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return InnerModifierCheckResult.ALLOWED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isIllegalNestedClass(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (!(descriptor instanceof ClassDescriptor)) return false;
|
|
||||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
|
||||||
if (!(containingDeclaration instanceof ClassDescriptor)) return false;
|
|
||||||
ClassDescriptor containingClass = (ClassDescriptor) containingDeclaration;
|
|
||||||
return containingClass.isInner() || containingClass.getContainingDeclaration() instanceof FunctionDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkPlatformNameApplicability(@NotNull DeclarationDescriptor descriptor) {
|
private void checkPlatformNameApplicability(@NotNull DeclarationDescriptor descriptor) {
|
||||||
AnnotationDescriptor annotation = descriptor.getAnnotations().findAnnotation(new FqName("kotlin.platform.platformName"));
|
AnnotationDescriptor annotation = descriptor.getAnnotations().findAnnotation(new FqName("kotlin.platform.platformName"));
|
||||||
if (annotation == null) return;
|
if (annotation == null) return;
|
||||||
@@ -321,38 +412,42 @@ public class ModifiersChecker {
|
|||||||
trace.report(INAPPLICABLE_PLATFORM_NAME.on(annotationEntry));
|
trace.report(INAPPLICABLE_PLATFORM_NAME.on(annotationEntry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isRenamableFunction(@NotNull FunctionDescriptor descriptor) {
|
|
||||||
|
private boolean isRenamableFunction(@NotNull FunctionDescriptor descriptor) {
|
||||||
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
|
||||||
|
|
||||||
return containingDescriptor instanceof PackageFragmentDescriptor || containingDescriptor instanceof ClassDescriptor;
|
return containingDescriptor instanceof PackageFragmentDescriptor || containingDescriptor instanceof ClassDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkCompatibility(@Nullable JetModifierList modifierList, Collection<JetModifierKeywordToken> availableModifiers, Collection<JetModifierKeywordToken>... availableCombinations) {
|
private void checkCompatibility(
|
||||||
checkIncompatibleModifiers(modifierList, trace, availableModifiers, availableCombinations);
|
@Nullable JetModifierList modifierList,
|
||||||
|
Collection<JetModifierKeywordToken> availableModifiers,
|
||||||
|
Collection<JetModifierKeywordToken>... availableCombinations
|
||||||
|
) {
|
||||||
|
checkIncompatibleModifiers(modifierList, availableModifiers, availableCombinations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRedundantModifier(@NotNull JetModifierList modifierList, Pair<JetModifierKeywordToken, JetModifierKeywordToken>... redundantBundles) {
|
private void checkRedundantModifier(
|
||||||
|
@NotNull JetModifierList modifierList,
|
||||||
|
Pair<JetModifierKeywordToken, JetModifierKeywordToken>... redundantBundles
|
||||||
|
) {
|
||||||
for (Pair<JetModifierKeywordToken, JetModifierKeywordToken> tokenPair : redundantBundles) {
|
for (Pair<JetModifierKeywordToken, JetModifierKeywordToken> tokenPair : redundantBundles) {
|
||||||
JetModifierKeywordToken redundantModifier = tokenPair.getFirst();
|
JetModifierKeywordToken redundantModifier = tokenPair.getFirst();
|
||||||
JetModifierKeywordToken sufficientModifier = tokenPair.getSecond();
|
JetModifierKeywordToken sufficientModifier = tokenPair.getSecond();
|
||||||
if (modifierList.hasModifier(redundantModifier) && modifierList.hasModifier(sufficientModifier)) {
|
if (modifierList.hasModifier(redundantModifier) && modifierList.hasModifier(sufficientModifier)) {
|
||||||
trace.report(Errors.REDUNDANT_MODIFIER.on(modifierList.getModifierNode(redundantModifier).getPsi(), redundantModifier, sufficientModifier));
|
trace.report(Errors.REDUNDANT_MODIFIER.on(modifierList.getModifierNode(redundantModifier).getPsi(), redundantModifier,
|
||||||
|
sufficientModifier));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reportIllegalModifiers(
|
|
||||||
@NotNull JetModifierListOwner modifierListOwner,
|
|
||||||
@NotNull Collection<JetModifierKeywordToken> illegalModifiers
|
|
||||||
) {
|
|
||||||
reportIllegalModifiers(modifierListOwner.getModifierList(), illegalModifiers, trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Map<JetModifierKeywordToken, ASTNode> getNodesCorrespondingToModifiers(@NotNull JetModifierList modifierList, @NotNull Collection<JetModifierKeywordToken> possibleModifiers) {
|
public Map<JetModifierKeywordToken, ASTNode> getNodesCorrespondingToModifiers(
|
||||||
|
@NotNull JetModifierList modifierList,
|
||||||
|
@NotNull Collection<JetModifierKeywordToken> possibleModifiers
|
||||||
|
) {
|
||||||
Map<JetModifierKeywordToken, ASTNode> nodes = Maps.newHashMap();
|
Map<JetModifierKeywordToken, ASTNode> nodes = Maps.newHashMap();
|
||||||
for (JetModifierKeywordToken modifier : possibleModifiers) {
|
for (JetModifierKeywordToken modifier : possibleModifiers) {
|
||||||
if (modifierList.hasModifier(modifier)) {
|
if (modifierList.hasModifier(modifier)) {
|
||||||
@@ -362,64 +457,6 @@ public class ModifiersChecker {
|
|||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static Modality resolveModalityFromModifiers(@NotNull JetModifierListOwner modifierListOwner, @NotNull Modality defaultModality) {
|
|
||||||
return resolveModalityFromModifiers(modifierListOwner.getModifierList(), defaultModality);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Modality resolveModalityFromModifiers(@Nullable JetModifierList modifierList, @NotNull Modality defaultModality) {
|
|
||||||
if (modifierList == null) return defaultModality;
|
|
||||||
boolean hasAbstractModifier = modifierList.hasModifier(ABSTRACT_KEYWORD);
|
|
||||||
boolean hasOverrideModifier = modifierList.hasModifier(OVERRIDE_KEYWORD);
|
|
||||||
|
|
||||||
if (modifierList.hasModifier(SEALED_KEYWORD)) {
|
|
||||||
return Modality.SEALED;
|
|
||||||
}
|
|
||||||
if (modifierList.hasModifier(OPEN_KEYWORD)) {
|
|
||||||
if (hasAbstractModifier || defaultModality == Modality.ABSTRACT) {
|
|
||||||
return Modality.ABSTRACT;
|
|
||||||
}
|
|
||||||
return Modality.OPEN;
|
|
||||||
}
|
|
||||||
if (hasAbstractModifier) {
|
|
||||||
return Modality.ABSTRACT;
|
|
||||||
}
|
|
||||||
boolean hasFinalModifier = modifierList.hasModifier(FINAL_KEYWORD);
|
|
||||||
if (hasOverrideModifier && !hasFinalModifier && !(defaultModality == Modality.ABSTRACT)) {
|
|
||||||
return Modality.OPEN;
|
|
||||||
}
|
|
||||||
if (hasFinalModifier) {
|
|
||||||
return Modality.FINAL;
|
|
||||||
}
|
|
||||||
return defaultModality;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static Visibility resolveVisibilityFromModifiers(@NotNull JetModifierListOwner modifierListOwner, @NotNull Visibility defaultVisibility) {
|
|
||||||
return resolveVisibilityFromModifiers(modifierListOwner.getModifierList(), defaultVisibility);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Visibility resolveVisibilityFromModifiers(@Nullable JetModifierList modifierList, @NotNull Visibility defaultVisibility) {
|
|
||||||
if (modifierList == null) return defaultVisibility;
|
|
||||||
if (modifierList.hasModifier(PRIVATE_KEYWORD)) return Visibilities.PRIVATE;
|
|
||||||
if (modifierList.hasModifier(PUBLIC_KEYWORD)) return Visibilities.PUBLIC;
|
|
||||||
if (modifierList.hasModifier(PROTECTED_KEYWORD)) return Visibilities.PROTECTED;
|
|
||||||
if (modifierList.hasModifier(INTERNAL_KEYWORD)) return Visibilities.INTERNAL;
|
|
||||||
return defaultVisibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isInnerClass(@Nullable JetModifierList modifierList) {
|
|
||||||
return modifierList != null && modifierList.hasModifier(INNER_KEYWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static Visibility getDefaultClassVisibility(@NotNull ClassDescriptor descriptor) {
|
|
||||||
if (isEnumEntry(descriptor) || isCompanionObject(descriptor)) {
|
|
||||||
// should be be accessible where containing class is accessible by default
|
|
||||||
return Visibilities.PUBLIC;
|
|
||||||
}
|
|
||||||
return Visibilities.INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runDeclarationCheckers(@NotNull JetDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
|
private void runDeclarationCheckers(@NotNull JetDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||||
for (DeclarationChecker checker : additionalCheckerProvider.getDeclarationCheckers()) {
|
for (DeclarationChecker checker : additionalCheckerProvider.getDeclarationCheckers()) {
|
||||||
@@ -428,12 +465,31 @@ public class ModifiersChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void checkVarianceModifiers(@NotNull JetModifierListOwner modifierListOwner) {
|
public void checkVarianceModifiers(@NotNull JetModifierListOwner modifierListOwner) {
|
||||||
reportIllegalModifiers(modifierListOwner, Arrays.asList(IN_KEYWORD, OUT_KEYWORD, REIFIED_KEYWORD));
|
reportIllegalModifiers(modifierListOwner.getModifierList(), Arrays.asList(IN_KEYWORD, OUT_KEYWORD, REIFIED_KEYWORD));
|
||||||
if (!(modifierListOwner instanceof JetTypeParameterListOwner)) return;
|
if (!(modifierListOwner instanceof JetTypeParameterListOwner)) return;
|
||||||
List<JetTypeParameter> typeParameters = ((JetTypeParameterListOwner) modifierListOwner).getTypeParameters();
|
List<JetTypeParameter> typeParameters = ((JetTypeParameterListOwner) modifierListOwner).getTypeParameters();
|
||||||
for (JetTypeParameter typeParameter : typeParameters) {
|
for (JetTypeParameter typeParameter : typeParameters) {
|
||||||
JetModifierList modifierList = typeParameter.getModifierList();
|
JetModifierList modifierList = typeParameter.getModifierList();
|
||||||
checkIncompatibleVarianceModifiers(modifierList, trace);
|
checkIncompatibleVarianceModifiers(modifierList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void checkParameterHasNoModifier(
|
||||||
|
@NotNull JetParameter parameter
|
||||||
|
) {
|
||||||
|
reportIllegalModifiers(parameter.getModifierList(), MODIFIERS_ILLEGAL_ON_PARAMETERS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final AdditionalCheckerProvider additionalCheckerProvider;
|
||||||
|
|
||||||
|
public ModifiersChecker(@NotNull AdditionalCheckerProvider additionalCheckerProvider) {
|
||||||
|
this.additionalCheckerProvider = additionalCheckerProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ModifiersCheckingProcedure withTrace(@NotNull BindingTrace trace) {
|
||||||
|
return new ModifiersCheckingProcedure(trace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ public class TypeResolver(
|
|||||||
private val flexibleTypeCapabilitiesProvider: FlexibleTypeCapabilitiesProvider,
|
private val flexibleTypeCapabilitiesProvider: FlexibleTypeCapabilitiesProvider,
|
||||||
private val storageManager: StorageManager,
|
private val storageManager: StorageManager,
|
||||||
private val lazinessToken: TypeLazinessToken,
|
private val lazinessToken: TypeLazinessToken,
|
||||||
private val dynamicTypesSettings: DynamicTypesSettings
|
private val dynamicTypesSettings: DynamicTypesSettings,
|
||||||
|
private val modifiersChecker: ModifiersChecker
|
||||||
) {
|
) {
|
||||||
|
|
||||||
public open class FlexibleTypeCapabilitiesProvider {
|
public open class FlexibleTypeCapabilitiesProvider {
|
||||||
@@ -268,9 +269,9 @@ public class TypeResolver(
|
|||||||
return argumentElements.mapIndexed { i, argumentElement ->
|
return argumentElements.mapIndexed { i, argumentElement ->
|
||||||
|
|
||||||
val projectionKind = argumentElement.getProjectionKind()
|
val projectionKind = argumentElement.getProjectionKind()
|
||||||
ModifiersChecker.checkIncompatibleVarianceModifiers(argumentElement.getModifierList(), c.trace)
|
modifiersChecker.withTrace(c.trace).checkIncompatibleVarianceModifiers(argumentElement.getModifierList())
|
||||||
if (projectionKind == JetProjectionKind.STAR) {
|
if (projectionKind == JetProjectionKind.STAR) {
|
||||||
ModifiersChecker.reportIllegalModifiers(argumentElement.getModifierList(), listOf(JetTokens.IN_KEYWORD, JetTokens.OUT_KEYWORD), c.trace)
|
modifiersChecker.withTrace(c.trace).reportIllegalModifiers(argumentElement.getModifierList(), listOf(JetTokens.IN_KEYWORD, JetTokens.OUT_KEYWORD))
|
||||||
|
|
||||||
val parameters = constructor.getParameters()
|
val parameters = constructor.getParameters()
|
||||||
if (parameters.size() > i) {
|
if (parameters.size() > i) {
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ import java.util.ArrayList
|
|||||||
public class CandidateResolver(
|
public class CandidateResolver(
|
||||||
private val argumentTypeResolver: ArgumentTypeResolver,
|
private val argumentTypeResolver: ArgumentTypeResolver,
|
||||||
private val genericCandidateResolver: GenericCandidateResolver,
|
private val genericCandidateResolver: GenericCandidateResolver,
|
||||||
private val reflectionTypes: ReflectionTypes
|
private val reflectionTypes: ReflectionTypes,
|
||||||
|
private val modifiersChecker: ModifiersChecker
|
||||||
){
|
){
|
||||||
|
|
||||||
public fun <D : CallableDescriptor, F : D> performResolutionForCandidateCall(
|
public fun <D : CallableDescriptor, F : D> performResolutionForCandidateCall(
|
||||||
@@ -123,7 +124,7 @@ public class CandidateResolver(
|
|||||||
for (projection in jetTypeArguments) {
|
for (projection in jetTypeArguments) {
|
||||||
if (projection.getProjectionKind() != JetProjectionKind.NONE) {
|
if (projection.getProjectionKind() != JetProjectionKind.NONE) {
|
||||||
trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection))
|
trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection))
|
||||||
ModifiersChecker.checkIncompatibleVarianceModifiers(projection.getModifierList(), trace)
|
modifiersChecker.withTrace(trace).checkIncompatibleVarianceModifiers(projection.getModifierList())
|
||||||
}
|
}
|
||||||
val type = argumentTypeResolver.resolveTypeRefWithDefault(
|
val type = argumentTypeResolver.resolveTypeRefWithDefault(
|
||||||
projection.getTypeReference(), scope, trace,
|
projection.getTypeReference(), scope, trace,
|
||||||
|
|||||||
@@ -20,13 +20,9 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind;
|
import org.jetbrains.kotlin.descriptors.ClassKind;
|
||||||
import org.jetbrains.kotlin.psi.JetObjectDeclaration;
|
import org.jetbrains.kotlin.psi.JetObjectDeclaration;
|
||||||
import org.jetbrains.kotlin.psi.JetParameter;
|
|
||||||
import org.jetbrains.kotlin.psi.JetTypeParameterList;
|
import org.jetbrains.kotlin.psi.JetTypeParameterList;
|
||||||
import org.jetbrains.kotlin.resolve.ModifiersChecker;
|
import org.jetbrains.kotlin.resolve.ModifiersChecker;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class JetObjectInfo extends JetClassOrObjectInfo<JetObjectDeclaration> {
|
public class JetObjectInfo extends JetClassOrObjectInfo<JetObjectDeclaration> {
|
||||||
@NotNull
|
@NotNull
|
||||||
private final ClassKind kind;
|
private final ClassKind kind;
|
||||||
@@ -49,6 +45,6 @@ public class JetObjectInfo extends JetClassOrObjectInfo<JetObjectDeclaration> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCompanionObject() {
|
public boolean isCompanionObject() {
|
||||||
return element.isCompanion() && ModifiersChecker.isDefaultModifierAllowed(element);
|
return element.isCompanion() && ModifiersChecker.isCompanionModifierAllowed(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-7
@@ -26,10 +26,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
|||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorResolver;
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
|
import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||||
@@ -426,7 +423,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
JetType expectedParameterType,
|
JetType expectedParameterType,
|
||||||
ExpressionTypingContext context
|
ExpressionTypingContext context
|
||||||
) {
|
) {
|
||||||
DescriptorResolver.checkParameterHasNoValOrVar(context.trace, loopParameter, VAL_OR_VAR_ON_LOOP_PARAMETER);
|
components.modifiersChecker.withTrace(context.trace).checkParameterHasNoValOrVar(loopParameter, VAL_OR_VAR_ON_LOOP_PARAMETER);
|
||||||
|
|
||||||
JetTypeReference typeReference = loopParameter.getTypeReference();
|
JetTypeReference typeReference = loopParameter.getTypeReference();
|
||||||
VariableDescriptor variableDescriptor;
|
VariableDescriptor variableDescriptor;
|
||||||
@@ -468,8 +465,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
JetParameter catchParameter = catchClause.getCatchParameter();
|
JetParameter catchParameter = catchClause.getCatchParameter();
|
||||||
JetExpression catchBody = catchClause.getCatchBody();
|
JetExpression catchBody = catchClause.getCatchBody();
|
||||||
if (catchParameter != null) {
|
if (catchParameter != null) {
|
||||||
DescriptorResolver.checkParameterHasNoValOrVar(context.trace, catchParameter, VAL_OR_VAR_ON_CATCH_PARAMETER);
|
ModifiersChecker.ModifiersCheckingProcedure modifiersChecking = components.modifiersChecker.withTrace(context.trace);
|
||||||
DescriptorResolver.checkParameterHasNoModifier(context.trace, catchParameter);
|
modifiersChecking.checkParameterHasNoValOrVar(catchParameter, VAL_OR_VAR_ON_CATCH_PARAMETER);
|
||||||
|
modifiersChecking.checkParameterHasNoModifier(catchParameter);
|
||||||
|
|
||||||
VariableDescriptor variableDescriptor = components.descriptorResolver.resolveLocalVariableDescriptor(
|
VariableDescriptor variableDescriptor = components.descriptorResolver.resolveLocalVariableDescriptor(
|
||||||
context.scope, catchParameter, context.trace);
|
context.scope, catchParameter, context.trace);
|
||||||
|
|||||||
+6
@@ -51,6 +51,7 @@ public class ExpressionTypingComponents {
|
|||||||
/*package*/ ValueParameterResolver valueParameterResolver;
|
/*package*/ ValueParameterResolver valueParameterResolver;
|
||||||
/*package*/ MultiDeclarationResolver multiDeclarationResolver;
|
/*package*/ MultiDeclarationResolver multiDeclarationResolver;
|
||||||
/*package*/ ConstantExpressionEvaluator constantExpressionEvaluator;
|
/*package*/ ConstantExpressionEvaluator constantExpressionEvaluator;
|
||||||
|
/*package*/ ModifiersChecker modifiersChecker;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void setGlobalContext(@NotNull GlobalContext globalContext) {
|
public void setGlobalContext(@NotNull GlobalContext globalContext) {
|
||||||
@@ -161,4 +162,9 @@ public class ExpressionTypingComponents {
|
|||||||
public void setConstantExpressionEvaluator(@NotNull ConstantExpressionEvaluator constantExpressionEvaluator) {
|
public void setConstantExpressionEvaluator(@NotNull ConstantExpressionEvaluator constantExpressionEvaluator) {
|
||||||
this.constantExpressionEvaluator = constantExpressionEvaluator;
|
this.constantExpressionEvaluator = constantExpressionEvaluator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setModifiersChecker(ModifiersChecker modifiersChecker) {
|
||||||
|
this.modifiersChecker = modifiersChecker;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -162,7 +162,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
}
|
}
|
||||||
|
|
||||||
scope.addVariableDescriptor(propertyDescriptor);
|
scope.addVariableDescriptor(propertyDescriptor);
|
||||||
ModifiersChecker.create(context.trace, components.additionalCheckerProvider).checkModifiersForLocalDeclaration(property, propertyDescriptor);
|
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(property, propertyDescriptor);
|
||||||
return typeInfo.replaceType(DataFlowUtils.checkStatementType(property, context));
|
return typeInfo.replaceType(DataFlowUtils.checkStatementType(property, context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -103,8 +103,7 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express
|
|||||||
function.getValueParameters(), functionDescriptor.getValueParameters(), context.scope, context.dataFlowInfo, context.trace
|
function.getValueParameters(), functionDescriptor.getValueParameters(), context.scope, context.dataFlowInfo, context.trace
|
||||||
)
|
)
|
||||||
|
|
||||||
ModifiersChecker.create(context.trace, components.additionalCheckerProvider)
|
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(function, functionDescriptor)
|
||||||
.checkModifiersForLocalDeclaration(function, functionDescriptor)
|
|
||||||
if (!function.hasBody()) {
|
if (!function.hasBody()) {
|
||||||
context.trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor))
|
context.trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user