Report special diagnostic when fake-call receiver is nullable
#KT-3602 Fixed
This commit is contained in:
@@ -547,6 +547,7 @@ public interface Errors {
|
|||||||
|
|
||||||
DiagnosticFactory0<KtDestructuringDeclaration> INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION = DiagnosticFactory0.create(ERROR, DEFAULT);
|
DiagnosticFactory0<KtDestructuringDeclaration> INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION = DiagnosticFactory0.create(ERROR, DEFAULT);
|
||||||
DiagnosticFactory2<KtExpression, Name, KotlinType> COMPONENT_FUNCTION_MISSING = DiagnosticFactory2.create(ERROR, DEFAULT);
|
DiagnosticFactory2<KtExpression, Name, KotlinType> COMPONENT_FUNCTION_MISSING = DiagnosticFactory2.create(ERROR, DEFAULT);
|
||||||
|
DiagnosticFactory1<KtExpression, Name> COMPONENT_FUNCTION_ON_NULLABLE = DiagnosticFactory1.create(ERROR, DEFAULT);
|
||||||
DiagnosticFactory2<KtExpression, Name, Collection<? extends ResolvedCall<?>>> COMPONENT_FUNCTION_AMBIGUITY = DiagnosticFactory2.create(ERROR, DEFAULT);
|
DiagnosticFactory2<KtExpression, Name, Collection<? extends ResolvedCall<?>>> COMPONENT_FUNCTION_AMBIGUITY = DiagnosticFactory2.create(ERROR, DEFAULT);
|
||||||
DiagnosticFactory3<KtExpression, Name, KotlinType, KotlinType> COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR, DEFAULT);
|
DiagnosticFactory3<KtExpression, Name, KotlinType, KotlinType> COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR, DEFAULT);
|
||||||
|
|
||||||
@@ -589,6 +590,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory1<KtExpression, KotlinType> NEXT_NONE_APPLICABLE = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<KtExpression, KotlinType> NEXT_NONE_APPLICABLE = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
DiagnosticFactory0<KtExpression> ITERATOR_MISSING = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<KtExpression> ITERATOR_MISSING = DiagnosticFactory0.create(ERROR);
|
||||||
|
DiagnosticFactory0<KtExpression> ITERATOR_ON_NULLABLE = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> ITERATOR_AMBIGUITY = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> ITERATOR_AMBIGUITY = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
DiagnosticFactory2<KtExpression, String, KotlinType> DELEGATE_SPECIAL_FUNCTION_MISSING = DiagnosticFactory2.create(ERROR);
|
DiagnosticFactory2<KtExpression, String, KotlinType> DELEGATE_SPECIAL_FUNCTION_MISSING = DiagnosticFactory2.create(ERROR);
|
||||||
|
|||||||
+2
@@ -214,6 +214,7 @@ public class DefaultErrorMessages {
|
|||||||
|
|
||||||
MAP.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration");
|
MAP.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration");
|
||||||
MAP.put(COMPONENT_FUNCTION_MISSING, "Destructuring declaration initializer of type {1} must have a ''{0}()'' function", TO_STRING, RENDER_TYPE);
|
MAP.put(COMPONENT_FUNCTION_MISSING, "Destructuring declaration initializer of type {1} must have a ''{0}()'' function", TO_STRING, RENDER_TYPE);
|
||||||
|
MAP.put(COMPONENT_FUNCTION_ON_NULLABLE, "Not nullable value required to call ''{0}()'' function of destructuring declaration initializer", TO_STRING);
|
||||||
MAP.put(COMPONENT_FUNCTION_AMBIGUITY, "Function ''{0}()'' is ambiguous for this expression: {1}", TO_STRING, AMBIGUOUS_CALLS);
|
MAP.put(COMPONENT_FUNCTION_AMBIGUITY, "Function ''{0}()'' is ambiguous for this expression: {1}", TO_STRING, AMBIGUOUS_CALLS);
|
||||||
MAP.put(COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, "''{0}()'' function returns ''{1}'', but ''{2}'' is expected",
|
MAP.put(COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, "''{0}()'' function returns ''{1}'', but ''{2}'' is expected",
|
||||||
TO_STRING, RENDER_TYPE, RENDER_TYPE);
|
TO_STRING, RENDER_TYPE, RENDER_TYPE);
|
||||||
@@ -368,6 +369,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(NEXT_NONE_APPLICABLE, "None of the next() functions is applicable for iterator() of type ''{0}''", RENDER_TYPE);
|
MAP.put(NEXT_NONE_APPLICABLE, "None of the next() functions is applicable for iterator() of type ''{0}''", RENDER_TYPE);
|
||||||
|
|
||||||
MAP.put(ITERATOR_MISSING, "For-loop range must have an iterator() method");
|
MAP.put(ITERATOR_MISSING, "For-loop range must have an iterator() method");
|
||||||
|
MAP.put(ITERATOR_ON_NULLABLE, "Not nullable value required to call an iterator() method on for-loop range");
|
||||||
MAP.put(ITERATOR_AMBIGUITY, "Method ''iterator()'' is ambiguous for this expression: {0}", AMBIGUOUS_CALLS);
|
MAP.put(ITERATOR_AMBIGUITY, "Method ''iterator()'' is ambiguous for this expression: {0}", AMBIGUOUS_CALLS);
|
||||||
|
|
||||||
MAP.put(DELEGATE_SPECIAL_FUNCTION_MISSING, "Missing ''{0}'' method on delegate of type ''{1}''", STRING, RENDER_TYPE);
|
MAP.put(DELEGATE_SPECIAL_FUNCTION_MISSING, "Missing ''{0}'' method on delegate of type ''{1}''", STRING, RENDER_TYPE);
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity;
|
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
@@ -39,8 +38,6 @@ import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
|
|||||||
import org.jetbrains.kotlin.util.slicedMap.*;
|
import org.jetbrains.kotlin.util.slicedMap.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.EnumMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.diagnostics.Errors.AMBIGUOUS_LABEL;
|
import static org.jetbrains.kotlin.diagnostics.Errors.AMBIGUOUS_LABEL;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||||
@@ -223,7 +220,7 @@ public class BindingContextUtils {
|
|||||||
map.forEach(new Function3<WritableSlice, Object, Object, Void>() {
|
map.forEach(new Function3<WritableSlice, Object, Object, Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void invoke(WritableSlice slice, Object key, Object value) {
|
public Void invoke(WritableSlice slice, Object key, Object value) {
|
||||||
if (filter == null || filter.accept(slice, null, key)) {
|
if (filter == null || filter.accept(slice, key)) {
|
||||||
trace.record(slice, key, value);
|
trace.record(slice, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +231,7 @@ public class BindingContextUtils {
|
|||||||
if (!commitDiagnostics) return;
|
if (!commitDiagnostics) return;
|
||||||
|
|
||||||
for (Diagnostic diagnostic : diagnostics.getOwnDiagnostics()) {
|
for (Diagnostic diagnostic : diagnostics.getOwnDiagnostics()) {
|
||||||
if (filter == null || filter.accept(null, diagnostic, diagnostic.getPsiElement())) {
|
if (filter == null || filter.accept(null, diagnostic.getPsiElement())) {
|
||||||
trace.report(diagnostic);
|
trace.report(diagnostic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers;
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderers;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
@@ -334,7 +333,7 @@ public class DelegatedPropertyResolver {
|
|||||||
dataFlowInfo, traceToResolveDelegatedProperty);
|
dataFlowInfo, traceToResolveDelegatedProperty);
|
||||||
traceToResolveDelegatedProperty.commit(new TraceEntryFilter() {
|
traceToResolveDelegatedProperty.commit(new TraceEntryFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(@Nullable WritableSlice<?, ?> slice, @Nullable Diagnostic diagnostic, Object key) {
|
public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
|
||||||
return slice != CONSTRAINT_SYSTEM_COMPLETER;
|
return slice != CONSTRAINT_SYSTEM_COMPLETER;
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
|
|||||||
@@ -17,9 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.resolve;
|
package org.jetbrains.kotlin.resolve;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
|
||||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
||||||
|
|
||||||
public interface TraceEntryFilter {
|
public interface TraceEntryFilter {
|
||||||
boolean accept(@Nullable WritableSlice<?, ?> slice, @Nullable Diagnostic diagnostic, Object key);
|
boolean accept(@Nullable WritableSlice<?, ?> slice, Object key);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.types.expressions;
|
package org.jetbrains.kotlin.types.expressions;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.openapi.util.Ref;
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import com.intellij.psi.tree.TokenSet;
|
import com.intellij.psi.tree.TokenSet;
|
||||||
@@ -32,7 +31,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
|||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtilsKt;
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
@@ -1181,7 +1179,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
|
traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(@Nullable WritableSlice<?, ?> slice, @Nullable Diagnostic diagnostic, Object key) {
|
public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
|
||||||
// the type of the right (and sometimes left) expression isn't 'Any?' actually
|
// the type of the right (and sometimes left) expression isn't 'Any?' actually
|
||||||
if ((key == right || key == left) && slice == EXPRESSION_TYPE_INFO) return false;
|
if ((key == right || key == left) && slice == EXPRESSION_TYPE_INFO) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.types.expressions
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -28,10 +29,10 @@ import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
|||||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.calls.CallResolver
|
import org.jetbrains.kotlin.resolve.calls.CallResolver
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
|
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.utils.doNothing
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
enum class FakeCallKind {
|
enum class FakeCallKind {
|
||||||
@@ -88,31 +89,34 @@ class FakeCallResolver(
|
|||||||
val fakeTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve fake call for", name)
|
val fakeTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve fake call for", name)
|
||||||
val fakeBindingTrace = context.replaceBindingTrace(fakeTrace)
|
val fakeBindingTrace = context.replaceBindingTrace(fakeTrace)
|
||||||
|
|
||||||
var hasUnreportedError = false
|
var unreportedDiagnostic: Diagnostic? = null
|
||||||
val result = makeAndResolveFakeCallInContext(receiver, fakeBindingTrace, valueArguments, name, callElement) { fake ->
|
val result = makeAndResolveFakeCallInContext(receiver, fakeBindingTrace, valueArguments, name, callElement) { fake, isSuccess ->
|
||||||
fakeTrace.commit({ slice, diagnostic, key ->
|
unreportedDiagnostic = fakeTrace.bindingContext.diagnostics.noSuppression().forElement(fake).firstOrNull { it.severity == Severity.ERROR }
|
||||||
|
|
||||||
|
if (!isSuccess) return@makeAndResolveFakeCallInContext
|
||||||
|
|
||||||
|
fakeTrace.commit({ slice, key ->
|
||||||
// excluding all entries related to fake expression
|
// excluding all entries related to fake expression
|
||||||
// convert all errors on this expression to ITERATOR_MISSING on callElement
|
// convert all errors on this expression to ITERATOR_MISSING on callElement
|
||||||
val isFakeKey = key == fake
|
key != fake
|
||||||
if (diagnostic?.severity == Severity.ERROR && isFakeKey) {
|
|
||||||
hasUnreportedError = true
|
|
||||||
}
|
|
||||||
!isFakeKey
|
|
||||||
}, true)
|
}, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
val resolutionResults = result.second
|
val resolutionResults = result.second
|
||||||
if ((!resolutionResults.isSuccess || hasUnreportedError) && reportErrorsOn != null) {
|
if ((!resolutionResults.isSuccess || unreportedDiagnostic != null) && reportErrorsOn != null) {
|
||||||
|
val isUnsafeCall = unreportedDiagnostic?.factory == Errors.UNSAFE_CALL
|
||||||
val diagnostic = when (callKind) {
|
val diagnostic = when (callKind) {
|
||||||
FakeCallKind.ITERATOR ->
|
FakeCallKind.ITERATOR ->
|
||||||
when {
|
when {
|
||||||
resolutionResults.isAmbiguity -> Errors.ITERATOR_AMBIGUITY.on(reportErrorsOn, resolutionResults.resultingCalls)
|
resolutionResults.isAmbiguity -> Errors.ITERATOR_AMBIGUITY.on(reportErrorsOn, resolutionResults.resultingCalls)
|
||||||
|
isUnsafeCall -> Errors.ITERATOR_ON_NULLABLE.on(reportErrorsOn)
|
||||||
else -> Errors.ITERATOR_MISSING.on(reportErrorsOn)
|
else -> Errors.ITERATOR_MISSING.on(reportErrorsOn)
|
||||||
}
|
}
|
||||||
FakeCallKind.COMPONENT ->
|
FakeCallKind.COMPONENT ->
|
||||||
when {
|
when {
|
||||||
resolutionResults.isAmbiguity -> Errors.COMPONENT_FUNCTION_AMBIGUITY.on(
|
resolutionResults.isAmbiguity -> Errors.COMPONENT_FUNCTION_AMBIGUITY.on(
|
||||||
reportErrorsOn, name, resolutionResults.resultingCalls)
|
reportErrorsOn, name, resolutionResults.resultingCalls)
|
||||||
|
isUnsafeCall -> Errors.COMPONENT_FUNCTION_ON_NULLABLE.on(reportErrorsOn, name)
|
||||||
receiver != null -> Errors.COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, name, receiver.type)
|
receiver != null -> Errors.COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, name, receiver.type)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -132,15 +136,13 @@ class FakeCallResolver(
|
|||||||
valueArguments: List<KtExpression>,
|
valueArguments: List<KtExpression>,
|
||||||
name: Name,
|
name: Name,
|
||||||
callElement: KtExpression?,
|
callElement: KtExpression?,
|
||||||
onSuccess: (KtSimpleNameExpression) -> Unit = doNothing()
|
onComplete: (KtSimpleNameExpression, Boolean) -> Unit = { x, y -> }
|
||||||
): Pair<Call, OverloadResolutionResults<FunctionDescriptor>> {
|
): Pair<Call, OverloadResolutionResults<FunctionDescriptor>> {
|
||||||
val fake = KtPsiFactory(project).createSimpleName(name.asString())
|
val fake = KtPsiFactory(project).createSimpleName(name.asString())
|
||||||
val call = CallMaker.makeCallWithExpressions(callElement ?: fake, receiver, null, fake, valueArguments)
|
val call = CallMaker.makeCallWithExpressions(callElement ?: fake, receiver, null, fake, valueArguments)
|
||||||
val results = callResolver.resolveCallWithGivenName(context, call, fake, name)
|
val results = callResolver.resolveCallWithGivenName(context, call, fake, name)
|
||||||
|
|
||||||
if (results.isSuccess) {
|
onComplete(fake, results.isSuccess)
|
||||||
onSuccess(fake)
|
|
||||||
}
|
|
||||||
|
|
||||||
return Pair(call, results)
|
return Pair(call, results)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -8,7 +8,7 @@ fun test() {
|
|||||||
// Error
|
// Error
|
||||||
container<!UNSAFE_CALL!>.<!>iterator()
|
container<!UNSAFE_CALL!>.<!>iterator()
|
||||||
// for extension iterator, this code compiles, but should not
|
// for extension iterator, this code compiles, but should not
|
||||||
for (s in <!ITERATOR_MISSING!>container<!>) {}
|
for (s in <!ITERATOR_ON_NULLABLE!>container<!>) {}
|
||||||
}
|
}
|
||||||
class OtherContainer<K>(val k: K) {
|
class OtherContainer<K>(val k: K) {
|
||||||
operator fun iterator(): Iterator<K> = null!!
|
operator fun iterator(): Iterator<K> = null!!
|
||||||
@@ -17,5 +17,5 @@ class OtherContainer<K>(val k: K) {
|
|||||||
fun test2() {
|
fun test2() {
|
||||||
val other: OtherContainer<String>? = null
|
val other: OtherContainer<String>? = null
|
||||||
// Error
|
// Error
|
||||||
for (s in <!ITERATOR_MISSING!>other<!>) {}
|
for (s in <!ITERATOR_ON_NULLABLE!>other<!>) {}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ class It {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test(c: Coll?) {
|
fun test(c: Coll?) {
|
||||||
for (x in <!ITERATOR_MISSING!>c<!>) {}
|
for (x in <!ITERATOR_ON_NULLABLE!>c<!>) {}
|
||||||
|
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
for(x in <!DEBUG_INFO_SMARTCAST!>c<!>) {}
|
for(x in <!DEBUG_INFO_SMARTCAST!>c<!>) {}
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@ operator fun <T> Data<T>.component2() = y
|
|||||||
fun foo(): Int {
|
fun foo(): Int {
|
||||||
val d: Data<Int>? = null
|
val d: Data<Int>? = null
|
||||||
// An error must be here
|
// An error must be here
|
||||||
val (x, y) = <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>d<!>
|
val (x, y) = <!COMPONENT_FUNCTION_ON_NULLABLE, COMPONENT_FUNCTION_ON_NULLABLE!>d<!>
|
||||||
return x + y
|
return x + y
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,6 +16,6 @@ data class NormalData<T>(val x: T, val y: T)
|
|||||||
fun bar(): Int {
|
fun bar(): Int {
|
||||||
val d: NormalData<Int>? = null
|
val d: NormalData<Int>? = null
|
||||||
// An error must be here
|
// An error must be here
|
||||||
val (x, y) = <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>d<!>
|
val (x, y) = <!COMPONENT_FUNCTION_ON_NULLABLE, COMPONENT_FUNCTION_ON_NULLABLE!>d<!>
|
||||||
return <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>y<!>
|
return <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>y<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ fun test() {
|
|||||||
val platformJ = J.staticJ
|
val platformJ = J.staticJ
|
||||||
|
|
||||||
for (x in platformNN) {}
|
for (x in platformNN) {}
|
||||||
for (x in <!ITERATOR_MISSING!>platformN<!>) {}
|
for (x in <!ITERATOR_ON_NULLABLE!>platformN<!>) {}
|
||||||
for (x in platformJ) {}
|
for (x in platformJ) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -27,6 +27,6 @@ fun test() {
|
|||||||
val platformJ = J.staticJ
|
val platformJ = J.staticJ
|
||||||
|
|
||||||
val (a1, b1) = platformNN
|
val (a1, b1) = platformNN
|
||||||
val (a2, b2) = <!COMPONENT_FUNCTION_MISSING, COMPONENT_FUNCTION_MISSING!>platformN<!>
|
val (a2, b2) = <!COMPONENT_FUNCTION_ON_NULLABLE, COMPONENT_FUNCTION_ON_NULLABLE!>platformN<!>
|
||||||
val (a3, b3) = platformJ
|
val (a3, b3) = platformJ
|
||||||
}
|
}
|
||||||
@@ -298,7 +298,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
NEXT_MISSING.registerFactory(CreateNextFunctionActionFactory)
|
NEXT_MISSING.registerFactory(CreateNextFunctionActionFactory)
|
||||||
NEXT_NONE_APPLICABLE.registerFactory(CreateNextFunctionActionFactory)
|
NEXT_NONE_APPLICABLE.registerFactory(CreateNextFunctionActionFactory)
|
||||||
ITERATOR_MISSING.registerFactory(CreateIteratorFunctionActionFactory)
|
ITERATOR_MISSING.registerFactory(CreateIteratorFunctionActionFactory)
|
||||||
ITERATOR_MISSING.registerFactory(MissingIteratorExclExclFixFactory)
|
ITERATOR_ON_NULLABLE.registerFactory(MissingIteratorExclExclFixFactory)
|
||||||
COMPONENT_FUNCTION_MISSING.registerFactory(CreateComponentFunctionActionFactory)
|
COMPONENT_FUNCTION_MISSING.registerFactory(CreateComponentFunctionActionFactory)
|
||||||
|
|
||||||
DELEGATE_SPECIAL_FUNCTION_MISSING.registerFactory(CreatePropertyDelegateAccessorsActionFactory)
|
DELEGATE_SPECIAL_FUNCTION_MISSING.registerFactory(CreatePropertyDelegateAccessorsActionFactory)
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// "Add non-null asserted (!!) call" "false"
|
// "Add non-null asserted (!!) call" "false"
|
||||||
// ACTION: Replace with a 'forEach' function call
|
// ACTION: Replace with a 'forEach' function call
|
||||||
// ERROR: For-loop range must have an iterator() method
|
// ERROR: Not nullable value required to call an iterator() method on for-loop range
|
||||||
|
|
||||||
class Some {
|
class Some {
|
||||||
fun iterator(): Iterator<Int> = null!!
|
fun iterator(): Iterator<Int> = null!!
|
||||||
|
|||||||
Reference in New Issue
Block a user