LowerAttributes.java revision 3088f83b806b82d866d119e344da274105f42821
1/* 2 * Copyright 2016 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.google.turbine.bytecode; 18 19import com.google.common.collect.ImmutableList; 20import com.google.turbine.bytecode.Attribute.AnnotationDefault; 21import com.google.turbine.bytecode.Attribute.ConstantValue; 22import com.google.turbine.bytecode.Attribute.ExceptionsAttribute; 23import com.google.turbine.bytecode.Attribute.InnerClasses; 24import com.google.turbine.bytecode.Attribute.Signature; 25import com.google.turbine.bytecode.ClassFile.AnnotationInfo; 26import java.util.ArrayList; 27import java.util.List; 28 29/** Lower information in {@link ClassFile} structures to attributes. */ 30public class LowerAttributes { 31 32 /** Collects the {@link Attribute}s for a {@link ClassFile}. */ 33 static List<Attribute> classAttributes(ClassFile classfile) { 34 List<Attribute> attributes = new ArrayList<>(); 35 if (!classfile.innerClasses().isEmpty()) { 36 attributes.add(new InnerClasses(classfile.innerClasses())); 37 } 38 addAllAnnotations(attributes, classfile.annotations()); 39 if (classfile.signature() != null) { 40 attributes.add(new Signature(classfile.signature())); 41 } 42 return attributes; 43 } 44 45 /** Collects the {@link Attribute}s for a {@link MethodInfo}. */ 46 static List<Attribute> methodAttributes(ClassFile.MethodInfo method) { 47 List<Attribute> attributes = new ArrayList<>(); 48 addAllAnnotations(attributes, method.annotations()); 49 if (method.signature() != null) { 50 attributes.add(new Signature(method.signature())); 51 } 52 addParameterAnnotations(attributes, method.parameterAnnotations()); 53 if (!method.exceptions().isEmpty()) { 54 attributes.add(new ExceptionsAttribute(method.exceptions())); 55 } 56 if (method.defaultValue() != null) { 57 attributes.add(new AnnotationDefault(method.defaultValue())); 58 } 59 return attributes; 60 } 61 62 /** Collects the {@link Attribute}s for a {@link FieldInfo}. */ 63 static List<Attribute> fieldAttributes(ClassFile.FieldInfo field) { 64 List<Attribute> attributes = new ArrayList<>(); 65 if (field.signature() != null) { 66 attributes.add(new Signature(field.signature())); 67 } 68 if (field.value() != null) { 69 attributes.add(new ConstantValue(field.value())); 70 } 71 addAllAnnotations(attributes, field.annotations()); 72 return attributes; 73 } 74 75 static void addAllAnnotations(List<Attribute> attributes, List<AnnotationInfo> annotations) { 76 List<AnnotationInfo> visible = new ArrayList<>(); 77 List<AnnotationInfo> invisible = new ArrayList<>(); 78 for (AnnotationInfo annotation : annotations) { 79 if (annotation.typeName().equals("Ljava/lang/Deprecated;")) { 80 attributes.add(Attribute.DEPRECATED); 81 } 82 (annotation.isRuntimeVisible() ? visible : invisible).add(annotation); 83 } 84 if (!visible.isEmpty()) { 85 attributes.add(new Attribute.RuntimeVisibleAnnotations(visible)); 86 } 87 if (!invisible.isEmpty()) { 88 attributes.add(new Attribute.RuntimeInvisibleAnnotations(invisible)); 89 } 90 } 91 92 static void addParameterAnnotations( 93 List<Attribute> attributes, ImmutableList<ImmutableList<AnnotationInfo>> annotations) { 94 List<List<AnnotationInfo>> visibles = new ArrayList<>(); 95 List<List<AnnotationInfo>> invisibles = new ArrayList<>(); 96 boolean hasVisible = false; 97 boolean hasInvisible = false; 98 for (List<AnnotationInfo> parameterAnnotations : annotations) { 99 List<AnnotationInfo> visible = new ArrayList<>(); 100 List<AnnotationInfo> invisible = new ArrayList<>(); 101 for (AnnotationInfo annotation : parameterAnnotations) { 102 if (annotation.isRuntimeVisible()) { 103 hasVisible = true; 104 visible.add(annotation); 105 } else { 106 hasInvisible = true; 107 invisible.add(annotation); 108 } 109 } 110 visibles.add(visible); 111 invisibles.add(invisible); 112 } 113 // only add the attributes if one of the nested lists is non-empty, 114 // i.e. at least one parameter was annotated 115 if (hasVisible) { 116 attributes.add(new Attribute.RuntimeVisibleParameterAnnotations(visibles)); 117 } 118 if (hasInvisible) { 119 attributes.add(new Attribute.RuntimeInvisibleParameterAnnotations(invisibles)); 120 } 121 } 122} 123