Explicit Api mode: Renamings after design discussions
Change CLI flag to -Xexplicit-api=strict|warning. 'Disable' state and 'mode' suffix are left out as implementation details. Change intention title to 'make X public explicitly' Do not report 'no explicit visibility' on property accessors Set DECLARATION_SIGNATURE as a range for report Rename internal diagnostic from _MIGRATION to _WARNING
This commit is contained in:
@@ -28,7 +28,7 @@ object AnalysisFlags {
|
||||
val allowResultReturnType by AnalysisFlag.Delegates.Boolean
|
||||
|
||||
@JvmStatic
|
||||
val apiMode by AnalysisFlag.Delegates.ApiModeDisabledByDefault
|
||||
val explicitApiMode by AnalysisFlag.Delegates.ApiModeDisabledByDefault
|
||||
|
||||
@JvmStatic
|
||||
val constraintSystemForOverloadResolution by AnalysisFlag.Delegates.ConstraintSystemForOverloadResolution
|
||||
|
||||
@@ -207,10 +207,10 @@ public interface Errors {
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> DEPRECATED_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken> DEPRECATED_MODIFIER = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> REDUNDANT_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, DeclarationDescriptor> NO_EXPLICIT_VISIBILITY_IN_API_MODE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> NO_EXPLICIT_RETURN_TYPE_IN_API_MODE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, DeclarationDescriptor> NO_EXPLICIT_VISIBILITY_IN_API_MODE_MIGRATION = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory0<PsiElement> NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_MIGRATION = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory1<KtDeclaration, DeclarationDescriptor> NO_EXPLICIT_VISIBILITY_IN_API_MODE = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtDeclaration> NO_EXPLICIT_RETURN_TYPE_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory1<KtDeclaration, DeclarationDescriptor> NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING = DiagnosticFactory1.create(WARNING, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtDeclaration> NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> WRONG_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> DEPRECATED_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, KtModifierKeywordToken> ILLEGAL_INLINE_PARAMETER_MODIFIER = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
+2
-2
@@ -121,8 +121,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(REDUNDANT_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is redundant for ''{1}''", TO_STRING, TO_STRING);
|
||||
MAP.put(NO_EXPLICIT_VISIBILITY_IN_API_MODE, "Declaration ''{0}'' is effectively public API and API mode is on, but no visibility is specified", NAME);
|
||||
MAP.put(NO_EXPLICIT_RETURN_TYPE_IN_API_MODE, "This declaration is effectively public API and API mode is on, but no explicit return type is specified");
|
||||
MAP.put(NO_EXPLICIT_VISIBILITY_IN_API_MODE_MIGRATION, "Declaration ''{0}'' is effectively public API and API mode is on, but no visibility is specified", NAME);
|
||||
MAP.put(NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_MIGRATION, "This declaration is effectively public API and API mode is on, but no explicit return type is specified");
|
||||
MAP.put(NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING, "Declaration ''{0}'' is effectively public API and API mode is on, but no visibility is specified", NAME);
|
||||
MAP.put(NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING, "This declaration is effectively public API and API mode is on, but no explicit return type is specified");
|
||||
MAP.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", TO_STRING, TO_STRING);
|
||||
MAP.put(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", TO_STRING, TO_STRING);
|
||||
MAP.put(ILLEGAL_INLINE_PARAMETER_MODIFIER, "Modifier ''{0}'' is allowed only for function parameters of an inline function", TO_STRING);
|
||||
|
||||
@@ -32,7 +32,7 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
||||
ReservedMembersAndConstructsForInlineClass(),
|
||||
ResultClassInReturnTypeChecker(),
|
||||
LocalVariableTypeParametersChecker(),
|
||||
ApiModeDeclarationChecker(),
|
||||
ExplicitApiDeclarationChecker(),
|
||||
TailrecFunctionChecker,
|
||||
TrailingCommaDeclarationChecker
|
||||
)
|
||||
|
||||
+17
-16
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.ApiMode
|
||||
import org.jetbrains.kotlin.config.ExplicitApiMode
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
@@ -15,13 +15,12 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
|
||||
|
||||
class ApiModeDeclarationChecker : DeclarationChecker {
|
||||
class ExplicitApiDeclarationChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
val state = isEnabled(context.languageVersionSettings)
|
||||
if (state == ApiMode.DISABLED) return
|
||||
if (state == ExplicitApiMode.DISABLED) return
|
||||
|
||||
val isApi = (descriptor as? DeclarationDescriptorWithVisibility)?.isEffectivelyPublicApi ?: return
|
||||
if (!isApi) return
|
||||
@@ -31,7 +30,7 @@ class ApiModeDeclarationChecker : DeclarationChecker {
|
||||
}
|
||||
|
||||
private fun checkVisibilityModifier(
|
||||
state: ApiMode,
|
||||
state: ExplicitApiMode,
|
||||
declaration: KtDeclaration,
|
||||
descriptor: DeclarationDescriptorWithVisibility,
|
||||
context: DeclarationCheckerContext
|
||||
@@ -41,15 +40,15 @@ class ApiModeDeclarationChecker : DeclarationChecker {
|
||||
|
||||
if (excludeForDiagnostic(descriptor)) return
|
||||
val diagnostic =
|
||||
if (state == ApiMode.ENABLED)
|
||||
if (state == ExplicitApiMode.STRICT)
|
||||
Errors.NO_EXPLICIT_VISIBILITY_IN_API_MODE.on(declaration, descriptor)
|
||||
else
|
||||
Errors.NO_EXPLICIT_VISIBILITY_IN_API_MODE_MIGRATION.on(declaration, descriptor)
|
||||
Errors.NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING.on(declaration, descriptor)
|
||||
context.trace.reportDiagnosticOnce(diagnostic)
|
||||
}
|
||||
|
||||
private fun checkExplicitReturnType(
|
||||
state: ApiMode,
|
||||
state: ExplicitApiMode,
|
||||
declaration: KtDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
context: DeclarationCheckerContext
|
||||
@@ -65,10 +64,10 @@ class ApiModeDeclarationChecker : DeclarationChecker {
|
||||
)
|
||||
if (shouldReport) {
|
||||
val diagnostic =
|
||||
if (state == ApiMode.ENABLED)
|
||||
if (state == ExplicitApiMode.STRICT)
|
||||
Errors.NO_EXPLICIT_RETURN_TYPE_IN_API_MODE.on(declaration)
|
||||
else
|
||||
Errors.NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_MIGRATION
|
||||
Errors.NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING
|
||||
.on(declaration)
|
||||
context.trace.reportDiagnosticOnce(diagnostic)
|
||||
}
|
||||
@@ -77,8 +76,9 @@ class ApiModeDeclarationChecker : DeclarationChecker {
|
||||
/**
|
||||
* Exclusion list:
|
||||
* 1. Primary constructors of public API classes
|
||||
* 3. Members of public API interfaces
|
||||
* 4. do not report overrides of public API? effectively, this means 'no report on overrides at all'
|
||||
* 2. Members of public API interfaces
|
||||
* 3. do not report overrides of public API? effectively, this means 'no report on overrides at all'
|
||||
* 4. Getters and setters (because getters can't change visibility and setter-only explicit visibility looks ugly)
|
||||
*
|
||||
* Do we need something like @PublicApiFile to disable (or invert) this inspection per-file?
|
||||
*/
|
||||
@@ -86,14 +86,15 @@ class ApiModeDeclarationChecker : DeclarationChecker {
|
||||
/* 1. */ if ((descriptor as? ClassConstructorDescriptor)?.isPrimary == true) return true
|
||||
val isMemberOfPublicInterface =
|
||||
(descriptor.containingDeclaration as? ClassDescriptor)?.let { DescriptorUtils.isInterface(it) && it.effectiveVisibility().publicApi }
|
||||
/* 3. */ if (descriptor is CallableDescriptor && isMemberOfPublicInterface == true) return true
|
||||
/* 4. */ if ((descriptor as? CallableDescriptor)?.overriddenDescriptors?.isNotEmpty() == true) return true
|
||||
/* 2. */ if (descriptor is CallableDescriptor && isMemberOfPublicInterface == true) return true
|
||||
/* 3. */ if ((descriptor as? CallableDescriptor)?.overriddenDescriptors?.isNotEmpty() == true) return true
|
||||
/* 4. */ if (descriptor is PropertyAccessorDescriptor) return true
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun isEnabled(settings: LanguageVersionSettings): ApiMode {
|
||||
return settings.getFlag(AnalysisFlags.apiMode)
|
||||
fun isEnabled(settings: LanguageVersionSettings): ExplicitApiMode {
|
||||
return settings.getFlag(AnalysisFlags.explicitApiMode)
|
||||
}
|
||||
|
||||
fun returnTypeRequired(
|
||||
Reference in New Issue
Block a user