Data flow value converted to Kotlin
This commit is contained in:
+1
-1
@@ -418,7 +418,7 @@ public class JavaNullabilityWarningsChecker : AdditionalTypeChecker {
|
||||
|
||||
private fun <T: Any> doIfNotNull(dataFlowValue: DataFlowValue, c: ResolutionContext<*>, body: () -> T): T? {
|
||||
if (c.dataFlowInfo.getNullability(dataFlowValue).canBeNull()
|
||||
&& dataFlowValue.getType().mustNotBeNull() == NullabilityInformationSource.JAVA) {
|
||||
&& dataFlowValue.type.mustNotBeNull() == NullabilityInformationSource.JAVA) {
|
||||
return body()
|
||||
}
|
||||
return null
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ class GenericCandidateResolver(
|
||||
if (deparenthesizedArgument == null || type == null) return type
|
||||
|
||||
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(deparenthesizedArgument, type, context)
|
||||
if (!dataFlowValue.isPredictable()) return type
|
||||
if (!dataFlowValue.isPredictable) return type
|
||||
|
||||
val possibleTypes = context.dataFlowInfo.getPossibleTypes(dataFlowValue)
|
||||
if (possibleTypes.isEmpty()) return type
|
||||
|
||||
-123
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* 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.calls.smartcasts;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
|
||||
/**
|
||||
* This class describes an arbitrary object which has some value in data flow analysis.
|
||||
* In general case it's some r-value.
|
||||
*/
|
||||
public class DataFlowValue {
|
||||
|
||||
public enum Kind {
|
||||
STABLE_VALUE("stable"),
|
||||
PREDICTABLE_VARIABLE("predictable"),
|
||||
UNPREDICTABLE_VARIABLE("unpredictable"),
|
||||
OTHER("other");
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
Kind(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private final String name;
|
||||
|
||||
public boolean isStable() {
|
||||
return this == STABLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
public static final DataFlowValue NULL = new DataFlowValue(new Object(), KotlinBuiltIns.getInstance().getNullableNothingType(), Kind.OTHER, Nullability.NULL);
|
||||
public static final DataFlowValue ERROR = new DataFlowValue(new Object(), ErrorUtils.createErrorType("Error type for data flow"), Kind.OTHER, Nullability.IMPOSSIBLE);
|
||||
|
||||
private final Kind kind;
|
||||
private final JetType type;
|
||||
private final Object id;
|
||||
private final Nullability immanentNullability;
|
||||
|
||||
// Use DataFlowValueFactory
|
||||
/*package*/ DataFlowValue(Object id, JetType type, Kind kind, Nullability immanentNullability) {
|
||||
this.kind = kind;
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
this.immanentNullability = immanentNullability;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Nullability getImmanentNullability() {
|
||||
return immanentNullability;
|
||||
}
|
||||
|
||||
public Kind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Both stable values and local variables (regardless captured or not) are considered "predictable".
|
||||
* Predictable means here we do not expect some sudden change of their values,
|
||||
* like accessing mutable properties in another thread.
|
||||
*/
|
||||
public boolean isPredictable() {
|
||||
return kind == Kind.STABLE_VALUE || kind == Kind.PREDICTABLE_VARIABLE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
DataFlowValue that = (DataFlowValue) o;
|
||||
|
||||
if (kind.isStable() != that.kind.isStable()) return false;
|
||||
if (id != null ? !id.equals(that.id) : that.id != null) return false;
|
||||
if (type != null ? !type.equals(that.type) : that.type != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return kind.toString() + (id == null ? null : id.toString()) + " " + immanentNullability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = kind.isStable() ? 1 : 0;
|
||||
result = 31 * result + (type != null ? type.hashCode() : 0);
|
||||
result = 31 * result + (id != null ? id.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.calls.smartcasts
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
|
||||
/**
|
||||
* This class describes an arbitrary object which has some value in data flow analysis.
|
||||
* In general case it's some r-value.
|
||||
*/
|
||||
class DataFlowValue(val id: Any?, val type: JetType, val kind: DataFlowValue.Kind, val immanentNullability: Nullability) {
|
||||
|
||||
enum class Kind(private val name: String) {
|
||||
// Smart casts are completely safe
|
||||
STABLE_VALUE("stable"),
|
||||
// Smart casts are safe but possible changes in loops / closures ahead must be taken into account
|
||||
PREDICTABLE_VARIABLE("predictable"),
|
||||
// Smart casts are not safe
|
||||
UNPREDICTABLE_VARIABLE("unpredictable"),
|
||||
OTHER("other");
|
||||
|
||||
override fun toString() = name
|
||||
|
||||
fun isStable() = this == STABLE_VALUE
|
||||
}
|
||||
|
||||
/**
|
||||
* Both stable values and predictable local variables are considered "predictable".
|
||||
* Predictable means here we do not expect some sudden change of their values,
|
||||
* like accessing mutable properties in another thread, so smart casts can be used safely.
|
||||
*/
|
||||
val isPredictable = (kind == Kind.STABLE_VALUE || kind == Kind.PREDICTABLE_VARIABLE)
|
||||
@JvmName("isPredictable") get
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is DataFlowValue) return false
|
||||
|
||||
if (kind.isStable() != other.kind.isStable()) return false
|
||||
if (id != other.id) return false
|
||||
if (type != other.type) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return kind.toString() + (id?.toString()) + " " + immanentNullability
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = if (kind.isStable()) 1 else 0
|
||||
result = 31 * result + (type?.hashCode() ?: 0)
|
||||
result = 31 * result + (id?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val NULL = DataFlowValue(Object(), KotlinBuiltIns.getInstance().nullableNothingType, Kind.OTHER, Nullability.NULL)
|
||||
val ERROR = DataFlowValue(Object(), ErrorUtils.createErrorType("Error type for data flow"), Kind.OTHER, Nullability.IMPOSSIBLE)
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||
|
||||
fun renderDataFlowValue(value: DataFlowValue): String? {
|
||||
// If it is not a stable identifier, there's no point in rendering it
|
||||
if (!value.isPredictable()) return null
|
||||
if (!value.isPredictable) return null
|
||||
|
||||
fun renderId(id: Any?): String? {
|
||||
return when (id) {
|
||||
@@ -36,5 +36,5 @@ fun renderDataFlowValue(value: DataFlowValue): String? {
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
return renderId(value.getId())
|
||||
return renderId(value.id)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user