Search in sources :

Example 1 with ReadWriteVariableInstruction

use of org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction in project intellij-community by JetBrains.

the class GrIntroduceClosureParameterProcessor method findUsagesForLocal.

private static Collection<PsiReference> findUsagesForLocal(GrClosableBlock initializer, final GrVariable var) {
    final Instruction[] flow = ControlFlowUtils.findControlFlowOwner(initializer).getControlFlow();
    final List<BitSet> writes = ControlFlowUtils.inferWriteAccessMap(flow, var);
    Instruction writeInstr = null;
    final PsiElement parent = initializer.getParent();
    if (parent instanceof GrVariable) {
        writeInstr = ContainerUtil.find(flow, instruction -> instruction.getElement() == var);
    } else if (parent instanceof GrAssignmentExpression) {
        final GrReferenceExpression refExpr = (GrReferenceExpression) ((GrAssignmentExpression) parent).getLValue();
        final Instruction instruction = ContainerUtil.find(flow, instruction1 -> instruction1.getElement() == refExpr);
        LOG.assertTrue(instruction != null);
        final BitSet prev = writes.get(instruction.num());
        if (prev.cardinality() == 1) {
            writeInstr = flow[prev.nextSetBit(0)];
        }
    }
    LOG.assertTrue(writeInstr != null);
    Collection<PsiReference> result = new ArrayList<>();
    for (Instruction instruction : flow) {
        if (!(instruction instanceof ReadWriteVariableInstruction))
            continue;
        if (((ReadWriteVariableInstruction) instruction).isWrite())
            continue;
        final PsiElement element = instruction.getElement();
        if (element instanceof GrVariable && element != var)
            continue;
        if (!(element instanceof GrReferenceExpression))
            continue;
        final GrReferenceExpression ref = (GrReferenceExpression) element;
        if (ref.isQualified() || ref.resolve() != var)
            continue;
        final BitSet prev = writes.get(instruction.num());
        if (prev.cardinality() == 1 && prev.get(writeInstr.num())) {
            result.add(ref);
        }
    }
    return result;
}
Also used : IntroduceParameterRefactoring(com.intellij.refactoring.IntroduceParameterRefactoring) PsiImplUtil(org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) ExternalUsageInfo(com.intellij.refactoring.introduceParameter.ExternalUsageInfo) StringPartInfo(org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo) GrArgumentList(org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList) RefactoringBundle(com.intellij.refactoring.RefactoringBundle) BaseRefactoringProcessor(com.intellij.refactoring.BaseRefactoringProcessor) ControlFlowUtils(org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) MethodReferencesSearch(com.intellij.psi.search.searches.MethodReferencesSearch) GrAccessorMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod) Logger(com.intellij.openapi.diagnostic.Logger) MultiMap(com.intellij.util.containers.MultiMap) GrMethodCallExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression) ReferencesSearch(com.intellij.psi.search.searches.ReferencesSearch) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) IncorrectOperationException(com.intellij.util.IncorrectOperationException) GrClosureSignatureUtil(org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil) Collection(java.util.Collection) Nullable(org.jetbrains.annotations.Nullable) org.jetbrains.plugins.groovy.lang.psi.api.statements(org.jetbrains.plugins.groovy.lang.psi.api.statements) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) List(java.util.List) FieldConflictsResolver(org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.FieldConflictsResolver) GrMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod) com.intellij.psi(com.intellij.psi) NotNull(org.jetbrains.annotations.NotNull) Ref(com.intellij.openapi.util.Ref) PsiUtil(org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil) GroovyRefactoringBundle(org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle) DescriptiveNameUtil(com.intellij.lang.findUsages.DescriptiveNameUtil) ChangedMethodCallInfo(com.intellij.refactoring.introduceParameter.ChangedMethodCallInfo) GrClosureSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature) Instruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction) ArrayUtil(com.intellij.util.ArrayUtil) PsiUtilBase(com.intellij.psi.util.PsiUtilBase) GroovyLanguage(org.jetbrains.plugins.groovy.GroovyLanguage) ChangeContextUtil(com.intellij.codeInsight.ChangeContextUtil) UsageViewDescriptorAdapter(com.intellij.refactoring.ui.UsageViewDescriptorAdapter) UsageInfo(com.intellij.usageView.UsageInfo) GrStatementOwner(org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner) ContainerUtil(com.intellij.util.containers.ContainerUtil) GrCodeBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock) AnySupers(org.jetbrains.plugins.groovy.refactoring.util.AnySupers) JavaCodeStyleManager(com.intellij.psi.codeStyle.JavaCodeStyleManager) ArrayList(java.util.ArrayList) OldReferencesResolver(org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.OldReferencesResolver) GroovyRefactoringUtil(org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil) GroovyPsiElementFactory(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory) GrParameterList(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList) InternalUsageInfo(com.intellij.refactoring.introduceParameter.InternalUsageInfo) Editor(com.intellij.openapi.editor.Editor) UsageViewUtil(com.intellij.usageView.UsageViewUtil) GroovyResolveResult(org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult) UsageViewDescriptor(com.intellij.usageView.UsageViewDescriptor) CommonRefactoringUtil(com.intellij.refactoring.util.CommonRefactoringUtil) CodeStyleManager(com.intellij.psi.codeStyle.CodeStyleManager) ExpressionConverter(com.intellij.psi.impl.ExpressionConverter) TIntProcedure(gnu.trove.TIntProcedure) org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions) BitSet(java.util.BitSet) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) BitSet(java.util.BitSet) ArrayList(java.util.ArrayList) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) Instruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction)

