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-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.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()} {@code // same as ofType(type -> true)}
    • *
    *
  • *
  • a method name *
      *
    • {@link NameBuilder#names(String...)}
    • *
    • {@link NameBuilder#constructor()}
    • *
    • {@link NameBuilder#name(Predicate)}
    • *
    • {@link NameBuilder#anyName()} {@code // 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()} {@code // 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: * {@code 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: * {@code MethodMatchers.create().ofAnyType().names("f")} *
      *
    • one parameter of type either {@code int} or {@code long} * {@code .addParametersMatcher("int").addParametersMatcher("long");} *
    • *
    • * one parameter of type {@code int} or one parameter of type {@code long} with any other number of parameters * {@code .addParametersMatcher("int").addParametersMatcher(params -> params.size() >= 1 && params.get(0).is("long"));} *
    • *
    * {@code .build();} *
  • *
  • match any method with any type, with parameter {@code int, any, int}: * {@code MethodMatchers.create().ofAnyType().anyName().addParametersMatcher("int", ANY, "int").build();} *
  • *
  • match any type AND method name {@code a} OR {@code b} AND parameter {@code int} OR {@code long}: * {@code 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