1 /*
2  * Copyright (C) 2010 The Android Open Source Project
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 
17 package com.android.tools.layoutlib.create;
18 
19 import org.objectweb.asm.ClassVisitor;
20 
21 import java.util.Map;
22 
23 /**
24  * Interface describing the work to be done by {@link AsmGenerator}.
25  */
26 public interface ICreateInfo {
27 
getMethodReplacers()28     MethodReplacer[] getMethodReplacers();
29 
30     /**
31      * Returns the list of class from layoutlib_create to inject in layoutlib.
32      * The list can be empty but must not be null.
33      */
getInjectedClasses()34     Class<?>[] getInjectedClasses();
35 
36     /**
37      * Returns the list of methods to rewrite as delegates.
38      * The list can be empty but must not be null.
39      */
getDelegateMethods()40     String[] getDelegateMethods();
41 
42     /**
43      * Returns the list of classes on which to delegate all native methods.
44      * The list can be empty but must not be null.
45      */
getDelegateClassNatives()46     String[] getDelegateClassNatives();
47 
48     /**
49      * Returns the list of classes for which to create a delegate class that delegates all native
50      * methods to corresponding native methods. This is useful for classes that call native
51      * methods during static initialization.
52      * The list can be empty but must not be null.
53      */
getDelegateClassNativesToNatives()54     String[] getDelegateClassNativesToNatives();
55 
56     /**
57      * Returns true if native methods should not be stubbed by default.
58      */
shouldKeepAllNativeClasses()59     boolean shouldKeepAllNativeClasses();
60 
61     /**
62      * Returns the list of classes for which not to delegate any native method.
63      * The list can be empty but must not be null.
64      *
65      * Only used when shouldKeepAllNativeClasses is false.
66      */
getKeepClassNatives()67     String[] getKeepClassNatives();
68 
69     /**
70      * Returns the list of classes to rename, must be an even list: the binary FQCN
71      * of class to replace followed by the new FQCN.
72      * The list can be empty but must not be null.
73      */
getRenamedClasses()74     String[] getRenamedClasses();
75 
76     /**
77      * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and
78      * {@link #getJavaPkgClasses()}.
79      * Classes included here will be renamed and then all their references in any other classes
80      * will be also modified.
81      * FQCN of class to refactor followed by its new FQCN.
82      */
getRefactoredClasses()83     String[] getRefactoredClasses();
84 
85     /**
86      * Returns the list of classes for which the methods returning them should be deleted.
87      * The array contains a list of null terminated section starting with the name of the class
88      * to rename in which the methods are deleted, followed by a list of return types identifying
89      * the methods to delete.
90      * The list can be empty but must not be null.
91      */
getDeleteReturns()92     String[] getDeleteReturns();
93 
94     /**
95      * Returns the list of classes to refactor, must be an even list: the
96      * binary FQCN of class to replace followed by the new FQCN. All references
97      * to the old class should be updated to the new class.
98      * The list can be empty but must not be null.
99      */
getJavaPkgClasses()100     String[] getJavaPkgClasses();
101 
getExcludedClasses()102     String[] getExcludedClasses();
103 
104     /**
105      * Returns a list of fields which should be promoted to public visibility. The array values
106      * are in the form of the binary FQCN of the class containing the field and the field name
107      * separated by a '#'.
108      */
getPromotedFields()109     String[] getPromotedFields();
110 
111     /**
112      * Returns a list of methods which should be promoted to public visibility. The array values
113      * are in the form of the binary FQCN of the class containing the method and the method name
114      * separated by a '#'.
115      */
getPromotedMethods()116     String[] getPromotedMethods();
117 
118     /**
119      * Returns a list of classes to be promoted to public visibility.
120      */
getPromotedClasses()121     String[] getPromotedClasses();
122 
123     /**
124      * Returns a map from binary FQCN className to {@link InjectMethodRunnable} which will be
125      * called to inject methods into a class.
126      * Can be empty but must not be null.
127      */
getInjectedMethodsMap()128     Map<String, InjectMethodRunnable> getInjectedMethodsMap();
129 
getDeferredStaticInitializerClasses()130     String[] getDeferredStaticInitializerClasses();
131 
132     /**
133      * Returns a list of fields which should have their final modifier removed.
134      * The array values are in the form of the binary FQCN of the class containing the field and
135      * the field name separated by a '#'.
136      */
getRemovedFinalModifierFields()137     String[] getRemovedFinalModifierFields();
138 
139     interface MethodReplacer {
isNeeded(String owner, String name, String desc, String sourceClass)140         boolean isNeeded(String owner, String name, String desc, String sourceClass);
141 
142         /**
143          * Updates the MethodInformation with the new values of the method attributes -
144          * opcode, owner, name and desc.
145          */
replace(MethodInformation mi)146         void replace(MethodInformation mi);
147     }
148 
149     abstract class InjectMethodRunnable {
150         /**
151          * @param cv Must be {@link ClassVisitor}. However, the param type is object so that when
152          * loading the class, ClassVisitor is not loaded. This is because when injecting
153          * CreateInfo in LayoutLib (see {@link #getInjectedClasses()}, we don't want to inject
154          * asm classes also, but still keep CreateInfo loadable.
155          */
generateMethods(Object cv)156         public abstract void generateMethods(Object cv);
157     }
158 
159     class MethodInformation {
160         public int opcode;
161         public String owner;
162         public String name;
163         public String desc;
164 
MethodInformation(int opcode, String owner, String name, String desc)165         public MethodInformation(int opcode, String owner, String name, String desc) {
166             this.opcode = opcode;
167             this.owner = owner;
168             this.name = name;
169             this.desc = desc;
170         }
171     }
172 }
173