@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement psiElement = descriptor.getPsiElement(); if(psiElement == null) { return; } final PsiAssignmentExpression assignmentExpression = PsiTreeUtil.getParentOfType(psiElement, PsiAssignmentExpression.class); if(assignmentExpression == null) { return; } final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); final String lExpressionText = assignmentExpression.getLExpression().getText(); final PsiExpression rExpression = assignmentExpression.getRExpression(); final String rExpressionText = rExpression != null ? rExpression.getText() : ""; assignmentExpression.replace(factory.createExpressionFromText(lExpressionText + " = " + rExpressionText, psiElement)); }
private static void replaceMultiplyOrDivideAssignWithShiftAssign( PsiAssignmentExpression expression) throws IncorrectOperationException { final PsiExpression lhs = expression.getLExpression(); final PsiExpression rhs = expression.getRExpression(); final IElementType tokenType = expression.getOperationTokenType(); final String assignString; if (tokenType.equals(JavaTokenType.ASTERISKEQ)) { assignString = "<<="; } else { assignString = ">>="; } final String expString = lhs.getText() + assignString + ShiftUtils.getLogBase2(rhs); replaceExpression(expString, expression); }
private static void replaceShiftAssignWithMultiplyOrDivideAssign( PsiElement element) throws IncorrectOperationException { final PsiAssignmentExpression exp = (PsiAssignmentExpression)element; final PsiExpression lhs = exp.getLExpression(); final PsiExpression rhs = exp.getRExpression(); final IElementType tokenType = exp.getOperationTokenType(); final String assignString; if (tokenType.equals(JavaTokenType.LTLTEQ)) { assignString = "*="; } else { assignString = "/="; } final String expString = lhs.getText() + assignString + ShiftUtils.getExpBase2(rhs); replaceExpression(expString, exp); }
@Override public void doFix(@NotNull Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement element = descriptor.getPsiElement(); if (!(element instanceof PsiAssignmentExpression)) { return; } final PsiAssignmentExpression expression = (PsiAssignmentExpression)element; final PsiExpression lhs = expression.getLExpression(); PsiExpression rhs = ParenthesesUtils.stripParentheses(expression.getRExpression()); if (rhs instanceof PsiTypeCastExpression) { final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)rhs; final PsiType castType = typeCastExpression.getType(); if (castType == null || !castType.equals(lhs.getType())) { return; } rhs = ParenthesesUtils.stripParentheses(typeCastExpression.getOperand()); } if (!(rhs instanceof PsiPolyadicExpression)) { return; } final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)rhs; final String newExpression = calculateReplacementExpression(lhs, polyadicExpression); replaceExpression(expression, newExpression); }
private static void replaceSimplifiableAssignment( PsiIfStatement statement) throws IncorrectOperationException { final PsiExpression condition = statement.getCondition(); if (condition == null) { return; } final String conditionText = condition.getText(); final PsiStatement thenBranch = statement.getThenBranch(); final PsiExpressionStatement assignmentStatement = (PsiExpressionStatement) ControlFlowUtils.stripBraces(thenBranch); final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)assignmentStatement.getExpression(); final PsiJavaToken operator = assignmentExpression.getOperationSign(); final String operand = operator.getText(); final PsiExpression lhs = assignmentExpression.getLExpression(); final String lhsText = lhs.getText(); replaceStatement(statement, lhsText + operand + conditionText + ';'); }
private static void replaceSimplifiableAssignmentNegated( PsiIfStatement statement) throws IncorrectOperationException { final PsiExpression condition = statement.getCondition(); if (condition == null) { return; } final String conditionText = BoolUtils.getNegatedExpressionText(condition); final PsiStatement thenBranch = statement.getThenBranch(); final PsiExpressionStatement assignmentStatement = (PsiExpressionStatement) ControlFlowUtils.stripBraces(thenBranch); final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) assignmentStatement.getExpression(); final PsiJavaToken operator = assignmentExpression.getOperationSign(); final String operand = operator.getText(); final PsiExpression lhs = assignmentExpression.getLExpression(); final String lhsText = lhs.getText(); replaceStatement(statement, lhsText + operand + conditionText + ';'); }
/** * メソッドが変更するフィールド変数(状態)を解析 * @param allFields クラスが所持するすべてのフィールド * @return メソッドが変更する全てのフィールド */ private Map<String, PsiField> parse(@NonNull Map<String, PsiField> allFields) { Map<String, PsiField> writeFields = new HashMap<>(); // メソッド内の全代入式を抽出 List<PsiAssignmentExpression> assignments = ElementUtil.extractAssignments(mMethod); for (PsiAssignmentExpression assignment : assignments) { // 左辺から変数名を取得 List<PsiIdentifier> ids = ElementUtil.extractIdentifiers(assignment.getLExpression()); PsiIdentifier id = ids.get(ids.size()-1); if (allFields.containsKey(id.getText())) { // フィールドと同名のクラス変数やインスタンス変数か否かをチェック boolean isInstance = ElementUtil.isThisExpression(id) || ElementUtil.isRefExpression(id); // フィールドと同名のローカル変数やパラメータか否かをチェック PsiElement element = ElementUtil.ScopeBacktrack .seek(assignment, allFields.get(id.getText()).getNameIdentifier()); if (element != null && !isInstance) continue; writeFields.put(id.getText(), allFields.get(id.getText())); } } return writeFields; }
private static void extractAssignments(@NonNull PsiElement element, List<PsiAssignmentExpression> assignments) { for (PsiElement child : element.getChildren()) { if (child instanceof PsiAssignmentExpression) { assignments.add((PsiAssignmentExpression) child); continue; } extractAssignments(child, assignments); } }
public static void debugAssignments(String tag, PsiElement root, List<PsiAssignmentExpression> assignments) { System.out.println(tag + " :root=>>>>\n" + root.getText() + "\n<<<"); for (PsiAssignmentExpression assignment : assignments) { System.out.println("assignment -> " + assignment.getText()); } System.out.println(); }
public boolean satisfiedBy(PsiElement element) { if (!(element instanceof PsiAssignmentExpression)) { return false; } final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)element; final IElementType tokenType = assignmentExpression.getOperationTokenType(); return OPERATOR_ASSIGNMENT_TOKENS.contains(tokenType); }
@Override public void visitAssignmentExpression( @NotNull PsiAssignmentExpression expression) { super.visitAssignmentExpression(expression); final PsiElement parent = expression.getParent(); if (parent == null) { return; } final PsiElement grandparent = parent.getParent(); if (parent instanceof PsiExpressionStatement || grandparent instanceof PsiExpressionListStatement) { return; } registerError(expression); }
private boolean constructorAssignsAllFields(final PsiMethod constructor, List<PsiField> allFields) { final Set<PsiField> unassignedFields = new HashSet<PsiField>(allFields); final PsiParameter copyParameter = constructor.getParameterList().getParameters()[0]; constructor.accept(new JavaRecursiveElementVisitor() { @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) { PsiExpression left = expression.getLExpression(); PsiExpression right = expression.getRExpression(); PsiReference assignee = left.getReference(); if (assignee != null) { PsiElement leftReference = assignee.resolve(); if (leftReference != null && leftReference instanceof PsiField) { PsiField referencedField = (PsiField) leftReference; if (isReferenceToFieldInInstance(left, referencedField, null)) { if (isReferenceToFieldInInstance(right, referencedField, copyParameter)) { unassignedFields.remove(referencedField); } else if (right != null) { // report problem: suspicious assignment copies value from wrong field: "this.x = copy.y" holder.registerProblem(expression, String.format("Suspicious assignment in copy constructor of '%s' to field %s", right.getText(), referencedField.getName()), ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } } } } } }); return unassignedFields.isEmpty(); }
@Nullable public PsiExpression getLExpression() { if(myRExpression == null) { return null; } if(myRExpression.getParent() instanceof PsiAssignmentExpression) { return ((PsiAssignmentExpression) myRExpression.getParent()).getLExpression(); } return null; }
@Override public void visitAssignmentExpression( @NotNull PsiAssignmentExpression assignment) { if (assignedFrom) { return; } super.visitAssignmentExpression(assignment); final PsiExpression arg = assignment.getRExpression(); if (VariableAccessUtils.mayEvaluateToVariable(arg, variable)) { assignedFrom = true; } }
@Override protected boolean shouldShowExplicitLambdaType(@NotNull PsiAnonymousClass anonymousClass, @NotNull PsiNewExpression expression) { PsiElement parent = expression.getParent(); if(parent instanceof PsiReferenceExpression || parent instanceof PsiAssignmentExpression) { return true; } ExpectedTypeInfo[] types = ExpectedTypesProvider.getExpectedTypes(expression, false); return types.length != 1 || !types[0].getType().equals(anonymousClass.getBaseClassType()); }
public boolean satisfiedBy(PsiElement element) { if (!(element instanceof PsiAssignmentExpression)) { return false; } final PsiAssignmentExpression assignment = (PsiAssignmentExpression)element; final IElementType tokenType = assignment.getOperationTokenType(); if (!JavaTokenType.EQ.equals(tokenType)) { return false; } final PsiExpression rhs = assignment.getRExpression(); final PsiExpression expression = PsiUtil.deparenthesizeExpression(rhs); if (!(expression instanceof PsiPolyadicExpression)) { return false; } final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression; final PsiExpression[] operands = polyadicExpression.getOperands(); if (operands.length < 2) { return false; } final IElementType rhsTokenType = polyadicExpression.getOperationTokenType(); if (JavaTokenType.OROR.equals(rhsTokenType) || JavaTokenType.ANDAND.equals(rhsTokenType) || JavaTokenType.EQEQ.equals(rhsTokenType) || JavaTokenType.NE.equals(rhsTokenType)) { return false; } final PsiExpression lhs = assignment.getLExpression(); if (SideEffectChecker.mayHaveSideEffects(lhs)) { return false; } if (!EquivalenceChecker.expressionsAreEquivalent(lhs, operands[0])) { return false; } return !ErrorUtil.containsError(element); }
@Override protected String getTextForElement(PsiElement element) { final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)element; final PsiJavaToken sign = assignmentExpression.getOperationSign(); final String operator = sign.getText(); return IntentionPowerPackBundle.message("replace.operator.assignment.with.assignment.intention.name", operator); }
@Override protected void processIntention(@NotNull PsiElement element) { final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)element; final PsiJavaToken sign = assignmentExpression.getOperationSign(); final PsiExpression lhs = assignmentExpression.getLExpression(); final PsiExpression rhs = assignmentExpression.getRExpression(); final String operator = sign.getText(); final String newOperator = operator.substring(0, operator.length() - 1); final String lhsText = lhs.getText(); final String rhsText = (rhs == null) ? "" : rhs.getText(); final boolean parentheses; if (rhs instanceof PsiPolyadicExpression) { final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)rhs; final int precedence1 = ParenthesesUtils.getPrecedenceForOperator(binaryExpression.getOperationTokenType()); final IElementType signTokenType = sign.getTokenType(); final IElementType newOperatorToken = tokenMap.get(signTokenType); final int precedence2 = ParenthesesUtils.getPrecedenceForOperator(newOperatorToken); parentheses = precedence1 >= precedence2 || !ParenthesesUtils.isCommutativeOperator(newOperatorToken); } else { parentheses = false; } final String cast = getCastString(lhs, rhs); final StringBuilder newExpression = new StringBuilder(lhsText); newExpression.append('=').append(cast); if (!cast.isEmpty()) { newExpression.append('('); } newExpression.append(lhsText).append(newOperator); if (parentheses) { newExpression.append('(').append(rhsText).append(')'); } else { newExpression.append(rhsText); } if (!cast.isEmpty()) { newExpression.append(')'); } replaceExpression(newExpression.toString(), assignmentExpression); }
public void processIntention(PsiElement element) throws IncorrectOperationException { if (element instanceof PsiBinaryExpression) { replaceMultiplyOrDivideWithShift((PsiBinaryExpression)element); } else { replaceMultiplyOrDivideAssignWithShiftAssign( (PsiAssignmentExpression)element); } }
private static void replaceSimplifiableImplicitAssignment( PsiIfStatement statement) throws IncorrectOperationException { final PsiElement prevStatement = PsiTreeUtil.skipSiblingsBackward(statement, PsiWhiteSpace.class); if (prevStatement == null) { return; } final PsiExpression condition = statement.getCondition(); if (condition == null) { return; } final String conditionText = condition.getText(); final PsiStatement thenBranch = statement.getThenBranch(); final PsiExpressionStatement assignmentStatement = (PsiExpressionStatement) ControlFlowUtils.stripBraces(thenBranch); final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)assignmentStatement.getExpression(); final PsiJavaToken operator = assignmentExpression.getOperationSign(); final String operand = operator.getText(); final PsiExpression lhs = assignmentExpression.getLExpression(); final String lhsText = lhs.getText(); replaceStatement(statement, lhsText + operand + conditionText + ';'); deleteElement(prevStatement); }
public static boolean isSimplifiableAssignment(PsiIfStatement ifStatement) { PsiStatement thenBranch = ifStatement.getThenBranch(); thenBranch = ControlFlowUtils.stripBraces(thenBranch); PsiStatement elseBranch = ifStatement.getElseBranch(); elseBranch = ControlFlowUtils.stripBraces(elseBranch); if (ConditionalUtils.isAssignment(thenBranch, PsiKeyword.TRUE) && ConditionalUtils.isAssignment(elseBranch, PsiKeyword.FALSE)) { final PsiExpressionStatement thenExpressionStatement = (PsiExpressionStatement)thenBranch; final PsiAssignmentExpression thenExpression = (PsiAssignmentExpression) thenExpressionStatement.getExpression(); final PsiExpressionStatement elseExpressionStatement = (PsiExpressionStatement)elseBranch; final PsiAssignmentExpression elseExpression = (PsiAssignmentExpression) elseExpressionStatement.getExpression(); final IElementType thenTokenType = thenExpression.getOperationTokenType(); if (!thenTokenType.equals(elseExpression.getOperationTokenType())) { return false; } final PsiExpression thenLhs = thenExpression.getLExpression(); final PsiExpression elseLhs = elseExpression.getLExpression(); return EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(thenLhs, elseLhs); } else { return false; } }
public static boolean isSimplifiableAssignmentNegated( PsiIfStatement ifStatement) { PsiStatement thenBranch = ifStatement.getThenBranch(); thenBranch = ControlFlowUtils.stripBraces(thenBranch); PsiStatement elseBranch = ifStatement.getElseBranch(); elseBranch = ControlFlowUtils.stripBraces(elseBranch); if (ConditionalUtils.isAssignment(thenBranch, PsiKeyword.FALSE) && ConditionalUtils.isAssignment(elseBranch, PsiKeyword.TRUE)) { final PsiExpressionStatement thenExpressionStatement = (PsiExpressionStatement)thenBranch; final PsiAssignmentExpression thenExpression = (PsiAssignmentExpression) thenExpressionStatement.getExpression(); final PsiExpressionStatement elseExpressionStatement = (PsiExpressionStatement)elseBranch; final PsiAssignmentExpression elseExpression = (PsiAssignmentExpression) elseExpressionStatement.getExpression(); final IElementType thenTokenType = thenExpression.getOperationTokenType(); if (!thenTokenType.equals(elseExpression.getOperationTokenType())) { return false; } final PsiExpression thenLhs = thenExpression.getLExpression(); final PsiExpression elseLhs = elseExpression.getLExpression(); return EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(thenLhs, elseLhs); } else { return false; } }
public static boolean isSimplifiableImplicitAssignment( PsiIfStatement ifStatement) { if (ifStatement.getElseBranch() != null) { return false; } PsiStatement thenBranch = ifStatement.getThenBranch(); thenBranch = ControlFlowUtils.stripBraces(thenBranch); final PsiElement nextStatement = PsiTreeUtil.skipSiblingsBackward(ifStatement, PsiWhiteSpace.class); if (!(nextStatement instanceof PsiStatement)) { return false; } PsiStatement elseBranch = (PsiStatement)nextStatement; elseBranch = ControlFlowUtils.stripBraces(elseBranch); if (ConditionalUtils.isAssignment(thenBranch, PsiKeyword.TRUE) && ConditionalUtils.isAssignment(elseBranch, PsiKeyword.FALSE)) { final PsiExpressionStatement thenExpressionStatement = (PsiExpressionStatement)thenBranch; final PsiAssignmentExpression thenExpression = (PsiAssignmentExpression) thenExpressionStatement.getExpression(); final PsiExpressionStatement elseExpressionStatement = (PsiExpressionStatement)elseBranch; final PsiAssignmentExpression elseExpression = (PsiAssignmentExpression) elseExpressionStatement.getExpression(); final IElementType thenTokenType = thenExpression.getOperationTokenType(); if (!thenTokenType.equals(elseExpression.getOperationTokenType())) { return false; } final PsiExpression thenLhs = thenExpression.getLExpression(); final PsiExpression elseLhs = elseExpression.getLExpression(); return EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(thenLhs, elseLhs); } else { return false; } }
public static boolean isSimplifiableImplicitAssignmentNegated( PsiIfStatement ifStatement) { if (ifStatement.getElseBranch() != null) { return false; } PsiStatement thenBranch = ifStatement.getThenBranch(); thenBranch = ControlFlowUtils.stripBraces(thenBranch); final PsiElement nextStatement = PsiTreeUtil.skipSiblingsBackward(ifStatement, PsiWhiteSpace.class); if (!(nextStatement instanceof PsiStatement)) { return false; } PsiStatement elseBranch = (PsiStatement)nextStatement; elseBranch = ControlFlowUtils.stripBraces(elseBranch); if (ConditionalUtils.isAssignment(thenBranch, PsiKeyword.FALSE) && ConditionalUtils.isAssignment(elseBranch, PsiKeyword.TRUE)) { final PsiExpressionStatement thenExpressionStatement = (PsiExpressionStatement)thenBranch; final PsiAssignmentExpression thenExpression = (PsiAssignmentExpression) thenExpressionStatement.getExpression(); final PsiExpressionStatement elseExpressionStatement = (PsiExpressionStatement)elseBranch; final PsiAssignmentExpression elseExpression = (PsiAssignmentExpression) elseExpressionStatement.getExpression(); final IElementType thenTokenType = thenExpression.getOperationTokenType(); if (!thenTokenType.equals(elseExpression.getOperationTokenType())) { return false; } final PsiExpression thenLhs = thenExpression.getLExpression(); final PsiExpression elseLhs = elseExpression.getLExpression(); return EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(thenLhs, elseLhs); } else { return false; } }
private static void ifThenBranchAssignment(PsiAssignmentExpression assignment, PsiExpression expr) { if (!DEBUG_DETAIL) return; System.out.println("condition thenBranch-> assignment=" + (assignment != null ? assignment.getText() : "null") + ", source=" + expr.getText()); }
private static void ifElseBranchAssignment(PsiAssignmentExpression assignment, PsiExpression expr) { if (!DEBUG_DETAIL) return; System.out.println("condition elseBranch-> assignment=" + (assignment != null ? assignment.getText() : "null") + ", source=" + expr.getText()); }
/** * 代入式 * @param element ルートノード * @return 代入式のリスト (空要素の場合もあります) */ public static @NonNull List<PsiAssignmentExpression> extractAssignments(@NonNull PsiElement element) { List<PsiAssignmentExpression> assignments = new ArrayList<>(); extractAssignments(element, assignments); return assignments; }
@Override public void visitAssignmentExpression(PsiAssignmentExpression expression) { mVisitor.report("PsiAssignmentExpression", expression.getText(), expression); super.visitExpression(expression); }
public static boolean isWellFormed(@NotNull PsiAssignmentExpression expression) { final PsiExpression rhs = expression.getRExpression(); return rhs != null; }
@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); final PsiElement parent; if(element instanceof PsiReferenceExpression) { parent = element.getParent(); } else { parent = element; } if(!(parent instanceof PsiAssignmentExpression)) { return; } final PsiExpression rExpression = ((PsiAssignmentExpression) parent).getRExpression(); final PsiElement gParent = parent.getParent(); if((gParent instanceof PsiExpression || gParent instanceof PsiExpressionList) && rExpression != null) { if(!FileModificationService.getInstance().prepareFileForWrite(gParent.getContainingFile())) { return; } if(gParent instanceof PsiParenthesizedExpression) { gParent.replace(rExpression); } else { parent.replace(rExpression); } return; } PsiElement resolve = null; if(element instanceof PsiReferenceExpression) { resolve = ((PsiReferenceExpression) element).resolve(); } else { final PsiExpression lExpr = PsiUtil.deparenthesizeExpression(((PsiAssignmentExpression) parent).getLExpression()); if(lExpr instanceof PsiReferenceExpression) { resolve = ((PsiReferenceExpression) lExpr).resolve(); } } if(!(resolve instanceof PsiVariable)) { return; } sideEffectAwareRemove(project, rExpression, parent, (PsiVariable) resolve); }
public ReplaceAssignmentWithComparisonFix(PsiAssignmentExpression expr) { super(expr); }
@Override public void visitAssignmentExpression(@NotNull PsiAssignmentExpression assignment) { super.visitAssignmentExpression(assignment); final IElementType assignmentTokenType = assignment.getOperationTokenType(); if (!assignmentTokenType.equals(JavaTokenType.EQ)) { return; } final PsiExpression lhs = assignment.getLExpression(); PsiExpression rhs = ParenthesesUtils.stripParentheses(assignment.getRExpression()); if (rhs instanceof PsiTypeCastExpression) { final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)rhs; final PsiType castType = typeCastExpression.getType(); if (castType == null || !castType.equals(lhs.getType())) { return; } rhs = ParenthesesUtils.stripParentheses(typeCastExpression.getOperand()); } if (!(rhs instanceof PsiPolyadicExpression)) { return; } final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)rhs; final PsiExpression[] operands = polyadicExpression.getOperands(); if (operands.length < 2) { return; } if (operands.length > 2 && !ParenthesesUtils.isAssociativeOperation(polyadicExpression)) { return; } for (PsiExpression operand : operands) { if (operand == null) { return; } } final IElementType expressionTokenType = polyadicExpression.getOperationTokenType(); if (JavaTokenType.EQEQ.equals(expressionTokenType) || JavaTokenType.NE.equals(expressionTokenType)) { return; } if (ignoreLazyOperators) { if (JavaTokenType.ANDAND.equals(expressionTokenType) || JavaTokenType.OROR.equals(expressionTokenType)) { return; } } if (ignoreObscureOperators) { if (JavaTokenType.XOR.equals(expressionTokenType) || JavaTokenType.PERC.equals(expressionTokenType)) { return; } } if (!EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(lhs, operands[0])) { return; } registerError(assignment, lhs, polyadicExpression); }