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

org.sonar.plugins.java.api.semantic.MethodMatchers Maven / Gradle / Ivy

/*
 * SonarQube Java
 * Copyright (C) 2012-2023 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 GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * 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 GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package org.sonar.plugins.java.api.semantic;

import org.sonar.java.annotations.Beta;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import org.sonar.java.matcher.NoneMethodMatchers;
import org.sonar.java.matcher.MethodMatchersBuilder;
import org.sonar.java.matcher.MethodMatchersList;
import org.sonar.plugins.java.api.tree.MethodInvocationTree;
import org.sonar.plugins.java.api.tree.MethodReferenceTree;
import org.sonar.plugins.java.api.tree.MethodTree;
import org.sonar.plugins.java.api.tree.NewClassTree;

/**
 * Immutable helper interface to help to identify method with given a Type, Name and Parameters.
 * 

* The starting point to define a MethodMatchers is {@link #create()}. *

* It is required to provide the following: *

    *
  • a type definition *
      *
    • {@link TypeBuilder#ofSubTypes(String...)}
    • *
    • {@link TypeBuilder#ofTypes(String...)}
    • *
    • {@link TypeBuilder#ofType(Predicate)}
    • *
    • {@link TypeBuilder#ofAnyType()} // same as ofType(type -> true)
    • *
    *
  • *
  • a method name *
      *
    • {@link NameBuilder#names(String...)}
    • *
    • {@link NameBuilder#constructor()}
    • *
    • {@link NameBuilder#name(Predicate)}
    • *
    • {@link NameBuilder#anyName()} // same as name(name -> true)
    • *
    *
  • *
  • a list of parameters, 1 or more call to: *

    * (It is possible to define several parameters matcher, to match several method signatures) *

      *
    • {@link ParametersBuilder#addWithoutParametersMatcher()}
    • *
    • {@link ParametersBuilder#addParametersMatcher(String...)}
    • *
    • {@link ParametersBuilder#addParametersMatcher(Predicate>)}
    • *
    • {@link ParametersBuilder#withAnyParameters()} // same as addParametersMatcher((List parameters) -> true)
    • *
    *
  • *
* The matcher will return true only when the three predicates are respected. *

* Examples: *

 *- match method "a" and "b" from any type, and without parameters:
 *    MethodMatchers.create().ofAnyType().names("a", "b").addWithoutParametersMatcher().build();
 *
 *- match method "a" and "b" from (subtype) of A, and "b" and "c" from B, with any parameters:
 *    MethodMatchers.or(
 *      MethodMatchers.create().ofSubTypes("A").names("a", "b").withAnyParameters().build(),
 *      MethodMatchers.create().ofSubTypes("B").names("b", "c").withAnyParameters().build());
 *- match method "f" with any type and with:
 *    MethodMatchers.create().ofAnyType().names("f")
 *      - one parameter of type either int or long
 *        .addParametersMatcher("int").addParametersMatcher("long");
 *      - one parameter of type int or one parameter of type long with any other number of parameters
 *        .addParametersMatcher("int").addParametersMatcher(params -> params.size() >= 1 && params.get(0).is("long"));
 *     .build()
 *- match any method with any type, with parameter int, any, int:
 *    MethodMatchers.create().ofAnyType().anyName().addParametersMatcher("int", ANY, "int").build();
 *
 *- match any type AND method name "a" OR "b" AND parameter int OR long:
 *    MethodMatchers.create().ofAnyType().names("a", "b").addParametersMatcher("int").addParametersMatcher("long").build()
 * 
*/ @Beta public interface MethodMatchers { boolean matches(NewClassTree newClassTree); boolean matches(MethodInvocationTree mit); boolean matches(MethodTree methodTree); boolean matches(MethodReferenceTree methodReferenceTree); boolean matches(Symbol symbol); static MethodMatchers.TypeBuilder create() { return new MethodMatchersBuilder(); } // Methods related to combination /** * Combine multiple method matcher. The matcher will match any of the given matcher. */ static MethodMatchers or(MethodMatchers... matchers) { return or(Arrays.asList(matchers)); } static MethodMatchers or(List matchers) { return new MethodMatchersList(matchers); } static MethodMatchers none() { return NoneMethodMatchers.getInstance(); } String ANY = "*"; String CONSTRUCTOR = ""; interface TypeBuilder { /** * Match any of the type and sub-type of the fully qualified names. */ MethodMatchers.NameBuilder ofSubTypes(String... fullyQualifiedTypeNames); /** * Match any type. */ MethodMatchers.NameBuilder ofAnyType(); /** * Match any of the fully qualified name types, but not the subtype. */ MethodMatchers.NameBuilder ofTypes(String... fullyQualifiedTypeNames); /** * Match a type matching a predicate. */ MethodMatchers.NameBuilder ofType(Predicate typePredicate); } interface NameBuilder { /** * Match a method with any name is the list. */ MethodMatchers.ParametersBuilder names(String... names); /** * Match a method with any name. * Equivalent to .name(n -> true). */ MethodMatchers.ParametersBuilder anyName(); /** * Match a constructor. * Equivalent to .name(n -> "".equals(n)) */ MethodMatchers.ParametersBuilder constructor(); /** * Match the name matching the predicate. */ MethodMatchers.ParametersBuilder name(Predicate namePredicate); } interface ParametersBuilder { /** * Match a method signature with any number of parameters of any types. * Others method adding parameters matchers can not be called with this method. */ MethodMatchers.ParametersBuilder withAnyParameters(); /** * Match a method signature without parameters. * Others method adding parameters matcher can be called to match multiples signatures. */ MethodMatchers.ParametersBuilder addWithoutParametersMatcher(); /** * Match a method signature with exactly the types provided. * Others method adding parameters matcher can be called to match multiples signatures. */ MethodMatchers.ParametersBuilder addParametersMatcher(String... parametersType); /** * Match a method signature respecting the predicate. * Others method adding parameters matcher can be called to match multiples signatures. */ MethodMatchers.ParametersBuilder addParametersMatcher(Predicate> parametersType); /** * Build a MethodMatchers. Throw an Exception if the MethodMatchers is not correctly setup (no parameters list defined). */ MethodMatchers build(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy