use of org.eclipse.jdt.internal.compiler.ast.SingleNameReference in project lombok by rzwitserloot.
the class HandleBuilder method generateToBuilderMethod.
private MethodDeclaration generateToBuilderMethod(String methodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, boolean fluent, ASTNode source) {
// return new ThingieBuilder<A, B>().setA(this.a).setB(this.b);
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.selector = methodName.toCharArray();
out.modifiers = ClassFileConstants.AccPublic;
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.returnType = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
AllocationExpression invoke = new AllocationExpression();
invoke.type = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
Expression receiver = invoke;
for (BuilderFieldData bfd : builderFields) {
char[] setterName = fluent ? bfd.name : HandlerUtil.buildAccessorName("set", new String(bfd.name)).toCharArray();
MessageSend ms = new MessageSend();
if (bfd.obtainVia == null || !bfd.obtainVia.field().isEmpty()) {
char[] fieldName = bfd.obtainVia == null ? bfd.rawName : bfd.obtainVia.field().toCharArray();
FieldReference fr = new FieldReference(fieldName, 0);
fr.receiver = new ThisReference(0, 0);
ms.arguments = new Expression[] { fr };
} else {
String obtainName = bfd.obtainVia.method();
boolean obtainIsStatic = bfd.obtainVia.isStatic();
MessageSend obtainExpr = new MessageSend();
obtainExpr.receiver = obtainIsStatic ? new SingleNameReference(type.getName().toCharArray(), 0) : new ThisReference(0, 0);
obtainExpr.selector = obtainName.toCharArray();
if (obtainIsStatic)
obtainExpr.arguments = new Expression[] { new ThisReference(0, 0) };
ms.arguments = new Expression[] { obtainExpr };
}
ms.receiver = receiver;
ms.selector = setterName;
receiver = ms;
}
out.statements = new Statement[] { new ReturnStatement(receiver, pS, pE) };
out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
return out;
}
use of org.eclipse.jdt.internal.compiler.ast.SingleNameReference in project lombok by rzwitserloot.
the class HandleCleanup method handle.
public void handle(AnnotationValues<Cleanup> annotation, Annotation ast, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.CLEANUP_FLAG_USAGE, "@Cleanup");
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;
}
LocalDeclaration decl = (LocalDeclaration) annotationNode.up().get();
if (decl.initialization == null) {
annotationNode.addError("@Cleanup variable declarations need to be initialized.");
return;
}
EclipseNode ancestor = annotationNode.up().directUp();
ASTNode blockNode = ancestor.get();
final boolean isSwitch;
final Statement[] statements;
if (blockNode instanceof AbstractMethodDeclaration) {
isSwitch = false;
statements = ((AbstractMethodDeclaration) blockNode).statements;
} else if (blockNode instanceof Block) {
isSwitch = false;
statements = ((Block) blockNode).statements;
} else if (blockNode instanceof SwitchStatement) {
isSwitch = true;
statements = ((SwitchStatement) blockNode).statements;
} else {
annotationNode.addError("@Cleanup is legal only on a local variable declaration inside a block.");
return;
}
if (statements == null) {
annotationNode.addError("LOMBOK BUG: Parent block does not contain any statements.");
return;
}
int start = 0;
for (; start < statements.length; start++) {
if (statements[start] == decl)
break;
}
if (start == statements.length) {
annotationNode.addError("LOMBOK BUG: Can't find this local variable declaration inside its parent.");
return;
}
// We start with try{} *AFTER* the var declaration.
start++;
int end;
if (isSwitch) {
end = start + 1;
for (; end < statements.length; end++) {
if (statements[end] instanceof CaseStatement) {
break;
}
}
} else
end = statements.length;
// At this point:
// start-1 = Local Declaration marked with @Cleanup
// start = first instruction that needs to be wrapped into a try block
// end = last instruction of the scope -OR- last instruction before the next case label in switch statements.
// hence:
// [start, end) = statements for the try block.
Statement[] tryBlock = new Statement[end - start];
System.arraycopy(statements, start, tryBlock, 0, end - start);
// Remove the stuff we just dumped into the tryBlock, and then leave room for the try node.
// Remove room for every statement moved into try block...
int newStatementsLength = statements.length - (end - start);
// But add room for the TryStatement node itself.
newStatementsLength += 1;
Statement[] newStatements = new Statement[newStatementsLength];
// copy all statements before the try block verbatim.
System.arraycopy(statements, 0, newStatements, 0, start);
// For switch statements.
System.arraycopy(statements, end, newStatements, start + 1, statements.length - end);
doAssignmentCheck(annotationNode, tryBlock, decl.name);
TryStatement tryStatement = new TryStatement();
setGeneratedBy(tryStatement, ast);
tryStatement.tryBlock = new Block(0);
tryStatement.tryBlock.statements = tryBlock;
setGeneratedBy(tryStatement.tryBlock, ast);
// Positions for in-method generated nodes are special
int ss = decl.declarationSourceEnd + 1;
int se = ss;
if (tryBlock.length > 0) {
// +1 for the closing semicolon. Yes, there could be spaces. Bummer.
se = tryBlock[tryBlock.length - 1].sourceEnd + 1;
tryStatement.sourceStart = ss;
tryStatement.sourceEnd = se;
tryStatement.tryBlock.sourceStart = ss;
tryStatement.tryBlock.sourceEnd = se;
}
newStatements[start] = tryStatement;
Statement[] finallyBlock = new Statement[1];
MessageSend unsafeClose = new MessageSend();
setGeneratedBy(unsafeClose, ast);
unsafeClose.sourceStart = ast.sourceStart;
unsafeClose.sourceEnd = ast.sourceEnd;
SingleNameReference receiver = new SingleNameReference(decl.name, 0);
setGeneratedBy(receiver, ast);
unsafeClose.receiver = receiver;
long nameSourcePosition = (long) ast.sourceStart << 32 | ast.sourceEnd;
if (ast.memberValuePairs() != null)
for (MemberValuePair pair : ast.memberValuePairs()) {
if (pair.name != null && new String(pair.name).equals("value")) {
nameSourcePosition = (long) pair.value.sourceStart << 32 | pair.value.sourceEnd;
break;
}
}
unsafeClose.nameSourcePosition = nameSourcePosition;
unsafeClose.selector = cleanupName.toCharArray();
int pS = ast.sourceStart, pE = ast.sourceEnd;
long p = (long) pS << 32 | pE;
SingleNameReference varName = new SingleNameReference(decl.name, p);
setGeneratedBy(varName, ast);
NullLiteral nullLiteral = new NullLiteral(pS, pE);
setGeneratedBy(nullLiteral, ast);
MessageSend preventNullAnalysis = preventNullAnalysis(ast, varName);
EqualExpression equalExpression = new EqualExpression(preventNullAnalysis, nullLiteral, OperatorIds.NOT_EQUAL);
equalExpression.sourceStart = pS;
equalExpression.sourceEnd = pE;
setGeneratedBy(equalExpression, ast);
Block closeBlock = new Block(0);
closeBlock.statements = new Statement[1];
closeBlock.statements[0] = unsafeClose;
setGeneratedBy(closeBlock, ast);
IfStatement ifStatement = new IfStatement(equalExpression, closeBlock, 0, 0);
setGeneratedBy(ifStatement, ast);
finallyBlock[0] = ifStatement;
tryStatement.finallyBlock = new Block(0);
// Positions for in-method generated nodes are special
if (!isSwitch) {
tryStatement.finallyBlock.sourceStart = blockNode.sourceEnd;
tryStatement.finallyBlock.sourceEnd = blockNode.sourceEnd;
}
setGeneratedBy(tryStatement.finallyBlock, ast);
tryStatement.finallyBlock.statements = finallyBlock;
tryStatement.catchArguments = null;
tryStatement.catchBlocks = null;
if (blockNode instanceof AbstractMethodDeclaration) {
((AbstractMethodDeclaration) blockNode).statements = newStatements;
} else if (blockNode instanceof Block) {
((Block) blockNode).statements = newStatements;
} else if (blockNode instanceof SwitchStatement) {
((SwitchStatement) blockNode).statements = newStatements;
}
ancestor.rebuild();
}
use of org.eclipse.jdt.internal.compiler.ast.SingleNameReference in project lombok by rzwitserloot.
the class EclipseJavaUtilListSetSingularizer method generatePluralMethod.
void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
List<Statement> statements = new ArrayList<Statement>();
statements.add(createConstructBuilderVarIfNeeded(data, builderType, false));
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
MessageSend thisDotFieldDotAddAll = new MessageSend();
thisDotFieldDotAddAll.arguments = new Expression[] { new SingleNameReference(data.getPluralName(), 0L) };
thisDotFieldDotAddAll.receiver = thisDotField;
thisDotFieldDotAddAll.selector = "addAll".toCharArray();
statements.add(thisDotFieldDotAddAll);
if (returnStatement != null)
statements.add(returnStatement);
md.statements = statements.toArray(new Statement[statements.size()]);
TypeReference paramType = new QualifiedTypeReference(TypeConstants.JAVA_UTIL_COLLECTION, NULL_POSS);
paramType = addTypeArgs(1, true, builderType, paramType, data.getTypeArgs());
Argument param = new Argument(data.getPluralName(), 0, paramType, 0);
md.arguments = new Argument[] { param };
md.returnType = returnType;
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
use of org.eclipse.jdt.internal.compiler.ast.SingleNameReference in project lombok by rzwitserloot.
the class EclipseJavaUtilListSetSingularizer method generateSingularMethod.
void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
List<Statement> statements = new ArrayList<Statement>();
statements.add(createConstructBuilderVarIfNeeded(data, builderType, false));
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
MessageSend thisDotFieldDotAdd = new MessageSend();
thisDotFieldDotAdd.arguments = new Expression[] { new SingleNameReference(data.getSingularName(), 0L) };
thisDotFieldDotAdd.receiver = thisDotField;
thisDotFieldDotAdd.selector = "add".toCharArray();
statements.add(thisDotFieldDotAdd);
if (returnStatement != null)
statements.add(returnStatement);
md.statements = statements.toArray(new Statement[statements.size()]);
TypeReference paramType = cloneParamType(0, data.getTypeArgs(), builderType);
Argument param = new Argument(data.getSingularName(), 0, paramType, 0);
md.arguments = new Argument[] { param };
md.returnType = returnType;
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
use of org.eclipse.jdt.internal.compiler.ast.SingleNameReference in project lombok by rzwitserloot.
the class EclipseJavaUtilMapSingularizer method generatePluralMethod.
private void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
String pN = new String(data.getPluralName());
char[] keyFieldName = (pN + "$key").toCharArray();
char[] valueFieldName = (pN + "$value").toCharArray();
List<Statement> statements = new ArrayList<Statement>();
statements.add(createConstructBuilderVarIfNeeded(data, builderType, true));
char[] entryName = "$lombokEntry".toCharArray();
TypeReference forEachType = new QualifiedTypeReference(JAVA_UTIL_MAP_ENTRY, NULL_POSS);
forEachType = addTypeArgs(2, true, builderType, forEachType, data.getTypeArgs());
MessageSend keyArg = new MessageSend();
keyArg.receiver = new SingleNameReference(entryName, 0L);
keyArg.selector = "getKey".toCharArray();
MessageSend addKey = new MessageSend();
FieldReference thisDotKeyField = new FieldReference(keyFieldName, 0L);
thisDotKeyField.receiver = new ThisReference(0, 0);
addKey.receiver = thisDotKeyField;
addKey.selector = new char[] { 'a', 'd', 'd' };
addKey.arguments = new Expression[] { keyArg };
MessageSend valueArg = new MessageSend();
valueArg.receiver = new SingleNameReference(entryName, 0L);
valueArg.selector = "getValue".toCharArray();
MessageSend addValue = new MessageSend();
FieldReference thisDotValueField = new FieldReference(valueFieldName, 0L);
thisDotValueField.receiver = new ThisReference(0, 0);
addValue.receiver = thisDotValueField;
addValue.selector = new char[] { 'a', 'd', 'd' };
addValue.arguments = new Expression[] { valueArg };
LocalDeclaration elementVariable = new LocalDeclaration(entryName, 0, 0);
elementVariable.type = forEachType;
ForeachStatement forEach = new ForeachStatement(elementVariable, 0);
MessageSend invokeEntrySet = new MessageSend();
invokeEntrySet.selector = new char[] { 'e', 'n', 't', 'r', 'y', 'S', 'e', 't' };
invokeEntrySet.receiver = new SingleNameReference(data.getPluralName(), 0L);
forEach.collection = invokeEntrySet;
Block forEachContent = new Block(0);
forEachContent.statements = new Statement[] { addKey, addValue };
forEach.action = forEachContent;
statements.add(forEach);
if (returnStatement != null)
statements.add(returnStatement);
md.statements = statements.toArray(new Statement[statements.size()]);
TypeReference paramType = new QualifiedTypeReference(JAVA_UTIL_MAP, NULL_POSS);
paramType = addTypeArgs(2, true, builderType, paramType, data.getTypeArgs());
Argument param = new Argument(data.getPluralName(), 0, paramType, 0);
md.arguments = new Argument[] { param };
md.returnType = returnType;
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("putAll", new String(data.getPluralName())).toCharArray();
md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
Aggregations