
lombok.javac.handlers.JavacHandlerUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of develhacked-lombok Show documentation
Show all versions of develhacked-lombok Show documentation
The library enhancing Java classes at compilation by annotations that contained in the Develhack Core Library.
The newest version!
/*
* Copyright (C) 2009-2015 The Project Lombok Authors.
*
* 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 static lombok.core.handlers.HandlerUtil.*;
import static lombok.javac.Javac.*;
import static lombok.javac.JavacAugments.JCTree_generatedNode;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.Data;
import lombok.Getter;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.core.LombokImmutableList;
import lombok.core.AnnotationValues.AnnotationValue;
import lombok.core.TypeResolver;
import lombok.core.configuration.NullCheckExceptionType;
import lombok.core.handlers.HandlerUtil;
import lombok.delombok.LombokOptionsFactory;
import lombok.experimental.Accessors;
import lombok.experimental.Tolerate;
import lombok.javac.Javac;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
import com.sun.tools.javac.code.BoundKind;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.parser.Tokens.Comment;
import com.sun.tools.javac.tree.DocCommentTable;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCImport;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
import com.sun.tools.javac.tree.JCTree.JCNewArray;
import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.JCTree.JCWildcard;
import com.sun.tools.javac.tree.JCTree.TypeBoundKind;
import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Options;
/**
* Container for static utility methods useful to handlers written for javac.
*/
public class JavacHandlerUtil {
private JavacHandlerUtil() {
//Prevent instantiation
}
private static class MarkingScanner extends TreeScanner {
private final JCTree source;
private final Context context;
MarkingScanner(JCTree source, Context context) {
this.source = source;
this.context = context;
}
@Override public void scan(JCTree tree) {
if (tree == null) return;
setGeneratedBy(tree, source, context);
super.scan(tree);
}
}
/**
* Contributed by Jan Lahoda; many lombok transformations should not be run (or a lite version should be run) when the netbeans editor
* is running javac on the open source file to find inline errors and such. As class files are compiled separately this does not affect
* actual runtime behaviour or file output of the netbeans IDE.
*/
public static boolean inNetbeansEditor(JavacNode node) {
return inNetbeansEditor(node.getContext());
}
private static boolean inNetbeansEditor(Context context) {
Options options = Options.instance(context);
return (options.keySet().contains("ide") && !options.keySet().contains("backgroundCompilation"));
}
public static JCTree getGeneratedBy(JCTree node) {
return JCTree_generatedNode.get(node);
}
public static boolean isGenerated(JCTree node) {
return getGeneratedBy(node) != null;
}
public static T recursiveSetGeneratedBy(T node, JCTree source, Context context) {
if (node == null) return null;
setGeneratedBy(node, source, context);
node.accept(new MarkingScanner(source, context));
return node;
}
public static T setGeneratedBy(T node, JCTree source, Context context) {
if (node == null) return null;
if (source == null) JCTree_generatedNode.clear(node);
else JCTree_generatedNode.set(node, source);
if (source != null && (!inNetbeansEditor(context) || (node instanceof JCVariableDecl && (((JCVariableDecl) node).mods.flags & Flags.PARAMETER) != 0))) node.pos = source.pos;
return node;
}
public static boolean hasAnnotation(Class extends Annotation> type, JavacNode node) {
return hasAnnotation(type, node, false);
}
public static boolean hasAnnotationAndDeleteIfNeccessary(Class extends Annotation> type, JavacNode node) {
return hasAnnotation(type, node, true);
}
private static boolean hasAnnotation(Class extends Annotation> type, JavacNode node, boolean delete) {
if (node == null) return false;
if (type == null) return false;
switch (node.getKind()) {
case ARGUMENT:
case FIELD:
case LOCAL:
case TYPE:
case METHOD:
for (JavacNode child : node.down()) {
if (annotationTypeMatches(type, child)) {
if (delete) deleteAnnotationIfNeccessary(child, type);
return true;
}
}
// intentional fallthrough
default:
return false;
}
}
/**
* Checks if the Annotation AST Node provided is likely to be an instance of the provided annotation type.
*
* @param type An actual annotation type, such as {@code lombok.Getter.class}.
* @param node A Lombok AST node representing an annotation in source code.
*/
public static boolean annotationTypeMatches(Class extends Annotation> type, JavacNode node) {
if (node.getKind() != Kind.ANNOTATION) return false;
return typeMatches(type, node, ((JCAnnotation)node.get()).annotationType);
}
/**
* Checks if the given TypeReference node is likely to be a reference to the provided class.
*
* @param type An actual type. This method checks if {@code typeNode} is likely to be a reference to this type.
* @param node A Lombok AST node. Any node in the appropriate compilation unit will do (used to get access to import statements).
* @param typeNode A type reference to check.
*/
public static boolean typeMatches(Class> type, JavacNode node, JCTree typeNode) {
String typeName = typeNode.toString();
TypeResolver resolver = new TypeResolver(node.getImportList());
return resolver.typeMatches(node, type.getName(), typeName);
}
/**
* Returns if a field is marked deprecated, either by {@code @Deprecated} or in javadoc
* @param field the field to check
* @return {@code true} if a field is marked deprecated, either by {@code @Deprecated} or in javadoc, otherwise {@code false}
*/
public static boolean isFieldDeprecated(JavacNode field) {
JCVariableDecl fieldNode = (JCVariableDecl) field.get();
if ((fieldNode.mods.flags & Flags.DEPRECATED) != 0) {
return true;
}
for (JavacNode child : field.down()) {
if (annotationTypeMatches(Deprecated.class, child)) {
return true;
}
}
return false;
}
/**
* Returns if a node is marked deprecated (as picked up on by the parser).
* @param node the node to check (type, method, or field decl).
*/
public static boolean nodeHasDeprecatedFlag(JCTree node) {
if (node instanceof JCVariableDecl) return (((JCVariableDecl) node).mods.flags & Flags.DEPRECATED) != 0;
if (node instanceof JCMethodDecl) return (((JCMethodDecl) node).mods.flags & Flags.DEPRECATED) != 0;
if (node instanceof JCClassDecl) return (((JCClassDecl) node).mods.flags & Flags.DEPRECATED) != 0;
return false;
}
/**
* Creates an instance of {@code AnnotationValues} for the provided AST Node.
*
* @param type An annotation class type, such as {@code lombok.Getter.class}.
* @param node A Lombok AST node representing an annotation in source code.
*/
public static AnnotationValues createAnnotation(Class type, final JavacNode node) {
Map values = new HashMap();
JCAnnotation anno = (JCAnnotation) node.get();
List arguments = anno.getArguments();
for (JCExpression arg : arguments) {
String mName;
JCExpression rhs;
java.util.List raws = new ArrayList();
java.util.List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy