diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java index 7b1af3b24ae9..01239024a52b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-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. @@ -63,6 +63,7 @@ public class ExpressionTypeMemoryState extends DfaMemoryStateImpl { super(toCopy); } + @NotNull @Override public DfaMemoryStateImpl createCopy() { final ExpressionTypeMemoryState copy = new ExpressionTypeMemoryState(this); diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java index b7e4660e5260..65be476e4b3e 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-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. @@ -17,10 +17,10 @@ package com.intellij.codeInsight.guess.impl; import com.intellij.codeInsight.guess.GuessManager; import com.intellij.codeInspection.dataFlow.*; -import com.intellij.codeInspection.dataFlow.instructions.PushInstruction; -import com.intellij.codeInspection.dataFlow.instructions.TypeCastInstruction; import com.intellij.codeInspection.dataFlow.instructions.InstanceofInstruction; import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction; +import com.intellij.codeInspection.dataFlow.instructions.PushInstruction; +import com.intellij.codeInspection.dataFlow.instructions.TypeCastInstruction; import com.intellij.codeInspection.dataFlow.value.DfaInstanceofValue; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; @@ -31,8 +31,8 @@ import com.intellij.psi.search.PsiElementProcessorAdapter; import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -151,6 +151,7 @@ public class GuessManagerImpl extends GuessManager { } DataFlowRunner runner = new DataFlowRunner() { + @NotNull @Override protected DfaMemoryState createMemoryState() { return new ExpressionTypeMemoryState(getFactory()); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractChecker.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractChecker.java index a7e41a910892..ad1fc779e46b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractChecker.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-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. @@ -25,6 +25,7 @@ import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; import com.intellij.psi.*; import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; import java.util.*; @@ -39,7 +40,7 @@ class ContractChecker extends DataFlowRunner { private final Set myNonViolations = ContainerUtil.newHashSet(); private final Set myFailures = ContainerUtil.newHashSet(); - ContractChecker(PsiMethod method, MethodContract contract, final boolean onTheFly) { + private ContractChecker(PsiMethod method, MethodContract contract, final boolean onTheFly) { myMethod = method; myContract = contract; myOnTheFly = onTheFly; @@ -77,8 +78,9 @@ class ContractChecker extends DataFlowRunner { return super.shouldCheckTimeLimit(); } + @NotNull @Override - protected DfaInstructionState[] acceptInstruction(InstructionVisitor visitor, DfaInstructionState instructionState) { + protected DfaInstructionState[] acceptInstruction(@NotNull InstructionVisitor visitor, @NotNull DfaInstructionState instructionState) { DfaMemoryState memState = instructionState.getMemoryState(); if (memState.isEphemeral()) { return DfaInstructionState.EMPTY_ARRAY; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java index 1adc7fa781d2..ec8fbf673817 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java @@ -52,11 +52,12 @@ public class DataFlowRunner { private Instruction[] myInstructions; private final MultiMap myNestedClosures = new MultiMap(); + @NotNull private final DfaValueFactory myValueFactory; // Maximum allowed attempts to process instruction. Fail as too complex to process if certain instruction // is executed more than this limit times. - public static final int MAX_STATES_PER_BRANCH = 300; + static final int MAX_STATES_PER_BRANCH = 300; protected DataFlowRunner() { this(false, true); @@ -66,12 +67,13 @@ public class DataFlowRunner { myValueFactory = new DfaValueFactory(honorFieldInitializers, unknownMembersAreNullable); } + @NotNull public DfaValueFactory getFactory() { return myValueFactory; } @Nullable - private Collection createInitialStates(@NotNull PsiElement psiBlock, InstructionVisitor visitor) { + private Collection createInitialStates(@NotNull PsiElement psiBlock, @NotNull InstructionVisitor visitor) { PsiClass containingClass = PsiTreeUtil.getParentOfType(psiBlock, PsiClass.class); if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) { final PsiElement parent = containingClass.getParent(); @@ -91,16 +93,17 @@ public class DataFlowRunner { return Collections.singletonList(createMemoryState()); } - public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, InstructionVisitor visitor) { + @NotNull + public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, @NotNull InstructionVisitor visitor) { Collection initialStates = createInitialStates(psiBlock, visitor); return initialStates == null ? RunnerResult.NOT_APPLICABLE : analyzeMethod(psiBlock, visitor, false, initialStates); } @NotNull - public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, - InstructionVisitor visitor, - boolean ignoreAssertions, - @NotNull Collection initialStates) { + final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, + @NotNull InstructionVisitor visitor, + boolean ignoreAssertions, + @NotNull Collection initialStates) { if (PsiTreeUtil.findChildOfType(psiBlock, OuterLanguageElement.class) != null) return RunnerResult.NOT_APPLICABLE; try { @@ -127,7 +130,7 @@ public class DataFlowRunner { if (LOG.isDebugEnabled()) { LOG.debug("Analyzing code block: " + psiBlock.getText()); for (int i = 0; i < myInstructions.length; i++) { - LOG.debug(i + ": " + myInstructions[i].toString()); + LOG.debug(i + ": " + myInstructions[i]); } } //for (int i = 0; i < myInstructions.length; i++) System.out.println(i + ": " + myInstructions[i].toString()); @@ -220,10 +223,11 @@ public class DataFlowRunner { private void handleStepOutOfLoop(@NotNull final Instruction prevInstruction, @NotNull Instruction nextInstruction, @NotNull final int[] loopNumber, - MultiMap processedStates, - MultiMap incomingStates, - List inFlightStates, - DfaInstructionState[] afterStates, StateQueue queue) { + @NotNull MultiMap processedStates, + @NotNull MultiMap incomingStates, + @NotNull List inFlightStates, + @NotNull DfaInstructionState[] afterStates, + @NotNull StateQueue queue) { if (loopNumber[prevInstruction.getIndex()] == 0 || inSameLoop(prevInstruction, nextInstruction, loopNumber)) { return; } @@ -247,10 +251,7 @@ public class DataFlowRunner { @Override public boolean process(DfaInstructionState state) { Instruction instruction = state.getInstruction(); - if (inSameLoop(prevInstruction, instruction, loopNumber)) { - return false; - } - return true; + return !inSameLoop(prevInstruction, instruction, loopNumber); } })) return; @@ -276,7 +277,8 @@ public class DataFlowRunner { return !ApplicationManager.getApplication().isUnitTestMode(); } - protected DfaInstructionState[] acceptInstruction(InstructionVisitor visitor, DfaInstructionState instructionState) { + @NotNull + protected DfaInstructionState[] acceptInstruction(@NotNull InstructionVisitor visitor, @NotNull DfaInstructionState instructionState) { Instruction instruction = instructionState.getInstruction(); PsiElement closure = DfaUtil.getClosureInside(instruction); if (closure instanceof PsiClass) { @@ -288,7 +290,7 @@ public class DataFlowRunner { return instruction.accept(this, instructionState.getMemoryState(), visitor); } - private void registerNestedClosures(DfaInstructionState instructionState, PsiClass nestedClass) { + private void registerNestedClosures(@NotNull DfaInstructionState instructionState, @NotNull PsiClass nestedClass) { DfaMemoryState state = instructionState.getMemoryState(); for (PsiMethod method : nestedClass.getMethods()) { PsiCodeBlock body = method.getBody(); @@ -304,7 +306,7 @@ public class DataFlowRunner { } } - private void registerNestedClosures(DfaInstructionState instructionState, PsiLambdaExpression expr) { + private void registerNestedClosures(@NotNull DfaInstructionState instructionState, @NotNull PsiLambdaExpression expr) { DfaMemoryState state = instructionState.getMemoryState(); PsiElement body = expr.getBody(); if (body != null) { @@ -312,22 +314,27 @@ public class DataFlowRunner { } } + @NotNull protected DfaMemoryState createMemoryState() { return new DfaMemoryStateImpl(myValueFactory); } + @NotNull public Instruction[] getInstructions() { return myInstructions; } + @NotNull public Instruction getInstruction(int index) { return myInstructions[index]; } - public MultiMap getNestedClosures() { + @NotNull + MultiMap getNestedClosures() { return new MultiMap(myNestedClosures); } + @NotNull public Pair,Set> getConstConditionalExpressions() { Set trueSet = new HashSet(); Set falseSet = new HashSet(); @@ -362,7 +369,8 @@ public class DataFlowRunner { return Pair.create(trueSet, falseSet); } - private static DfaMemoryStateImpl createClosureState(DfaMemoryState memState) { + @NotNull + private static DfaMemoryStateImpl createClosureState(@NotNull DfaMemoryState memState) { DfaMemoryStateImpl copy = (DfaMemoryStateImpl)memState.createCopy(); copy.flushFields(); Set vars = new HashSet(copy.getVariableStates().keySet()); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java index 2fb0de1705e3..326a7c76cf21 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-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. @@ -30,6 +30,7 @@ import org.jetbrains.annotations.Nullable; * To change this template use Options | File Templates. */ public interface DfaMemoryState { + @NotNull DfaMemoryState createCopy(); DfaValue pop(); @@ -40,7 +41,7 @@ public interface DfaMemoryState { void setVarValue(DfaVariableValue var, DfaValue value); - boolean applyInstanceofOrNull(DfaRelationValue dfaCond); + boolean applyInstanceofOrNull(@NotNull DfaRelationValue dfaCond); boolean applyCondition(DfaValue dfaCond); @@ -55,7 +56,7 @@ public interface DfaMemoryState { boolean isNotNull(DfaValue dfaVar); @Nullable - DfaConstValue getConstantValue(DfaVariableValue value); + DfaConstValue getConstantValue(@NotNull DfaVariableValue value); /** * Ephemeral means a state that was created when considering a method contract and checking if one of its arguments is null. diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index b015f5bfa80d..30eae15890a5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -59,7 +59,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { private final LinkedHashSet myUnknownVariables; private boolean myEphemeral; - public DfaMemoryStateImpl(final DfaValueFactory factory) { + protected DfaMemoryStateImpl(final DfaValueFactory factory) { myFactory = factory; myDefaultVariableStates = ContainerUtil.newTroveMap(); myEqClasses = ContainerUtil.newArrayList(); @@ -95,10 +95,12 @@ public class DfaMemoryStateImpl implements DfaMemoryState { myCachedHash = toCopy.myCachedHash; } + @NotNull public DfaValueFactory getFactory() { return myFactory; } + @NotNull @Override public DfaMemoryStateImpl createCopy() { return new DfaMemoryStateImpl(this); @@ -112,7 +114,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return equalsSuperficially(that) && equalsByUnknownVariables(that) && equalsByRelations(that) && equalsByVariableStates(that); } - boolean equalsByUnknownVariables(DfaMemoryStateImpl that) { + private boolean equalsByUnknownVariables(DfaMemoryStateImpl that) { return myUnknownVariables.equals(that.myUnknownVariables); } @@ -178,7 +180,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return hash; } - @SuppressWarnings({"HardCodedStringLiteral"}) + @SuppressWarnings("HardCodedStringLiteral") public String toString() { StringBuilder result = new StringBuilder(); result.append('<'); @@ -285,7 +287,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { } @Nullable("for boxed values which can't be compared by ==") - private Integer getOrCreateEqClassIndex(DfaValue dfaValue) { + private Integer getOrCreateEqClassIndex(@NotNull DfaValue dfaValue) { int i = getEqClassIndex(dfaValue); if (i != -1) return i; if (!canBeInRelation(dfaValue) || @@ -340,7 +342,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { } - private static boolean canBeInRelation(DfaValue dfaValue) { + private static boolean canBeInRelation(@NotNull DfaValue dfaValue) { DfaValue unwrapped = unwrap(dfaValue); return unwrapped instanceof DfaVariableValue || unwrapped instanceof DfaConstValue; } @@ -393,7 +395,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return result; } - private boolean canBeReused(final DfaValue dfaValue) { + private boolean canBeReused(@NotNull DfaValue dfaValue) { if (dfaValue instanceof DfaBoxedValue) { DfaValue valueToWrap = ((DfaBoxedValue)dfaValue).getWrappedValue(); if (valueToWrap instanceof DfaConstValue) { @@ -410,12 +412,12 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return true; } - private static boolean cacheable(DfaConstValue dfaConstValue) { + private static boolean cacheable(@NotNull DfaConstValue dfaConstValue) { Object value = dfaConstValue.getValue(); return box(value) == box(value); } - @SuppressWarnings({"UnnecessaryBoxing"}) + @SuppressWarnings("UnnecessaryBoxing") private static Object box(final Object value) { Object newBoxedValue; if (value instanceof Integer) { @@ -577,7 +579,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { @Override @Nullable - public DfaConstValue getConstantValue(DfaVariableValue value) { + public DfaConstValue getConstantValue(@NotNull DfaVariableValue value) { int index = getEqClassIndex(value); EqClass ec = index == -1 ? null : myEqClasses.get(index); return ec == null ? null : (DfaConstValue)unwrap(ec.findConstant(true)); @@ -594,7 +596,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { } @Override - public boolean applyInstanceofOrNull(DfaRelationValue dfaCond) { + public boolean applyInstanceofOrNull(@NotNull DfaRelationValue dfaCond) { DfaValue left = unwrap(dfaCond.getLeftOperand()); if (!(left instanceof DfaVariableValue)) return true; @@ -648,7 +650,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return applyRelationCondition((DfaRelationValue)dfaCond); } - private boolean applyRelationCondition(DfaRelationValue dfaRelation) { + private boolean applyRelationCondition(@NotNull DfaRelationValue dfaRelation) { DfaValue dfaLeft = dfaRelation.getLeftOperand(); DfaValue dfaRight = dfaRelation.getRightOperand(); if (dfaLeft instanceof DfaUnknownValue || dfaRight instanceof DfaUnknownValue) return true; @@ -702,7 +704,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return applyEquivalenceRelation(dfaRelation, dfaLeft, dfaRight); } - private void updateVarStateOnComparison(DfaVariableValue dfaVar, DfaValue value) { + private void updateVarStateOnComparison(@NotNull DfaVariableValue dfaVar, DfaValue value) { if (!isUnknownState(dfaVar)) { if (value instanceof DfaConstValue && ((DfaConstValue)value).getValue() == null) { setVariableState(dfaVar, getVariableState(dfaVar).withNullability(Nullness.NULLABLE)); @@ -713,7 +715,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { } } - private boolean applyEquivalenceRelation(DfaRelationValue dfaRelation, DfaValue dfaLeft, DfaValue dfaRight) { + private boolean applyEquivalenceRelation(@NotNull DfaRelationValue dfaRelation, DfaValue dfaLeft, DfaValue dfaRight) { boolean isNegated = dfaRelation.isNonEquality(); if (!isNegated && !dfaRelation.isEquality()) { return true; @@ -761,7 +763,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return true; } - private boolean applyBoxedRelation(DfaVariableValue dfaLeft, DfaValue dfaRight, boolean negated) { + private boolean applyBoxedRelation(@NotNull DfaVariableValue dfaLeft, DfaValue dfaRight, boolean negated) { if (!TypeConversionUtil.isPrimitiveAndNotNull(dfaLeft.getVariableType())) return true; DfaBoxedValue.Factory boxedFactory = myFactory.getBoxedFactory(); @@ -770,7 +772,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return boxedLeft == null || boxedRight == null || applyRelation(boxedLeft, boxedRight, negated); } - private boolean applyUnboxedRelation(DfaVariableValue dfaLeft, DfaValue dfaRight, boolean negated) { + private boolean applyUnboxedRelation(@NotNull DfaVariableValue dfaLeft, DfaValue dfaRight, boolean negated) { PsiType type = dfaLeft.getVariableType(); if (!TypeConversionUtil.isPrimitiveWrapper(type)) { return true; @@ -912,7 +914,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { myCachedHash = null; } - public DfaVariableState getVariableState(DfaVariableValue dfaVar) { + DfaVariableState getVariableState(DfaVariableValue dfaVar) { DfaVariableState state = myVariableStates.get(dfaVar); if (state == null) { @@ -935,11 +937,13 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return state; } - protected Map getVariableStates() { + @NotNull + Map getVariableStates() { return myVariableStates; } - protected DfaVariableState createVariableState(final DfaVariableValue var) { + @NotNull + protected DfaVariableState createVariableState(@NotNull DfaVariableValue var) { return new DfaVariableState(var); } @@ -958,7 +962,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { } } - private boolean shouldMarkUnknown(DfaVariableValue value) { + private boolean shouldMarkUnknown(@NotNull DfaVariableValue value) { int eqClassIndex = getEqClassIndex(value); if (eqClassIndex < 0) return false; @@ -975,6 +979,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return false; } + @NotNull Set getChangedVariables() { return myVariableStates.keySet(); } @@ -999,17 +1004,18 @@ public class DfaMemoryStateImpl implements DfaMemoryState { myCachedHash = null; } - public void flushDependencies(DfaVariableValue variable) { + void flushDependencies(@NotNull DfaVariableValue variable) { for (DfaVariableValue dependent : myFactory.getVarFactory().getAllQualifiedBy(variable)) { doFlush(dependent, false); } } + @NotNull Set getUnknownVariables() { return myUnknownVariables; } - void doFlush(DfaVariableValue varPlain, boolean markUnknown) { + void doFlush(@NotNull DfaVariableValue varPlain, boolean markUnknown) { DfaVariableValue varNegated = varPlain.getNegatedValue(); final int idPlain = varPlain.getID(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java index 4c78c4807069..f6f72dbb32d7 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-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. @@ -155,8 +155,9 @@ public class DfaPsiUtil { return false; } + @NotNull @Override - protected DfaInstructionState[] acceptInstruction(InstructionVisitor visitor, DfaInstructionState instructionState) { + protected DfaInstructionState[] acceptInstruction(@NotNull InstructionVisitor visitor, @NotNull DfaInstructionState instructionState) { Instruction instruction = instructionState.getInstruction(); if (isCallExposingNonInitializedFields(instruction) || instruction instanceof ReturnInstruction && !((ReturnInstruction)instruction).isViaException()) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java index 43657cd75ded..80e1f64cac16 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-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. @@ -40,18 +40,19 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -public class DfaVariableState { - protected final Set myInstanceofValues; - protected final Set myNotInstanceofValues; - protected final Nullness myNullability; +class DfaVariableState { + @NotNull final Set myInstanceofValues; + @NotNull final Set myNotInstanceofValues; + @NotNull final Nullness myNullability; private final int myHash; - public DfaVariableState(@NotNull DfaVariableValue dfaVar) { + DfaVariableState(@NotNull DfaVariableValue dfaVar) { this(Collections.emptySet(), Collections.emptySet(), dfaVar.getInherentNullability()); } - protected DfaVariableState(Set instanceofValues, - Set notInstanceofValues, Nullness nullability) { + DfaVariableState(@NotNull Set instanceofValues, + @NotNull Set notInstanceofValues, + @NotNull Nullness nullability) { myInstanceofValues = instanceofValues; myNotInstanceofValues = notInstanceofValues; myNullability = nullability; @@ -62,7 +63,7 @@ public class DfaVariableState { return myNullability == Nullness.NULLABLE; } - private boolean checkInstanceofValue(DfaPsiType dfaType) { + private boolean checkInstanceofValue(@NotNull DfaPsiType dfaType) { if (myInstanceofValues.contains(dfaType)) return true; for (DfaPsiType dfaTypeValue : myNotInstanceofValues) { @@ -77,7 +78,7 @@ public class DfaVariableState { } @Nullable - public DfaVariableState withInstanceofValue(DfaTypeValue dfaType) { + DfaVariableState withInstanceofValue(@NotNull DfaTypeValue dfaType) { if (dfaType.getDfaType().getPsiType() instanceof PsiPrimitiveType) return this; if (checkInstanceofValue(dfaType.getDfaType())) { @@ -103,7 +104,7 @@ public class DfaVariableState { } @Nullable - public DfaVariableState withNotInstanceofValue(DfaTypeValue dfaType) { + DfaVariableState withNotInstanceofValue(@NotNull DfaTypeValue dfaType) { if (myNotInstanceofValues.contains(dfaType.getDfaType())) return this; for (DfaPsiType dfaTypeValue : myInstanceofValues) { @@ -126,7 +127,8 @@ public class DfaVariableState { return createCopy(myInstanceofValues, newNotInstanceof, myNullability); } - DfaVariableState withoutType(DfaPsiType type) { + @NotNull + DfaVariableState withoutType(@NotNull DfaPsiType type) { if (myInstanceofValues.contains(type)) { HashSet newInstanceof = ContainerUtil.newHashSet(myInstanceofValues); newInstanceof.remove(type); @@ -154,7 +156,8 @@ public class DfaVariableState { myNotInstanceofValues.equals(aState.myNotInstanceofValues); } - protected DfaVariableState createCopy(Set instanceofValues, Set notInstanceofValues, Nullness nullability) { + @NotNull + protected DfaVariableState createCopy(@NotNull Set instanceofValues, @NotNull Set notInstanceofValues, @NotNull Nullness nullability) { return new DfaVariableState(instanceofValues, notInstanceofValues, nullability); } @@ -172,7 +175,8 @@ public class DfaVariableState { return buf.toString(); } - public Nullness getNullability() { + @NotNull + Nullness getNullability() { return myNullability; } @@ -180,14 +184,17 @@ public class DfaVariableState { return myNullability == Nullness.NOT_NULL; } + @NotNull DfaVariableState withNullability(@NotNull Nullness nullness) { return myNullability == nullness ? this : createCopy(myInstanceofValues, myNotInstanceofValues, nullness); } - public DfaVariableState withNullable(final boolean nullable) { + @NotNull + DfaVariableState withNullable(final boolean nullable) { return myNullability != Nullness.NOT_NULL ? withNullability(nullable ? Nullness.NULLABLE : Nullness.UNKNOWN) : this; } + @NotNull public DfaVariableState withValue(DfaValue value) { return this; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java index fb866355d052..e07ed22d6681 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-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. @@ -32,11 +32,11 @@ import java.util.*; * @author peter */ class StateMerger { - private final Map> myFacts = ContainerUtil.newIdentityHashMap(); + private final Map> myFacts = ContainerUtil.newIdentityHashMap(); private final Map> myCopyCache = ContainerUtil.newIdentityHashMap(); @Nullable - List mergeByFacts(List states) { + List mergeByFacts(@NotNull List states) { MultiMap statesByFact = MultiMap.createLinked(); for (DfaMemoryStateImpl state : states) { ProgressManager.checkCanceled(); @@ -84,8 +84,8 @@ class StateMerger { } @NotNull - private MultiMap, DfaMemoryStateImpl> mapByUnrelatedFacts(Fact fact, - Collection states1) { + private MultiMap, DfaMemoryStateImpl> mapByUnrelatedFacts(@NotNull Fact fact, + @NotNull Collection states1) { MultiMap, DfaMemoryStateImpl> statesByUnrelatedFacts1 = MultiMap.createLinked(); for (DfaMemoryStateImpl state : states1) { statesByUnrelatedFacts1.putValue(getUnrelatedFacts(fact, state), state); @@ -93,7 +93,8 @@ class StateMerger { return statesByUnrelatedFacts1; } - private LinkedHashSet getUnrelatedFacts(final Fact fact, DfaMemoryStateImpl state) { + @NotNull + private LinkedHashSet getUnrelatedFacts(@NotNull final Fact fact, @NotNull DfaMemoryStateImpl state) { return new LinkedHashSet(ContainerUtil.filter(getFacts(state), new Condition() { @Override public boolean value(Fact another) { @@ -102,10 +103,10 @@ class StateMerger { })); } - private void restoreOtherInequalities(Fact removedFact, Collection mergedGroup, DfaMemoryStateImpl state) { + private void restoreOtherInequalities(@NotNull Fact removedFact, @NotNull Collection mergedGroup, @NotNull DfaMemoryStateImpl state) { Set inequalitiesToRestore = null; for (DfaMemoryStateImpl member : mergedGroup) { - LinkedHashSet memberFacts = getFacts(member); + Set memberFacts = getFacts(member); if (memberFacts.contains(removedFact)) { Set otherInequalities = getOtherInequalities(removedFact, memberFacts, member); if (inequalitiesToRestore == null) { @@ -123,7 +124,8 @@ class StateMerger { } } - private static Set getOtherInequalities(Fact removedFact, LinkedHashSet memberFacts, DfaMemoryStateImpl state) { + @NotNull + private static Set getOtherInequalities(@NotNull Fact removedFact, @NotNull Set memberFacts, @NotNull DfaMemoryStateImpl state) { Set otherInequalities = ContainerUtil.newLinkedHashSet(); Set eqValues = ContainerUtil.newHashSet(state.getEquivalentValues((DfaValue)removedFact.myArg)); for (Fact candidate : memberFacts) { @@ -136,7 +138,8 @@ class StateMerger { return otherInequalities; } - private static Set getAllUnknownVariables(Collection complementary) { + @NotNull + private static Set getAllUnknownVariables(@NotNull Collection complementary) { final Set toFlush = ContainerUtil.newLinkedHashSet(); for (DfaMemoryStateImpl removedState : complementary) { toFlush.addAll(removedState.getUnknownVariables()); @@ -144,7 +147,8 @@ class StateMerger { return toFlush; } - private static DfaMemoryStateImpl withUnknownVariables(DfaMemoryStateImpl original, Set toFlush) { + @NotNull + private static DfaMemoryStateImpl withUnknownVariables(@NotNull DfaMemoryStateImpl original, @NotNull Set toFlush) { DfaMemoryStateImpl copy = original.createCopy(); for (DfaVariableValue value : toFlush) { copy.doFlush(value, true); @@ -153,7 +157,7 @@ class StateMerger { } @Nullable - public List mergeByUnknowns(List states) { + List mergeByUnknowns(@NotNull List states) { MultiMap byHash = new MultiMap(); for (DfaMemoryStateImpl state : states) { ProgressManager.checkCanceled(); @@ -181,7 +185,7 @@ class StateMerger { } @Nullable - public List mergeByNullability(List states) { + List mergeByNullability(List states) { MultiMap byHash = new MultiMap(); for (DfaMemoryStateImpl state : states) { ProgressManager.checkCanceled(); @@ -217,7 +221,7 @@ class StateMerger { return replacements.getMergeResult(); } - private static boolean mergeUnknowns(Replacements replacements, List complementary) { + private static boolean mergeUnknowns(@NotNull Replacements replacements, @NotNull List complementary) { if (complementary.size() < 2) return false; final Set toFlush = getAllUnknownVariables(complementary); @@ -231,13 +235,14 @@ class StateMerger { }); } - private boolean areEquivalentModuloVar(DfaMemoryStateImpl state1, DfaMemoryStateImpl state2, DfaVariableValue var) { + private boolean areEquivalentModuloVar(@NotNull DfaMemoryStateImpl state1, @NotNull DfaMemoryStateImpl state2, @NotNull DfaVariableValue var) { DfaMemoryStateImpl copy1 = copyWithoutVar(state1, var); DfaMemoryStateImpl copy2 = copyWithoutVar(state2, var); return copy2.equalsByRelations(copy1) && copy2.equalsByVariableStates(copy1); } - private DfaMemoryStateImpl copyWithoutVar(DfaMemoryStateImpl state, DfaVariableValue var) { + @NotNull + private DfaMemoryStateImpl copyWithoutVar(@NotNull DfaMemoryStateImpl state, @NotNull DfaVariableValue var) { Map map = myCopyCache.get(state); if (map == null) { myCopyCache.put(state, map = ContainerUtil.newIdentityHashMap()); @@ -251,12 +256,13 @@ class StateMerger { return copy; } - private static boolean areVarStatesEqualModuloNullability(DfaMemoryStateImpl state1, DfaMemoryStateImpl state2, DfaVariableValue var) { + private static boolean areVarStatesEqualModuloNullability(@NotNull DfaMemoryStateImpl state1, @NotNull DfaMemoryStateImpl state2, @NotNull DfaVariableValue var) { return state1.getVariableState(var).withNullability(Nullness.UNKNOWN).equals(state2.getVariableState(var).withNullability(Nullness.UNKNOWN)); } - private LinkedHashSet getFacts(DfaMemoryStateImpl state) { - LinkedHashSet result = myFacts.get(state); + @NotNull + private Set getFacts(@NotNull DfaMemoryStateImpl state) { + Set result = myFacts.get(state); if (result != null) { return result; } @@ -317,12 +323,13 @@ class StateMerger { private enum FactType { equality, instanceOf } private static class Fact { - final FactType myType; - final DfaVariableValue myVar; - final boolean myPositive; - final Object myArg; // DfaValue for equality fact, DfaPsiType for instanceOf fact + @NotNull final FactType myType; + @NotNull private final DfaVariableValue myVar; + private final boolean myPositive; + @NotNull + private final Object myArg; // DfaValue for equality fact, DfaPsiType for instanceOf fact - private Fact(FactType type, DfaVariableValue var, boolean positive, Object arg) { + private Fact(@NotNull FactType type, @NotNull DfaVariableValue var, boolean positive, @NotNull Object arg) { myType = type; myVar = var; myPositive = positive; @@ -358,18 +365,20 @@ class StateMerger { return myVar + " " + (myPositive ? "" : "!") + myType + " " + myArg; } - static Fact createEqualityFact(DfaVariableValue var, DfaValue val, boolean equal) { + @NotNull + private static Fact createEqualityFact(@NotNull DfaVariableValue var, @NotNull DfaValue val, boolean equal) { if (val instanceof DfaVariableValue && val.getID() < var.getID()) { return new Fact(FactType.equality, (DfaVariableValue)val, equal, var); } return new Fact(FactType.equality, var, equal, val); } - Fact getPositiveCounterpart() { + @NotNull + private Fact getPositiveCounterpart() { return new Fact(myType, myVar, true, myArg); } - boolean invalidatesFact(Fact another) { + boolean invalidatesFact(@NotNull Fact another) { if (another.myType != myType) return false; if (myType == FactType.equality) { return aboutSame(myVar, another.myVar) || aboutSame(myVar, another.myArg); @@ -377,18 +386,18 @@ class StateMerger { return aboutSame(myVar, another.myVar) && aboutSame(myArg, another.myArg); } - static boolean aboutSame(Object v1, Object v2) { + private static boolean aboutSame(Object v1, Object v2) { return normalize(v1) == normalize(v2); } - static Object normalize(Object value) { + private static Object normalize(Object value) { if (value instanceof DfaVariableValue && ((DfaVariableValue)value).isNegated()) { return ((DfaVariableValue)value).createNegated(); } return value; } - void removeFromState(DfaMemoryStateImpl state) { + void removeFromState(@NotNull DfaMemoryStateImpl state) { DfaVariableState varState = state.getVariableState(myVar); if (myType == FactType.equality) { state.flushVariable(myVar); @@ -400,18 +409,18 @@ class StateMerger { } private static class Replacements { - private final List myAllStates; + @NotNull private final List myAllStates; private final Set myRemovedStates = ContainerUtil.newIdentityTroveSet(); private final List myMerged = ContainerUtil.newArrayList(); - Replacements(List allStates) { + private Replacements(@NotNull List allStates) { myAllStates = allStates; } - boolean hasMerges() { return !myMerged.isEmpty(); } + private boolean hasMerges() { return !myMerged.isEmpty(); } @Nullable - List getMergeResult() { + private List getMergeResult() { if (hasMerges()) { List result = ContainerUtil.newArrayList(myMerged); for (DfaMemoryStateImpl state : myAllStates) { @@ -424,15 +433,15 @@ class StateMerger { return null; } - boolean stripAndMerge(Collection group, - Function stripper) { + private boolean stripAndMerge(@NotNull Collection group, + @NotNull Function stripper) { if (group.size() <= 1) return false; - boolean hasMerges = false; MultiMap strippedToOriginals = MultiMap.create(); for (DfaMemoryStateImpl original : group) { strippedToOriginals.putValue(stripper.fun(original), original); } + boolean hasMerges = false; for (Map.Entry> entry : strippedToOriginals.entrySet()) { Collection merged = entry.getValue(); if (merged.size() > 1) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java index 7037613ff003..b86085c4bb2d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java @@ -35,19 +35,21 @@ import java.util.Map; public class DfaTypeValue extends DfaValue { public static class Factory { private final Map> myCache = ContainerUtil.newHashMap(); + @NotNull private final DfaValueFactory myFactory; - Factory(DfaValueFactory factory) { + Factory(@NotNull DfaValueFactory factory) { myFactory = factory; } @NotNull - public DfaTypeValue createTypeValue(@NotNull DfaPsiType type, @NotNull Nullness nullness) { + DfaTypeValue createTypeValue(@NotNull DfaPsiType type, @NotNull Nullness nullness) { ArrayList conditions = myCache.get(type); if (conditions == null) { conditions = new ArrayList(); myCache.put(type, conditions); - } else { + } + else { for (DfaTypeValue aType : conditions) { if (aType.myNullness == nullness) return aType; } @@ -60,15 +62,18 @@ public class DfaTypeValue extends DfaValue { } + @NotNull private final DfaPsiType myType; + @NotNull private final Nullness myNullness; - private DfaTypeValue(DfaPsiType type, Nullness nullness, DfaValueFactory factory) { + private DfaTypeValue(@NotNull DfaPsiType type, @NotNull Nullness nullness, @NotNull DfaValueFactory factory) { super(factory); myType = type; myNullness = nullness; } + @NotNull public DfaPsiType getDfaType() { return myType; } @@ -81,6 +86,7 @@ public class DfaTypeValue extends DfaValue { return myNullness == Nullness.NOT_NULL; } + @NotNull public Nullness getNullness() { return myNullness; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java index 4a260d7c827b..9a20ae691695 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-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. @@ -64,7 +64,8 @@ public class DfaValueFactory { return myUnknownMembersAreNullable; } - public DfaValue createTypeValue(@Nullable PsiType type, Nullness nullability) { + @NotNull + public DfaValue createTypeValue(@Nullable PsiType type, @NotNull Nullness nullability) { type = TypeConversionUtil.erasure(type); if (type == null) return DfaUnknownValue.getInstance(); return getTypeFactory().createTypeValue(internType(type), nullability); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java index f8f6d16aed13..ae3107236e11 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-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. @@ -81,10 +81,10 @@ public class DfaVariableValue extends DfaValue { return result; } - public List getAllQualifiedBy(DfaVariableValue value) { + @NotNull + public List getAllQualifiedBy(@NotNull DfaVariableValue value) { return value.myDependents; } - } private final PsiModifierListOwner myVariable; @@ -159,6 +159,7 @@ public class DfaVariableValue extends DfaValue { return myQualifier; } + @NotNull public Nullness getInherentNullability() { if (myInherentNullability != null) { return myInherentNullability; @@ -167,6 +168,7 @@ public class DfaVariableValue extends DfaValue { return myInherentNullability = calcInherentNullability(); } + @NotNull private Nullness calcInherentNullability() { PsiModifierListOwner var = getPsiVariable(); Nullness nullability = DfaPsiUtil.getElementNullability(getVariableType(), var);