mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
DfaVariableSource -> VariableDescriptor
This commit is contained in:
@@ -118,18 +118,18 @@ public class CFGBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate instructions to load a qualified field described by given source which qualifier is on the stack
|
||||
* Generate instructions to load a qualified field described by given descriptor which qualifier is on the stack
|
||||
* <p>
|
||||
* Stack before: ... qualifier
|
||||
* <p>
|
||||
* Stack after: ... loaded_field
|
||||
*
|
||||
* @param source a {@link DfaVariableSource} which describes a field to load
|
||||
* @param descriptor a {@link VariableDescriptor} which describes a field to load
|
||||
* @param type a loaded field type
|
||||
* @return this builder
|
||||
*/
|
||||
public CFGBuilder getField(@NotNull DfaVariableSource source, @Nullable PsiType type) {
|
||||
return add(new GetFieldInstruction(source, type));
|
||||
public CFGBuilder getField(@NotNull VariableDescriptor descriptor, @Nullable PsiType type) {
|
||||
return add(new GetFieldInstruction(descriptor, type));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+6
-6
@@ -179,9 +179,9 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
for (DfaValue value : myFactory.getValues()) {
|
||||
if (value instanceof DfaVariableValue) {
|
||||
DfaVariableValue var = (DfaVariableValue)value;
|
||||
DfaVariableSource source = var.getSource();
|
||||
if (source instanceof Synthetic) {
|
||||
if (((Synthetic)source).myLocation >= startOffset) {
|
||||
VariableDescriptor descriptor = var.getDescriptor();
|
||||
if (descriptor instanceof Synthetic) {
|
||||
if (((Synthetic)descriptor).myLocation >= startOffset) {
|
||||
synthetics.add(var);
|
||||
}
|
||||
}
|
||||
@@ -900,7 +900,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
}
|
||||
if (syntheticVar) {
|
||||
expressionValue = getFactory().getVarFactory().createVariableValue(new DfaVariableSource() {
|
||||
expressionValue = getFactory().getVarFactory().createVariableValue(new VariableDescriptor() {
|
||||
@Override
|
||||
public boolean isStable() {
|
||||
return true;
|
||||
@@ -2114,7 +2114,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
* @return true if supplied variable is a temp variable.
|
||||
*/
|
||||
public static boolean isTempVariable(@NotNull DfaVariableValue variable) {
|
||||
return variable.getSource() instanceof Synthetic;
|
||||
return variable.getDescriptor() instanceof Synthetic;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2125,7 +2125,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
return Arrays.stream(INLINERS).anyMatch(inliner -> inliner.mayInferPreciseType(expression));
|
||||
}
|
||||
|
||||
private static final class Synthetic implements DfaVariableSource {
|
||||
private static final class Synthetic implements VariableDescriptor {
|
||||
private final int myLocation;
|
||||
|
||||
private Synthetic(int location) {
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ final class DataFlowInstructionVisitor extends StandardInstructionVisitor {
|
||||
if (!(target instanceof DfaVariableValue)) return false;
|
||||
DfaVariableValue var = (DfaVariableValue)target;
|
||||
if (!(var.getPsiVariable() instanceof PsiField) || var.getQualifier() == null ||
|
||||
!(var.getQualifier().getSource() instanceof DfaExpressionFactory.ThisSource)) {
|
||||
!(var.getQualifier().getDescriptor() instanceof DfaExpressionFactory.ThisDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -402,8 +402,8 @@ public class DataFlowRunner {
|
||||
@Nullable
|
||||
private static DfaValue makeInitialValue(DfaVariableValue var, @NotNull PsiMethod method) {
|
||||
DfaValueFactory factory = var.getFactory();
|
||||
if (var.getSource() instanceof DfaExpressionFactory.ThisSource) {
|
||||
PsiClass aClass = ((DfaExpressionFactory.ThisSource)var.getSource()).getPsiElement();
|
||||
if (var.getDescriptor() instanceof DfaExpressionFactory.ThisDescriptor) {
|
||||
PsiClass aClass = ((DfaExpressionFactory.ThisDescriptor)var.getDescriptor()).getPsiElement();
|
||||
DfaValue value = factory.createTypeValue(var.getType(), Nullability.NOT_NULL);
|
||||
if (method.getContainingClass() == aClass && MutationSignature.fromMethod(method).preservesThis()) {
|
||||
// Unmodifiable view, because we cannot call mutating methods, but it's not guaranteed that all fields are stable
|
||||
|
||||
@@ -167,9 +167,9 @@ public abstract class DfaFactType<T> extends Key<T> {
|
||||
@Nullable
|
||||
@Override
|
||||
LongRangeSet calcFromVariable(@NotNull DfaVariableValue var) {
|
||||
DfaVariableSource source = var.getSource();
|
||||
if(source instanceof SpecialField) {
|
||||
DfaValue defaultValue = ((SpecialField)source).getDefaultValue(var.getFactory());
|
||||
VariableDescriptor descriptor = var.getDescriptor();
|
||||
if(descriptor instanceof SpecialField) {
|
||||
DfaValue defaultValue = ((SpecialField)descriptor).getDefaultValue(var.getFactory());
|
||||
LongRangeSet fromSpecialField = LongRangeSet.fromDfaValue(defaultValue);
|
||||
if (fromSpecialField != null) {
|
||||
return fromSpecialField;
|
||||
|
||||
+1
-1
@@ -1020,7 +1020,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
private boolean applyBooleanInequality(DfaValue var, DfaValue value) {
|
||||
if (!(var instanceof DfaVariableValue) ||
|
||||
!PsiType.BOOLEAN.equals(var.getType()) ||
|
||||
((DfaVariableValue)var).getSource() == SpecialField.UNBOX) {
|
||||
((DfaVariableValue)var).getDescriptor() == SpecialField.UNBOX) {
|
||||
return false;
|
||||
}
|
||||
if (!(value instanceof DfaConstValue)) return false;
|
||||
|
||||
@@ -298,7 +298,7 @@ public class DfaUtil {
|
||||
|
||||
static boolean isEffectivelyUnqualified(DfaVariableValue variableValue) {
|
||||
return variableValue.getQualifier() == null ||
|
||||
variableValue.getQualifier().getSource() instanceof DfaExpressionFactory.ThisSource;
|
||||
variableValue.getQualifier().getDescriptor() instanceof DfaExpressionFactory.ThisDescriptor;
|
||||
}
|
||||
|
||||
public static boolean hasImplicitImpureSuperCall(PsiClass aClass, PsiMethod constructor) {
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ public abstract class InstructionVisitor {
|
||||
|
||||
public DfaInstructionState[] visitGetField(GetFieldInstruction instruction, DataFlowRunner runner, DfaMemoryState state) {
|
||||
DfaValue value = state.pop();
|
||||
DfaValue field = instruction.getSource().createValue(runner.getFactory(), value, instruction.getTargetType());
|
||||
DfaValue field = instruction.getDescriptor().createValue(runner.getFactory(), value, instruction.getTargetType());
|
||||
pushExpressionResult(field, instruction, state);
|
||||
return nextInstruction(instruction, runner, state);
|
||||
}
|
||||
|
||||
+1
-1
@@ -209,7 +209,7 @@ public class LiveVariablesAnalyzer {
|
||||
for (FinishElementInstruction instruction : toFlush.keySet()) {
|
||||
Collection<DfaVariableValue> values = toFlush.get(instruction);
|
||||
// Do not flush special values and this value as they could be used implicitly
|
||||
values.removeIf(var -> var.getSource() instanceof SpecialField || var.getSource() instanceof DfaExpressionFactory.ThisSource);
|
||||
values.removeIf(var -> var.getDescriptor() instanceof SpecialField || var.getDescriptor() instanceof DfaExpressionFactory.ThisDescriptor);
|
||||
instruction.getVarsToFlush().addAll(values);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import java.util.List;
|
||||
public class NullabilityUtil {
|
||||
|
||||
static DfaNullability calcCanBeNull(DfaVariableValue value) {
|
||||
if (value.getSource() instanceof DfaExpressionFactory.ThisSource) {
|
||||
if (value.getDescriptor() instanceof DfaExpressionFactory.ThisDescriptor) {
|
||||
return DfaNullability.NOT_NULL;
|
||||
}
|
||||
PsiModifierListOwner var = value.getPsiVariable();
|
||||
|
||||
@@ -25,7 +25,7 @@ import static com.intellij.psi.CommonClassNames.*;
|
||||
*
|
||||
* @author Tagir Valeev
|
||||
*/
|
||||
public enum SpecialField implements DfaVariableSource {
|
||||
public enum SpecialField implements VariableDescriptor {
|
||||
ARRAY_LENGTH(null, "length", true) {
|
||||
@Override
|
||||
boolean isMyQualifierType(PsiType type) {
|
||||
@@ -189,7 +189,7 @@ public enum SpecialField implements DfaVariableSource {
|
||||
}
|
||||
}
|
||||
}
|
||||
return DfaVariableSource.super.createValue(factory, qualifier, targetType == null ? getType(variableValue) : targetType);
|
||||
return VariableDescriptor.super.createValue(factory, qualifier, targetType == null ? getType(variableValue) : targetType);
|
||||
}
|
||||
if(qualifier instanceof DfaFactMapValue) {
|
||||
SpecialFieldValue sfValue = ((DfaFactMapValue)qualifier).get(DfaFactType.SPECIAL_FIELD_VALUE);
|
||||
|
||||
+3
-3
@@ -512,9 +512,9 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
|
||||
if (instruction.getContext() instanceof PsiMethodReferenceExpression && qualifierValue instanceof DfaVariableValue) {
|
||||
PsiMethod method = instruction.getTargetMethod();
|
||||
DfaVariableSource source = DfaExpressionFactory.getAccessedVariableOrGetter(method);
|
||||
if (source != null) {
|
||||
return source.createValue(factory, qualifierValue, instruction.getResultType());
|
||||
VariableDescriptor descriptor = DfaExpressionFactory.getAccessedVariableOrGetter(method);
|
||||
if (descriptor != null) {
|
||||
return descriptor.createValue(factory, qualifierValue, instruction.getResultType());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-9
@@ -5,7 +5,7 @@ import com.intellij.codeInspection.dataFlow.DataFlowRunner;
|
||||
import com.intellij.codeInspection.dataFlow.DfaInstructionState;
|
||||
import com.intellij.codeInspection.dataFlow.DfaMemoryState;
|
||||
import com.intellij.codeInspection.dataFlow.InstructionVisitor;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableSource;
|
||||
import com.intellij.codeInspection.dataFlow.value.VariableDescriptor;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -16,16 +16,16 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public class GetFieldInstruction extends Instruction implements ExpressionPushingInstruction {
|
||||
@Nullable private final PsiType myTargetType;
|
||||
@NotNull private final DfaVariableSource mySource;
|
||||
@NotNull private final VariableDescriptor myDescriptor;
|
||||
@Nullable private final PsiExpression myAnchor;
|
||||
|
||||
public GetFieldInstruction(@NotNull DfaVariableSource source, @Nullable PsiType targetType) {
|
||||
this(null, source, targetType);
|
||||
public GetFieldInstruction(@NotNull VariableDescriptor descriptor, @Nullable PsiType targetType) {
|
||||
this(null, descriptor, targetType);
|
||||
}
|
||||
|
||||
public GetFieldInstruction(@Nullable PsiExpression anchor, @NotNull DfaVariableSource source, @Nullable PsiType targetType) {
|
||||
public GetFieldInstruction(@Nullable PsiExpression anchor, @NotNull VariableDescriptor descriptor, @Nullable PsiType targetType) {
|
||||
myTargetType = targetType;
|
||||
mySource = source;
|
||||
myDescriptor = descriptor;
|
||||
myAnchor = anchor;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ public class GetFieldInstruction extends Instruction implements ExpressionPushin
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DfaVariableSource getSource() {
|
||||
return mySource;
|
||||
public VariableDescriptor getDescriptor() {
|
||||
return myDescriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -46,7 +46,7 @@ public class GetFieldInstruction extends Instruction implements ExpressionPushin
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GET_FIELD " + mySource;
|
||||
return "GET_FIELD " + myDescriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ public class DfaBoxedValue extends DfaValue {
|
||||
|
||||
@Nullable
|
||||
public DfaValue createBoxed(DfaValue valueToWrap, @Nullable PsiType type) {
|
||||
if (valueToWrap instanceof DfaVariableValue && ((DfaVariableValue)valueToWrap).getSource() == SpecialField.UNBOX) {
|
||||
if (valueToWrap instanceof DfaVariableValue && ((DfaVariableValue)valueToWrap).getDescriptor() == SpecialField.UNBOX) {
|
||||
return ((DfaVariableValue)valueToWrap).getQualifier();
|
||||
}
|
||||
if (valueToWrap instanceof DfaConstValue || valueToWrap instanceof DfaFactMapValue) {
|
||||
|
||||
+22
-22
@@ -65,7 +65,7 @@ public class DfaExpressionFactory {
|
||||
}
|
||||
|
||||
private final DfaValueFactory myFactory;
|
||||
private final Map<Integer, ArrayElementSource> myMockIndices = ContainerUtil.newHashMap();
|
||||
private final Map<Integer, ArrayElementDescriptor> myArrayIndices = ContainerUtil.newHashMap();
|
||||
|
||||
DfaExpressionFactory(DfaValueFactory factory) {
|
||||
myFactory = factory;
|
||||
@@ -147,7 +147,7 @@ public class DfaExpressionFactory {
|
||||
if (constValue != null && !maybeUninitializedConstant(constValue, refExpr, variable)) return constValue;
|
||||
}
|
||||
}
|
||||
DfaVariableSource var = getAccessedVariableOrGetter(target);
|
||||
VariableDescriptor var = getAccessedVariableOrGetter(target);
|
||||
if (var == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -216,27 +216,27 @@ public class DfaExpressionFactory {
|
||||
|
||||
@Contract("null -> null")
|
||||
@Nullable
|
||||
public static DfaVariableSource getAccessedVariableOrGetter(final PsiElement target) {
|
||||
public static VariableDescriptor getAccessedVariableOrGetter(final PsiElement target) {
|
||||
SpecialField sf = SpecialField.findSpecialField(target);
|
||||
if (sf != null) {
|
||||
return sf;
|
||||
}
|
||||
if (target instanceof PsiVariable) {
|
||||
return new PlainSource((PsiVariable)target);
|
||||
return new PlainDescriptor((PsiVariable)target);
|
||||
}
|
||||
if (target instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod)target;
|
||||
if (PropertyUtilBase.isSimplePropertyGetter(method) && isContractAllowedForGetter(method)) {
|
||||
String qName = PsiUtil.getMemberQualifiedName(method);
|
||||
if (qName == null || !FALSE_GETTERS.value(qName)) {
|
||||
return new GetterSource(method);
|
||||
return new GetterDescriptor(method);
|
||||
}
|
||||
}
|
||||
if (method.getParameterList().isEmpty()) {
|
||||
if ((JavaMethodContractUtil.isPure(method) ||
|
||||
AnnotationUtil.findAnnotation(method.getContainingClass(), "javax.annotation.concurrent.Immutable") != null) &&
|
||||
isContractAllowedForGetter(method)) {
|
||||
return new GetterSource(method);
|
||||
return new GetterDescriptor(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,23 +315,23 @@ public class DfaExpressionFactory {
|
||||
return getAdvancedExpressionDfaValue(constantArrayElement, componentType);
|
||||
}
|
||||
}
|
||||
ArrayElementSource indexVariable = getArrayIndexVariable(index);
|
||||
ArrayElementDescriptor indexVariable = getArrayIndexVariable(index);
|
||||
if (indexVariable == null) return null;
|
||||
return indexVariable.createValue(myFactory, arrayDfaVar, componentType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ArrayElementSource getArrayIndexVariable(int index) {
|
||||
private ArrayElementDescriptor getArrayIndexVariable(int index) {
|
||||
if (index >= 0) {
|
||||
return myMockIndices.computeIfAbsent(index, ArrayElementSource::new);
|
||||
return myArrayIndices.computeIfAbsent(index, ArrayElementDescriptor::new);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static final class PlainSource implements DfaVariableSource {
|
||||
static final class PlainDescriptor implements VariableDescriptor {
|
||||
private final @NotNull PsiVariable myVariable;
|
||||
|
||||
PlainSource(@NotNull PsiVariable variable) {
|
||||
PlainDescriptor(@NotNull PsiVariable variable) {
|
||||
myVariable = variable;
|
||||
}
|
||||
|
||||
@@ -367,19 +367,19 @@ public class DfaExpressionFactory {
|
||||
(!myVariable.hasModifierProperty(PsiModifier.FINAL) || !DfaUtil.hasInitializationHacks((PsiField)myVariable)))) {
|
||||
return factory.getVarFactory().createVariableValue(this, type);
|
||||
}
|
||||
return DfaVariableSource.super.createValue(factory, qualifier, type);
|
||||
return VariableDescriptor.super.createValue(factory, qualifier, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj == this || obj instanceof PlainSource && ((PlainSource)obj).myVariable == myVariable;
|
||||
return obj == this || obj instanceof PlainDescriptor && ((PlainDescriptor)obj).myVariable == myVariable;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class GetterSource implements DfaVariableSource {
|
||||
private static final class GetterDescriptor implements VariableDescriptor {
|
||||
private final @NotNull PsiMethod myGetter;
|
||||
|
||||
GetterSource(@NotNull PsiMethod getter) {
|
||||
GetterDescriptor(@NotNull PsiMethod getter) {
|
||||
myGetter = getter;
|
||||
}
|
||||
|
||||
@@ -411,19 +411,19 @@ public class DfaExpressionFactory {
|
||||
if (myGetter.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return factory.getVarFactory().createVariableValue(this, type);
|
||||
}
|
||||
return DfaVariableSource.super.createValue(factory, qualifier, type);
|
||||
return VariableDescriptor.super.createValue(factory, qualifier, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj == this || (obj instanceof GetterSource && ((GetterSource)obj).myGetter == myGetter);
|
||||
return obj == this || (obj instanceof GetterDescriptor && ((GetterDescriptor)obj).myGetter == myGetter);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ArrayElementSource implements DfaVariableSource {
|
||||
private static final class ArrayElementDescriptor implements VariableDescriptor {
|
||||
private final int myIndex;
|
||||
|
||||
ArrayElementSource(int index) {
|
||||
ArrayElementDescriptor(int index) {
|
||||
myIndex = index;
|
||||
}
|
||||
|
||||
@@ -439,11 +439,11 @@ public class DfaExpressionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public static final class ThisSource implements DfaVariableSource {
|
||||
public static final class ThisDescriptor implements VariableDescriptor {
|
||||
@NotNull
|
||||
private final PsiClass myQualifier;
|
||||
|
||||
ThisSource(@NotNull PsiClass qualifier) {
|
||||
ThisDescriptor(@NotNull PsiClass qualifier) {
|
||||
myQualifier = qualifier;
|
||||
}
|
||||
|
||||
@@ -465,7 +465,7 @@ public class DfaExpressionFactory {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj || obj instanceof ThisSource && ((ThisSource)obj).myQualifier == myQualifier;
|
||||
return this == obj || obj instanceof ThisDescriptor && ((ThisDescriptor)obj).myQualifier == myQualifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
-21
@@ -53,7 +53,7 @@ public final class DfaVariableValue extends DfaValue {
|
||||
if (variable instanceof PsiField && !(variable.hasModifierProperty(PsiModifier.STATIC))) {
|
||||
qualifier = createThisValue(((PsiField)variable).getContainingClass());
|
||||
}
|
||||
return createVariableValue(new DfaExpressionFactory.PlainSource(variable), varType, qualifier);
|
||||
return createVariableValue(new DfaExpressionFactory.PlainDescriptor(variable), varType, qualifier);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,24 +65,24 @@ public final class DfaVariableValue extends DfaValue {
|
||||
public DfaVariableValue createThisValue(@Nullable PsiClass aClass) {
|
||||
if (aClass == null) return null;
|
||||
PsiClassType type = JavaPsiFacade.getElementFactory(aClass.getProject()).createType(aClass);
|
||||
return createVariableValue(new DfaExpressionFactory.ThisSource(aClass), type);
|
||||
return createVariableValue(new DfaExpressionFactory.ThisDescriptor(aClass), type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DfaVariableValue createVariableValue(@NotNull DfaVariableSource source, @Nullable PsiType varType) {
|
||||
return createVariableValue(source, varType, null);
|
||||
public DfaVariableValue createVariableValue(@NotNull VariableDescriptor descriptor, @Nullable PsiType varType) {
|
||||
return createVariableValue(descriptor, varType, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
DfaVariableValue createVariableValue(@NotNull DfaVariableSource source,
|
||||
DfaVariableValue createVariableValue(@NotNull VariableDescriptor descriptor,
|
||||
@Nullable PsiType varType,
|
||||
@Nullable DfaVariableValue qualifier) {
|
||||
Pair<String, DfaVariableValue> key = Pair.create(source.toString(), qualifier);
|
||||
Pair<String, DfaVariableValue> key = Pair.create(descriptor.toString(), qualifier);
|
||||
for (DfaVariableValue aVar : myExistingVars.get(key)) {
|
||||
if (aVar.hardEquals(source, varType, qualifier)) return aVar;
|
||||
if (aVar.hardEquals(descriptor, varType, qualifier)) return aVar;
|
||||
}
|
||||
|
||||
DfaVariableValue result = new DfaVariableValue(source, varType, myFactory, qualifier);
|
||||
DfaVariableValue result = new DfaVariableValue(descriptor, varType, myFactory, qualifier);
|
||||
myExistingVars.putValue(key, result);
|
||||
while (qualifier != null) {
|
||||
qualifier.myDependents.add(result);
|
||||
@@ -92,24 +92,24 @@ public final class DfaVariableValue extends DfaValue {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull private final DfaVariableSource mySource;
|
||||
@NotNull private final VariableDescriptor myDescriptor;
|
||||
private final PsiType myVarType;
|
||||
@Nullable private final DfaVariableValue myQualifier;
|
||||
private DfaFactMap myInherentFacts;
|
||||
private final DfaPsiType myDfaType;
|
||||
private final List<DfaVariableValue> myDependents = new SmartList<>();
|
||||
|
||||
private DfaVariableValue(@NotNull DfaVariableSource source,
|
||||
private DfaVariableValue(@NotNull VariableDescriptor descriptor,
|
||||
@Nullable PsiType varType,
|
||||
DfaValueFactory factory,
|
||||
@Nullable DfaVariableValue qualifier) {
|
||||
super(factory);
|
||||
mySource = source;
|
||||
myDescriptor = descriptor;
|
||||
myQualifier = qualifier;
|
||||
myVarType = varType;
|
||||
myDfaType = varType == null ? null : myFactory.createDfaType(varType);
|
||||
if (varType != null && !varType.isValid()) {
|
||||
PsiUtil.ensureValidType(varType, "Variable: " + source + " of class " + source.getClass());
|
||||
PsiUtil.ensureValidType(varType, "Variable: " + descriptor + " of class " + descriptor.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,12 +120,12 @@ public final class DfaVariableValue extends DfaValue {
|
||||
|
||||
@Nullable
|
||||
public PsiModifierListOwner getPsiVariable() {
|
||||
return mySource.getPsiElement();
|
||||
return myDescriptor.getPsiElement();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DfaVariableSource getSource() {
|
||||
return mySource;
|
||||
public VariableDescriptor getDescriptor() {
|
||||
return myDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,15 +160,15 @@ public final class DfaVariableValue extends DfaValue {
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
public DfaVariableValue withQualifier(DfaVariableValue newQualifier) {
|
||||
return newQualifier == myQualifier ? this : myFactory.getVarFactory().createVariableValue(mySource, myVarType, newQualifier);
|
||||
return newQualifier == myQualifier ? this : myFactory.getVarFactory().createVariableValue(myDescriptor, myVarType, newQualifier);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (myQualifier == null ? "" : myQualifier + ".") + mySource;
|
||||
return (myQualifier == null ? "" : myQualifier + ".") + myDescriptor;
|
||||
}
|
||||
|
||||
private boolean hardEquals(DfaVariableSource source, PsiType varType, DfaVariableValue qualifier) {
|
||||
return source.equals(mySource) && qualifier == myQualifier &&
|
||||
private boolean hardEquals(VariableDescriptor descriptor, PsiType varType, DfaVariableValue qualifier) {
|
||||
return descriptor.equals(myDescriptor) && qualifier == myQualifier &&
|
||||
Comparing.equal(TypeConversionUtil.erasure(varType), TypeConversionUtil.erasure(myVarType));
|
||||
}
|
||||
|
||||
@@ -191,10 +191,10 @@ public final class DfaVariableValue extends DfaValue {
|
||||
}
|
||||
|
||||
public boolean isFlushableByCalls() {
|
||||
return !mySource.isStable() || (myQualifier != null && myQualifier.isFlushableByCalls());
|
||||
return !myDescriptor.isStable() || (myQualifier != null && myQualifier.isFlushableByCalls());
|
||||
}
|
||||
|
||||
public boolean containsCalls() {
|
||||
return mySource.isCall() || myQualifier != null && myQualifier.containsCalls();
|
||||
return myDescriptor.isCall() || myQualifier != null && myQualifier.containsCalls();
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -8,15 +8,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a source of {@link DfaVariableValue}. Two variables are the same if they have the same source and qualifier.
|
||||
* A source could be a PsiVariable, getter method, array element with given index, this expression, etc.
|
||||
* Represents a descriptor of {@link DfaVariableValue}. Two variables are the same if they have the same descriptor and qualifier.
|
||||
* A descriptor could be a PsiVariable, getter method, array element with given index, this expression, etc.
|
||||
* <p>
|
||||
* Subclasses must have proper {@link Object#equals(Object)} and implementation or instantiation must be controlled to prevent
|
||||
* creating equal objects. Also {@link #toString()} must return sane representation of the source.
|
||||
* creating equal objects. Also {@link #toString()} must return sane representation of the descriptor.
|
||||
*/
|
||||
public interface DfaVariableSource {
|
||||
public interface VariableDescriptor {
|
||||
/**
|
||||
* @return a PSI element associated with given source or null if not applicable
|
||||
* @return a PSI element associated with this descriptor or null if not applicable
|
||||
*/
|
||||
@Nullable
|
||||
default PsiModifierListOwner getPsiElement() {
|
||||
@@ -24,26 +24,26 @@ public interface DfaVariableSource {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the value stored in this source cannot be changed implicitly (e.g. inside the unknown method call)
|
||||
* @return true if the value stored in this descriptor cannot be changed implicitly (e.g. inside the unknown method call)
|
||||
*/
|
||||
boolean isStable();
|
||||
|
||||
/**
|
||||
* @return true if the value behind this source is a method call which result might be computed from other sources
|
||||
* @return true if the value behind this descriptor is a method call which result might be computed from other sources
|
||||
*/
|
||||
default boolean isCall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be overridden to return stable string representation of the source.
|
||||
* In particular {@code source1.equals(source2)} implies that {@code source1.toString().equals(source2.toString())}
|
||||
* Must be overridden to return stable string representation of the descriptor.
|
||||
* In particular {@code desc1.equals(desc2)} implies that {@code desc1.toString().equals(desc2.toString())}
|
||||
*/
|
||||
@Override
|
||||
String toString();
|
||||
|
||||
/**
|
||||
* Returns a value which describes the field qualified by given qualifier and described by this source
|
||||
* Returns a value which describes the field qualified by given qualifier and described by this descriptor
|
||||
* @param factory factory to use
|
||||
* @param qualifier qualifier to use
|
||||
* @param type field type
|
||||
Reference in New Issue
Block a user