Example 2 with ReadWriteVariableInstruction

use of org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction in project intellij-community by JetBrains.

the class UnassignedVariableAccessInspection method check.

@Override
protected void check(@NotNull GrControlFlowOwner owner, @NotNull ProblemsHolder problemsHolder) {
    Instruction[] flow = owner.getControlFlow();
    ReadWriteVariableInstruction[] reads = ControlFlowBuilderUtil.getReadsWithoutPriorWrites(flow, true);
    for (ReadWriteVariableInstruction read : reads) {
        PsiElement element = read.getElement();
        if (element instanceof GroovyPsiElement && !(element instanceof GrClosableBlock)) {
            String name = read.getVariableName();
            GroovyPsiElement property = ResolveUtil.resolveProperty((GroovyPsiElement) element, name);
            if (property != null && !(property instanceof PsiParameter) && !(property instanceof PsiField) && PsiTreeUtil.isAncestor(owner, property, false) && !(myIgnoreBooleanExpressions && isBooleanCheck(element))) {
                problemsHolder.registerProblem(element, GroovyInspectionBundle.message("unassigned.access.tooltip", name));
            }
        }
    }
}
Also used : GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) PsiParameter(com.intellij.psi.PsiParameter) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) PsiField(com.intellij.psi.PsiField) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) Instruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) PsiElement(com.intellij.psi.PsiElement) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Example 3 with ReadWriteVariableInstruction

use of org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction in project intellij-community by JetBrains.

the class ControlFlowUtils method findAccess.

/**
   * searches for next or previous write access to local variable
   * @param local variable to analyze
   * @param place place to start searching
   * @param ahead if true search for next write. if false searches for previous write
   * @return all write instructions leading to (or preceding) the place
   */
public static List<ReadWriteVariableInstruction> findAccess(GrVariable local, final PsiElement place, boolean ahead, boolean writeAccessOnly) {
    LOG.assertTrue(!(local instanceof GrField), local.getClass());
    final GrControlFlowOwner owner = findControlFlowOwner(place);
    assert owner != null;
    final Instruction cur = findInstruction(place, owner.getControlFlow());
    if (cur == null) {
        throw new IllegalArgumentException("place is not in the flow");
    }
    return findAccess(local, ahead, writeAccessOnly, cur);
}
Also used : GrControlFlowOwner(org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner) Instruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction) MaybeReturnInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.MaybeReturnInstruction) AfterCallInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.AfterCallInstruction) ThrowingInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ThrowingInstruction) IfEndInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.IfEndInstruction) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction)

Example 4 with ReadWriteVariableInstruction

use of org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction in project intellij-community by JetBrains.

the class ControlFlowUtils method inferWriteAccessMap.

@NotNull
public static List<BitSet> inferWriteAccessMap(final Instruction[] flow, final GrVariable var) {
    final Semilattice<BitSet> sem = new Semilattice<BitSet>() {

        @NotNull
        @Override
        public BitSet join(@NotNull List<BitSet> ins) {
            BitSet result = new BitSet(flow.length);
            for (BitSet set : ins) {
                result.or(set);
            }
            return result;
        }

        @Override
        public boolean eq(@NotNull BitSet e1, @NotNull BitSet e2) {
            return e1.equals(e2);
        }
    };
    DfaInstance<BitSet> dfa = new DfaInstance<BitSet>() {

        @Override
        public void fun(@NotNull BitSet bitSet, @NotNull Instruction instruction) {
            if (!(instruction instanceof ReadWriteVariableInstruction))
                return;
            if (!((ReadWriteVariableInstruction) instruction).isWrite())
                return;
            final PsiElement element = instruction.getElement();
            if (element instanceof GrVariable && element != var)
                return;
            if (element instanceof GrReferenceExpression) {
                final GrReferenceExpression ref = (GrReferenceExpression) element;
                if (ref.isQualified() || ref.resolve() != var) {
                    return;
                }
            }
            if (!((ReadWriteVariableInstruction) instruction).getVariableName().equals(var.getName())) {
                return;
            }
            bitSet.clear();
            bitSet.set(instruction.num());
        }

        @NotNull
        @Override
        public BitSet initial() {
            return new BitSet(flow.length);
        }
    };
    return new DFAEngine<>(flow, dfa, sem).performForceDFA();
}
Also used : ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) Instruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction) MaybeReturnInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.MaybeReturnInstruction) AfterCallInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.AfterCallInstruction) ThrowingInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ThrowingInstruction) IfEndInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.IfEndInstruction) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) NotNull(org.jetbrains.annotations.NotNull) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression) DfaInstance(org.jetbrains.plugins.groovy.lang.psi.dataFlow.DfaInstance) Semilattice(org.jetbrains.plugins.groovy.lang.psi.dataFlow.Semilattice) PsiElement(com.intellij.psi.PsiElement) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with ReadWriteVariableInstruction

