Do not use IntelliJ extensions for unused parameter suppressor in JS

This commit is contained in:
Alexander Udalov
2017-10-24 17:55:33 +02:00
parent d782c8a644
commit 7f81601123
8 changed files with 104 additions and 22 deletions
@@ -52,6 +52,7 @@ import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getDispatchReceiverWi
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.hasThisOrNoDispatchReceiver
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.types.KotlinType
@@ -64,15 +65,26 @@ class ControlFlowInformationProvider private constructor(
private val subroutine: KtElement,
private val trace: BindingTrace,
private val pseudocode: Pseudocode,
private val languageVersionSettings: LanguageVersionSettings
private val languageVersionSettings: LanguageVersionSettings,
private val diagnosticSuppressor: PlatformDiagnosticSuppressor
) {
private val pseudocodeVariablesData by lazy {
PseudocodeVariablesData(pseudocode, trace.bindingContext)
}
constructor(declaration: KtElement, trace: BindingTrace, languageVersionSettings: LanguageVersionSettings)
: this(declaration, trace, ControlFlowProcessor(trace).generatePseudocode(declaration), languageVersionSettings)
constructor(
declaration: KtElement,
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings,
diagnosticSuppressor: PlatformDiagnosticSuppressor
) : this(
declaration,
trace,
ControlFlowProcessor(trace).generatePseudocode(declaration),
languageVersionSettings,
diagnosticSuppressor
)
fun checkForLocalClassOrObjectMode() {
// Local classes and objects are analyzed twice: when TopDownAnalyzer processes it and as a part of its container.
@@ -178,7 +190,8 @@ class ControlFlowInformationProvider private constructor(
val expectedType = functionDescriptor?.returnType
val providerForLocalDeclaration = ControlFlowInformationProvider(
element, trace, localDeclarationInstruction.body, languageVersionSettings)
element, trace, localDeclarationInstruction.body, languageVersionSettings, diagnosticSuppressor
)
providerForLocalDeclaration.checkFunction(expectedType)
}
@@ -656,8 +669,10 @@ class ControlFlowInformationProvider private constructor(
is KtPrimaryConstructor -> if (!element.hasValOrVar()) {
val containingClass = owner.getContainingClassOrObject()
val containingClassDescriptor = trace.get(DECLARATION_TO_DESCRIPTOR, containingClass) as? ClassDescriptor
if (!DescriptorUtils.isAnnotationClass(containingClassDescriptor) && containingClassDescriptor?.isExpect == false &&
!containingClassDescriptor.isEffectivelyExternal()
if (!DescriptorUtils.isAnnotationClass(containingClassDescriptor) &&
containingClassDescriptor?.isExpect == false &&
!containingClassDescriptor.isEffectivelyExternal() &&
diagnosticSuppressor.shouldReportUnusedParameter(variableDescriptor)
) {
report(UNUSED_PARAMETER.on(element, variableDescriptor), ctxt)
}
@@ -680,7 +695,8 @@ class ControlFlowInformationProvider private constructor(
|| functionDescriptor.isEffectivelyExternal()
|| OperatorNameConventions.GET_VALUE == functionName
|| OperatorNameConventions.SET_VALUE == functionName
|| OperatorNameConventions.PROVIDE_DELEGATE == functionName) {
|| OperatorNameConventions.PROVIDE_DELEGATE == functionName
|| !diagnosticSuppressor.shouldReportUnusedParameter(variableDescriptor)) {
return
}
if (anonymous) {
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor;
import org.jetbrains.kotlin.types.KotlinType;
import java.util.Map;
@@ -32,16 +33,21 @@ import java.util.Map;
import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
public class ControlFlowAnalyzer {
@NotNull private final BindingTrace trace;
@NotNull private final KotlinBuiltIns builtIns;
@NotNull private final LanguageVersionSettings languageVersionSettings;
private final BindingTrace trace;
private final KotlinBuiltIns builtIns;
private final LanguageVersionSettings languageVersionSettings;
private final PlatformDiagnosticSuppressor diagnosticSuppressor;
public ControlFlowAnalyzer(
@NotNull BindingTrace trace, @NotNull KotlinBuiltIns builtIns, @NotNull LanguageVersionSettings languageVersionSettings
@NotNull BindingTrace trace,
@NotNull KotlinBuiltIns builtIns,
@NotNull LanguageVersionSettings languageVersionSettings,
@NotNull PlatformDiagnosticSuppressor diagnosticSuppressor
) {
this.trace = trace;
this.builtIns = builtIns;
this.languageVersionSettings = languageVersionSettings;
this.diagnosticSuppressor = diagnosticSuppressor;
}
public void process(@NotNull BodiesResolveContext c) {
@@ -74,7 +80,7 @@ public class ControlFlowAnalyzer {
private void checkSecondaryConstructor(@NotNull KtSecondaryConstructor constructor) {
ControlFlowInformationProvider controlFlowInformationProvider =
new ControlFlowInformationProvider(constructor, trace, languageVersionSettings);
new ControlFlowInformationProvider(constructor, trace, languageVersionSettings, diagnosticSuppressor);
controlFlowInformationProvider.checkDeclaration();
controlFlowInformationProvider.checkFunction(builtIns.getUnitType());
}
@@ -82,8 +88,9 @@ public class ControlFlowAnalyzer {
private void checkDeclarationContainer(@NotNull BodiesResolveContext c, KtDeclarationContainer declarationContainer) {
// A pseudocode of class/object initialization corresponds to a class/object
// or initialization of properties corresponds to a package declared in a file
ControlFlowInformationProvider controlFlowInformationProvider =
new ControlFlowInformationProvider((KtElement) declarationContainer, trace, languageVersionSettings);
ControlFlowInformationProvider controlFlowInformationProvider = new ControlFlowInformationProvider(
(KtElement) declarationContainer, trace, languageVersionSettings, diagnosticSuppressor
);
if (c.getTopDownAnalysisMode().isLocalDeclarations()) {
controlFlowInformationProvider.checkForLocalClassOrObjectMode();
return;
@@ -102,9 +109,11 @@ public class ControlFlowAnalyzer {
}
}
private void checkFunction(@NotNull BodiesResolveContext c, @NotNull KtDeclarationWithBody function, @Nullable KotlinType expectedReturnType) {
private void checkFunction(
@NotNull BodiesResolveContext c, @NotNull KtDeclarationWithBody function, @Nullable KotlinType expectedReturnType
) {
ControlFlowInformationProvider controlFlowInformationProvider =
new ControlFlowInformationProvider(function, trace, languageVersionSettings);
new ControlFlowInformationProvider(function, trace, languageVersionSettings, diagnosticSuppressor);
if (c.getTopDownAnalysisMode().isLocalDeclarations()) {
controlFlowInformationProvider.checkForLocalClassOrObjectMode();
return;
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve.checkers
import org.jetbrains.kotlin.container.DefaultImplementation
import org.jetbrains.kotlin.descriptors.VariableDescriptor
@DefaultImplementation(PlatformDiagnosticSuppressor.Default::class)
interface PlatformDiagnosticSuppressor {
fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean
object Default : PlatformDiagnosticSuppressor {
override fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean = true
}
}
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor;
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension;
import org.jetbrains.kotlin.resolve.lazy.data.KtClassOrObjectInfo;
import org.jetbrains.kotlin.resolve.lazy.data.KtScriptInfo;
@@ -82,6 +83,7 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
private LanguageVersionSettings languageVersionSettings;
private DelegationFilter delegationFilter;
private WrappedTypeFactory wrappedTypeFactory;
private PlatformDiagnosticSuppressor platformDiagnosticSuppressor;
private final SyntheticResolveExtension syntheticResolveExtension;
@@ -135,17 +137,21 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
this.languageVersionSettings = languageVersionSettings;
}
@Inject
public void setDelegationFilter(@NotNull DelegationFilter delegationFilter) {
this.delegationFilter = delegationFilter;
}
@Inject
public void setWrappedTypeFactory(WrappedTypeFactory wrappedTypeFactory) {
public void setWrappedTypeFactory(@NotNull WrappedTypeFactory wrappedTypeFactory) {
this.wrappedTypeFactory = wrappedTypeFactory;
}
@Inject
public void setPlatformDiagnosticSuppressor(@NotNull PlatformDiagnosticSuppressor platformDiagnosticSuppressor) {
this.platformDiagnosticSuppressor = platformDiagnosticSuppressor;
}
// Only calls from injectors expected
@Deprecated
public ResolveSession(
@@ -462,6 +468,11 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
return wrappedTypeFactory;
}
@NotNull
public PlatformDiagnosticSuppressor getPlatformDiagnosticSuppressor() {
return platformDiagnosticSuppressor;
}
@Override
public void assertValid() {
module.assertValid();
@@ -349,7 +349,9 @@ class ResolveElementCache(
}
val controlFlowTrace = DelegatingBindingTrace(trace.bindingContext, "Element control flow resolve", resolveElement, allowSliceRewrite = true)
ControlFlowInformationProvider(resolveElement, controlFlowTrace, resolveElement.languageVersionSettings).checkDeclaration()
ControlFlowInformationProvider(
resolveElement, controlFlowTrace, resolveElement.languageVersionSettings, resolveSession.platformDiagnosticSuppressor
).checkDeclaration()
controlFlowTrace.addOwnDataTo(trace, null, false)
return Pair(trace.bindingContext, statementFilterUsed)
@@ -485,7 +487,9 @@ class ResolveElementCache(
forceResolveAnnotationsInside(property)
for (accessor in property.accessors) {
ControlFlowInformationProvider(accessor, trace, accessor.languageVersionSettings).checkDeclaration()
ControlFlowInformationProvider(
accessor, trace, accessor.languageVersionSettings, resolveSession.platformDiagnosticSuppressor
).checkDeclaration()
}
return trace
@@ -2,7 +2,6 @@
<id>org.jetbrains.kotlin</id>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<suppressStringProvider implementation="org.jetbrains.kotlin.js.analyze.SuppressUnusedParameterForJsNative"/>
<suppressStringProvider implementation="org.jetbrains.kotlin.js.analyze.SuppressNoBodyErrorsForNativeDeclarations"/>
<diagnosticSuppressor implementation="org.jetbrains.kotlin.js.analyze.SuppressUninitializedErrorsForNativeDeclarations"/>
</extensions>
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.js.analyze
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters1
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.js.PredefinedAnnotation.*
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor
import org.jetbrains.kotlin.resolve.diagnostics.DiagnosticSuppressor
import org.jetbrains.kotlin.resolve.diagnostics.FUNCTION_NO_BODY_ERRORS
import org.jetbrains.kotlin.resolve.diagnostics.PROPERTY_NOT_INITIALIZED_ERRORS
@@ -30,7 +32,17 @@ import org.jetbrains.kotlin.resolve.diagnostics.SuppressDiagnosticsByAnnotations
private val NATIVE_ANNOTATIONS = arrayOf(NATIVE.fqName, NATIVE_INVOKE.fqName, NATIVE_GETTER.fqName, NATIVE_SETTER.fqName)
class SuppressUnusedParameterForJsNative : SuppressDiagnosticsByAnnotations(listOf(Errors.UNUSED_PARAMETER), *NATIVE_ANNOTATIONS)
object JsNativeDiagnosticSuppressor : PlatformDiagnosticSuppressor {
override fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean {
var descriptor: DeclarationDescriptor = parameter
while (true) {
val annotations = descriptor.annotations
if (!annotations.isEmpty() && NATIVE_ANNOTATIONS.any(annotations::hasAnnotation)) return false
descriptor = descriptor.containingDeclaration ?: break
}
return true
}
}
class SuppressNoBodyErrorsForNativeDeclarations : SuppressDiagnosticsByAnnotations(FUNCTION_NO_BODY_ERRORS + PROPERTY_NOT_INITIALIZED_ERRORS, *NATIVE_ANNOTATIONS)
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.resolve
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useImpl
import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.js.analyze.JsNativeDiagnosticSuppressor
import org.jetbrains.kotlin.js.naming.NameSuggestion
import org.jetbrains.kotlin.js.resolve.diagnostics.*
import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap
@@ -72,5 +73,6 @@ object JsPlatformConfigurator : PlatformConfigurator(
container.useImpl<JsReifiedNativeChecker>()
container.useInstance(ExtensionFunctionToExternalIsInlinable)
container.useInstance(JsQualifierChecker)
container.useInstance(JsNativeDiagnosticSuppressor)
}
}