Search in sources :

Example 6 with ReadWriteVariableInstruction

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

the class ReachingDefinitionsCollector method postprocess.

@NotNull
private static DefinitionMap postprocess(@NotNull final List<DefinitionMap> dfaResult, @NotNull Instruction[] flow, @NotNull ReachingDefinitionsDfaInstance dfaInstance) {
    DefinitionMap result = new DefinitionMap();
    for (int i = 0; i < flow.length; i++) {
        Instruction insn = flow[i];
        if (insn instanceof ReadWriteVariableInstruction) {
            ReadWriteVariableInstruction rwInsn = (ReadWriteVariableInstruction) insn;
            if (!rwInsn.isWrite()) {
                int idx = dfaInstance.getVarIndex(rwInsn.getVariableName());
                result.copyFrom(dfaResult.get(i), idx, i);
            }
        }
    }
    return result;
}
Also used : ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) Instruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) NotNull(org.jetbrains.annotations.NotNull)

Example 7 with ReadWriteVariableInstruction

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

the class TypeInferenceHelper method getInferredType.

@Nullable
public static PsiType getInferredType(@NotNull final GrReferenceExpression refExpr) {
    final GrControlFlowOwner scope = ControlFlowUtils.findControlFlowOwner(refExpr);
    if (scope == null)
        return null;
    final String referenceName = refExpr.getReferenceName();
    if (referenceName == null)
        return null;
    final ReadWriteVariableInstruction rwInstruction = ControlFlowUtils.findRWInstruction(refExpr, scope.getControlFlow());
    if (rwInstruction == null)
        return null;
    return getInferenceCache(scope).getInferredType(referenceName, rwInstruction);
}
Also used : GrControlFlowOwner(org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) Nullable(org.jetbrains.annotations.Nullable)

Example 8 with ReadWriteVariableInstruction

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

the class GrFinalVariableAccessInspection method buildVisitor.

@NotNull
@Override
protected BaseInspectionVisitor buildVisitor() {
    return new BaseInspectionVisitor() {

        @Override
        public void visitMethod(@NotNull GrMethod method) {
            super.visitMethod(method);
            final GrOpenBlock block = method.getBlock();
            if (block != null) {
                processLocalVars(block);
            }
            if (method.isConstructor()) {
                processFieldsInConstructors(method);
            }
        }

        @Override
        public void visitFile(@NotNull GroovyFileBase file) {
            super.visitFile(file);
            if (file instanceof GroovyFile && file.isScript()) {
                processLocalVars(file);
            }
        }

        @Override
        public void visitField(@NotNull GrField field) {
            super.visitField(field);
            final GrExpression initializer = field.getInitializerGroovy();
            if (initializer != null) {
                processLocalVars(initializer);
            }
            if (field.hasModifierProperty(PsiModifier.FINAL)) {
                if (!isFieldInitialized(field)) {
                    registerError(field.getNameIdentifierGroovy(), GroovyBundle.message("variable.0.might.not.have.been.initialized", field.getName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
                }
            }
        }

        @Override
        public void visitReferenceExpression(@NotNull GrReferenceExpression ref) {
            super.visitReferenceExpression(ref);
            final PsiElement resolved = ref.resolve();
            if (resolved instanceof GrField && ((GrField) resolved).hasModifierProperty(PsiModifier.FINAL)) {
                final GrField field = (GrField) resolved;
                final PsiClass containingClass = field.getContainingClass();
                if (PsiUtil.isLValue(ref)) {
                    if (containingClass == null || !PsiTreeUtil.isAncestor(containingClass, ref, true)) {
                        registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.field.0", field.getName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
                    }
                } else if (PsiUtil.isUsedInIncOrDec(ref)) {
                    if (containingClass == null || !isInsideConstructorOrInitializer(containingClass, ref, field.hasModifierProperty(PsiModifier.STATIC))) {
                        registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.field.0", field.getName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
                    }
                }
            } else if (resolved instanceof GrParameter && ((GrParameter) resolved).getDeclarationScope() instanceof GrMethod && ((GrParameter) resolved).hasModifierProperty(PsiModifier.FINAL) && PsiUtil.isUsedInIncOrDec(ref)) {
                registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.parameter.0", ((GrParameter) resolved).getName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
            }
        }

        @Override
        public void visitClassInitializer(@NotNull GrClassInitializer initializer) {
            super.visitClassInitializer(initializer);
            processLocalVars(initializer.getBlock());
            processFieldsInClassInitializer(initializer);
        }

        private void processFieldsInConstructors(@NotNull GrMethod constructor) {
            final GrOpenBlock block = constructor.getBlock();
            if (block == null)
                return;
            final GrTypeDefinition clazz = (GrTypeDefinition) constructor.getContainingClass();
            if (clazz == null)
                return;
            final GrClassInitializer[] initializers = clazz.getInitializers();
            final List<GrField> fields = getFinalFields(clazz);
            Set<GrVariable> initializedFields = ContainerUtil.newHashSet();
            appendFieldInitializedInDeclaration(false, fields, initializedFields);
            appendFieldsInitializedInClassInitializer(initializers, null, false, fields, initializedFields);
            appendInitializationFromChainedConstructors(constructor, fields, initializedFields);
            final Instruction[] flow = buildFlowForField(block);
            final Map<String, GrVariable> variables = buildVarMap(fields, false);
            highlightInvalidWriteAccess(flow, variables, initializedFields);
        }

        private void processFieldsInClassInitializer(@NotNull GrClassInitializer initializer) {
            final GrTypeDefinition clazz = (GrTypeDefinition) initializer.getContainingClass();
            if (clazz == null)
                return;
            final boolean isStatic = initializer.isStatic();
            final GrClassInitializer[] initializers = clazz.getInitializers();
            final List<GrField> fields = getFinalFields(clazz);
            Set<GrVariable> initializedFields = ContainerUtil.newHashSet();
            appendFieldInitializedInDeclaration(isStatic, fields, initializedFields);
            appendFieldsInitializedInClassInitializer(initializers, initializer, isStatic, fields, initializedFields);
            final Instruction[] flow = buildFlowForField(initializer.getBlock());
            final Map<String, GrVariable> variables = buildVarMap(fields, isStatic);
            highlightInvalidWriteAccess(flow, variables, initializedFields);
        }

        private void processLocalVars(@NotNull GroovyPsiElement scope) {
            final MultiMap<PsiElement, GrVariable> scopes = collectVariables(scope);
            for (final Map.Entry<PsiElement, Collection<GrVariable>> entry : scopes.entrySet()) {
                final PsiElement scopeToProcess = entry.getKey();
                final Set<GrVariable> forInParameters = ContainerUtil.newHashSet();
                final Map<String, GrVariable> variables = ContainerUtil.newHashMap();
                for (final GrVariable var : entry.getValue()) {
                    variables.put(var.getName(), var);
                    if (var instanceof GrParameter && ((GrParameter) var).getDeclarationScope() instanceof GrForStatement) {
                        forInParameters.add(var);
                    }
                }
                final Instruction[] flow = getFlow(scopeToProcess);
                highlightInvalidWriteAccess(flow, variables, forInParameters);
            }
        }

        private void highlightInvalidWriteAccess(@NotNull Instruction[] flow, @NotNull Map<String, GrVariable> variables, @NotNull Set<GrVariable> initializedVariables) {
            final List<ReadWriteVariableInstruction> result = InvalidWriteAccessSearcher.findInvalidWriteAccess(flow, variables, initializedVariables);
            if (result == null)
                return;
            for (final ReadWriteVariableInstruction instruction : result) {
                if (variables.containsKey(instruction.getVariableName())) {
                    registerError(instruction.getElement(), GroovyBundle.message("cannot.assign.a.value.to.final.field.0", instruction.getVariableName()), LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
                }
            }
        }
    };
}
Also used : BaseInspectionVisitor(org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) Instruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) NotNull(org.jetbrains.annotations.NotNull) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) GrMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression) GrTypeDefinition(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition) GrOpenBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock) MultiMap(com.intellij.util.containers.MultiMap) NotNull(org.jetbrains.annotations.NotNull)

Example 9 with ReadWriteVariableInstruction

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

the class InvalidWriteAccessSearcher method findInvalidWriteAccess.

@Nullable
public static List<ReadWriteVariableInstruction> findInvalidWriteAccess(@NotNull Instruction[] flow, @NotNull Map<String, GrVariable> variables, @NotNull Set<GrVariable> alreadyInitialized) {
    DFAEngine<MyData> engine = new DFAEngine<>(flow, new MyDFAInstance(), new MySemilattice());
    final List<MyData> dfaResult = engine.performDFAWithTimeout();
    if (dfaResult == null)
        return null;
    List<ReadWriteVariableInstruction> result = ContainerUtil.newArrayList();
    for (int i = 0; i < flow.length; i++) {
        Instruction instruction = flow[i];
        if (instruction instanceof ReadWriteVariableInstruction && ((ReadWriteVariableInstruction) instruction).isWrite()) {
            final MyData initialized = dfaResult.get(i);
            final GrVariable var = variables.get(((ReadWriteVariableInstruction) instruction).getVariableName());
            if (alreadyInitialized.contains(var)) {
                if (initialized.isInitialized(((ReadWriteVariableInstruction) instruction).getVariableName())) {
                    result.add((ReadWriteVariableInstruction) instruction);
                }
            } else {
                if (initialized.isOverInitialized(((ReadWriteVariableInstruction) instruction).getVariableName())) {
                    result.add((ReadWriteVariableInstruction) instruction);
                }
            }
        }
    }
    return result;
}
Also used : DFAEngine(org.jetbrains.plugins.groovy.lang.psi.dataFlow.DFAEngine) GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) Instruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) Nullable(org.jetbrains.annotations.Nullable)

Example 10 with ReadWriteVariableInstruction

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

the class WritesCounterDFAInstance method fun.

@Override
public void fun(@NotNull TObjectIntHashMap<GrVariable> map, @NotNull Instruction instruction) {
    if (!(instruction instanceof ReadWriteVariableInstruction))
        return;
    final ReadWriteVariableInstruction rwInstruction = (ReadWriteVariableInstruction) instruction;
    if (!rwInstruction.isWrite())
        return;
    final GrVariable variable = getVariable(instruction.getElement());
    if (variable == null)
        return;
    int currentVal = map.get(variable);
    if (currentVal == 2)
        return;
    if (currentVal == 0 || currentVal == 1 && !(variable.getParent() instanceof GrForInClause))
        currentVal++;
    map.put(variable, currentVal);
}
Also used : GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) ReadWriteVariableInstruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction) GrForInClause(org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClause)

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