Names containing only '_' are deprecated (declarations, parameters, import aliases, labels, but not backquoted names)

This commit is contained in:
Mikhail Glukhikh
2015-09-25 14:51:00 +03:00
parent ebfb6c8468
commit 0a0bfdacb1
12 changed files with 130 additions and 10 deletions
@@ -522,6 +522,8 @@ public interface Errors {
DiagnosticFactory1<JetSimpleNameExpression, JetType> COMPARE_TO_TYPE_MISMATCH = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> UNDESCORE_IS_DEPRECATED = DiagnosticFactory0.create(WARNING);
// Labels
DiagnosticFactory0<JetSimpleNameExpression> LABEL_NAME_CLASH = DiagnosticFactory0.create(WARNING);
@@ -352,6 +352,8 @@ public class DefaultErrorMessages {
MAP.put(COMPARE_TO_TYPE_MISMATCH, "''compareTo()'' must return kotlin.Int, but returns {0}", RENDER_TYPE);
MAP.put(UNDESCORE_IS_DEPRECATED, "Names _, __, ___, ..., are deprecated");
MAP.put(RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY,
"Returns are not allowed for functions with expression body. Use block body in '{...}'");
MAP.put(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY, "A 'return' expression required in a function with a block body ('{...}')");
@@ -200,6 +200,7 @@ public class ModifiersChecker {
for (JetMultiDeclarationEntry multiEntry: multiDeclaration.getEntries()) {
annotationChecker.check(multiEntry, trace, null);
ModifierCheckerCore.INSTANCE$.check(multiEntry, trace, null);
UnderscoreChecker.INSTANCE$.checkNamed(multiEntry, trace);
}
}
@@ -38,7 +38,7 @@ public abstract class TargetPlatform(
}
}
private val DEFAULT_DECLARATION_CHECKERS = listOf(DataClassAnnotationChecker(), ConstModifierChecker)
private val DEFAULT_DECLARATION_CHECKERS = listOf(DataClassAnnotationChecker(), ConstModifierChecker, UnderscoreChecker)
private val DEFAULT_CALL_CHECKERS = listOf(CapturingInClosureChecker(), InlineCheckerWrapper(), ReifiedTypeParameterSubstitutionChecker())
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
private val DEFAULT_VALIDATORS = listOf(DeprecatedSymbolValidator(), AccessToPrivateTopLevelSymbolValidator())
@@ -0,0 +1,60 @@
/*
* 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 com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.JetCallableDeclaration
import org.jetbrains.kotlin.psi.JetDeclaration
import org.jetbrains.kotlin.psi.JetNamedDeclaration
import org.jetbrains.kotlin.psi.JetTypeParameterListOwner
object UnderscoreChecker : DeclarationChecker {
fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) {
if (identifier == null || identifier.text.isEmpty()) return
if (identifier.text.all { it == '_' }) {
diagnosticHolder.report(Errors.UNDESCORE_IS_DEPRECATED.on(identifier))
}
}
fun checkNamed(declaration: JetNamedDeclaration, diagnosticHolder: DiagnosticSink) {
checkIdentifier(declaration.nameIdentifier, diagnosticHolder)
}
override fun check(
declaration: JetDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
if (declaration is JetCallableDeclaration) {
for (parameter in declaration.valueParameters) {
checkNamed(parameter, diagnosticHolder)
}
}
if (declaration is JetTypeParameterListOwner) {
for (typeParameter in declaration.typeParameters) {
checkNamed(typeParameter, diagnosticHolder)
}
}
if (declaration !is JetNamedDeclaration) return
checkNamed(declaration, diagnosticHolder)
}
}
@@ -100,6 +100,11 @@ class LazyImportResolver(
}
}
}
for ((alias, import) in explicitClassImports.entries()) {
if (alias.all { it == '_' }) {
traceForImportResolve.report(Errors.UNDESCORE_IS_DEPRECATED.on(import))
}
}
for (alias in explicitClassImports.keySet()) {
val imports = explicitClassImports.get(alias)
if (imports.size() > 1) {
@@ -867,6 +867,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@NotNull ExpressionTypingContext context,
boolean isStatement
) {
JetSimpleNameExpression labelExpression = expression.getTargetLabel();
if (labelExpression != null) {
PsiElement labelIdentifier = labelExpression.getIdentifier();
UnderscoreChecker.INSTANCE$.checkIdentifier(labelIdentifier, context.trace);
}
JetExpression baseExpression = expression.getBaseExpression();
if (baseExpression == null) return TypeInfoFactoryPackage.noTypeInfo(context);
+16
View File
@@ -0,0 +1,16 @@
// !DIAGNOSTICS: -DEPRECATED_SYMBOL_WITH_MESSAGE
<!UNDESCORE_IS_DEPRECATED!>import kotlin.Deprecated as ___<!>
@___("") data class Pair(val x: Int, val y: Int)
class <!UNDESCORE_IS_DEPRECATED!>_<!><<!UNDESCORE_IS_DEPRECATED!>________<!>>
val <!UNDESCORE_IS_DEPRECATED!>______<!> = _<Int>()
fun <!UNDESCORE_IS_DEPRECATED!>__<!>(<!UNDESCORE_IS_DEPRECATED!>___<!>: Int, y: _<Int>?): Int {
val (x, <!UNDESCORE_IS_DEPRECATED!>__________<!>) = Pair(___ - 1, 42)
val <!UNDESCORE_IS_DEPRECATED!>____<!> = x
// in backquotes: allowed
val `_` = __________
<!UNDESCORE_IS_DEPRECATED!>__<!>@ return if (y != null) __(____, y) else __(`_`, ______)
}
+23
View File
@@ -0,0 +1,23 @@
package
public val ______: _<kotlin.Int>
public fun __(/*0*/ ___: kotlin.Int, /*1*/ y: _<kotlin.Int>?): kotlin.Int
@kotlin.Deprecated(value = "") @kotlin.data() public final class Pair {
public constructor Pair(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
public final val x: kotlin.Int
public final val y: kotlin.Int
public final /*synthesized*/ fun component1(): kotlin.Int
public final /*synthesized*/ fun component2(): kotlin.Int
public final /*synthesized*/ fun copy(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.Int = ...): Pair
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 _</*0*/ ________> {
public constructor _</*0*/ ________>()
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
}
@@ -4,7 +4,7 @@
// FILE: a.kt
package p
public interface B<T, _> {
public interface B<T, Z> {
public fun foo(a: T?)
}
@@ -12,7 +12,7 @@ public interface B<T, _> {
// FILE: b.kt
package p
public interface C<X, _> : B<X, _> {
public interface C<X, Z> : B<X, Z> {
override fun foo(a: X?)
}
@@ -21,7 +21,7 @@ public interface C<X, _> : B<X, _> {
// FILE: b.kt
package p
public interface B<_, T> {
public interface B<Z, T> {
public fun foo(a: T?)
}
@@ -3,7 +3,7 @@ package
package p {
public interface B</*0*/ T, /*1*/ _> {
public interface B</*0*/ T, /*1*/ Z> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(/*0*/ a: T?): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -17,11 +17,11 @@ package
package p {
public interface B</*0*/ T, /*1*/ _> {
public interface B</*0*/ T, /*1*/ Z> {
// -- Module: <m1> --
}
public interface C</*0*/ X, /*1*/ _> : p.B<X, _> {
public interface C</*0*/ X, /*1*/ Z> : p.B<X, Z> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ fun foo(/*0*/ a: X?): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -35,7 +35,7 @@ package
package p {
public interface B</*0*/ _, /*1*/ T> {
public interface B</*0*/ Z, /*1*/ T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(/*0*/ a: T?): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -51,11 +51,11 @@ public fun </*0*/ Y, /*1*/ Z> test(/*0*/ b: p.B<Y, Z>?): kotlin.Unit
package p {
public interface B</*0*/ _, /*1*/ T> {
public interface B</*0*/ Z, /*1*/ T> {
// -- Module: <m3> --
}
public interface C</*0*/ X, /*1*/ _> : p.B<X, _> {
public interface C</*0*/ X, /*1*/ Z> : p.B<X, Z> {
// -- Module: <m2> --
}
}
@@ -541,6 +541,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("Underscore.kt")
public void testUnderscore() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/Underscore.kt");
doTest(fileName);
}
@TestMetadata("UnitByDefaultForFunctionTypes.kt")
public void testUnitByDefaultForFunctionTypes() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/UnitByDefaultForFunctionTypes.kt");