• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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.mkstubs.sourcer;
18 
19 import org.objectweb.asm.AnnotationVisitor;
20 import org.objectweb.asm.Attribute;
21 import org.objectweb.asm.Label;
22 import org.objectweb.asm.MethodVisitor;
23 import org.objectweb.asm.Type;
24 import org.objectweb.asm.signature.SignatureReader;
25 
26 import java.util.ArrayList;
27 
28 /**
29  * A method visitor that generates the Java source for a whole method.
30  */
31 class MethodSourcer implements MethodVisitor {
32 
33     private final Output mOutput;
34     private final int mAccess;
35     private final String mClassName;
36     private final String mName;
37     private final String mDesc;
38     private final String mSignature;
39     private final String[] mExceptions;
40     private boolean mNeedDeclaration;
41     private boolean mIsConstructor;
42 
MethodSourcer(Output output, String className, int access, String name, String desc, String signature, String[] exceptions)43     public MethodSourcer(Output output, String className, int access, String name,
44             String desc, String signature, String[] exceptions) {
45         mOutput = output;
46         mClassName = className;
47         mAccess = access;
48         mName = name;
49         mDesc = desc;
50         mSignature = signature;
51         mExceptions = exceptions;
52 
53         mNeedDeclaration = true;
54         mIsConstructor = "<init>".equals(name);
55     }
56 
writeHeader()57     private void writeHeader() {
58         if (!mNeedDeclaration) {
59             return;
60         }
61 
62         AccessSourcer as = new AccessSourcer(mOutput);
63         as.write(mAccess, AccessSourcer.IS_METHOD);
64 
65         // preprocess the signature to get the return type and the arguments
66         SignatureSourcer sigSourcer = null;
67         if (mSignature != null) {
68             SignatureReader sigReader = new SignatureReader(mSignature);
69             sigSourcer = new SignatureSourcer();
70             sigReader.accept(sigSourcer);
71 
72             if (sigSourcer.hasFormalsContent()) {
73                 // dump formal template parameter definitions
74                 mOutput.write(" %s", sigSourcer.formalsToString());
75             }
76         }
77 
78         // output return type (constructor have no return type)
79         if (!mIsConstructor) {
80             // The signature overrides desc, if present
81             if (sigSourcer == null || sigSourcer.getReturnType() == null) {
82                 mOutput.write(" %s", Type.getReturnType(mDesc).getClassName());
83 
84             } else {
85                 mOutput.write(" %s", sigSourcer.getReturnType().toString());
86             }
87         }
88 
89         // output name
90         mOutput.write(" %s(", mIsConstructor ? mClassName : mName);
91 
92         // output arguments. The signature overrides desc, if present
93         if (mSignature == null) {
94             Type[] types = Type.getArgumentTypes(mDesc);
95 
96             for(int i = 0; i < types.length; i++) {
97                 if (i > 0) {
98                     mOutput.write(", ");
99                 }
100                 mOutput.write("%s arg%d", types[i].getClassName(), i);
101             }
102         } else {
103             ArrayList<SignatureSourcer> params = sigSourcer.getParameters();
104 
105             for(int i = 0; i < params.size(); i++) {
106                 if (i > 0) {
107                     mOutput.write(", ");
108                 }
109                 mOutput.write("%s arg%d", params.get(i).toString(), i);
110             }
111         }
112         mOutput.write(")");
113 
114         // output throwable exceptions
115         if (mExceptions != null && mExceptions.length > 0) {
116             mOutput.write(" throws ");
117 
118             for (int i = 0; i < mExceptions.length; i++) {
119                 if (i > 0) {
120                     mOutput.write(", ");
121                 }
122                 mOutput.write(mExceptions[i].replace('/', '.'));
123             }
124         }
125 
126         mOutput.write(" {\n");
127 
128         mNeedDeclaration = false;
129     }
130 
visitCode()131     public void visitCode() {
132         writeHeader();
133 
134         // write the stub itself
135         mOutput.write("throw new RuntimeException(\"Stub\");");
136     }
137 
visitEnd()138     public void visitEnd() {
139         writeHeader();
140         mOutput.write("\n}\n");
141     }
142 
visitAnnotation(String desc, boolean visible)143     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
144         mOutput.write("@%s", desc);
145         return new AnnotationSourcer(mOutput);
146     }
147 
visitAnnotationDefault()148     public AnnotationVisitor visitAnnotationDefault() {
149         // pass
150         return null;
151     }
152 
visitAttribute(Attribute attr)153     public void visitAttribute(Attribute attr) {
154         mOutput.write("%s /* non-standard method attribute */ ", attr.type);
155     }
156 
visitFieldInsn(int opcode, String owner, String name, String desc)157     public void visitFieldInsn(int opcode, String owner, String name, String desc) {
158         // pass
159     }
160 
visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2)161     public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
162         // pass
163     }
164 
visitIincInsn(int var, int increment)165     public void visitIincInsn(int var, int increment) {
166         // pass
167     }
168 
visitInsn(int opcode)169     public void visitInsn(int opcode) {
170         // pass
171     }
172 
visitIntInsn(int opcode, int operand)173     public void visitIntInsn(int opcode, int operand) {
174         // pass
175     }
176 
visitJumpInsn(int opcode, Label label)177     public void visitJumpInsn(int opcode, Label label) {
178         // pass
179     }
180 
visitLabel(Label label)181     public void visitLabel(Label label) {
182         // pass
183     }
184 
visitLdcInsn(Object cst)185     public void visitLdcInsn(Object cst) {
186         // pass
187     }
188 
visitLineNumber(int line, Label start)189     public void visitLineNumber(int line, Label start) {
190         // pass
191     }
192 
visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index)193     public void visitLocalVariable(String name, String desc, String signature,
194             Label start, Label end, int index) {
195         // pass
196     }
197 
visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)198     public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
199         // pass
200     }
201 
visitMaxs(int maxStack, int maxLocals)202     public void visitMaxs(int maxStack, int maxLocals) {
203         // pass
204     }
205 
visitMethodInsn(int opcode, String owner, String name, String desc)206     public void visitMethodInsn(int opcode, String owner, String name, String desc) {
207         // pass
208     }
209 
visitMultiANewArrayInsn(String desc, int dims)210     public void visitMultiANewArrayInsn(String desc, int dims) {
211         // pass
212     }
213 
visitParameterAnnotation(int parameter, String desc, boolean visible)214     public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
215         // pass
216         return null;
217     }
218 
visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels)219     public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
220         // pass
221     }
222 
visitTryCatchBlock(Label start, Label end, Label handler, String type)223     public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
224         // pass
225     }
226 
visitTypeInsn(int opcode, String type)227     public void visitTypeInsn(int opcode, String type) {
228         // pass
229     }
230 
visitVarInsn(int opcode, int var)231     public void visitVarInsn(int opcode, int var) {
232         // pass
233     }
234 
235 }
236