| 1 | /* |
|---|---|
| 2 | * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser. |
| 3 | * Copyright (C) 2011, 2013-2020 The JavaParser Team. |
| 4 | * |
| 5 | * This file is part of JavaParser. |
| 6 | * |
| 7 | * JavaParser can be used either under the terms of |
| 8 | * a) the GNU Lesser General Public License as published by |
| 9 | * the Free Software Foundation, either version 3 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | * b) the terms of the Apache License |
| 12 | * |
| 13 | * You should have received a copy of both licenses in LICENCE.LGPL and |
| 14 | * LICENCE.APACHE. Please refer to those files for details. |
| 15 | * |
| 16 | * JavaParser is distributed in the hope that it will be useful, |
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | * GNU Lesser General Public License for more details. |
| 20 | */ |
| 21 | |
| 22 | package com.github.javaparser.ast.nodeTypes; |
| 23 | |
| 24 | import com.github.javaparser.ast.Node; |
| 25 | import com.github.javaparser.ast.NodeList; |
| 26 | import com.github.javaparser.ast.body.Parameter; |
| 27 | import com.github.javaparser.ast.type.Type; |
| 28 | |
| 29 | import java.util.Arrays; |
| 30 | import java.util.Optional; |
| 31 | import java.util.stream.Stream; |
| 32 | |
| 33 | import static com.github.javaparser.StaticJavaParser.parseType; |
| 34 | import static java.util.stream.Collectors.toList; |
| 35 | |
| 36 | public interface NodeWithParameters<N extends Node> { |
| 37 | NodeList<Parameter> getParameters(); |
| 38 | |
| 39 | default Parameter getParameter(int i) { |
| 40 | return getParameters().get(i); |
| 41 | } |
| 42 | |
| 43 | void tryAddImportToParentCompilationUnit(Class<?> clazz); |
| 44 | |
| 45 | @SuppressWarnings("unchecked") |
| 46 | default N setParameter(int i, Parameter parameter) { |
| 47 | getParameters().set(i, parameter); |
| 48 | return (N) this; |
| 49 | } |
| 50 | |
| 51 | N setParameters(NodeList<Parameter> parameters); |
| 52 | |
| 53 | default N addParameter(Type type, String name) { |
| 54 | return addParameter(new Parameter(type, name)); |
| 55 | } |
| 56 | |
| 57 | default N addParameter(Class<?> paramClass, String name) { |
| 58 | tryAddImportToParentCompilationUnit(paramClass); |
| 59 | return addParameter(parseType(paramClass.getSimpleName()), name); |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Remember to import the class in the compilation unit yourself |
| 64 | * |
| 65 | * @param className the name of the class, ex : org.test.Foo or Foo if you added manually the import |
| 66 | * @param name the name of the parameter |
| 67 | */ |
| 68 | default N addParameter(String className, String name) { |
| 69 | return addParameter(parseType(className), name); |
| 70 | } |
| 71 | |
| 72 | @SuppressWarnings("unchecked") |
| 73 | default N addParameter(Parameter parameter) { |
| 74 | getParameters().add(parameter); |
| 75 | return (N) this; |
| 76 | } |
| 77 | |
| 78 | default Parameter addAndGetParameter(Type type, String name) { |
| 79 | return addAndGetParameter(new Parameter(type, name)); |
| 80 | } |
| 81 | |
| 82 | default Parameter addAndGetParameter(Class<?> paramClass, String name) { |
| 83 | tryAddImportToParentCompilationUnit(paramClass); |
| 84 | return addAndGetParameter(parseType(paramClass.getSimpleName()), name); |
| 85 | } |
| 86 | |
| 87 | /** |
| 88 | * Remember to import the class in the compilation unit yourself |
| 89 | * |
| 90 | * @param className the name of the class, ex : org.test.Foo or Foo if you added manually the import |
| 91 | * @param name the name of the parameter |
| 92 | * @return the {@link Parameter} created |
| 93 | */ |
| 94 | default Parameter addAndGetParameter(String className, String name) { |
| 95 | return addAndGetParameter(parseType(className), name); |
| 96 | } |
| 97 | |
| 98 | default Parameter addAndGetParameter(Parameter parameter) { |
| 99 | getParameters().add(parameter); |
| 100 | return parameter; |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * Try to find a {@link Parameter} by its name |
| 105 | * |
| 106 | * @param name the name of the param |
| 107 | * @return null if not found, the param found otherwise |
| 108 | */ |
| 109 | default Optional<Parameter> getParameterByName(String name) { |
| 110 | return getParameters().stream() |
| 111 | .filter(p -> p.getNameAsString().equals(name)).findFirst(); |
| 112 | } |
| 113 | |
| 114 | /** |
| 115 | * Try to find a {@link Parameter} by its type |
| 116 | * |
| 117 | * @param type the type of the param |
| 118 | * @return null if not found, the param found otherwise |
| 119 | */ |
| 120 | default Optional<Parameter> getParameterByType(String type) { |
| 121 | return getParameters().stream() |
| 122 | .filter(p -> p.getType().toString().equals(type)).findFirst(); |
| 123 | } |
| 124 | |
| 125 | /** |
| 126 | * Try to find a {@link Parameter} by its type |
| 127 | * |
| 128 | * @param type the type of the param <b>take care about generics, it wont work</b> |
| 129 | * @return null if not found, the param found otherwise |
| 130 | */ |
| 131 | default Optional<Parameter> getParameterByType(Class<?> type) { |
| 132 | return getParameters().stream() |
| 133 | .filter(p -> p.getType().toString().equals(type.getSimpleName())).findFirst(); |
| 134 | } |
| 135 | |
| 136 | /** |
| 137 | * Check if the parameters have certain types. The given parameter types must <i>literally</i> match the declared |
| 138 | * types of this node's parameters, so passing the string {@code "List"} to this method will be considered a match |
| 139 | * if this node has exactly one parameter whose type is declared as {@code List}, but not if the parameter type is |
| 140 | * declared as {@code java.util.List} or {@code java.awt.List}. Conversely, passing the string |
| 141 | * {@code "java.util.List"} to this method will be considered a match if this node has exactly one parameter whose |
| 142 | * type is declared as {@code java.util.List}, but not if the parameter type is declared as {@code List}. Similarly, |
| 143 | * note that generics are matched as well: If this node has one parameter declared as {@code List<String>}, |
| 144 | * then it will be considered as a match only if the given string is {@code "List<String>"}, but not if the |
| 145 | * given string is only {@code "List"}. |
| 146 | * |
| 147 | * @param paramTypes the types of parameters like {@code "Map<Integer,String>", "int"} to match |
| 148 | * {@code void foo(Map<Integer,String> myMap, int number)}. |
| 149 | * @return {@code true} if all parameters match one by one, in the given order. |
| 150 | */ |
| 151 | default boolean hasParametersOfType(String... paramTypes) { |
| 152 | return getParameters().stream() |
| 153 | .map(p -> p.getType().asString()) |
| 154 | .collect(toList()) |
| 155 | .equals(Arrays.asList(paramTypes)); |
| 156 | } |
| 157 | |
| 158 | /** |
| 159 | * Check if the parameters have certain types. Note that this is a match in SimpleName, so {@code java.awt.List} and |
| 160 | * {@code java.util.List} are identical to this algorithm. In addition, note that it is the erasure of each type |
| 161 | * which is considered, so passing {@code List.class} to this method will be considered a match if this node has |
| 162 | * exactly one parameter whose type is named {@code List}, regardless of whether the parameter type is declared |
| 163 | * without generics as {@code List}, or with generics as {@code List<String>}, or {@code List<Integer>}, |
| 164 | * etc. |
| 165 | * |
| 166 | * @param paramTypes the types of parameters like {@code Map.class, int.class} to match |
| 167 | * {@code void foo(Map<Integer,String> myMap, int number)}. |
| 168 | * @return {@code true} if all parameters match one by one, in the given order. |
| 169 | */ |
| 170 | default boolean hasParametersOfType(Class<?>... paramTypes) { |
| 171 | return getParameters().stream() |
| 172 | // if p.getType() is a class or interface type, we want to consider its erasure, i.e., if the parameter |
| 173 | // is "List<String>", we want to consider it as "List", so we need to call getName() |
| 174 | .map(p -> p.getType().toClassOrInterfaceType() |
| 175 | .map(NodeWithSimpleName::getNameAsString) |
| 176 | .orElse(p.getType().asString())) |
| 177 | .collect(toList()) |
| 178 | .equals(Stream.of(paramTypes).map(Class::getSimpleName).collect(toList())); |
| 179 | } |
| 180 | } |
| 181 |
Members