1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jdk.experimental.bytecode; 25 26 import java.util.function.Consumer; 27 28 /** 29 * Declaration (class, class member, ...) builder. 30 * 31 * @param <S> the type of symbol representation 32 * @param <T> the type of type descriptors representation 33 * @param <E> the type of pool entries 34 * @param <D> the type of this builder 35 */ 36 public class DeclBuilder<S, T, E, D extends DeclBuilder<S, T, E, D>> 37 extends AttributeBuilder<S, T, E, D> { 38 39 /** 40 * The access flags of the declaration, as bit flags. 41 */ 42 protected int flags; 43 44 AnnotationsBuilder<S, T, E> runtimeInvisibleAnnotations; 45 AnnotationsBuilder<S, T, E> runtimeVisibleAnnotations; 46 47 /** 48 * Create a declaration builder, 49 * 50 * @param poolHelper the helper to build the constant pool 51 * @param typeHelper the helper to use to manipulate type descriptors 52 */ 53 DeclBuilder(PoolHelper<S, T, E> poolHelper, TypeHelper<S, T> typeHelper) { 54 super(poolHelper, typeHelper); 55 } 56 57 /** 58 * Specify the class file flags for this declaration. 59 * 60 * @param flags the flags as {@code Flag} objects 61 * @return this builder, for chained calls 62 */ 63 public D withFlags(Flag... flags) { 64 for (Flag f : flags) { 65 this.flags |= f.flag; 66 } 67 return thisBuilder(); 68 } 69 70 /** 71 * Specify, via bits, the class file flags for this declaration. 72 * 73 * @param flags the flags as bit settings 74 * @return this builder, for chained calls 75 */ 76 public D withFlags(int flags) { 77 withFlags(Flag.parse(flags)); 78 return thisBuilder(); 79 } 80 81 public D withAnnotation(AnnotationsBuilder.Kind kind, T annoType) { 82 getAnnotations(kind).withAnnotation(annoType, null); 83 return thisBuilder(); 84 } 85 86 public D withAnnotation(AnnotationsBuilder.Kind kind, T annoType, Consumer<? super AnnotationsBuilder<S, T, E>.AnnotationElementBuilder> annotations) { 87 getAnnotations(kind).withAnnotation(annoType, annotations); 88 return thisBuilder(); 89 } 90 91 private AnnotationsBuilder<S, T, E> getAnnotations(AnnotationsBuilder.Kind kind) { 92 switch (kind) { 93 case RUNTIME_INVISIBLE: 94 if (runtimeInvisibleAnnotations == null) { 95 runtimeInvisibleAnnotations = new AnnotationsBuilder<>(poolHelper, typeHelper); 96 } 97 return runtimeInvisibleAnnotations; 98 case RUNTIME_VISIBLE: 99 if (runtimeVisibleAnnotations == null) { 100 runtimeVisibleAnnotations = new AnnotationsBuilder<>(poolHelper, typeHelper); 101 } 102 return runtimeVisibleAnnotations; 103 } 104 throw new IllegalStateException(); 105 } 106 107 void addAnnotations() { 108 if (runtimeVisibleAnnotations != null) { 109 withAttribute("RuntimeVisibleAnnotations", runtimeVisibleAnnotations.build()); 110 } 111 if (runtimeInvisibleAnnotations != null) { 112 withAttribute("RuntimeInvisibleAnnotations", runtimeVisibleAnnotations.build()); 113 } 114 } 115 }