aboutsummaryrefslogtreecommitdiff
path: root/src/lombok/javac/handlers/JavacHandlerUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/lombok/javac/handlers/JavacHandlerUtil.java')
-rw-r--r--src/lombok/javac/handlers/JavacHandlerUtil.java335
1 files changed, 0 insertions, 335 deletions
diff --git a/src/lombok/javac/handlers/JavacHandlerUtil.java b/src/lombok/javac/handlers/JavacHandlerUtil.java
deleted file mode 100644
index 34d8b849..00000000
--- a/src/lombok/javac/handlers/JavacHandlerUtil.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package lombok.javac.handlers;
-
-import java.util.regex.Pattern;
-
-import lombok.AccessLevel;
-import lombok.core.TransformationsUtil;
-import lombok.core.AST.Kind;
-import lombok.javac.JavacNode;
-
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.TypeTags;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.tree.JCTree.JCAnnotation;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
-import com.sun.tools.javac.tree.JCTree.JCExpression;
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
-import com.sun.tools.javac.tree.JCTree.JCStatement;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Name;
-
-/**
- * Container for static utility methods useful to handlers written for javac.
- */
-public class JavacHandlerUtil {
- private JavacHandlerUtil() {
- //Prevent instantiation
- }
-
- /**
- * Checks if the given expression (that really ought to refer to a type expression) represents a primitive type.
- */
- public static boolean isPrimitive(JCExpression ref) {
- String typeName = ref.toString();
- return TransformationsUtil.PRIMITIVE_TYPE_NAME_PATTERN.matcher(typeName).matches();
- }
-
- /**
- * Translates the given field into all possible getter names.
- * Convenient wrapper around {@link TransformationsUtil#toAllGetterNames(CharSequence, boolean)}.
- */
- public static java.util.List<String> toAllGetterNames(JCVariableDecl field) {
- CharSequence fieldName = field.name;
-
- boolean isBoolean = field.vartype.toString().equals("boolean");
-
- return TransformationsUtil.toAllGetterNames(fieldName, isBoolean);
- }
-
- /**
- * @return the likely getter name for the stated field. (e.g. private boolean foo; to isFoo).
- *
- * Convenient wrapper around {@link TransformationsUtil#toGetterName(CharSequence, boolean)}.
- */
- public static String toGetterName(JCVariableDecl field) {
- CharSequence fieldName = field.name;
-
- boolean isBoolean = field.vartype.toString().equals("boolean");
-
- return TransformationsUtil.toGetterName(fieldName, isBoolean);
- }
-
- /**
- * @return the likely setter name for the stated field. (e.g. private boolean foo; to setFoo).
- *
- * Convenient wrapper around {@link TransformationsUtil#toSetterName(CharSequence)}.
- */
- public static String toSetterName(JCVariableDecl field) {
- CharSequence fieldName = field.name;
-
- return TransformationsUtil.toSetterName(fieldName);
- }
-
- /** Serves as return value for the methods that check for the existence of fields and methods. */
- public enum MemberExistsResult {
- NOT_EXISTS, EXISTS_BY_USER, EXISTS_BY_LOMBOK;
- }
-
- /**
- * Checks if there is a field with the provided name.
- *
- * @param fieldName the field name to check for.
- * @param node Any node that represents the Type (JCClassDecl) to look in, or any child node thereof.
- */
- public static MemberExistsResult fieldExists(String fieldName, JavacNode node) {
- while (node != null && !(node.get() instanceof JCClassDecl)) {
- node = node.up();
- }
-
- if (node != null && node.get() instanceof JCClassDecl) {
- for (JCTree def : ((JCClassDecl)node.get()).defs) {
- if (def instanceof JCVariableDecl) {
- if (((JCVariableDecl)def).name.contentEquals(fieldName)) {
- JavacNode existing = node.getNodeFor(def);
- if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER;
- return MemberExistsResult.EXISTS_BY_LOMBOK;
- }
- }
- }
- }
-
- return MemberExistsResult.NOT_EXISTS;
- }
-
- /**
- * Checks if there is a method with the provided name. In case of multiple methods (overloading), only
- * the first method decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned.
- *
- * @param methodName the method name to check for.
- * @param node Any node that represents the Type (JCClassDecl) to look in, or any child node thereof.
- */
- public static MemberExistsResult methodExists(String methodName, JavacNode node) {
- while (node != null && !(node.get() instanceof JCClassDecl)) {
- node = node.up();
- }
-
- if (node != null && node.get() instanceof JCClassDecl) {
- for (JCTree def : ((JCClassDecl)node.get()).defs) {
- if (def instanceof JCMethodDecl) {
- if (((JCMethodDecl)def).name.contentEquals(methodName)) {
- JavacNode existing = node.getNodeFor(def);
- if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER;
- return MemberExistsResult.EXISTS_BY_LOMBOK;
- }
- }
- }
- }
-
- return MemberExistsResult.NOT_EXISTS;
- }
-
- /**
- * Checks if there is a (non-default) constructor. In case of multiple constructors (overloading), only
- * the first constructor decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned.
- *
- * @param node Any node that represents the Type (JCClassDecl) to look in, or any child node thereof.
- */
- public static MemberExistsResult constructorExists(JavacNode node) {
- while (node != null && !(node.get() instanceof JCClassDecl)) {
- node = node.up();
- }
-
- if (node != null && node.get() instanceof JCClassDecl) {
- for (JCTree def : ((JCClassDecl)node.get()).defs) {
- if (def instanceof JCMethodDecl) {
- if (((JCMethodDecl)def).name.contentEquals("<init>")) {
- if ((((JCMethodDecl)def).mods.flags & Flags.GENERATEDCONSTR) != 0) continue;
- JavacNode existing = node.getNodeFor(def);
- if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER;
- return MemberExistsResult.EXISTS_BY_LOMBOK;
- }
- }
- }
- }
-
- return MemberExistsResult.NOT_EXISTS;
- }
-
- /**
- * Turns an {@code AccessLevel} instance into the flag bit used by javac.
- */
- public static int toJavacModifier(AccessLevel accessLevel) {
- switch (accessLevel) {
- case MODULE:
- case PACKAGE:
- return 0;
- default:
- case PUBLIC:
- return Flags.PUBLIC;
- case PRIVATE:
- return Flags.PRIVATE;
- case PROTECTED:
- return Flags.PROTECTED;
- }
- }
-
- /**
- * Adds the given new field declaration to the provided type AST Node.
- *
- * Also takes care of updating the JavacAST.
- */
- public static void injectField(JavacNode typeNode, JCVariableDecl field) {
- JCClassDecl type = (JCClassDecl) typeNode.get();
-
- type.defs = type.defs.append(field);
-
- typeNode.add(field, Kind.FIELD).recursiveSetHandled();
- }
-
- /**
- * Adds the given new method declaration to the provided type AST Node.
- * Can also inject constructors.
- *
- * Also takes care of updating the JavacAST.
- */
- public static void injectMethod(JavacNode typeNode, JCMethodDecl method) {
- JCClassDecl type = (JCClassDecl) typeNode.get();
-
- if (method.getName().contentEquals("<init>")) {
- //Scan for default constructor, and remove it.
- int idx = 0;
- for (JCTree def : type.defs) {
- if (def instanceof JCMethodDecl) {
- if ((((JCMethodDecl)def).mods.flags & Flags.GENERATEDCONSTR) != 0) {
- JavacNode tossMe = typeNode.getNodeFor(def);
- if (tossMe != null) tossMe.up().removeChild(tossMe);
- type.defs = addAllButOne(type.defs, idx);
- break;
- }
- }
- idx++;
- }
- }
-
- type.defs = type.defs.append(method);
-
- typeNode.add(method, Kind.METHOD).recursiveSetHandled();
- }
-
- private static List<JCTree> addAllButOne(List<JCTree> defs, int idx) {
- List<JCTree> out = List.nil();
- int i = 0;
- for (JCTree def : defs) {
- if (i++ != idx) out = out.append(def);
- }
- return out;
- }
-
- /**
- * In javac, dotted access of any kind, from {@code java.lang.String} to {@code var.methodName}
- * is represented by a fold-left of {@code Select} nodes with the leftmost string represented by
- * a {@code Ident} node. This method generates such an expression.
- *
- * For example, maker.Select(maker.Select(maker.Ident(NAME[java]), NAME[lang]), NAME[String]).
- *
- * @see com.sun.tools.javac.tree.JCTree.JCIdent
- * @see com.sun.tools.javac.tree.JCTree.JCFieldAccess
- */
- public static JCExpression chainDots(TreeMaker maker, JavacNode node, String... elems) {
- assert elems != null;
- assert elems.length > 0;
-
- JCExpression e = maker.Ident(node.toName(elems[0]));
- for (int i = 1 ; i < elems.length ; i++) {
- e = maker.Select(e, node.toName(elems[i]));
- }
-
- return e;
- }
-
- /**
- * Searches the given field node for annotations and returns each one that matches the provided regular expression pattern.
- *
- * Only the simple name is checked - the package and any containing class are ignored.
- */
- public static List<JCAnnotation> findAnnotations(JavacNode fieldNode, Pattern namePattern) {
- List<JCAnnotation> result = List.nil();
- for (JavacNode child : fieldNode.down()) {
- if (child.getKind() == Kind.ANNOTATION) {
- JCAnnotation annotation = (JCAnnotation) child.get();
- String name = annotation.annotationType.toString();
- int idx = name.lastIndexOf(".");
- String suspect = idx == -1 ? name : name.substring(idx + 1);
- if (namePattern.matcher(suspect).matches()) {
- result = result.append(annotation);
- }
- }
- }
- return result;
- }
-
- /**
- * Generates a new statement that checks if the given variable is null, and if so, throws a {@code NullPointerException} with the
- * variable name as message.
- */
- public static JCStatement generateNullCheck(TreeMaker treeMaker, JavacNode variable) {
- JCVariableDecl varDecl = (JCVariableDecl) variable.get();
- if (isPrimitive(varDecl.vartype)) return null;
- Name fieldName = varDecl.name;
- JCExpression npe = chainDots(treeMaker, variable, "java", "lang", "NullPointerException");
- JCTree exception = treeMaker.NewClass(null, List.<JCExpression>nil(), npe, List.<JCExpression>of(treeMaker.Literal(fieldName.toString())), null);
- JCStatement throwStatement = treeMaker.Throw(exception);
- return treeMaker.If(treeMaker.Binary(JCTree.EQ, treeMaker.Ident(fieldName), treeMaker.Literal(TypeTags.BOT, null)), throwStatement, null);
- }
-
- /**
- * Given a list of field names and a node referring to a type, finds each name in the list that does not match a field within the type.
- */
- public static List<Integer> createListOfNonExistentFields(List<String> list, JavacNode type, boolean excludeStandard, boolean excludeTransient) {
- boolean[] matched = new boolean[list.size()];
-
- for (JavacNode child : type.down()) {
- if (list.isEmpty()) break;
- if (child.getKind() != Kind.FIELD) continue;
- JCVariableDecl field = (JCVariableDecl)child.get();
- if (excludeStandard) {
- if ((field.mods.flags & Flags.STATIC) != 0) continue;
- if (field.name.toString().startsWith("$")) continue;
- }
- if (excludeTransient && (field.mods.flags & Flags.TRANSIENT) != 0) continue;
-
- int idx = list.indexOf(child.getName());
- if (idx > -1) matched[idx] = true;
- }
-
- List<Integer> problematic = List.nil();
- for (int i = 0 ; i < list.size() ; i++) {
- if (!matched[i]) problematic = problematic.append(i);
- }
-
- return problematic;
- }
-}