mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] negate types when negations instruction is encountered
This commit is contained in:
+17
-16
@@ -9,7 +9,6 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.NegatingGotoInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ConditionInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
@@ -42,7 +41,7 @@ public class DFAType {
|
||||
myNegated = negated;
|
||||
}
|
||||
|
||||
Mixin negate() {
|
||||
private Mixin negate() {
|
||||
return new Mixin(ID, myType, myCondition, !myNegated);
|
||||
}
|
||||
|
||||
@@ -97,24 +96,26 @@ public class DFAType {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Contract("-> new")
|
||||
@NotNull
|
||||
public DFAType copy() {
|
||||
final DFAType type = new DFAType(primary);
|
||||
type.mixins.addAll(mixins);
|
||||
return type;
|
||||
}
|
||||
|
||||
@Contract("_ -> new")
|
||||
@NotNull
|
||||
public DFAType negate(@NotNull Instruction instruction) {
|
||||
final DFAType type = new DFAType(primary);
|
||||
|
||||
type.mixins.addAll(mixins);
|
||||
|
||||
for (NegatingGotoInstruction negation: instruction.getNegatingGotoInstruction()) {
|
||||
final Set<ConditionInstruction> conditionsToNegate = negation.getCondition().getDependentConditions();
|
||||
|
||||
for (ListIterator<Mixin> iterator = type.mixins.listIterator(); iterator.hasNext(); ) {
|
||||
Mixin mixin = iterator.next();
|
||||
if (conditionsToNegate.contains(mixin.myCondition)) {
|
||||
iterator.set(mixin.negate());
|
||||
}
|
||||
public DFAType negate(@NotNull NegatingGotoInstruction negation) {
|
||||
DFAType result = copy();
|
||||
final Set<ConditionInstruction> conditionsToNegate = negation.getCondition().getDependentConditions();
|
||||
for (ListIterator<Mixin> iterator = result.mixins.listIterator(); iterator.hasNext(); ) {
|
||||
Mixin mixin = iterator.next();
|
||||
if (conditionsToNegate.contains(mixin.myCondition)) {
|
||||
iterator.set(mixin.negate());
|
||||
}
|
||||
}
|
||||
return type;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+2
-3
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.plugins.groovy.lang.psi.dataFlow.types;
|
||||
|
||||
import com.intellij.openapi.util.Couple;
|
||||
@@ -88,8 +88,7 @@ class InferenceCache {
|
||||
|
||||
@Nullable
|
||||
DFAType getCachedInferredType(@NotNull String variableName, @NotNull Instruction instruction) {
|
||||
DFAType dfaType = myVarTypes.get().get(instruction.num()).getVariableType(variableName);
|
||||
return dfaType == null ? null : dfaType.negate(instruction);
|
||||
return myVarTypes.get().get(instruction.num()).getVariableType(variableName);
|
||||
}
|
||||
|
||||
private Couple<Set<Instruction>> collectRequiredInstructions(@NotNull Instruction instruction,
|
||||
|
||||
+13
-3
@@ -10,6 +10,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.GroovyMethodResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.MixinTypeInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.NegatingGotoInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ArgumentsInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.DFAType;
|
||||
@@ -47,6 +48,9 @@ class TypeDfaInstance implements DfaInstance<TypeDfaState> {
|
||||
else if (instruction instanceof ArgumentsInstruction) {
|
||||
handleArguments(state, (ArgumentsInstruction)instruction);
|
||||
}
|
||||
else if (instruction instanceof NegatingGotoInstruction) {
|
||||
handleNegation(state, (NegatingGotoInstruction)instruction);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMixin(@NotNull final TypeDfaState state, @NotNull final MixinTypeInstruction instruction) {
|
||||
@@ -57,7 +61,7 @@ class TypeDfaInstance implements DfaInstance<TypeDfaState> {
|
||||
ReadWriteVariableInstruction originalInstr = instruction.getInstructionToMixin(myFlow);
|
||||
assert originalInstr != null && !originalInstr.isWrite();
|
||||
|
||||
final DFAType original = state.getOrCreateVariableType(varName).negate(originalInstr);
|
||||
DFAType original = state.getOrCreateVariableType(varName);
|
||||
original.addMixin(instruction.inferMixinType(), instruction.getConditionInstruction());
|
||||
return original;
|
||||
});
|
||||
@@ -83,7 +87,7 @@ class TypeDfaInstance implements DfaInstance<TypeDfaState> {
|
||||
|
||||
private void handleArgument(TypeDfaState state, ArgumentsInstruction instruction, String variableName, Collection<Argument> arguments) {
|
||||
updateVariableType(state, instruction, variableName, () -> {
|
||||
final DFAType result = state.getOrCreateVariableType(variableName).negate(instruction);
|
||||
final DFAType result = state.getOrCreateVariableType(variableName);
|
||||
final GroovyResolveResult[] results = instruction.getElement().multiResolve(false);
|
||||
for (GroovyResolveResult variant : results) {
|
||||
if (!(variant instanceof GroovyMethodResult)) continue;
|
||||
@@ -121,12 +125,18 @@ class TypeDfaInstance implements DfaInstance<TypeDfaState> {
|
||||
type = computation.compute();
|
||||
}
|
||||
else {
|
||||
type = TypeInferenceHelper.doInference(state.getBindings(instruction), computation);
|
||||
type = TypeInferenceHelper.doInference(state.getBindings(), computation);
|
||||
}
|
||||
}
|
||||
state.putType(variableName, type);
|
||||
}
|
||||
|
||||
private static void handleNegation(@NotNull TypeDfaState state, @NotNull NegatingGotoInstruction negation) {
|
||||
for (Map.Entry<String, DFAType> entry : state.getVarTypes().entrySet()) {
|
||||
entry.setValue(entry.getValue().negate(negation));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public TypeDfaState initial() {
|
||||
|
||||
+8
-5
@@ -7,7 +7,6 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.DFAType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.Semilattice;
|
||||
|
||||
@@ -54,6 +53,10 @@ class TypeDfaState {
|
||||
myVarTypes = ContainerUtil.newHashMap(another.myVarTypes);
|
||||
}
|
||||
|
||||
Map<String, DFAType> getVarTypes() {
|
||||
return myVarTypes;
|
||||
}
|
||||
|
||||
TypeDfaState mergeWith(TypeDfaState another) {
|
||||
if (another.myVarTypes.isEmpty()) {
|
||||
return this;
|
||||
@@ -92,14 +95,14 @@ class TypeDfaState {
|
||||
@NotNull
|
||||
DFAType getOrCreateVariableType(String variableName) {
|
||||
DFAType result = getVariableType(variableName);
|
||||
return result == null ? DFAType.create(null) : result;
|
||||
return result == null ? DFAType.create(null) : result.copy();
|
||||
}
|
||||
|
||||
Map<String, PsiType> getBindings(Instruction instruction) {
|
||||
HashMap<String,PsiType> map = ContainerUtil.newHashMap();
|
||||
Map<String, PsiType> getBindings() {
|
||||
HashMap<String, PsiType> map = ContainerUtil.newHashMap();
|
||||
for (Map.Entry<String, DFAType> entry : myVarTypes.entrySet()) {
|
||||
DFAType value = entry.getValue();
|
||||
map.put(entry.getKey(), value == null ? null : value.negate(instruction).getResultType());
|
||||
map.put(entry.getKey(), value == null ? null : value.getResultType());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user