use of org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction in project intellij-community by JetBrains.

the class ReachingDefinitionsCollector method obtainVariableFlowInformation.

@NotNull
public static FragmentVariableInfos obtainVariableFlowInformation(@NotNull final GrStatement first, @NotNull final GrStatement last, @NotNull final GrControlFlowOwner flowOwner, @NotNull final Instruction[] flow) {
    final DefinitionMap dfaResult = inferDfaResult(flow);
    final LinkedHashSet<Integer> fragmentInstructions = getFragmentInstructions(first, last, flow);
    final int[] postorder = reversedPostOrder(flow);
    LinkedHashSet<Integer> reachableFromFragmentReads = getReachable(fragmentInstructions, flow, dfaResult, postorder);
    LinkedHashSet<Integer> fragmentReads = filterReads(fragmentInstructions, flow);
    final Map<String, VariableInfo> imap = new LinkedHashMap<>();
    final Map<String, VariableInfo> omap = new LinkedHashMap<>();
    final PsiManager manager = first.getManager();
    for (final Integer ref : fragmentReads) {
        ReadWriteVariableInstruction rwInstruction = (ReadWriteVariableInstruction) flow[ref];
        String name = rwInstruction.getVariableName();
        final int[] defs = dfaResult.getDefinitions(ref);
        if (!allDefsInFragment(defs, fragmentInstructions)) {
            addVariable(name, imap, manager, getType(rwInstruction.getElement()));
        }
    }
    for (final Integer ref : reachableFromFragmentReads) {
        ReadWriteVariableInstruction rwInstruction = (ReadWriteVariableInstruction) flow[ref];
        String name = rwInstruction.getVariableName();
        final int[] defs = dfaResult.getDefinitions(ref);
        if (anyDefInFragment(defs, fragmentInstructions)) {
            for (int def : defs) {
                if (fragmentInstructions.contains(def)) {
                    PsiType outputType = getType(flow[def].getElement());
                    addVariable(name, omap, manager, outputType);
                }
            }
            if (!allProperDefsInFragment(defs, ref, fragmentInstructions, postorder)) {
                PsiType inputType = getType(rwInstruction.getElement());
                addVariable(name, imap, manager, inputType);
            }
        }
    }
    addClosureUsages(imap, omap, first, last, flowOwner);
    final VariableInfo[] iarr = filterNonlocals(imap, last);
    final VariableInfo[] oarr = filterNonlocals(omap, last);
    return new FragmentVariableInfos() {

        @Override
        public VariableInfo[] getInputVariableNames() {
            return iarr;
        }

        @Override
        public VariableInfo[] getOutputVariableNames() {
            return oarr;
        }
    };
}
Also used : ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

ReadWriteVariableInstruction (org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction)14 Instruction (org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction)10 NotNull (org.jetbrains.annotations.NotNull)5 PsiElement (com.intellij.psi.PsiElement)4 GrVariable (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable)4 Nullable (org.jetbrains.annotations.Nullable)3 GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)3 GrClosableBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock)3 AfterCallInstruction (org.jetbrains.plugins.groovy.lang.psi.controlFlow.AfterCallInstruction)3 IfEndInstruction (org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.IfEndInstruction)3 MaybeReturnInstruction (org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.MaybeReturnInstruction)3 ThrowingInstruction (org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ThrowingInstruction)3 UsageInfo (com.intellij.usageView.UsageInfo)2 GrControlFlowOwner (org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner)2 GroovyRecursiveElementVisitor (org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor)2 GrOpenBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock)2 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)2 GrReferenceExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression)2 GrMethod (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod)2 DFAEngine (org.jetbrains.plugins.groovy.lang.psi.dataFlow.DFAEngine)2