private static boolean isGoodExpression( PsiExpression expression, @NotNull AllowedValues allowedValues, @NotNull PsiElement scope, @NotNull PsiManager manager) { expression = PsiUtil.deparenthesizeExpression(expression); if (expression == null) return true; if (expression instanceof PsiConditionalExpression) { PsiExpression thenExpression = ((PsiConditionalExpression) expression).getThenExpression(); boolean thenAllowed = thenExpression == null || isAllowed(scope, thenExpression, allowedValues, manager); if (!thenAllowed) return false; PsiExpression elseExpression = ((PsiConditionalExpression) expression).getElseExpression(); return elseExpression == null || isAllowed(scope, elseExpression, allowedValues, manager); } if (isOneOf(expression, allowedValues, manager)) return true; if (allowedValues.canBeOred) { PsiExpression zero = getLiteralExpression(expression, manager, "0"); if (same(expression, zero, manager)) return true; PsiExpression mOne = getLiteralExpression(expression, manager, "-1"); if (same(expression, mOne, manager)) return true; if (expression instanceof PsiPolyadicExpression) { IElementType tokenType = ((PsiPolyadicExpression) expression).getOperationTokenType(); if (JavaTokenType.OR.equals(tokenType) || JavaTokenType.AND.equals(tokenType)) { for (PsiExpression operand : ((PsiPolyadicExpression) expression).getOperands()) { if (!isAllowed(scope, operand, allowedValues, manager)) return false; } return true; } } if (expression instanceof PsiPrefixExpression && JavaTokenType.TILDE.equals( ((PsiPrefixExpression) expression).getOperationTokenType())) { PsiExpression operand = ((PsiPrefixExpression) expression).getOperand(); return operand == null || isAllowed(scope, operand, allowedValues, manager); } } PsiElement resolved = null; if (expression instanceof PsiReference) { resolved = ((PsiReference) expression).resolve(); } else if (expression instanceof PsiCallExpression) { resolved = ((PsiCallExpression) expression).resolveMethod(); } AllowedValues allowedForRef; if (resolved instanceof PsiModifierListOwner && (allowedForRef = getAllowedValues( (PsiModifierListOwner) resolved, getType((PsiModifierListOwner) resolved), null)) != null && allowedForRef.isSubsetOf(allowedValues, manager)) return true; return PsiType.NULL.equals(expression.getType()); }
private static void checkExpression( PsiExpression expression, PsiModifierListOwner owner, PsiType type, ProblemsHolder holder) { AllowedValues allowed = getAllowedValues(owner, type, null); if (allowed == null) return; PsiElement scope = PsiUtil.getTopLevelEnclosingCodeBlock(expression, null); if (scope == null) scope = expression; if (!isAllowed(scope, expression, allowed, expression.getManager())) { registerProblem(expression, allowed, holder); } }
private static void checkMagicParameterArgument( @NotNull PsiParameter parameter, PsiExpression argument, @NotNull AllowedValues allowedValues, @NotNull ProblemsHolder holder) { final PsiManager manager = PsiManager.getInstance(holder.getProject()); if (!argument.getTextRange().isEmpty() && !isAllowed(parameter.getDeclarationScope(), argument, allowedValues, manager)) { registerProblem(argument, allowedValues, holder); } }
private static boolean processValuesFlownTo( @NotNull final PsiExpression argument, PsiElement scope, @NotNull final Processor<PsiExpression> processor) { SliceAnalysisParams params = new SliceAnalysisParams(); params.dataFlowToThis = true; params.scope = new AnalysisScope(new LocalSearchScope(scope), argument.getProject()); SliceRootNode rootNode = new SliceRootNode( scope.getProject(), new DuplicateMap(), SliceManager.createRootUsage(argument, params)); Collection<? extends AbstractTreeNode> children = rootNode.getChildren().iterator().next().getChildren(); for (AbstractTreeNode child : children) { SliceUsage usage = (SliceUsage) child.getValue(); PsiElement element = usage.getElement(); if (element instanceof PsiExpression && !processor.process((PsiExpression) element)) return false; } return !children.isEmpty(); }