use of com.sun.tools.javac.tree.JCTree.JCBlock in project lombok by rzwitserloot.
the class HandleNonNull method createRecordArgslessConstructor.
private JCMethodDecl createRecordArgslessConstructor(JavacNode typeNode, JavacNode source, JCMethodDecl existingCtr) {
JavacTreeMaker maker = typeNode.getTreeMaker();
java.util.List<JCVariableDecl> fields = new ArrayList<JCVariableDecl>();
for (JavacNode child : typeNode.down()) {
if (child.getKind() == Kind.FIELD) {
JCVariableDecl v = (JCVariableDecl) child.get();
if ((v.mods.flags & RECORD) != 0) {
fields.add(v);
}
}
}
ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
for (int i = 0; i < fields.size(); i++) {
JCVariableDecl arg = fields.get(i);
JCModifiers mods = maker.Modifiers(GENERATED_MEMBER | Flags.PARAMETER, arg.mods.annotations);
params.append(maker.VarDef(mods, arg.name, arg.vartype, null));
}
JCModifiers mods = maker.Modifiers(toJavacModifier(AccessLevel.PUBLIC) | COMPACT_RECORD_CONSTRUCTOR, List.<JCAnnotation>nil());
JCBlock body = maker.Block(0L, List.<JCStatement>nil());
if (existingCtr == null) {
JCMethodDecl constr = maker.MethodDef(mods, typeNode.toName("<init>"), null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(), body, null);
return recursiveSetGeneratedBy(constr, source);
} else {
existingCtr.mods = mods;
existingCtr.body = body;
existingCtr = recursiveSetGeneratedBy(existingCtr, source);
addSuppressWarningsAll(existingCtr.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(existingCtr)), typeNode.getContext());
addGenerated(existingCtr.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(existingCtr)), typeNode.getContext());
return existingCtr;
}
}
use of com.sun.tools.javac.tree.JCTree.JCBlock in project lombok by rzwitserloot.
the class HandleCleanup method handle.
@Override
public void handle(AnnotationValues<Cleanup> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.CLEANUP_FLAG_USAGE, "@Cleanup");
if (inNetbeansEditor(annotationNode))
return;
deleteAnnotationIfNeccessary(annotationNode, Cleanup.class);
String cleanupName = annotation.getInstance().value();
if (cleanupName.length() == 0) {
annotationNode.addError("cleanupName cannot be the empty string.");
return;
}
if (annotationNode.up().getKind() != Kind.LOCAL) {
annotationNode.addError("@Cleanup is legal only on local variable declarations.");
return;
}
JCVariableDecl decl = (JCVariableDecl) annotationNode.up().get();
if (decl.init == null) {
annotationNode.addError("@Cleanup variable declarations need to be initialized.");
return;
}
JavacNode ancestor = annotationNode.up().directUp();
JCTree blockNode = ancestor.get();
final List<JCStatement> statements;
if (blockNode instanceof JCBlock) {
statements = ((JCBlock) blockNode).stats;
} else if (blockNode instanceof JCCase) {
statements = ((JCCase) blockNode).stats;
} else if (blockNode instanceof JCMethodDecl) {
statements = ((JCMethodDecl) blockNode).body.stats;
} else {
annotationNode.addError("@Cleanup is legal only on a local variable declaration inside a block.");
return;
}
boolean seenDeclaration = false;
ListBuffer<JCStatement> newStatements = new ListBuffer<JCStatement>();
ListBuffer<JCStatement> tryBlock = new ListBuffer<JCStatement>();
for (JCStatement statement : statements) {
if (!seenDeclaration) {
if (statement == decl)
seenDeclaration = true;
newStatements.append(statement);
} else {
tryBlock.append(statement);
}
}
if (!seenDeclaration) {
annotationNode.addError("LOMBOK BUG: Can't find this local variable declaration inside its parent.");
return;
}
doAssignmentCheck(annotationNode, tryBlock.toList(), decl.name);
JavacTreeMaker maker = annotationNode.getTreeMaker();
JCFieldAccess cleanupMethod = maker.Select(maker.Ident(decl.name), annotationNode.toName(cleanupName));
List<JCStatement> cleanupCall = List.<JCStatement>of(maker.Exec(maker.Apply(List.<JCExpression>nil(), cleanupMethod, List.<JCExpression>nil())));
JCExpression preventNullAnalysis = preventNullAnalysis(maker, annotationNode, maker.Ident(decl.name));
JCBinary isNull = maker.Binary(CTC_NOT_EQUAL, preventNullAnalysis, maker.Literal(CTC_BOT, null));
JCIf ifNotNullCleanup = maker.If(isNull, maker.Block(0, cleanupCall), null);
JCBlock finalizer = recursiveSetGeneratedBy(maker.Block(0, List.<JCStatement>of(ifNotNullCleanup)), annotationNode);
newStatements.append(setGeneratedBy(maker.Try(setGeneratedBy(maker.Block(0, tryBlock.toList()), annotationNode), List.<JCCatch>nil(), finalizer), annotationNode));
if (blockNode instanceof JCBlock) {
((JCBlock) blockNode).stats = newStatements.toList();
} else if (blockNode instanceof JCCase) {
((JCCase) blockNode).stats = newStatements.toList();
} else if (blockNode instanceof JCMethodDecl) {
((JCMethodDecl) blockNode).body.stats = newStatements.toList();
} else
throw new AssertionError("Should not get here");
ancestor.rebuild();
}
use of com.sun.tools.javac.tree.JCTree.JCBlock in project lombok by rzwitserloot.
the class JavacJavaUtilMapSingularizer method generateSingularMethod.
private void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrown = List.nil();
JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, true, source));
Name keyName = builderType.toName(data.getSingularName().toString() + "Key");
Name valueName = builderType.toName(data.getSingularName().toString() + "Value");
/* this.pluralname$key.add(singularnameKey); */
{
JCExpression thisDotKeyFieldDotAdd = chainDots(builderType, "this", data.getPluralName() + "$key", "add");
JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotKeyFieldDotAdd, List.<JCExpression>of(maker.Ident(keyName)));
statements.append(maker.Exec(invokeAdd));
}
/* this.pluralname$value.add(singularnameValue); */
{
JCExpression thisDotValueFieldDotAdd = chainDots(builderType, "this", data.getPluralName() + "$value", "add");
JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotValueFieldDotAdd, List.<JCExpression>of(maker.Ident(valueName)));
statements.append(maker.Exec(invokeAdd));
}
if (returnStatement != null)
statements.append(returnStatement);
JCBlock body = maker.Block(0, statements.toList());
long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
Name name = data.getSingularName();
if (!fluent)
name = builderType.toName(HandlerUtil.buildAccessorName("put", name.toString()));
JCExpression paramTypeKey = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
JCExpression paramTypeValue = cloneParamType(1, maker, data.getTypeArgs(), builderType, source);
JCVariableDecl paramKey = maker.VarDef(maker.Modifiers(paramFlags), keyName, paramTypeKey, null);
JCVariableDecl paramValue = maker.VarDef(maker.Modifiers(paramFlags), valueName, paramTypeValue, null);
JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(paramKey, paramValue), thrown, body, null);
injectMethod(builderType, method);
}
use of com.sun.tools.javac.tree.JCTree.JCBlock in project lombok by rzwitserloot.
the class JavacHandlerUtil method generateNullCheck.
/**
* Generates a new statement that checks if the given variable is null, and if so, throws a specified exception with the
* variable name as message.
*
* @param exName The name of the exception to throw; normally {@code java.lang.NullPointerException}.
*/
public static JCStatement generateNullCheck(JavacTreeMaker maker, JavacNode variable, JavacNode source) {
NullCheckExceptionType exceptionType = source.getAst().readConfiguration(ConfigurationKeys.NON_NULL_EXCEPTION_TYPE);
if (exceptionType == null)
exceptionType = NullCheckExceptionType.NULL_POINTER_EXCEPTION;
JCVariableDecl varDecl = (JCVariableDecl) variable.get();
if (isPrimitive(varDecl.vartype))
return null;
Name fieldName = varDecl.name;
JCExpression exType = genTypeRef(variable, exceptionType.getExceptionType());
JCExpression exception = maker.NewClass(null, List.<JCExpression>nil(), exType, List.<JCExpression>of(maker.Literal(exceptionType.toExceptionMessage(fieldName.toString()))), null);
JCStatement throwStatement = maker.Throw(exception);
JCBlock throwBlock = maker.Block(0, List.of(throwStatement));
return maker.If(maker.Binary(CTC_EQUAL, maker.Ident(fieldName), maker.Literal(CTC_BOT, null)), throwBlock, null);
}
use of com.sun.tools.javac.tree.JCTree.JCBlock in project lombok by rzwitserloot.
the class HandleToString method createToString.
static JCMethodDecl createToString(JavacNode typeNode, Collection<JavacNode> fields, boolean includeFieldNames, boolean callSuper, FieldAccess fieldAccess, JCTree source) {
JavacTreeMaker maker = typeNode.getTreeMaker();
JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
JCExpression returnType = genJavaLangTypeRef(typeNode, "String");
boolean first = true;
String typeName = getTypeName(typeNode);
String infix = ", ";
String suffix = ")";
String prefix;
if (callSuper) {
prefix = typeName + "(super=";
} else if (fields.isEmpty()) {
prefix = typeName + "()";
} else if (includeFieldNames) {
prefix = typeName + "(" + ((JCVariableDecl) fields.iterator().next().get()).name.toString() + "=";
} else {
prefix = typeName + "(";
}
JCExpression current = maker.Literal(prefix);
if (callSuper) {
JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("toString")), List.<JCExpression>nil());
current = maker.Binary(CTC_PLUS, current, callToSuper);
first = false;
}
for (JavacNode fieldNode : fields) {
JCExpression expr;
JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess);
JCExpression fieldType = getFieldType(fieldNode, fieldAccess);
// The distinction between primitive and object will be useful if we ever add a 'hideNulls' option.
boolean fieldIsPrimitive = fieldType instanceof JCPrimitiveTypeTree;
boolean fieldIsPrimitiveArray = fieldType instanceof JCArrayTypeTree && ((JCArrayTypeTree) fieldType).elemtype instanceof JCPrimitiveTypeTree;
boolean fieldIsObjectArray = !fieldIsPrimitiveArray && fieldType instanceof JCArrayTypeTree;
@SuppressWarnings("unused") boolean fieldIsObject = !fieldIsPrimitive && !fieldIsPrimitiveArray && !fieldIsObjectArray;
if (fieldIsPrimitiveArray || fieldIsObjectArray) {
JCExpression tsMethod = chainDots(typeNode, "java", "util", "Arrays", fieldIsObjectArray ? "deepToString" : "toString");
expr = maker.Apply(List.<JCExpression>nil(), tsMethod, List.<JCExpression>of(fieldAccessor));
} else
expr = fieldAccessor;
if (first) {
current = maker.Binary(CTC_PLUS, current, expr);
first = false;
continue;
}
if (includeFieldNames) {
current = maker.Binary(CTC_PLUS, current, maker.Literal(infix + fieldNode.getName() + "="));
} else {
current = maker.Binary(CTC_PLUS, current, maker.Literal(infix));
}
current = maker.Binary(CTC_PLUS, current, expr);
}
if (!first)
current = maker.Binary(CTC_PLUS, current, maker.Literal(suffix));
JCStatement returnStatement = maker.Return(current);
JCBlock body = maker.Block(0, List.of(returnStatement));
return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("toString"), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
Aggregations