private <T extends Attribute.Compound> List<T> getAttributesForCompletion( final Annotate.AnnotateRepeatedContext<T> ctx) { Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated; boolean atLeastOneRepeated = false; List<T> buf = List.<T>nil(); for (ListBuffer<T> lb : annotated.values()) { if (lb.size() == 1) { buf = buf.prepend(lb.first()); } else { // repeated // This will break when other subtypes of Attributs.Compound // are introduced, because PlaceHolder is a subtype of TypeCompound. T res; @SuppressWarnings("unchecked") T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym); res = ph; buf = buf.prepend(res); atLeastOneRepeated = true; } } if (atLeastOneRepeated) { // The Symbol s is now annotated with a combination of // finished non-repeating annotations and placeholders for // repeating annotations. // // We need to do this in two passes because when creating // a container for a repeating annotation we must // guarantee that the @Repeatable on the // contained annotation is fully annotated // // The way we force this order is to do all repeating // annotations in a pass after all non-repeating are // finished. This will work because @Repeatable // is non-repeating and therefore will be annotated in the // fist pass. // Queue a pass that will replace Attribute.Placeholders // with Attribute.Compound (made from synthesized containers). ctx.annotateRepeated( new Annotate.Annotator() { @Override public String toString() { return "repeated annotation pass of: " + sym + " in: " + sym.owner; } @Override public void enterAnnotation() { complete(ctx); } }); } // Add non-repeating attributes return buf.reverse(); }
private <T extends Attribute.Compound> T replaceOne( Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) { Log log = ctx.log; // Process repeated annotations T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym); if (validRepeated != null) { // Check that the container isn't manually // present along with repeated instances of // its contained annotation. ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym); if (manualContainer != null) { log.error( ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present", manualContainer.first().type.tsym); } } // A null return will delete the Placeholder return validRepeated; }