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()]); }
static TypeBinding getFirstParameterType(TypeDeclaration decl, CompletionProposalCollector completionProposalCollector) { TypeBinding firstParameterType = null; ASTNode node = getAssistNode(completionProposalCollector); if (node == null) return null; if (!(node instanceof CompletionOnQualifiedNameReference) && !(node instanceof CompletionOnSingleNameReference) && !(node instanceof CompletionOnMemberAccess)) return null; // Never offer on 'super.<autocomplete>'. if (node instanceof FieldReference && ((FieldReference)node).receiver instanceof SuperReference) return null; if (node instanceof NameReference) { Binding binding = ((NameReference) node).binding; // Unremark next block to allow a 'blank' autocomplete to list any extensions that apply to the current scope, but make sure we're not in a static context first, which this doesn't do. // Lacking good use cases, and having this particular concept be a little tricky on javac, means for now we don't support extension methods like this. this.X() will be fine, though. /* if ((node instanceof SingleNameReference) && (((SingleNameReference) node).token.length == 0)) { firstParameterType = decl.binding; } else */if (binding instanceof VariableBinding) { firstParameterType = ((VariableBinding) binding).type; } } else if (node instanceof FieldReference) { firstParameterType = ((FieldReference) node).actualReceiverType; } return firstParameterType; }
private static NameReference createNameRef(TypeBinding typeBinding, ASTNode source) { long p = ((long) source.sourceStart << 32) | source.sourceEnd; char[] pkg = typeBinding.qualifiedPackageName(); char[] basename = typeBinding.qualifiedSourceName(); StringBuilder sb = new StringBuilder(); if (pkg != null) sb.append(pkg); if (sb.length() > 0) sb.append("."); sb.append(basename); String tName = sb.toString(); if (tName.indexOf('.') == -1) { return new SingleNameReference(basename, p); } else { char[][] sources; String[] in = tName.split("\\."); sources = new char[in.length][]; for (int i = 0; i < in.length; i++) sources[i] = in[i].toCharArray(); long[] poss = new long[in.length]; Arrays.fill(poss, p); return new QualifiedNameReference(sources, poss, source.sourceStart, source.sourceEnd); } }
/** {@inheritDoc} */ @Override protected EclipseNode buildTree(ASTNode node, Kind kind) { switch (kind) { case COMPILATION_UNIT: return buildCompilationUnit((CompilationUnitDeclaration) node); case TYPE: return buildType((TypeDeclaration) node); case FIELD: return buildField((FieldDeclaration) node); case INITIALIZER: return buildInitializer((Initializer) node); case METHOD: return buildMethod((AbstractMethodDeclaration) node); case ARGUMENT: return buildLocal((Argument) node, kind); case LOCAL: return buildLocal((LocalDeclaration) node, kind); case STATEMENT: return buildStatement((Statement) node); case ANNOTATION: return buildAnnotation((Annotation) node, false); default: throw new AssertionError("Did not expect to arrive here: " + kind); } }
public void setFieldDefaultsForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level, boolean makeFinal) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); if (level != null && level != AccessLevel.NONE) { if ((field.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected)) == 0) { if (!hasAnnotation(PackagePrivate.class, fieldNode)) { field.modifiers |= EclipseHandlerUtil.toEclipseModifier(level); } } } if (makeFinal && (field.modifiers & ClassFileConstants.AccFinal) == 0) { if (!hasAnnotation(NonFinal.class, fieldNode)) { if ((field.modifiers & ClassFileConstants.AccStatic) == 0 || field.initialization != null) { field.modifiers |= ClassFileConstants.AccFinal; } } } fieldNode.rebuild(); }
public static MarkerAnnotation generateDeprecatedAnnotation(ASTNode source) { QualifiedTypeReference qtr = new QualifiedTypeReference(new char[][] { {'j', 'a', 'v', 'a'}, {'l', 'a', 'n', 'g'}, {'D', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd'}}, poss(source, 3)); setGeneratedBy(qtr, source); MarkerAnnotation ma = new MarkerAnnotation(qtr, source.sourceStart); // No matter what value you input for sourceEnd, the AST->DOM converter of eclipse will reparse to find the end, and will fail as // it can't find code that isn't really there. This results in the end position being set to 2 or 0 or some weird magic value, and thus, // length, as calculated by end-start, is all screwed up, resulting in IllegalArgumentException during a setSourceRange call MUCH later in the process. // We solve it by going with a voodoo magic source start value such that the calculated length so happens to exactly be 0. 0 lengths are accepted // by eclipse. For some reason. // TL;DR: Don't change 1. 1 is sacred. Trust the 1. // issue: #408. ma.sourceStart = 1; setGeneratedBy(ma, source); return ma; }
/** * Checks if there is a (non-default) constructor. In case of multiple constructors (overloading), only * the first constructor decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned. * * @param node Any node that represents the Type (TypeDeclaration) to look in, or any child node thereof. */ public static MemberExistsResult constructorExists(EclipseNode node) { while (node != null && !(node.get() instanceof TypeDeclaration)) { node = node.up(); } if (node != null && node.get() instanceof TypeDeclaration) { TypeDeclaration typeDecl = (TypeDeclaration)node.get(); if (typeDecl.methods != null) top: for (AbstractMethodDeclaration def : typeDecl.methods) { if (def instanceof ConstructorDeclaration) { if ((def.bits & ASTNode.IsDefaultConstructor) != 0) continue; if (def.annotations != null) for (Annotation anno : def.annotations) { if (typeMatches(Tolerate.class, node, anno.type)) continue top; } return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } return MemberExistsResult.NOT_EXISTS; }
private MethodDeclaration generateCleanMethod(List<BuilderFieldData> builderFields, EclipseNode builderType, ASTNode source) { 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; }
public MethodDeclaration generateBuilderMethod(boolean isStatic, 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; if (isStatic) out.modifiers |= 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; }
public IfStatement generateCompareFloatOrDouble(Expression thisRef, Expression otherRef, char[] floatOrDouble, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; /* if (Float.compare(fieldName, other.fieldName) != 0) return false */ MessageSend floatCompare = new MessageSend(); floatCompare.sourceStart = pS; floatCompare.sourceEnd = pE; setGeneratedBy(floatCompare, source); floatCompare.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.LANG, floatOrDouble); floatCompare.selector = "compare".toCharArray(); floatCompare.arguments = new Expression[] {thisRef, otherRef}; IntLiteral int0 = makeIntLiteral("0".toCharArray(), source); EqualExpression ifFloatCompareIsNot0 = new EqualExpression(floatCompare, int0, OperatorIds.NOT_EQUAL); ifFloatCompareIsNot0.sourceStart = pS; ifFloatCompareIsNot0.sourceEnd = pE; setGeneratedBy(ifFloatCompareIsNot0, source); FalseLiteral falseLiteral = new FalseLiteral(pS, pE); setGeneratedBy(falseLiteral, source); ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); setGeneratedBy(returnFalse, source); IfStatement ifStatement = new IfStatement(ifFloatCompareIsNot0, returnFalse, pS, pE); setGeneratedBy(ifStatement, source); return ifStatement; }
/** Give 2 clones! */ public Expression longToIntForHashCode(Expression ref1, Expression ref2, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; /* (int)(ref >>> 32 ^ ref) */ IntLiteral int32 = makeIntLiteral("32".toCharArray(), source); BinaryExpression higherBits = new BinaryExpression(ref1, int32, OperatorIds.UNSIGNED_RIGHT_SHIFT); setGeneratedBy(higherBits, source); BinaryExpression xorParts = new BinaryExpression(ref2, higherBits, OperatorIds.XOR); setGeneratedBy(xorParts, source); TypeReference intRef = TypeReference.baseTypeReference(TypeIds.T_int, 0); intRef.sourceStart = pS; intRef.sourceEnd = pE; setGeneratedBy(intRef, source); CastExpression expr = makeCastExpression(xorParts, intRef, source); expr.sourceStart = pS; expr.sourceEnd = pE; return expr; }
public char[] returnVarNameIfNullCheck(Statement stat) { if (!(stat instanceof IfStatement)) return null; /* Check that the if's statement is a throw statement, possibly in a block. */ { Statement then = ((IfStatement) stat).thenStatement; if (then instanceof Block) { Statement[] blockStatements = ((Block) then).statements; if (blockStatements == null || blockStatements.length == 0) return null; then = blockStatements[0]; } if (!(then instanceof ThrowStatement)) return null; } /* Check that the if's conditional is like 'x == null'. Return from this method (don't generate a nullcheck) if 'x' is equal to our own variable's name: There's already a nullcheck here. */ { Expression cond = ((IfStatement) stat).condition; if (!(cond instanceof EqualExpression)) return null; EqualExpression bin = (EqualExpression) cond; int operatorId = ((bin.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT); if (operatorId != OperatorIds.EQUAL_EQUAL) return null; if (!(bin.left instanceof SingleNameReference)) return null; if (!(bin.right instanceof NullLiteral)) return null; return ((SingleNameReference) bin.left).token; } }
@Override protected ASTNode parseWithTargetCompiler(Source source) { CompilerOptions compilerOptions = ecjCompilerOptions(); Parser parser = new Parser(new ProblemReporter( DefaultErrorHandlingPolicies.proceedWithAllProblems(), compilerOptions, new DefaultProblemFactory() ), compilerOptions.parseLiteralExpressionsAsConstants); parser.javadocParser.checkDocComment = true; CompilationUnit sourceUnit = new CompilationUnit(source.getRawInput().toCharArray(), source.getName(), "UTF-8"); CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, 0); CompilationUnitDeclaration cud = parser.parse(sourceUnit, compilationResult); if (cud.hasErrors()) return null; return cud; }
public void setFieldDefaultsForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level, boolean makeFinal) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); if (level != null && level != AccessLevel.NONE) { if ((field.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected)) == 0) { if (!hasAnnotation(PackagePrivate.class, fieldNode)) { field.modifiers |= EclipseHandlerUtil.toEclipseModifier(level); } } } if (makeFinal && (field.modifiers & ClassFileConstants.AccFinal) == 0) { if (!hasAnnotation(NonFinal.class, fieldNode)) { field.modifiers |= ClassFileConstants.AccFinal; } } fieldNode.rebuild(); }
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; }
@Override public String toString() { StringBuffer sb = new StringBuffer(); ASTNode.printModifiers(modifiers, sb); sb.append(returnType != null ? returnType.getName() : "<no type>"); sb.append(' '); sb.append((name != null) ? name : "<no name>"); sb.append('('); ITypeBinding[] params = getParameterTypes(); for (int i = 0; i < params.length; i++) { sb.append(params[i].getName()); if ((i + 1) < params.length) { sb.append(", "); } } sb.append(')'); return sb.toString(); }
@Override public ASTNode process(Source in, Void irrelevant) throws ConversionProblem { CompilerOptions compilerOptions = ecjCompilerOptions(); Parser parser = new Parser(new ProblemReporter( DefaultErrorHandlingPolicies.proceedWithAllProblems(), compilerOptions, new DefaultProblemFactory() ), compilerOptions.parseLiteralExpressionsAsConstants); parser.javadocParser.checkDocComment = true; CompilationUnit sourceUnit = new CompilationUnit(in.getRawInput().toCharArray(), in.getName(), charset.name()); CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, 0); CompilationUnitDeclaration cud = parser.parse(sourceUnit, compilationResult); if (cud.hasErrors()) { throw new ConversionProblem(String.format("Can't read file %s due to parse error: %s", in.getName(), compilationResult.getErrors()[0])); } return cud; }
private <T extends ASTNode> T[] toArray(Class<T> type, lombok.ast.StrictListAccessor<?, ?> accessor) { List<T> list = Lists.newArrayList(); for (lombok.ast.Node node : accessor) { EcjTreeBuilder newBuilder = create(); node.accept(newBuilder.visitor); bubblingFlags.addAll(newBuilder.bubblingFlags); List<? extends ASTNode> values; values = newBuilder.getAll(); for (ASTNode value : values) { if (value != null && !type.isInstance(value)) { throw new ClassCastException(value.getClass().getName() + " cannot be cast to " + type.getName()); } list.add(type.cast(value)); } } return toArray(type, list); }
@Override protected ASTNode parseWithLombok(Source source) { CompilerOptions compilerOptions = ecjCompilerOptions(); Parser parser = new Parser(new ProblemReporter( DefaultErrorHandlingPolicies.proceedWithAllProblems(), compilerOptions, new DefaultProblemFactory() ), compilerOptions.parseLiteralExpressionsAsConstants); parser.javadocParser.checkDocComment = true; CompilationUnit sourceUnit = new CompilationUnit(source.getRawInput().toCharArray(), source.getName(), "UTF-8"); CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, 0); CompilationUnitDeclaration cud = parser.parse(sourceUnit, compilationResult); if (cud.hasErrors()) return null; EcjTreeConverter converter = new EcjTreeConverter(); converter.visit(source.getRawInput(), cud); Node lombokized = converter.get(); EcjTreeBuilder builder = new EcjTreeBuilder(source.getRawInput(), source.getName(), ecjCompilerOptions()); builder.visit(lombokized); return builder.get(); }
public Expression get(final ASTNode source, char[] name) { MessageSend call = new MessageSend(); call.sourceStart = source.sourceStart; call.sourceEnd = source.sourceEnd; call.nameSourcePosition = pos(source); setGeneratedBy(call, source); call.selector = name; call.receiver = new ThisReference(source.sourceStart, source.sourceEnd); setGeneratedBy(call.receiver, source); return call; }
public Expression get(final ASTNode source, char[] name) { FieldReference fieldRef = new FieldReference(name, pos(source)); setGeneratedBy(fieldRef, source); fieldRef.receiver = new ThisReference(source.sourceStart, source.sourceEnd); setGeneratedBy(fieldRef.receiver, source); return fieldRef; }
private static ASTNode getAssistNode(CompletionProposalCollector completionProposalCollector) { try { InternalCompletionContext context = (InternalCompletionContext) Reflection.contextField.get(completionProposalCollector); InternalExtendedCompletionContext extendedContext = (InternalExtendedCompletionContext) Reflection.extendedContextField.get(context); if (extendedContext == null) return null; return (ASTNode) Reflection.assistNodeField.get(extendedContext); } catch (Exception ignore) { return null; } }
@Override public String getFullyQualifiedNameForSimpleName(String unqualified) { if (imports != null) { outer: for (ImportReference imp : imports) { if ((imp.bits & ASTNode.OnDemand) != 0) continue; char[][] tokens = imp.tokens; char[] token = tokens.length == 0 ? new char[0] : tokens[tokens.length - 1]; int len = token.length; if (len != unqualified.length()) continue; for (int i = 0; i < len; i++) if (token[i] != unqualified.charAt(i)) continue outer; return LombokInternalAliasing.processAliases(toQualifiedName(tokens)); } } return null; }
@Override public Collection<String> applyNameToStarImports(String startsWith, String name) { List<String> out = Collections.emptyList(); if (pkg != null && pkg.tokens != null && pkg.tokens.length != 0) { char[] first = pkg.tokens[0]; int len = first.length; boolean match = true; if (startsWith.length() == len) { for (int i = 0; match && i < len; i++) { if (startsWith.charAt(i) != first[i]) match = false; } if (match) out.add(toQualifiedName(pkg.tokens) + "." + name); } } if (imports != null) { outer: for (ImportReference imp : imports) { if ((imp.bits & ASTNode.OnDemand) == 0) continue; if (imp.isStatic()) continue; if (imp.tokens == null || imp.tokens.length == 0) continue; char[] firstToken = imp.tokens[0]; if (firstToken.length != startsWith.length()) continue; for (int i = 0; i < firstToken.length; i++) if (startsWith.charAt(i) != firstToken[i]) continue outer; String fqn = toQualifiedName(imp.tokens) + "." + name; if (out.isEmpty()) out = Collections.singletonList(fqn); else if (out.size() == 1) { out = new ArrayList<String>(out); out.add(fqn); } else { out.add(fqn); } } } return out; }
public static Annotation[] createConstructorProperties(ASTNode source, Collection<EclipseNode> fields) { if (fields.isEmpty()) return null; int pS = source.sourceStart, pE = source.sourceEnd; long p = (long) pS << 32 | pE; long[] poss = new long[3]; Arrays.fill(poss, p); QualifiedTypeReference constructorPropertiesType = new QualifiedTypeReference(JAVA_BEANS_CONSTRUCTORPROPERTIES, poss); setGeneratedBy(constructorPropertiesType, source); SingleMemberAnnotation ann = new SingleMemberAnnotation(constructorPropertiesType, pS); ann.declarationSourceEnd = pE; ArrayInitializer fieldNames = new ArrayInitializer(); fieldNames.sourceStart = pS; fieldNames.sourceEnd = pE; fieldNames.expressions = new Expression[fields.size()]; int ctr = 0; for (EclipseNode field : fields) { char[] fieldName = removePrefixFromField(field); fieldNames.expressions[ctr] = new StringLiteral(fieldName, pS, pE, 0); setGeneratedBy(fieldNames.expressions[ctr], source); ctr++; } ann.memberValue = fieldNames; setGeneratedBy(ann, source); setGeneratedBy(ann.memberValue, source); return new Annotation[] { ann }; }
private void createPrivateDefaultConstructor(EclipseNode typeNode, EclipseNode sourceNode) { ASTNode source = sourceNode.get(); TypeDeclaration typeDeclaration = ((TypeDeclaration) typeNode.get()); long p = (long) source.sourceStart << 32 | source.sourceEnd; ConstructorDeclaration constructor = new ConstructorDeclaration(((CompilationUnitDeclaration) typeNode.top().get()).compilationResult); constructor.modifiers = ClassFileConstants.AccPrivate; constructor.selector = typeDeclaration.name; constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper); constructor.constructorCall.sourceStart = source.sourceStart; constructor.constructorCall.sourceEnd = source.sourceEnd; constructor.thrownExceptions = null; constructor.typeParameters = null; constructor.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart; constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd; constructor.arguments = null; AllocationExpression exception = new AllocationExpression(); setGeneratedBy(exception, source); long[] ps = new long[JAVA_LANG_UNSUPPORTED_OPERATION_EXCEPTION.length]; Arrays.fill(ps, p); exception.type = new QualifiedTypeReference(JAVA_LANG_UNSUPPORTED_OPERATION_EXCEPTION, ps); setGeneratedBy(exception.type, source); exception.arguments = new Expression[] { new StringLiteral(UNSUPPORTED_MESSAGE, source.sourceStart, source.sourceEnd, 0) }; setGeneratedBy(exception.arguments[0], source); ThrowStatement throwStatement = new ThrowStatement(exception, source.sourceStart, source.sourceEnd); setGeneratedBy(throwStatement, source); constructor.statements = new Statement[] {throwStatement}; injectMethod(typeNode, constructor); }
/** * You can't share TypeParameter objects or bad things happen; for example, one 'T' resolves differently * from another 'T', even for the same T in a single class file. Unfortunately the TypeParameter type hierarchy * is complicated and there's no clone method on TypeParameter itself. This method can clone them. */ public static TypeParameter[] copyTypeParams(TypeParameter[] params, ASTNode source) { if (params == null) return null; TypeParameter[] out = new TypeParameter[params.length]; int idx = 0; for (TypeParameter param : params) { TypeParameter o = new TypeParameter(); setGeneratedBy(o, source); o.annotations = param.annotations; o.bits = param.bits; o.modifiers = param.modifiers; o.name = param.name; o.type = copyType(param.type, source); o.sourceStart = param.sourceStart; o.sourceEnd = param.sourceEnd; o.declarationEnd = param.declarationEnd; o.declarationSourceStart = param.declarationSourceStart; o.declarationSourceEnd = param.declarationSourceEnd; if (param.bounds != null) { TypeReference[] b = new TypeReference[param.bounds.length]; int idx2 = 0; for (TypeReference ref : param.bounds) b[idx2++] = copyType(ref, source); o.bounds = b; } out[idx++] = o; } return out; }
/** * Convenience method that creates a new array and copies each TypeReference in the source array via * {@link #copyType(TypeReference, ASTNode)}. */ public static TypeReference[] copyTypes(TypeReference[] refs, ASTNode source) { if (refs == null) return null; TypeReference[] outs = new TypeReference[refs.length]; int idx = 0; for (TypeReference ref : refs) { outs[idx++] = copyType(ref, source); } return outs; }
public static Annotation[] copyAnnotations(ASTNode source, Annotation[]... allAnnotations) { List<Annotation> result = null; for (Annotation[] annotations : allAnnotations) { if (annotations != null) { for (Annotation annotation : annotations) { if (result == null) result = new ArrayList<Annotation>(); result.add(copyAnnotation(annotation, source)); } } } return result == null ? null : result.toArray(new Annotation[0]); }