use of org.eclipse.jdt.internal.compiler.ast.ASTNode in project lombok by rzwitserloot.
the class PatchExtensionMethodCompletionProposal method getJavaCompletionProposals.
public static IJavaCompletionProposal[] getJavaCompletionProposals(IJavaCompletionProposal[] javaCompletionProposals, CompletionProposalCollector completionProposalCollector) {
List<IJavaCompletionProposal> proposals = new ArrayList<IJavaCompletionProposal>(Arrays.asList(javaCompletionProposals));
if (canExtendCodeAssist(proposals)) {
IJavaCompletionProposal firstProposal = proposals.get(0);
int replacementOffset = getReplacementOffset(firstProposal);
for (Extension extension : getExtensionMethods(completionProposalCollector)) {
for (MethodBinding method : extension.extensionMethods) {
ExtensionMethodCompletionProposal newProposal = new ExtensionMethodCompletionProposal(replacementOffset);
copyNameLookupAndCompletionEngine(completionProposalCollector, firstProposal, newProposal);
ASTNode node = getAssistNode(completionProposalCollector);
newProposal.setMethodBinding(method, node);
createAndAddJavaCompletionProposal(completionProposalCollector, newProposal, proposals);
}
}
}
return proposals.toArray(new IJavaCompletionProposal[proposals.size()]);
}
use of org.eclipse.jdt.internal.compiler.ast.ASTNode in project lombok by rzwitserloot.
the class HandleSetter method createSetter.
static MethodDeclaration createSetter(TypeDeclaration parent, EclipseNode fieldNode, String name, boolean shouldReturnThis, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam) {
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
ASTNode source = sourceNode.get();
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
MethodDeclaration method = new MethodDeclaration(parent.compilationResult);
method.modifiers = modifier;
if (shouldReturnThis) {
method.returnType = cloneSelfType(fieldNode, source);
}
if (method.returnType == null) {
method.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
method.returnType.sourceStart = pS;
method.returnType.sourceEnd = pE;
shouldReturnThis = false;
}
Annotation[] deprecated = null;
if (isFieldDeprecated(fieldNode)) {
deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
}
method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated);
Argument param = new Argument(field.name, p, copyType(field.type, source), Modifier.FINAL);
param.sourceStart = pS;
param.sourceEnd = pE;
method.arguments = new Argument[] { param };
method.selector = name.toCharArray();
method.binding = null;
method.thrownExceptions = null;
method.typeParameters = null;
method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source);
NameReference fieldNameRef = new SingleNameReference(field.name, p);
Assignment assignment = new Assignment(fieldRef, fieldNameRef, (int) p);
assignment.sourceStart = pS;
assignment.sourceEnd = assignment.statementEnd = pE;
method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd;
Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN);
Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN);
List<Statement> statements = new ArrayList<Statement>(5);
if (nonNulls.length == 0) {
statements.add(assignment);
} else {
Statement nullCheck = generateNullCheck(field, sourceNode);
if (nullCheck != null)
statements.add(nullCheck);
statements.add(assignment);
}
if (shouldReturnThis) {
ThisReference thisRef = new ThisReference(pS, pE);
ReturnStatement returnThis = new ReturnStatement(thisRef, pS, pE);
statements.add(returnThis);
}
method.statements = statements.toArray(new Statement[0]);
param.annotations = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0]));
method.traverse(new SetGeneratedByVisitor(source), parent.scope);
return method;
}
use of org.eclipse.jdt.internal.compiler.ast.ASTNode in project lombok by rzwitserloot.
the class HandleWither method createWitherForField.
public void createWitherForField(AccessLevel level, EclipseNode fieldNode, EclipseNode sourceNode, boolean whineIfExists, List<Annotation> onMethod, List<Annotation> onParam) {
ASTNode source = sourceNode.get();
if (fieldNode.getKind() != Kind.FIELD) {
sourceNode.addError("@Wither is only supported on a class or a field.");
return;
}
EclipseNode typeNode = fieldNode.up();
boolean makeAbstract = typeNode != null && typeNode.getKind() == Kind.TYPE && (((TypeDeclaration) typeNode.get()).modifiers & ClassFileConstants.AccAbstract) != 0;
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
TypeReference fieldType = copyType(field.type, source);
boolean isBoolean = isBoolean(fieldType);
String witherName = toWitherName(fieldNode, isBoolean);
if (witherName == null) {
fieldNode.addWarning("Not generating wither for this field: It does not fit your @Accessors prefix list.");
return;
}
if ((field.modifiers & ClassFileConstants.AccStatic) != 0) {
fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for static fields.");
return;
}
if ((field.modifiers & ClassFileConstants.AccFinal) != 0 && field.initialization != null) {
fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for final, initialized fields.");
return;
}
if (field.name != null && field.name.length > 0 && field.name[0] == '$') {
fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for fields starting with $.");
return;
}
for (String altName : toAllWitherNames(fieldNode, isBoolean)) {
switch(methodExists(altName, fieldNode, false, 1)) {
case EXISTS_BY_LOMBOK:
return;
case EXISTS_BY_USER:
if (whineIfExists) {
String altNameExpl = "";
if (!altName.equals(witherName))
altNameExpl = String.format(" (%s)", altName);
fieldNode.addWarning(String.format("Not generating %s(): A method with that name already exists%s", witherName, altNameExpl));
}
return;
default:
case NOT_EXISTS:
}
}
int modifier = toEclipseModifier(level);
MethodDeclaration method = createWither((TypeDeclaration) fieldNode.up().get(), fieldNode, witherName, modifier, sourceNode, onMethod, onParam, makeAbstract);
injectMethod(fieldNode.up(), method);
}
use of org.eclipse.jdt.internal.compiler.ast.ASTNode in project lombok by rzwitserloot.
the class HandleWither method createWither.
public MethodDeclaration createWither(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam, boolean makeAbstract) {
ASTNode source = sourceNode.get();
if (name == null)
return null;
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
MethodDeclaration method = new MethodDeclaration(parent.compilationResult);
if (makeAbstract)
modifier = modifier | ClassFileConstants.AccAbstract | ExtraCompilerModifiers.AccSemicolonBody;
method.modifiers = modifier;
method.returnType = cloneSelfType(fieldNode, source);
if (method.returnType == null)
return null;
Annotation[] deprecated = null;
if (isFieldDeprecated(fieldNode)) {
deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
}
method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated);
Argument param = new Argument(field.name, p, copyType(field.type, source), ClassFileConstants.AccFinal);
param.sourceStart = pS;
param.sourceEnd = pE;
method.arguments = new Argument[] { param };
method.selector = name.toCharArray();
method.binding = null;
method.thrownExceptions = null;
method.typeParameters = null;
method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN);
Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN);
if (!makeAbstract) {
List<Expression> args = new ArrayList<Expression>();
for (EclipseNode child : fieldNode.up().down()) {
if (child.getKind() != Kind.FIELD)
continue;
FieldDeclaration childDecl = (FieldDeclaration) child.get();
// Skip fields that start with $
if (childDecl.name != null && childDecl.name.length > 0 && childDecl.name[0] == '$')
continue;
long fieldFlags = childDecl.modifiers;
// Skip static fields.
if ((fieldFlags & ClassFileConstants.AccStatic) != 0)
continue;
// Skip initialized final fields.
if (((fieldFlags & ClassFileConstants.AccFinal) != 0) && childDecl.initialization != null)
continue;
if (child.get() == fieldNode.get()) {
args.add(new SingleNameReference(field.name, p));
} else {
args.add(createFieldAccessor(child, FieldAccess.ALWAYS_FIELD, source));
}
}
AllocationExpression constructorCall = new AllocationExpression();
constructorCall.arguments = args.toArray(new Expression[0]);
constructorCall.type = cloneSelfType(fieldNode, source);
Expression identityCheck = new EqualExpression(createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source), new SingleNameReference(field.name, p), OperatorIds.EQUAL_EQUAL);
ThisReference thisRef = new ThisReference(pS, pE);
Expression conditional = new ConditionalExpression(identityCheck, thisRef, constructorCall);
Statement returnStatement = new ReturnStatement(conditional, pS, pE);
method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd;
List<Statement> statements = new ArrayList<Statement>(5);
if (nonNulls.length > 0) {
Statement nullCheck = generateNullCheck(field, sourceNode);
if (nullCheck != null)
statements.add(nullCheck);
}
statements.add(returnStatement);
method.statements = statements.toArray(new Statement[0]);
}
param.annotations = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0]));
method.traverse(new SetGeneratedByVisitor(source), parent.scope);
return method;
}
use of org.eclipse.jdt.internal.compiler.ast.ASTNode in project lombok by rzwitserloot.
the class HandleConstructor method generateConstructor.
public void generateConstructor(EclipseNode typeNode, AccessLevel level, List<EclipseNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, List<Annotation> onConstructor, EclipseNode sourceNode) {
ASTNode source = sourceNode.get();
boolean staticConstrRequired = staticName != null && !staticName.equals("");
if (skipIfConstructorExists != SkipIfConstructorExists.NO && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS)
return;
if (skipIfConstructorExists != SkipIfConstructorExists.NO) {
for (EclipseNode child : typeNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
boolean skipGeneration = (annotationTypeMatches(NoArgsConstructor.class, child) || annotationTypeMatches(AllArgsConstructor.class, child) || annotationTypeMatches(RequiredArgsConstructor.class, child));
if (!skipGeneration && skipIfConstructorExists == SkipIfConstructorExists.YES) {
skipGeneration = annotationTypeMatches(Builder.class, child);
}
if (skipGeneration) {
if (staticConstrRequired) {
// @Data has asked us to generate a constructor, but we're going to skip this instruction, as an explicit 'make a constructor' annotation
// will take care of it. However, @Data also wants a specific static name; this will be ignored; the appropriate way to do this is to use
// the 'staticName' parameter of the @XArgsConstructor you've stuck on your type.
// We should warn that we're ignoring @Data's 'staticConstructor' param.
typeNode.addWarning("Ignoring static constructor name: explicit @XxxArgsConstructor annotation present; its `staticName` parameter will be used.", source.sourceStart, source.sourceEnd);
}
return;
}
}
}
}
ConstructorDeclaration constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, allToDefault, sourceNode, onConstructor);
injectMethod(typeNode, constr);
if (staticConstrRequired) {
MethodDeclaration staticConstr = createStaticConstructor(level, staticName, typeNode, allToDefault ? Collections.<EclipseNode>emptyList() : fields, source);
injectMethod(typeNode, staticConstr);
}
}
Aggregations