Control-Flow Analysis: Reuse pseudo-value information for unused expression analysis
This commit is contained in:
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableInitState;
|
|||||||
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState;
|
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.PseudoValue;
|
import org.jetbrains.jet.lang.cfg.pseudocode.PseudoValue;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
|
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
|
||||||
|
import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodePackage;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeUtil;
|
import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeUtil;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.Instruction;
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.Instruction;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.InstructionVisitor;
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.InstructionVisitor;
|
||||||
@@ -50,6 +51,7 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
|
|||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.TailRecursionKind;
|
import org.jetbrains.jet.lang.resolve.calls.TailRecursionKind;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
@@ -121,10 +123,10 @@ public class JetFlowInformationProvider {
|
|||||||
|
|
||||||
markUnusedVariables();
|
markUnusedVariables();
|
||||||
|
|
||||||
markUnusedLiteralsInBlock();
|
|
||||||
|
|
||||||
markStatements();
|
markStatements();
|
||||||
|
|
||||||
|
markUnusedExpressions();
|
||||||
|
|
||||||
markWhenWithoutElse();
|
markWhenWithoutElse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,36 +668,28 @@ public class JetFlowInformationProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// "Unused literals" in block
|
// "Unused expressions" in block
|
||||||
|
|
||||||
public void markUnusedLiteralsInBlock() {
|
public void markUnusedExpressions() {
|
||||||
final Map<Instruction, DiagnosticFactory<?>> reportedDiagnosticMap = Maps.newHashMap();
|
final Map<Instruction, DiagnosticFactory<?>> reportedDiagnosticMap = Maps.newHashMap();
|
||||||
PseudocodeTraverserPackage.traverse(
|
PseudocodeTraverserPackage.traverse(
|
||||||
pseudocode, FORWARD, new FunctionVoid1<Instruction>() {
|
pseudocode, FORWARD, new JetFlowInformationProvider.FunctionVoid1<Instruction>() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(@NotNull Instruction instruction) {
|
public void execute(@NotNull Instruction instruction) {
|
||||||
if (!(instruction instanceof ReadValueInstruction || instruction instanceof MagicInstruction)) return;
|
if (!(instruction instanceof JetElementInstruction)) return;
|
||||||
|
|
||||||
JetElement element = ((JetElementInstruction) instruction).getElement();
|
JetElement element = ((JetElementInstruction)instruction).getElement();
|
||||||
if (!(element instanceof JetFunctionLiteralExpression
|
if (!(element instanceof JetExpression)) return;
|
||||||
|| element instanceof JetConstantExpression
|
|
||||||
|| element instanceof JetStringTemplateExpression
|
|
||||||
|| element instanceof JetSimpleNameExpression)) return;
|
|
||||||
|
|
||||||
if (!(element instanceof JetStringTemplateExpression || instruction instanceof ReadValueInstruction)) return;
|
if (BindingContextUtilPackage.isUsedAsStatement((JetExpression) element, trace.getBindingContext())
|
||||||
|
&& PseudocodePackage.getSideEffectFree(instruction)) {
|
||||||
VariableContext ctxt = new VariableContext(instruction, reportedDiagnosticMap);
|
VariableContext ctxt = new VariableContext(instruction, reportedDiagnosticMap);
|
||||||
|
report(
|
||||||
PsiElement parent = element.getParent();
|
element instanceof JetFunctionLiteralExpression
|
||||||
if (parent instanceof JetBlockExpression) {
|
? Errors.UNUSED_FUNCTION_LITERAL.on((JetFunctionLiteralExpression) element)
|
||||||
if (!JetPsiUtil.isImplicitlyUsed(element)) {
|
: Errors.UNUSED_EXPRESSION.on(element),
|
||||||
if (element instanceof JetFunctionLiteralExpression) {
|
ctxt
|
||||||
report(Errors.UNUSED_FUNCTION_LITERAL.on((JetFunctionLiteralExpression) element), ctxt);
|
);
|
||||||
}
|
|
||||||
else {
|
|
||||||
report(Errors.UNUSED_EXPRESSION.on(element), ctxt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,4 +64,6 @@ public interface Pseudocode {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
List<? extends Instruction> getUsages(@Nullable PseudoValue value);
|
List<? extends Instruction> getUsages(@Nullable PseudoValue value);
|
||||||
|
|
||||||
|
boolean isSideEffectFree(@NotNull Instruction instruction);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,16 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
|||||||
|
|
||||||
import com.google.common.collect.*;
|
import com.google.common.collect.*;
|
||||||
import com.intellij.util.containers.BidirectionalMap;
|
import com.intellij.util.containers.BidirectionalMap;
|
||||||
|
import jet.runtime.typeinfo.JetValueParameter;
|
||||||
import kotlin.Function0;
|
import kotlin.Function0;
|
||||||
|
import kotlin.Function1;
|
||||||
import kotlin.KotlinPackage;
|
import kotlin.KotlinPackage;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.cfg.Label;
|
import org.jetbrains.jet.lang.cfg.Label;
|
||||||
import org.jetbrains.jet.lang.cfg.LoopInfo;
|
import org.jetbrains.jet.lang.cfg.LoopInfo;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.*;
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.*;
|
||||||
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.InstructionWithValue;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.MergeInstruction;
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.MergeInstruction;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.AbstractJumpInstruction;
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.AbstractJumpInstruction;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.ConditionalJumpInstruction;
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.ConditionalJumpInstruction;
|
||||||
@@ -95,6 +98,7 @@ public class PseudocodeImpl implements Pseudocode {
|
|||||||
|
|
||||||
private final Map<PseudoValue, List<Instruction>> valueUsages = Maps.newHashMap();
|
private final Map<PseudoValue, List<Instruction>> valueUsages = Maps.newHashMap();
|
||||||
private final Map<PseudoValue, Set<PseudoValue>> mergedValues = Maps.newHashMap();
|
private final Map<PseudoValue, Set<PseudoValue>> mergedValues = Maps.newHashMap();
|
||||||
|
private final Set<Instruction> sideEffectFree = Sets.newHashSet();
|
||||||
|
|
||||||
private Pseudocode parent = null;
|
private Pseudocode parent = null;
|
||||||
private Set<LocalFunctionDeclarationInstruction> localDeclarations = null;
|
private Set<LocalFunctionDeclarationInstruction> localDeclarations = null;
|
||||||
@@ -239,6 +243,9 @@ public class PseudocodeImpl implements Pseudocode {
|
|||||||
addValueUsage(mergedValue, instruction);
|
addValueUsage(mergedValue, instruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (PseudocodePackage.calcSideEffectFree(instruction)) {
|
||||||
|
sideEffectFree.add(instruction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ void recordLoopInfo(JetExpression expression, LoopInfo blockInfo) {
|
/*package*/ void recordLoopInfo(JetExpression expression, LoopInfo blockInfo) {
|
||||||
@@ -283,6 +290,11 @@ public class PseudocodeImpl implements Pseudocode {
|
|||||||
return result != null ? result : Collections.<Instruction>emptyList();
|
return result != null ? result : Collections.<Instruction>emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSideEffectFree(@NotNull Instruction instruction) {
|
||||||
|
return sideEffectFree.contains(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
/*package*/ void bindElementToValue(@NotNull JetElement element, @NotNull PseudoValue value) {
|
/*package*/ void bindElementToValue(@NotNull JetElement element, @NotNull PseudoValue value) {
|
||||||
elementsToValues.put(element, value);
|
elementsToValues.put(element, value);
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-16
@@ -131,25 +131,25 @@ public class MagicInstruction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum class MagicKind {
|
public enum class MagicKind(val sideEffectFree: Boolean = false) {
|
||||||
// builtin operations
|
// builtin operations
|
||||||
STRING_TEMPLATE
|
STRING_TEMPLATE: MagicKind(true)
|
||||||
AND
|
AND: MagicKind(true)
|
||||||
OR
|
OR: MagicKind(true)
|
||||||
NOT_NULL_ASSERTION
|
NOT_NULL_ASSERTION: MagicKind()
|
||||||
EQUALS_IN_WHEN_CONDITION
|
EQUALS_IN_WHEN_CONDITION: MagicKind()
|
||||||
IS
|
IS: MagicKind()
|
||||||
CAST
|
CAST: MagicKind()
|
||||||
CALLABLE_REFERENCE
|
CALLABLE_REFERENCE: MagicKind(true)
|
||||||
// implicit operations
|
// implicit operations
|
||||||
LOOP_RANGE_ITERATION
|
LOOP_RANGE_ITERATION: MagicKind()
|
||||||
IMPLICIT_RECEIVER
|
IMPLICIT_RECEIVER: MagicKind()
|
||||||
VALUE_CONSUMER
|
VALUE_CONSUMER: MagicKind()
|
||||||
// unrecognized operations
|
// unrecognized operations
|
||||||
UNRESOLVED_CALL
|
UNRESOLVED_CALL: MagicKind()
|
||||||
UNSUPPORTED_ELEMENT
|
UNSUPPORTED_ELEMENT: MagicKind()
|
||||||
UNRECOGNIZED_WRITE_RHS
|
UNRECOGNIZED_WRITE_RHS: MagicKind()
|
||||||
FAKE_INITIALIZER
|
FAKE_INITIALIZER: MagicKind()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merges values produced by alternative control-flow paths (such as 'if' branches)
|
// Merges values produced by alternative control-flow paths (such as 'if' branches)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.cfg.pseudocode
|
package org.jetbrains.jet.lang.cfg.pseudocode
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.*
|
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.*
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.*
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.*
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.*
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.*
|
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.*
|
||||||
@@ -31,7 +30,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue
|
|||||||
import org.jetbrains.jet.lang.resolve.OverridingUtil
|
import org.jetbrains.jet.lang.resolve.OverridingUtil
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils
|
import org.jetbrains.jet.lang.types.TypeUtils
|
||||||
import org.jetbrains.jet.lang.types.JetType
|
import org.jetbrains.jet.lang.types.JetType
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.special.LocalFunctionDeclarationInstruction
|
import org.jetbrains.jet.lang.descriptors.impl.LocalVariableDescriptor
|
||||||
|
|
||||||
fun getReceiverTypePredicate(resolvedCall: ResolvedCall<*>, receiverValue: ReceiverValue): TypePredicate? {
|
fun getReceiverTypePredicate(resolvedCall: ResolvedCall<*>, receiverValue: ReceiverValue): TypePredicate? {
|
||||||
val callableDescriptor = resolvedCall.getResultingDescriptor()
|
val callableDescriptor = resolvedCall.getResultingDescriptor()
|
||||||
@@ -134,4 +133,32 @@ public fun Instruction.getPrimaryDeclarationDescriptorIfAny(bindingContext: Bind
|
|||||||
is CallInstruction -> return resolvedCall.getResultingDescriptor()
|
is CallInstruction -> return resolvedCall.getResultingDescriptor()
|
||||||
else -> PseudocodeUtil.extractVariableDescriptorIfAny(this, false, bindingContext)
|
else -> PseudocodeUtil.extractVariableDescriptorIfAny(this, false, bindingContext)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public val Instruction.sideEffectFree: Boolean
|
||||||
|
get() = owner.isSideEffectFree(this)
|
||||||
|
|
||||||
|
private fun Instruction.calcSideEffectFree(): Boolean {
|
||||||
|
if (this !is InstructionWithValue) return false
|
||||||
|
if (!inputValues.all { it.createdAt?.sideEffectFree ?: false }) return false
|
||||||
|
|
||||||
|
return when (this) {
|
||||||
|
is ReadValueInstruction -> target.let {
|
||||||
|
when (it) {
|
||||||
|
is AccessTarget.Call -> when (it.resolvedCall.getResultingDescriptor()) {
|
||||||
|
is LocalVariableDescriptor, is ValueParameterDescriptor, is ReceiverParameterDescriptor -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> when (element) {
|
||||||
|
is JetConstantExpression, is JetFunctionLiteralExpression, is JetStringTemplateExpression -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is MagicInstruction -> kind.sideEffectFree
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -282,29 +282,6 @@ public class JetPsiUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isImplicitlyUsed(@NotNull JetElement element) {
|
|
||||||
PsiElement parent = element.getParent();
|
|
||||||
if (!(parent instanceof JetBlockExpression)) return true;
|
|
||||||
JetBlockExpression block = (JetBlockExpression) parent;
|
|
||||||
List<JetElement> statements = block.getStatements();
|
|
||||||
if (statements.get(statements.size() - 1) == element) {
|
|
||||||
JetExpression expression = getDirectParentOfTypeForBlock(block, JetIfExpression.class);
|
|
||||||
if (expression == null) {
|
|
||||||
expression = getDirectParentOfTypeForBlock(block, JetWhenExpression.class);
|
|
||||||
}
|
|
||||||
if (expression == null) {
|
|
||||||
expression = getDirectParentOfTypeForBlock(block, JetFunctionLiteral.class);
|
|
||||||
}
|
|
||||||
if (expression == null) {
|
|
||||||
expression = getDirectParentOfTypeForBlock(block, JetTryExpression.class);
|
|
||||||
}
|
|
||||||
if (expression != null) {
|
|
||||||
return isImplicitlyUsed(expression);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deleteClass(@NotNull JetClassOrObject clazz) {
|
public static void deleteClass(@NotNull JetClassOrObject clazz) {
|
||||||
CheckUtil.checkWritable(clazz);
|
CheckUtil.checkWritable(clazz);
|
||||||
JetFile file = clazz.getContainingJetFile();
|
JetFile file = clazz.getContainingJetFile();
|
||||||
|
|||||||
-1
@@ -265,7 +265,6 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
else {
|
else {
|
||||||
facade.getTypeInfo(body, context.replaceScope(context.scope));
|
facade.getTypeInfo(body, context.replaceScope(context.scope));
|
||||||
}
|
}
|
||||||
context.trace.report(UNUSED_FUNCTION_LITERAL.on(function));
|
|
||||||
}
|
}
|
||||||
else if (body != null) {
|
else if (body != null) {
|
||||||
WritableScope writableScope = newWritableScopeImpl(context, "do..while body scope");
|
WritableScope writableScope = newWritableScopeImpl(context, "do..while body scope");
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ fun f(): Unit {
|
|||||||
<!TYPE_MISMATCH!>x<!> in 1..2
|
<!TYPE_MISMATCH!>x<!> in 1..2
|
||||||
|
|
||||||
val y : Boolean? = true
|
val y : Boolean? = true
|
||||||
false || <!TYPE_MISMATCH!>y<!>
|
<!UNUSED_EXPRESSION!>false || <!TYPE_MISMATCH!>y<!><!>
|
||||||
<!TYPE_MISMATCH!>y<!> && true
|
<!UNUSED_EXPRESSION!><!TYPE_MISMATCH!>y<!> && true<!>
|
||||||
<!TYPE_MISMATCH!>y<!> && <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>
|
<!UNUSED_EXPRESSION!><!TYPE_MISMATCH!>y<!> && <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!><!>
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ fun blockReturnValueTypeMatch() : Int {return 1}
|
|||||||
fun blockReturnValueTypeMismatchUnit() : Int {return <!TYPE_MISMATCH!>Unit<!>}
|
fun blockReturnValueTypeMismatchUnit() : Int {return <!TYPE_MISMATCH!>Unit<!>}
|
||||||
|
|
||||||
fun blockAndAndMismatch() : Int {
|
fun blockAndAndMismatch() : Int {
|
||||||
true && false
|
<!UNUSED_EXPRESSION!>true && false<!>
|
||||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
fun blockAndAndMismatch1() : Int {
|
fun blockAndAndMismatch1() : Int {
|
||||||
return <!TYPE_MISMATCH!>true && false<!>
|
return <!TYPE_MISMATCH!>true && false<!>
|
||||||
@@ -57,7 +57,7 @@ fun blockAndAndMismatch2() : Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun blockAndAndMismatch3() : Int {
|
fun blockAndAndMismatch3() : Int {
|
||||||
true || false
|
<!UNUSED_EXPRESSION!>true || false<!>
|
||||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
fun blockAndAndMismatch4() : Int {
|
fun blockAndAndMismatch4() : Int {
|
||||||
return <!TYPE_MISMATCH!>true || false<!>
|
return <!TYPE_MISMATCH!>true || false<!>
|
||||||
@@ -91,18 +91,18 @@ fun blockReturnValueTypeMatch6() : Int {
|
|||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch7() : Int {
|
fun blockReturnValueTypeMatch7() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
1.0
|
<!UNUSED_EXPRESSION!>1.0<!>
|
||||||
else 2.0
|
else <!UNUSED_EXPRESSION!>2.0<!>
|
||||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
fun blockReturnValueTypeMatch8() : Int {
|
fun blockReturnValueTypeMatch8() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
1.0
|
<!UNUSED_EXPRESSION!>1.0<!>
|
||||||
else 2.0
|
else <!UNUSED_EXPRESSION!>2.0<!>
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch9() : Int {
|
fun blockReturnValueTypeMatch9() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
1.0
|
<!UNUSED_EXPRESSION!>1.0<!>
|
||||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
fun blockReturnValueTypeMatch10() : Int {
|
fun blockReturnValueTypeMatch10() : Int {
|
||||||
return <!TYPE_MISMATCH!>if (1 > 2)
|
return <!TYPE_MISMATCH!>if (1 > 2)
|
||||||
@@ -110,7 +110,7 @@ fun blockReturnValueTypeMatch10() : Int {
|
|||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch11() : Int {
|
fun blockReturnValueTypeMatch11() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
else 1.0
|
else <!UNUSED_EXPRESSION!>1.0<!>
|
||||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
fun blockReturnValueTypeMatch12() : Int {
|
fun blockReturnValueTypeMatch12() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ fun demo() {
|
|||||||
<!UNUSED_EXPRESSION!>"$.$.asdf$\t"<!>
|
<!UNUSED_EXPRESSION!>"$.$.asdf$\t"<!>
|
||||||
<!UNUSED_EXPRESSION!>"asd\$"<!>
|
<!UNUSED_EXPRESSION!>"asd\$"<!>
|
||||||
<!UNUSED_EXPRESSION!>"asd$a<!ILLEGAL_ESCAPE!>\x<!>"<!>
|
<!UNUSED_EXPRESSION!>"asd$a<!ILLEGAL_ESCAPE!>\x<!>"<!>
|
||||||
<!UNUSED_EXPRESSION!>"asd$a$asd$ $<!UNRESOLVED_REFERENCE!>xxx<!>"<!>
|
"asd$a$asd$ $<!UNRESOLVED_REFERENCE!>xxx<!>"
|
||||||
<!UNUSED_EXPRESSION!>"fosdfasdo${1 + bar + 100}}sdsdfgdsfsdf"<!>
|
"fosdfasdo${1 + bar + 100}}sdsdfgdsfsdf"
|
||||||
<!UNUSED_EXPRESSION!>"foo${bar + map {foo}}sdfsdf"<!>
|
"foo${bar + map {foo}}sdfsdf"
|
||||||
<!UNUSED_EXPRESSION!>"foo${bar + map { "foo" }}sdfsdf"<!>
|
"foo${bar + map { "foo" }}sdfsdf"
|
||||||
<!UNUSED_EXPRESSION!>"foo${bar + map {
|
"foo${bar + map {
|
||||||
"foo$sdf${ buzz{}}" }}sdfsdf"<!>
|
"foo$sdf${ buzz{}}" }}sdfsdf"
|
||||||
<!UNUSED_EXPRESSION!>"a<!ILLEGAL_ESCAPE!>\u<!> <!ILLEGAL_ESCAPE!>\u<!>0 <!ILLEGAL_ESCAPE!>\u<!>00 <!ILLEGAL_ESCAPE!>\u<!>000 \u0000 \u0AaA <!ILLEGAL_ESCAPE!>\u<!>0AAz.length( ) + \u0022b"<!>
|
<!UNUSED_EXPRESSION!>"a<!ILLEGAL_ESCAPE!>\u<!> <!ILLEGAL_ESCAPE!>\u<!>0 <!ILLEGAL_ESCAPE!>\u<!>00 <!ILLEGAL_ESCAPE!>\u<!>000 \u0000 \u0AaA <!ILLEGAL_ESCAPE!>\u<!>0AAz.length( ) + \u0022b"<!>
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ fun testIf() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testIf1(b: Boolean) {
|
fun testIf1(b: Boolean) {
|
||||||
if (b) todo() else 1
|
if (b) todo() else <!UNUSED_EXPRESSION!>1<!>
|
||||||
|
|
||||||
bar()
|
bar()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ package kt1075
|
|||||||
fun foo(b: String) {
|
fun foo(b: String) {
|
||||||
if (<!TYPE_MISMATCH!>b<!> in 1..10) {} //type mismatch
|
if (<!TYPE_MISMATCH!>b<!> in 1..10) {} //type mismatch
|
||||||
when (b) {
|
when (b) {
|
||||||
<!TYPE_MISMATCH_IN_RANGE!>in<!> 1..10 -> 1 //no type mismatch, but it should be here
|
<!TYPE_MISMATCH_IN_RANGE!>in<!> 1..10 -> <!UNUSED_EXPRESSION!>1<!> //no type mismatch, but it should be here
|
||||||
else -> 2
|
else -> <!UNUSED_EXPRESSION!>2<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ fun foo() : Int {
|
|||||||
fun fff(): Int {
|
fun fff(): Int {
|
||||||
var d = 3
|
var d = 3
|
||||||
when(d) {
|
when(d) {
|
||||||
4 -> 21
|
4 -> <!UNUSED_EXPRESSION!>21<!>
|
||||||
return 2 -> <!UNREACHABLE_CODE!>return 47<!>
|
return 2 -> <!UNREACHABLE_CODE!>return 47<!>
|
||||||
<!UNREACHABLE_CODE!>bar() -> 45<!>
|
<!UNREACHABLE_CODE!>bar() -> 45<!>
|
||||||
<!UNREACHABLE_CODE!>444 -> true<!>
|
<!UNREACHABLE_CODE!>444 -> true<!>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fun test1(t : Pair<Int, Int>) : Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//more tests
|
//more tests
|
||||||
fun t1(x: Int) = when(x) {
|
fun t1(x: Int) = when(<!UNUSED_EXPRESSION!>x<!>) {
|
||||||
else -> 1
|
else -> 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ class BinOp(val operator : String) : Expr
|
|||||||
fun test(e : Expr) {
|
fun test(e : Expr) {
|
||||||
if (e is BinOp) {
|
if (e is BinOp) {
|
||||||
when (<!DEBUG_INFO_AUTOCAST!>e<!>.operator) {
|
when (<!DEBUG_INFO_AUTOCAST!>e<!>.operator) {
|
||||||
else -> 0
|
else -> <!UNUSED_EXPRESSION!>0<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,13 +2,10 @@
|
|||||||
|
|
||||||
fun foo(s: String?) {
|
fun foo(s: String?) {
|
||||||
when {
|
when {
|
||||||
s == null -> 1
|
s == null -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
<!DEBUG_INFO_AUTOCAST!>s<!>.foo() -> 2
|
<!DEBUG_INFO_AUTOCAST!>s<!>.foo() -> <!UNUSED_EXPRESSION!>2<!>
|
||||||
else -> 3
|
else -> <!UNUSED_EXPRESSION!>3<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.foo() = true
|
fun String.foo() = true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -71,5 +71,5 @@ import outer.*
|
|||||||
val c = Command()
|
val c = Command()
|
||||||
c<!UNNECESSARY_SAFE_CALL!>?.<!>equals2(null)
|
c<!UNNECESSARY_SAFE_CALL!>?.<!>equals2(null)
|
||||||
|
|
||||||
if (command == null) 1
|
if (command == null) <!UNUSED_EXPRESSION!>1<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ fun unusedLiteralInDoWhile(){
|
|||||||
do<!UNUSED_FUNCTION_LITERAL!>{() ->
|
do<!UNUSED_FUNCTION_LITERAL!>{() ->
|
||||||
val <!UNUSED_VARIABLE!>i<!> = 1
|
val <!UNUSED_VARIABLE!>i<!> = 1
|
||||||
}<!> while(false)
|
}<!> while(false)
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
package d
|
package d
|
||||||
|
|
||||||
trait A<T>
|
trait A<T>
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
fun test(a: Any) {
|
fun test(a: Any) {
|
||||||
when (a)<!SYNTAX!><!>
|
when (<!UNUSED_EXPRESSION!>a<!>)<!SYNTAX!><!>
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
package d
|
package d
|
||||||
|
|
||||||
fun foo(a : IntArray) {
|
fun foo(a : IntArray) {
|
||||||
|
|||||||
@@ -2,21 +2,21 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
|
|||||||
(s)(11)
|
(s)(11)
|
||||||
(s).invoke(11)
|
(s).invoke(11)
|
||||||
(s) invoke 11
|
(s) invoke 11
|
||||||
(<!USAGE_IS_NOT_INLINABLE!>s<!>)
|
(<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>s<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Function1<Int, Unit>.inlineExt() {
|
inline fun Function1<Int, Unit>.inlineExt() {
|
||||||
(this).invoke(11)
|
(this).invoke(11)
|
||||||
(this) invoke 11
|
(this) invoke 11
|
||||||
(this)(11)
|
(this)(11)
|
||||||
(<!USAGE_IS_NOT_INLINABLE!>this<!>)
|
(<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>this<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun inlineFunWithInvoke2(s: (p: Int) -> Unit) {
|
inline fun inlineFunWithInvoke2(s: (p: Int) -> Unit) {
|
||||||
(((s)))(11)
|
(((s)))(11)
|
||||||
(((s))).invoke(11)
|
(((s))).invoke(11)
|
||||||
(((s))) invoke 11
|
(((s))) invoke 11
|
||||||
(((<!USAGE_IS_NOT_INLINABLE!>s<!>)))
|
(((<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>s<!>)))
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun propagation(s: (p: Int) -> Unit) {
|
inline fun propagation(s: (p: Int) -> Unit) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ inline fun Function1<Int, Unit>.inlineExt() {
|
|||||||
this invoke 11
|
this invoke 11
|
||||||
this(11)
|
this(11)
|
||||||
|
|
||||||
<!USAGE_IS_NOT_INLINABLE!>this<!>
|
<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>this<!>
|
||||||
|
|
||||||
11
|
11
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
|
|||||||
(s: (p: Int) -> Unit)(11)
|
(s: (p: Int) -> Unit)(11)
|
||||||
(s: (p: Int) -> Unit).invoke(11)
|
(s: (p: Int) -> Unit).invoke(11)
|
||||||
(s: (p: Int) -> Unit) invoke 11
|
(s: (p: Int) -> Unit) invoke 11
|
||||||
(<!USAGE_IS_NOT_INLINABLE!>s<!>)
|
(<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>s<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Function1<Int, Unit>.inlineExt() {
|
inline fun Function1<Int, Unit>.inlineExt() {
|
||||||
@@ -18,4 +18,4 @@ inline fun inlineFunWithInvoke2(s: (p: Int) -> Unit) {
|
|||||||
(((s: (p: Int) -> Unit): (p: Int) -> Unit): (p: Int) -> Unit).invoke(11)
|
(((s: (p: Int) -> Unit): (p: Int) -> Unit): (p: Int) -> Unit).invoke(11)
|
||||||
(((s: (p: Int) -> Unit): (p: Int) -> Unit): (p: Int) -> Unit) invoke 11
|
(((s: (p: Int) -> Unit): (p: Int) -> Unit): (p: Int) -> Unit) invoke 11
|
||||||
(((<!USAGE_IS_NOT_INLINABLE!>s<!>: (p: Int) -> Unit)))
|
(((<!USAGE_IS_NOT_INLINABLE!>s<!>: (p: Int) -> Unit)))
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//FILE: foo.kt
|
//FILE: foo.kt
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val c: Type
|
val c: Type
|
||||||
when (<!UNINITIALIZED_VARIABLE!>c<!>) {
|
when (<!UNINITIALIZED_VARIABLE, UNUSED_EXPRESSION!>c<!>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
fun nonlocals(b : Boolean) {
|
fun nonlocals(b : Boolean) {
|
||||||
@a{(): Int ->
|
@a<!UNUSED_FUNCTION_LITERAL!>{(): Int ->
|
||||||
fun foo() {
|
fun foo() {
|
||||||
if (b) {
|
if (b) {
|
||||||
<!RETURN_NOT_ALLOWED!>return@a 1<!> // The label must be resolved, but an error should be reported for a non-local return
|
<!RETURN_NOT_ALLOWED!>return@a 1<!> // The label must be resolved, but an error should be reported for a non-local return
|
||||||
@@ -7,6 +7,5 @@ fun nonlocals(b : Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return@a 5
|
return@a 5
|
||||||
}
|
}<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
+3
-3
@@ -15,11 +15,11 @@ fun B.b() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
@b { B.() ->
|
@b <!UNUSED_FUNCTION_LITERAL!>{ B.() ->
|
||||||
object : A {
|
object : A {
|
||||||
override fun foo() {
|
override fun foo() {
|
||||||
this@b.bar()
|
this@b.bar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}<!>
|
||||||
}
|
}
|
||||||
@@ -6,5 +6,5 @@ fun Any.equals(other : Any?) : Boolean = this === other
|
|||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val command = parse("")
|
val command = parse("")
|
||||||
if (command == null) 1 // error on this line, but must be OK
|
if (command == null) <!UNUSED_EXPRESSION!>1<!> // error on this line, but must be OK
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
fun <T> T.mustBe(t : T) {
|
fun <T> T.mustBe(t : T) {
|
||||||
<!UNUSED_EXPRESSION!>"$this must be$<!SYNTAX!>as<!>$t"<!>
|
"$this must be$<!SYNTAX!>as<!>$t"
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
fun foo(i: Int) {
|
fun foo(i: Int) {
|
||||||
<!FUNCTION_EXPECTED!>i<!>()
|
<!FUNCTION_EXPECTED!>i<!>()
|
||||||
<!FUNCTION_EXPECTED!>1<!>()
|
<!FUNCTION_EXPECTED!>1<!>()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// FILE: f.kt
|
// FILE: f.kt
|
||||||
class A() {
|
class A() {
|
||||||
fun foo() : Unit {
|
fun foo() : Unit {
|
||||||
this@A
|
<!UNUSED_EXPRESSION!>this@A<!>
|
||||||
this<!UNRESOLVED_REFERENCE!>@a<!>
|
this<!UNRESOLVED_REFERENCE!>@a<!>
|
||||||
this
|
<!UNUSED_EXPRESSION!>this<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val x = this@A.foo()
|
val x = this@A.foo()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ fun notAnExpression() {
|
|||||||
if (<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>) {} else {} // not an expression
|
if (<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>) {} else {} // not an expression
|
||||||
val <!UNUSED_VARIABLE!>x<!> = <!SUPER_IS_NOT_AN_EXPRESSION!>super<!> // not an expression
|
val <!UNUSED_VARIABLE!>x<!> = <!SUPER_IS_NOT_AN_EXPRESSION!>super<!> // not an expression
|
||||||
when (1) {
|
when (1) {
|
||||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!> -> 1 // not an expression
|
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!> -> <!UNUSED_EXPRESSION!>1<!> // not an expression
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ fun foo() : Int {
|
|||||||
val s = ""
|
val s = ""
|
||||||
val x = 1
|
val x = 1
|
||||||
when (x) {
|
when (x) {
|
||||||
is <!INCOMPATIBLE_TYPES!>String<!> -> 1
|
is <!INCOMPATIBLE_TYPES!>String<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
!is Int -> 1
|
!is Int -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
is Any<!USELESS_NULLABLE_CHECK!>?<!> -> 1
|
is Any<!USELESS_NULLABLE_CHECK!>?<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
<!INCOMPATIBLE_TYPES!>s<!> -> 1
|
<!INCOMPATIBLE_TYPES!>s<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
1 -> 1
|
1 -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
1 + <!UNRESOLVED_REFERENCE!>a<!> -> 1
|
1 + <!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
in 1..<!UNRESOLVED_REFERENCE!>a<!> -> 1
|
in 1..<!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
!in 1..<!UNRESOLVED_REFERENCE!>a<!> -> 1
|
!in 1..<!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
else -> 1
|
else -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
@@ -25,20 +25,20 @@ fun test() {
|
|||||||
val s = "";
|
val s = "";
|
||||||
|
|
||||||
when (x) {
|
when (x) {
|
||||||
<!INCOMPATIBLE_TYPES!>s<!> -> 1
|
<!INCOMPATIBLE_TYPES!>s<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
<!INCOMPATIBLE_TYPES!>""<!> -> 1
|
<!INCOMPATIBLE_TYPES!>""<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
x -> 1
|
x -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
1 -> 1
|
1 -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val z = 1
|
val z = 1
|
||||||
|
|
||||||
when (z) {
|
when (z) {
|
||||||
<!ELSE_MISPLACED_IN_WHEN!>else<!> -> 1
|
<!ELSE_MISPLACED_IN_WHEN!>else<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
<!UNREACHABLE_CODE!>1 -> 2<!>
|
<!UNREACHABLE_CODE!>1 -> 2<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
when (z) {
|
when (<!UNUSED_EXPRESSION!>z<!>) {
|
||||||
else -> 1
|
else -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
trait A
|
trait A
|
||||||
abstract class B
|
abstract class B
|
||||||
annotation class C
|
annotation class C
|
||||||
@@ -8,4 +9,4 @@ fun main() {
|
|||||||
::<!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B<!>
|
::<!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B<!>
|
||||||
::C // KT-3465
|
::C // KT-3465
|
||||||
::<!INVISIBLE_MEMBER!>D<!>
|
::<!INVISIBLE_MEMBER!>D<!>
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
fun foo(x: Int, <!UNUSED_PARAMETER!>y<!>: Any) = x
|
fun foo(x: Int, <!UNUSED_PARAMETER!>y<!>: Any) = x
|
||||||
fun foo(<!UNUSED_PARAMETER!>x<!>: Any, y: Int) = y
|
fun foo(<!UNUSED_PARAMETER!>x<!>: Any, y: Int) = y
|
||||||
|
|
||||||
@@ -5,4 +6,4 @@ fun main() {
|
|||||||
::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
|
::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
|
||||||
|
|
||||||
::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!> : (Int, Any) -> Unit
|
::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!> : (Int, Any) -> Unit
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
// FILE: a.kt
|
// FILE: a.kt
|
||||||
|
|
||||||
package first
|
package first
|
||||||
@@ -23,4 +24,4 @@ fun main() {
|
|||||||
A::<!UNRESOLVED_REFERENCE!>baz<!>
|
A::<!UNRESOLVED_REFERENCE!>baz<!>
|
||||||
|
|
||||||
x : KExtensionFunction0<A, Unit>
|
x : KExtensionFunction0<A, Unit>
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
class A {
|
class A {
|
||||||
fun Int.extInt() = 42
|
fun Int.extInt() = 42
|
||||||
fun A.extA(x: String) = x
|
fun A.extA(x: String) = x
|
||||||
@@ -11,4 +12,4 @@ class A {
|
|||||||
fun main() {
|
fun main() {
|
||||||
A::<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>extInt<!>
|
A::<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>extInt<!>
|
||||||
A::<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>extA<!>
|
A::<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>extA<!>
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
import A.Inner
|
import A.Inner
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
@@ -6,4 +7,4 @@ class A {
|
|||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
::<!UNRESOLVED_REFERENCE!>Inner<!>
|
::<!UNRESOLVED_REFERENCE!>Inner<!>
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
import kotlin.reflect.KMemberFunction0
|
import kotlin.reflect.KMemberFunction0
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
@@ -28,4 +29,4 @@ class B {
|
|||||||
|
|
||||||
y : KMemberFunction0<A, A.Inner>
|
y : KMemberFunction0<A, A.Inner>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
import kotlin.reflect.KMemberFunction0
|
import kotlin.reflect.KMemberFunction0
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
@@ -17,4 +18,4 @@ fun Int.main() {
|
|||||||
val y = A::Inner
|
val y = A::Inner
|
||||||
|
|
||||||
y : KMemberFunction0<A, A.Inner>
|
y : KMemberFunction0<A, A.Inner>
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
import kotlin.reflect.KMemberFunction0
|
import kotlin.reflect.KMemberFunction0
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
@@ -9,4 +10,4 @@ fun main() {
|
|||||||
val y = A::Inner
|
val y = A::Inner
|
||||||
|
|
||||||
y : KMemberFunction0<A, A.Inner>
|
y : KMemberFunction0<A, A.Inner>
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
import kotlin.reflect.KFunction0
|
import kotlin.reflect.KFunction0
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
@@ -28,4 +29,4 @@ class B {
|
|||||||
|
|
||||||
y : KFunction0<A.Nested>
|
y : KFunction0<A.Nested>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
import kotlin.reflect.KFunction0
|
import kotlin.reflect.KFunction0
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
@@ -16,4 +17,4 @@ fun Int.main() {
|
|||||||
val y = A::Nested
|
val y = A::Nested
|
||||||
|
|
||||||
y : KFunction0<A.Nested>
|
y : KFunction0<A.Nested>
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,7 +1,8 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
fun bar() = 42
|
fun bar() = 42
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
fun bar() = 239
|
fun bar() = 239
|
||||||
|
|
||||||
::bar
|
::bar
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
class A
|
class A
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
@@ -8,4 +9,4 @@ fun main() {
|
|||||||
A::<!UNRESOLVED_REFERENCE!>bar<!>
|
A::<!UNRESOLVED_REFERENCE!>bar<!>
|
||||||
|
|
||||||
<!UNRESOLVED_REFERENCE!>B<!>::<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>bar<!>
|
<!UNRESOLVED_REFERENCE!>B<!>::<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>bar<!>
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
fun foo() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
fun foo() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class B
|
||||||
|
}
|
||||||
|
|
||||||
|
fun A.bar() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<!UNUSED_EXPRESSION!>::foo<!>
|
||||||
|
<!UNUSED_EXPRESSION!>::A<!>
|
||||||
|
<!UNUSED_EXPRESSION!>A::B<!>
|
||||||
|
<!UNUSED_EXPRESSION!>A::foo<!>
|
||||||
|
<!UNUSED_EXPRESSION!>A::bar<!>
|
||||||
|
}
|
||||||
@@ -111,6 +111,11 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/testsWithStdLib/callableReference"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/testsWithStdLib/callableReference"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unused.kt")
|
||||||
|
public void testUnused() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/unused.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/callableReference/function")
|
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/callableReference/function")
|
||||||
public static class Function extends AbstractJetDiagnosticsTestWithStdLib {
|
public static class Function extends AbstractJetDiagnosticsTestWithStdLib {
|
||||||
@TestMetadata("abstractClassConstructors.kt")
|
@TestMetadata("abstractClassConstructors.kt")
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ fun f(): Unit {
|
|||||||
<error>x</error> in 1..2
|
<error>x</error> in 1..2
|
||||||
|
|
||||||
val y : Boolean? = true
|
val y : Boolean? = true
|
||||||
false || <error>y</error>
|
<warning>false || <error>y</error></warning>
|
||||||
<error>y</error> && true
|
<warning><error>y</error> && true</warning>
|
||||||
<error>y</error> && <error>1</error>
|
<warning><error>y</error> && <error>1</error></warning>
|
||||||
}
|
}
|
||||||
@@ -66,5 +66,5 @@ fun Int.foo() = this
|
|||||||
val c = Command()
|
val c = Command()
|
||||||
c<warning>?.</warning>equals2(null)
|
c<warning>?.</warning>equals2(null)
|
||||||
|
|
||||||
if (command == null) 1
|
if (command == null) <warning>1</warning>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ fun blockReturnValueTypeMatch() : Int {return 1}
|
|||||||
fun blockReturnValueTypeMismatchUnit() : Int {return <error>Unit</error>}
|
fun blockReturnValueTypeMismatchUnit() : Int {return <error>Unit</error>}
|
||||||
|
|
||||||
fun blockAndAndMismatch() : Int {
|
fun blockAndAndMismatch() : Int {
|
||||||
true && false
|
<warning>true && false</warning>
|
||||||
<error>}</error>
|
<error>}</error>
|
||||||
fun blockAndAndMismatch1() : Int {
|
fun blockAndAndMismatch1() : Int {
|
||||||
return <error>true && false</error>
|
return <error>true && false</error>
|
||||||
@@ -52,7 +52,7 @@ fun blockAndAndMismatch2() : Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun blockAndAndMismatch3() : Int {
|
fun blockAndAndMismatch3() : Int {
|
||||||
true || false
|
<warning>true || false</warning>
|
||||||
<error>}</error>
|
<error>}</error>
|
||||||
fun blockAndAndMismatch4() : Int {
|
fun blockAndAndMismatch4() : Int {
|
||||||
return <error>true || false</error>
|
return <error>true || false</error>
|
||||||
@@ -86,18 +86,18 @@ fun blockReturnValueTypeMatch6() : Int {
|
|||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch7() : Int {
|
fun blockReturnValueTypeMatch7() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
1.0
|
<warning>1.0</warning>
|
||||||
else 2.0
|
else <warning>2.0</warning>
|
||||||
<error>}</error>
|
<error>}</error>
|
||||||
fun blockReturnValueTypeMatch8() : Int {
|
fun blockReturnValueTypeMatch8() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
1.0
|
<warning>1.0</warning>
|
||||||
else 2.0
|
else <warning>2.0</warning>
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch9() : Int {
|
fun blockReturnValueTypeMatch9() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
1.0
|
<warning>1.0</warning>
|
||||||
<error>}</error>
|
<error>}</error>
|
||||||
fun blockReturnValueTypeMatch10() : Int {
|
fun blockReturnValueTypeMatch10() : Int {
|
||||||
return <error>if (1 > 2)
|
return <error>if (1 > 2)
|
||||||
@@ -105,7 +105,7 @@ fun blockReturnValueTypeMatch10() : Int {
|
|||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch11() : Int {
|
fun blockReturnValueTypeMatch11() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
else 1.0
|
else <warning>1.0</warning>
|
||||||
<error>}</error>
|
<error>}</error>
|
||||||
fun blockReturnValueTypeMatch12() : Int {
|
fun blockReturnValueTypeMatch12() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ class Dup {
|
|||||||
|
|
||||||
class A() {
|
class A() {
|
||||||
fun foo() : Unit {
|
fun foo() : Unit {
|
||||||
this@A
|
<warning>this@A</warning>
|
||||||
this<error>@a</error>
|
this<error>@a</error>
|
||||||
this
|
<warning>this</warning>
|
||||||
}
|
}
|
||||||
|
|
||||||
val x = this@A.foo()
|
val x = this@A.foo()
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ fun foo() : Int {
|
|||||||
val s = ""
|
val s = ""
|
||||||
val x = 1
|
val x = 1
|
||||||
when (x) {
|
when (x) {
|
||||||
is <error>String</error> -> 1
|
is <error>String</error> -> <warning>1</warning>
|
||||||
!is Int -> 1
|
!is Int -> <warning>1</warning>
|
||||||
is Any<warning>?</warning> -> 1
|
is Any<warning>?</warning> -> <warning>1</warning>
|
||||||
<error>s</error> -> 1
|
<error>s</error> -> <warning>1</warning>
|
||||||
1 -> 1
|
1 -> <warning>1</warning>
|
||||||
1 + <error>a</error> -> 1
|
1 + <error>a</error> -> <warning>1</warning>
|
||||||
in 1..<error>a</error> -> 1
|
in 1..<error>a</error> -> <warning>1</warning>
|
||||||
!in 1..<error>a</error> -> 1
|
!in 1..<error>a</error> -> <warning>1</warning>
|
||||||
else -> 1
|
else -> <warning>1</warning>
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
@@ -25,21 +25,21 @@ fun test() {
|
|||||||
val s = "";
|
val s = "";
|
||||||
|
|
||||||
when (x) {
|
when (x) {
|
||||||
<error>s</error> -> 1
|
<error>s</error> -> <warning>1</warning>
|
||||||
<error>""</error> -> 1
|
<error>""</error> -> <warning>1</warning>
|
||||||
x -> 1
|
x -> <warning>1</warning>
|
||||||
1 -> 1
|
1 -> <warning>1</warning>
|
||||||
else -> 1
|
else -> <warning>1</warning>
|
||||||
}
|
}
|
||||||
|
|
||||||
val z = 1
|
val z = 1
|
||||||
|
|
||||||
when (z) {
|
when (z) {
|
||||||
<error>else</error> -> 1
|
<error>else</error> -> <warning>1</warning>
|
||||||
<warning>1 -> 2</warning>
|
<warning>1 -> 2</warning>
|
||||||
}
|
}
|
||||||
|
|
||||||
when (z) {
|
when (<warning>z</warning>) {
|
||||||
else -> 1
|
else -> <warning>1</warning>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,5 +6,5 @@ fun Any.equals(other : Any?) : Boolean = this === other
|
|||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val command = parse("")
|
val command = parse("")
|
||||||
if (command == null) 1 // error on this line, but must be OK
|
if (command == null) <warning>1</warning> // error on this line, but must be OK
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
// "Suppress 'UNUSED_EXPRESSION' for statement " "true"
|
// "Suppress 'UNUSED_EXPRESSION' for statement " "true"
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
|
val a = 1
|
||||||
[suppress("UNUSED_EXPRESSION")]
|
[suppress("UNUSED_EXPRESSION")]
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
|
|
||||||
val a = 1
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
// "Suppress 'UNUSED_EXPRESSION' for statement " "true"
|
// "Suppress 'UNUSED_EXPRESSION' for statement " "true"
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
|
val a = 1
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
|
|
||||||
val a = 1
|
|
||||||
Reference in New Issue
Block a user