List of usage examples for org.eclipse.jdt.internal.compiler.ast MethodDeclaration traverse
@Override public void traverse(ASTVisitor visitor, ClassScope classScope)
From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.MatchLocatorParser.java
License:Open Source License
/** * Parses the member bodies in the given type. * @param type TypeDeclaration//from w w w . j ava 2 s . c o m * @param unit CompilationUnitDeclaration */ protected void parseBodies(TypeDeclaration type, CompilationUnitDeclaration unit) { FieldDeclaration[] fields = type.fields; if (fields != null) { for (int i = 0; i < fields.length; i++) { FieldDeclaration field = fields[i]; if (field instanceof Initializer) this.parse((Initializer) field, type, unit); field.traverse(this.localDeclarationVisitor, null); } } AbstractMethodDeclaration[] methods = type.methods; if (methods != null) { for (int i = 0; i < methods.length; i++) { AbstractMethodDeclaration method = methods[i]; if (method.sourceStart >= type.bodyStart) { // if not synthetic if (method instanceof MethodDeclaration) { MethodDeclaration methodDeclaration = (MethodDeclaration) method; this.parse(methodDeclaration, unit); methodDeclaration.traverse(this.localDeclarationVisitor, (ClassScope) null); } else if (method instanceof ConstructorDeclaration) { ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) method; this.parse(constructorDeclaration, unit, false); constructorDeclaration.traverse(this.localDeclarationVisitor, (ClassScope) null); } } else if (method.isDefaultConstructor()) { method.parseStatements(this, unit); } } } TypeDeclaration[] memberTypes = type.memberTypes; if (memberTypes != null) { for (int i = 0; i < memberTypes.length; i++) { TypeDeclaration memberType = memberTypes[i]; this.parseBodies(memberType, unit); memberType.traverse(this.localDeclarationVisitor, (ClassScope) null); } } }
From source file:lombok.eclipse.agent.PatchDelegate.java
License:Open Source License
private static void generateDelegateMethods(EclipseNode typeNode, List<BindingTuple> methods, DelegateReceiver delegateReceiver) { CompilationUnitDeclaration top = (CompilationUnitDeclaration) typeNode.top().get(); for (BindingTuple pair : methods) { EclipseNode annNode = typeNode.getAst().get(pair.responsible); MethodDeclaration method = createDelegateMethod(pair.fieldName, typeNode, pair, top.compilationResult, annNode, delegateReceiver); if (method != null) { SetGeneratedByVisitor visitor = new SetGeneratedByVisitor(annNode.get()); method.traverse(visitor, ((TypeDeclaration) typeNode.get()).scope); injectMethod(typeNode, method); }//from ww w .ja v a2 s .c om } }
From source file:lombok.eclipse.handlers.HandleBuilder.java
License:Open Source License
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 {/*from www . j a v a 2 s. com*/ 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; }
From source file:lombok.eclipse.handlers.HandleBuilder.java
License:Open Source License
private MethodDeclaration generateCleanMethod(List<BuilderFieldData> builderFields, EclipseNode builderType, ASTNode source) {// w w w .j av a 2 s.co m List<Statement> statements = new ArrayList<Statement>(); for (BuilderFieldData bfd : builderFields) { if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) { bfd.singularData.getSingularizer().appendCleaningCode(bfd.singularData, builderType, statements); } } FieldReference thisUnclean = new FieldReference(CLEAN_FIELD_NAME, 0); thisUnclean.receiver = new ThisReference(0, 0); statements.add(new Assignment(thisUnclean, new FalseLiteral(0, 0), 0)); MethodDeclaration decl = new MethodDeclaration( ((CompilationUnitDeclaration) builderType.top().get()).compilationResult); decl.selector = CLEAN_METHOD_NAME; decl.modifiers = ClassFileConstants.AccPrivate; decl.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; decl.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0); decl.statements = statements.toArray(new Statement[0]); decl.traverse(new SetGeneratedByVisitor(source), (ClassScope) null); return decl; }
From source file:lombok.eclipse.handlers.HandleBuilder.java
License:Open Source License
public MethodDeclaration generateBuildMethod(String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source) { MethodDeclaration out = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; List<Statement> statements = new ArrayList<Statement>(); if (addCleaning) { FieldReference thisUnclean = new FieldReference(CLEAN_FIELD_NAME, 0); thisUnclean.receiver = new ThisReference(0, 0); Expression notClean = new UnaryExpression(thisUnclean, OperatorIds.NOT); MessageSend invokeClean = new MessageSend(); invokeClean.selector = CLEAN_METHOD_NAME; statements.add(new IfStatement(notClean, invokeClean, 0, 0)); }/*from w w w . j a va2s .c om*/ for (BuilderFieldData bfd : builderFields) { if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) { bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, type, statements, bfd.name); } } List<Expression> args = new ArrayList<Expression>(); for (BuilderFieldData bfd : builderFields) { args.add(new SingleNameReference(bfd.name, 0L)); } if (addCleaning) { FieldReference thisUnclean = new FieldReference(CLEAN_FIELD_NAME, 0); thisUnclean.receiver = new ThisReference(0, 0); statements.add(new Assignment(thisUnclean, new TrueLiteral(0, 0), 0)); } out.modifiers = ClassFileConstants.AccPublic; out.selector = name.toCharArray(); out.thrownExceptions = copyTypes(thrownExceptions); out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; out.returnType = returnType; if (staticName == null) { AllocationExpression allocationStatement = new AllocationExpression(); allocationStatement.type = copyType(out.returnType); allocationStatement.arguments = args.isEmpty() ? null : args.toArray(new Expression[args.size()]); statements.add(new ReturnStatement(allocationStatement, 0, 0)); } else { MessageSend invoke = new MessageSend(); invoke.selector = staticName; invoke.receiver = new SingleNameReference(type.up().getName().toCharArray(), 0); TypeParameter[] tps = ((TypeDeclaration) type.get()).typeParameters; if (tps != null) { TypeReference[] trs = new TypeReference[tps.length]; for (int i = 0; i < trs.length; i++) { trs[i] = new SingleTypeReference(tps[i].name, 0); } invoke.typeArguments = trs; } invoke.arguments = args.isEmpty() ? null : args.toArray(new Expression[args.size()]); if (returnType instanceof SingleTypeReference && Arrays.equals(TypeConstants.VOID, ((SingleTypeReference) returnType).token)) { statements.add(invoke); } else { statements.add(new ReturnStatement(invoke, 0, 0)); } } out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[statements.size()]); out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null); return out; }
From source file:lombok.eclipse.handlers.HandleBuilder.java
License:Open Source License
public MethodDeclaration generateBuilderMethod(String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long) pS << 32 | pE; MethodDeclaration out = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); out.selector = builderMethodName.toCharArray(); out.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic; out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; out.returnType = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p); out.typeParameters = copyTypeParams(typeParams, source); AllocationExpression invoke = new AllocationExpression(); invoke.type = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p); out.statements = new Statement[] { new ReturnStatement(invoke, pS, pE) }; out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope); return out;//from w w w .ja va 2s .c o m }
From source file:lombok.eclipse.handlers.HandleConstructor.java
License:Open Source License
public MethodDeclaration createStaticConstructor(AccessLevel level, String name, EclipseNode type, Collection<EclipseNode> fields, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long) pS << 32 | pE; MethodDeclaration constructor = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); constructor.modifiers = toEclipseModifier(level) | ClassFileConstants.AccStatic; TypeDeclaration typeDecl = (TypeDeclaration) type.get(); constructor.returnType = EclipseHandlerUtil.namePlusTypeParamsToTypeReference(typeDecl.name, typeDecl.typeParameters, p); constructor.annotations = null;//w w w .j a v a 2 s .c o m constructor.selector = name.toCharArray(); constructor.thrownExceptions = null; constructor.typeParameters = copyTypeParams(((TypeDeclaration) type.get()).typeParameters, source); constructor.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart; constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd; List<Argument> params = new ArrayList<Argument>(); List<Expression> assigns = new ArrayList<Expression>(); AllocationExpression statement = new AllocationExpression(); statement.sourceStart = pS; statement.sourceEnd = pE; statement.type = copyType(constructor.returnType, source); for (EclipseNode fieldNode : fields) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); long fieldPos = (((long) field.sourceStart) << 32) | field.sourceEnd; SingleNameReference nameRef = new SingleNameReference(field.name, fieldPos); assigns.add(nameRef); Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL); parameter.annotations = copyAnnotations(source, findAnnotations(field, NON_NULL_PATTERN), findAnnotations(field, NULLABLE_PATTERN)); params.add(parameter); } statement.arguments = assigns.isEmpty() ? null : assigns.toArray(new Expression[assigns.size()]); constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[params.size()]); constructor.statements = new Statement[] { new ReturnStatement(statement, (int) (p >> 32), (int) p) }; constructor.traverse(new SetGeneratedByVisitor(source), typeDecl.scope); return constructor; }
From source file:lombok.eclipse.handlers.HandleEqualsAndHashCode.java
License:Open Source License
public void generateMethods(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess, List<Annotation> onParam) { assert excludes == null || includes == null; TypeDeclaration typeDecl = null;//from w w w . ja v a2s .c o m if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0; if (typeDecl == null || notAClass) { errorNode.addError("@EqualsAndHashCode is only supported on a class."); return; } boolean implicitCallSuper = callSuper == null; if (callSuper == null) { try { callSuper = ((Boolean) EqualsAndHashCode.class.getMethod("callSuper").getDefaultValue()) .booleanValue(); } catch (Exception ignore) { throw new InternalError( "Lombok bug - this cannot happen - can't find callSuper field in EqualsAndHashCode annotation."); } } boolean isDirectDescendantOfObject = true; if (typeDecl.superclass != null) { String p = typeDecl.superclass.toString(); isDirectDescendantOfObject = p.equals("Object") || p.equals("java.lang.Object"); } if (isDirectDescendantOfObject && callSuper) { errorNode.addError("Generating equals/hashCode with a supercall to java.lang.Object is pointless."); return; } if (!isDirectDescendantOfObject && !callSuper && implicitCallSuper) { errorNode.addWarning( "Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type."); } List<EclipseNode> nodesForEquality = new ArrayList<EclipseNode>(); if (includes != null) { for (EclipseNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; FieldDeclaration fieldDecl = (FieldDeclaration) child.get(); if (includes.contains(new String(fieldDecl.name))) nodesForEquality.add(child); } } else { for (EclipseNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; FieldDeclaration fieldDecl = (FieldDeclaration) child.get(); if (!filterField(fieldDecl)) continue; //Skip transient fields. if ((fieldDecl.modifiers & ClassFileConstants.AccTransient) != 0) continue; //Skip excluded fields. if (excludes != null && excludes.contains(new String(fieldDecl.name))) continue; nodesForEquality.add(child); } } boolean isFinal = (typeDecl.modifiers & ClassFileConstants.AccFinal) != 0; boolean needsCanEqual = !isFinal || !isDirectDescendantOfObject; MemberExistsResult equalsExists = methodExists("equals", typeNode, 1); MemberExistsResult hashCodeExists = methodExists("hashCode", typeNode, 0); MemberExistsResult canEqualExists = methodExists("canEqual", typeNode, 1); switch (Collections.max(Arrays.asList(equalsExists, hashCodeExists))) { case EXISTS_BY_LOMBOK: return; case EXISTS_BY_USER: if (whineIfExists) { String msg = "Not generating equals and hashCode: A method with one of those names already exists. (Either both or none of these methods will be generated)."; errorNode.addWarning(msg); } else if (equalsExists == MemberExistsResult.NOT_EXISTS || hashCodeExists == MemberExistsResult.NOT_EXISTS) { // This means equals OR hashCode exists and not both. // Even though we should suppress the message about not generating these, this is such a weird and surprising situation we should ALWAYS generate a warning. // The user code couldn't possibly (barring really weird subclassing shenanigans) be in a shippable state anyway; the implementations of these 2 methods are // all inter-related and should be written by the same entity. String msg = String.format("Not generating %s: One of equals or hashCode exists. " + "You should either write both of these or none of these (in the latter case, lombok generates them).", equalsExists == MemberExistsResult.NOT_EXISTS ? "equals" : "hashCode"); errorNode.addWarning(msg); } return; case NOT_EXISTS: default: //fallthrough } MethodDeclaration equalsMethod = createEquals(typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess, needsCanEqual, onParam); equalsMethod.traverse(new SetGeneratedByVisitor(errorNode.get()), ((TypeDeclaration) typeNode.get()).scope); injectMethod(typeNode, equalsMethod); if (needsCanEqual && canEqualExists == MemberExistsResult.NOT_EXISTS) { MethodDeclaration canEqualMethod = createCanEqual(typeNode, errorNode.get(), onParam); canEqualMethod.traverse(new SetGeneratedByVisitor(errorNode.get()), ((TypeDeclaration) typeNode.get()).scope); injectMethod(typeNode, canEqualMethod); } MethodDeclaration hashCodeMethod = createHashCode(typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess); hashCodeMethod.traverse(new SetGeneratedByVisitor(errorNode.get()), ((TypeDeclaration) typeNode.get()).scope); injectMethod(typeNode, hashCodeMethod); }
From source file:lombok.eclipse.handlers.HandleGetter.java
License:Open Source License
public MethodDeclaration createGetter(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source, boolean lazy, List<Annotation> onMethod) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); // Remember the type; lazy will change it; TypeReference returnType = copyType(((FieldDeclaration) fieldNode.get()).type, source); Statement[] statements;//from w w w.j a v a 2 s. c o m if (lazy) { statements = createLazyGetterBody(source, fieldNode); } else { statements = createSimpleGetterBody(source, fieldNode); } MethodDeclaration method = new MethodDeclaration(parent.compilationResult); method.modifiers = modifier; method.returnType = returnType; method.annotations = null; method.arguments = null; method.selector = name.toCharArray(); method.binding = null; method.thrownExceptions = null; method.typeParameters = null; method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; method.statements = statements; EclipseHandlerUtil.registerCreatedLazyGetter((FieldDeclaration) fieldNode.get(), method.selector, returnType); /* Generate annotations that must be put on the generated method, and attach them. */ { Annotation[] deprecated = null; if (isFieldDeprecated(fieldNode)) { deprecated = new Annotation[] { generateDeprecatedAnnotation(source) }; } method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), findAnnotations(field, NON_NULL_PATTERN), findAnnotations(field, NULLABLE_PATTERN), findDelegatesAndMarkAsHandled(fieldNode), deprecated); } method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; }
From source file:lombok.eclipse.handlers.HandleSetter.java
License:Open Source License
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();/*w w w . ja va 2 s .com*/ 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; }