FieldDefinition.java revision 00fc68adf2e39aeb9fed35293f2576bbe729ec4b
1/*
2 * [The "BSD licence"]
3 * Copyright (c) 2010 Ben Gruver (JesusFreke)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29package org.jf.baksmali.Adaptors;
30
31import org.jf.baksmali.Adaptors.EncodedValue.EncodedValueAdaptor;
32import org.jf.dexlib.ClassDataItem;
33import org.jf.dexlib.EncodedValue.EncodedValue;
34import org.jf.dexlib.EncodedValue.NullEncodedValue;
35import org.jf.dexlib.AnnotationSetItem;
36import org.jf.dexlib.AnnotationItem;
37import org.jf.dexlib.Util.AccessFlags;
38import org.antlr.stringtemplate.StringTemplate;
39import org.antlr.stringtemplate.StringTemplateGroup;
40
41import java.util.ArrayList;
42import java.util.List;
43
44public class FieldDefinition {
45    public static StringTemplate createTemplate(StringTemplateGroup stg, ClassDataItem.EncodedField encodedField,
46                                                EncodedValue initialValue, AnnotationSetItem annotationSet,
47                                                boolean setInStaticConstructor) {
48        StringTemplate template = stg.getInstanceOf("field");
49
50        String fieldTypeDescriptor = encodedField.field.getFieldType().getTypeDescriptor();
51
52        template.setAttribute("AccessFlags", getAccessFlags(encodedField));
53        template.setAttribute("FieldName", encodedField.field.getFieldName().getStringValue());
54        template.setAttribute("FieldType", encodedField.field.getFieldType().getTypeDescriptor());
55        template.setAttribute("Annotations", getAnnotations(stg, annotationSet));
56
57        if (setInStaticConstructor &&
58            encodedField.isStatic() &&
59            (encodedField.accessFlags & AccessFlags.FINAL.getValue()) != 0 &&
60            initialValue != null &&
61            (
62                //it's a primitive type, or it's an array/reference type and the initial value isn't null
63                fieldTypeDescriptor.length() == 1 ||
64                initialValue != NullEncodedValue.NullValue
65            )) {
66
67            template.setAttribute("Comments",
68                    new String[]{"the value of this static final field might be set in the static constructor"});
69        } else {
70            template.setAttribute("Comments", null);
71        }
72
73        if (initialValue != null) {
74            template.setAttribute("InitialValue", EncodedValueAdaptor.create(stg, initialValue));
75        }
76
77        return template;
78    }
79
80    public static StringTemplate createTemplate(StringTemplateGroup stg, ClassDataItem.EncodedField encodedField,
81                                                AnnotationSetItem annotationSet) {
82        return createTemplate(stg, encodedField, null, annotationSet, false);
83    }
84
85    private static List<String> getAccessFlags(ClassDataItem.EncodedField encodedField) {
86        List<String> accessFlags = new ArrayList<String>();
87
88        for (AccessFlags accessFlag: AccessFlags.getAccessFlagsForField(encodedField.accessFlags)) {
89            accessFlags.add(accessFlag.toString());
90        }
91
92        return accessFlags;
93    }
94
95    private static List<StringTemplate> getAnnotations(StringTemplateGroup stg, AnnotationSetItem annotationSet) {
96        if (annotationSet == null) {
97            return null;
98        }
99
100        List<StringTemplate> annotationAdaptors = new ArrayList<StringTemplate>();
101
102        for (AnnotationItem annotationItem: annotationSet.getAnnotations()) {
103            annotationAdaptors.add(AnnotationAdaptor.createTemplate(stg, annotationItem));
104        }
105        return annotationAdaptors;
106    }
107}
108