Simple diagnostic on 'operator' keyword

This commit is contained in:
Yan Zhulanow
2015-09-18 19:15:59 +03:00
parent 43bf87e82d
commit ce4bcbba6d
6 changed files with 115 additions and 1 deletions
@@ -0,0 +1,80 @@
/*
* Copyright 2010-2015 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.
*/
/*
* Copyright 2010-2015 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
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.JetDeclaration
import org.jetbrains.kotlin.types.expressions.OperatorConventions.*
public class OperatorModifierChecker : DeclarationChecker {
private companion object {
private val GET = Name.identifier("get")
private val SET = Name.identifier("set")
private val COMPONENT_REGEX = "component\\d+".toRegex()
}
override fun check(
declaration: JetDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
val functionDescriptor = descriptor as? FunctionDescriptor ?: return
if (!functionDescriptor.isOperator) return
val modifier = declaration.modifierList?.getModifier(JetTokens.OPERATOR_KEYWORD) ?: return
val name = functionDescriptor.name
when {
GET == name -> {}
SET == name -> {}
INVOKE == name -> {}
CONTAINS == name -> {}
ITERATOR == name -> {}
EQUALS == name -> {}
COMPARE_TO == name -> {}
UNARY_OPERATION_NAMES.any { it.value == name } && functionDescriptor.valueParameters.isEmpty() -> {}
BINARY_OPERATION_NAMES.any { it.value == name } && functionDescriptor.valueParameters.size() == 1 -> {}
ASSIGNMENT_OPERATIONS.any { it.value == name } -> {}
name.asString().matches(COMPONENT_REGEX) -> {}
else -> diagnosticHolder.report(Errors.INAPPLICABLE_OPERATOR_MODIFIER.on(modifier))
}
}
}
@@ -39,7 +39,7 @@ public abstract class TargetPlatform(
}
}
private val DEFAULT_DECLARATION_CHECKERS = listOf(DataClassAnnotationChecker(), ConstModifierChecker, UnderscoreChecker)
private val DEFAULT_DECLARATION_CHECKERS = listOf(DataClassAnnotationChecker(), ConstModifierChecker, UnderscoreChecker, OperatorModifierChecker())
private val DEFAULT_CALL_CHECKERS = listOf(CapturingInClosureChecker(), InlineCheckerWrapper(), ReifiedTypeParameterSubstitutionChecker())
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
private val DEFAULT_VALIDATORS = listOf(DeprecatedSymbolValidator(), AccessToPrivateTopLevelSymbolValidator(), OperatorValidator())
@@ -32,6 +32,7 @@ public class OperatorConventions {
public static final Name COMPARE_TO = Name.identifier("compareTo");
public static final Name CONTAINS = Name.identifier("contains");
public static final Name INVOKE = Name.identifier("invoke");
public static final Name ITERATOR = Name.identifier("iterator");
private OperatorConventions() {}
@@ -0,0 +1,11 @@
class A {
operator fun A.minus(o: A) = o
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun A.add(o: A) = o
operator fun A.get(o: A) = o
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun A.invokee() {}
}
operator fun A.plus(o: A) = o
operator fun A.component1() = 1
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun A.componentN() = 1
@@ -0,0 +1,16 @@
package
public operator fun A.component1(): kotlin.Int
public operator fun A.componentN(): kotlin.Int
public operator fun A.plus(/*0*/ o: A): A
public final class A {
public constructor A()
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 operator fun A.add(/*0*/ o: A): A
public final operator fun A.get(/*0*/ o: A): A
public final operator fun A.invokee(): kotlin.Unit
public final operator fun A.minus(/*0*/ o: A): A
}
@@ -343,6 +343,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("OperatorsWithWrongNames.kt")
public void testOperatorsWithWrongNames() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/OperatorsWithWrongNames.kt");
doTest(fileName);
}
@TestMetadata("OverrideFunctionWithParamDefaultValue.kt")
public void testOverrideFunctionWithParamDefaultValue() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/OverrideFunctionWithParamDefaultValue.kt");