All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.java.checks.tests.AssertJChainSimplificationQuickFix Maven / Gradle / Ivy

/*
 * SonarQube Java
 * Copyright (C) 2012-2024 SonarSource SA
 * mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the Sonar Source-Available License for more details.
 *
 * You should have received a copy of the Sonar Source-Available License
 * along with this program; if not, see https://sonarsource.com/license/ssal/
 */
package org.sonar.java.checks.tests;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import org.sonar.java.model.ExpressionUtils;
import org.sonar.java.reporting.JavaQuickFix;
import org.sonar.java.reporting.JavaTextEdit;
import org.sonar.plugins.java.api.tree.Arguments;
import org.sonar.plugins.java.api.tree.ExpressionTree;
import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree;
import org.sonar.plugins.java.api.tree.MethodInvocationTree;
import org.sonar.plugins.java.api.tree.Tree;

import static org.sonar.java.reporting.AnalyzerMessage.textSpanBetween;

interface AssertJChainSimplificationQuickFix extends BiFunction>> {
  String QUICK_FIX_MESSAGE_FORMAT_STRING = "Use \"%s\"";

  @Override
  Supplier> apply(MethodInvocationTree subject, MethodInvocationTree predicate);
}

class NoQuickFix implements AssertJChainSimplificationQuickFix {

  @Override
  public Supplier> apply(MethodInvocationTree subject, MethodInvocationTree predicate) {
    return null;
  }
}

/**
 * Replace assertThat(x.y(a)).z(b); or assertThat(x.y).z(b); by:
 * 

* - keepPredicateArgument = true * assertThat(x).replacement(b); *

* - keepPredicateArgument = false * assertThat(x).replacement(); */ class ActualExpectedInPredicateQuickFix implements AssertJChainSimplificationQuickFix { private final boolean keepPredicateArgument; final String replacement; final String predicateName; ActualExpectedInPredicateQuickFix(String replacement, String predicateName, boolean keepPredicateArgument) { this.replacement = replacement; this.predicateName = predicateName; this.keepPredicateArgument = keepPredicateArgument; } @Override public Supplier> apply(MethodInvocationTree subject, MethodInvocationTree predicate) { return () -> { Arguments arguments = subject.arguments(); if (arguments.size() == 1) { ExpressionTree argument = arguments.get(0); Optional memberSelectInSubject = getMemberSelectInSubject(argument); if (memberSelectInSubject.isPresent()) { MemberSelectExpressionTree memberSelect = memberSelectInSubject.get(); return Collections.singletonList(getJavaQuick(predicate, argument, memberSelect)); } } return Collections.emptyList(); }; } private JavaQuickFix getJavaQuick(MethodInvocationTree predicate, ExpressionTree argument, MemberSelectExpressionTree memberSelect) { JavaQuickFix.Builder builder = JavaQuickFix.newQuickFix(QUICK_FIX_MESSAGE_FORMAT_STRING, replacement); // assertThat(x.y()).z() --> assertThat(x).z() builder.addTextEdit(JavaTextEdit.removeTextSpan(textSpanBetween(memberSelect.expression(), false, argument, true))); if (keepPredicateArgument) { // assertThat(x).z(a) --> assertThat(x).predicateName(a) builder.addTextEdit(JavaTextEdit.replaceTree(ExpressionUtils.methodName(predicate), predicateName)); } else { // assertThat(x).z(a) --> assertThat(x).predicateName() builder.addTextEdit(JavaTextEdit.replaceBetweenTree(ExpressionUtils.methodName(predicate), predicate, predicateName + "()")); } return builder.build(); } private static Optional getMemberSelectInSubject(ExpressionTree tree) { if (tree.is(Tree.Kind.MEMBER_SELECT)) { return Optional.of((MemberSelectExpressionTree) tree); } else if (tree.is(Tree.Kind.METHOD_INVOCATION)) { return getMemberSelectInSubject(((MethodInvocationTree) tree).methodSelect()); } return Optional.empty(); } } /** * Replace assertThat(x.y(a)).y(b); by assertThat(x).replacement(a); */ class ActualExpectedInSubjectQuickFix implements AssertJChainSimplificationQuickFix { final String replacement; final String predicateName; ActualExpectedInSubjectQuickFix(String replacement, String predicateName) { this.replacement = replacement; this.predicateName = predicateName; } @Override public Supplier> apply(MethodInvocationTree subject, MethodInvocationTree predicate) { return () -> { Optional methodInvocationInArguments = getMethodInvocationInArguments(subject.arguments()); if (methodInvocationInArguments.isPresent()) { MethodInvocationTree invocationTree = methodInvocationInArguments.get(); ExpressionTree methodSelect = invocationTree.methodSelect(); if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) { MemberSelectExpressionTree memberSelect = (MemberSelectExpressionTree) methodSelect; return Collections.singletonList(getJavaQuickFix(predicate, memberSelect, invocationTree)); } } return Collections.emptyList(); }; } private static Optional getMethodInvocationInArguments(Arguments arguments) { if (arguments.size() == 1) { ExpressionTree argument = arguments.get(0); if (argument.is(Tree.Kind.METHOD_INVOCATION)) { return Optional.of((MethodInvocationTree) argument); } } return Optional.empty(); } private JavaQuickFix getJavaQuickFix(MethodInvocationTree predicate, MemberSelectExpressionTree memberSelect, MethodInvocationTree invocationTree) { return JavaQuickFix.newQuickFix(QUICK_FIX_MESSAGE_FORMAT_STRING, replacement) .addTextEdit( // assertThat(x.y(a)).z() --> assertThat(x).predicateName(a)).z() JavaTextEdit.replaceTextSpan(textSpanBetween(memberSelect.expression(), false, invocationTree.arguments().get(0), false), String.format(").%s(", predicateName)), // assertThat(x).predicateName(a)).z() --> assertThat(x).predicateName(a) JavaTextEdit.removeTextSpan(textSpanBetween(invocationTree.arguments(), false, predicate, true)) ).build(); } } /** * Replace assertThat(x).y(a); by assertThat(x).replacement(); */ class ContextFreeQuickFix implements AssertJChainSimplificationQuickFix { private final String replacement; ContextFreeQuickFix(String replacement) { this.replacement = replacement; } @Override public Supplier> apply(MethodInvocationTree subject, MethodInvocationTree predicate) { return apply(predicate); } public Supplier> apply(MethodInvocationTree predicate) { return () -> Collections.singletonList(JavaQuickFix.newQuickFix(QUICK_FIX_MESSAGE_FORMAT_STRING, replacement) .addTextEdit(JavaTextEdit.replaceBetweenTree(ExpressionUtils.methodName(predicate), predicate, replacement)) .build()); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy