• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.dx.io;
18 
19 import com.android.dex.DexException;
20 import com.android.dx.io.instructions.DecodedInstruction;
21 
22 /**
23  * Walks through a block of code and calls visitor call backs.
24  */
25 public final class CodeReader {
26     private Visitor fallbackVisitor = null;
27     private Visitor stringVisitor = null;
28     private Visitor typeVisitor = null;
29     private Visitor fieldVisitor = null;
30     private Visitor methodVisitor = null;
31     private Visitor methodAndProtoVisitor = null;
32     private Visitor callSiteVisitor = null;
33 
34     /**
35      * Sets {@code visitor} as the visitor for all instructions.
36      */
setAllVisitors(Visitor visitor)37     public void setAllVisitors(Visitor visitor) {
38         fallbackVisitor = visitor;
39         stringVisitor = visitor;
40         typeVisitor = visitor;
41         fieldVisitor = visitor;
42         methodVisitor = visitor;
43         methodAndProtoVisitor = visitor;
44         callSiteVisitor = visitor;
45     }
46 
47     /**
48      * Sets {@code visitor} as the visitor for all instructions not
49      * otherwise handled.
50      */
setFallbackVisitor(Visitor visitor)51     public void setFallbackVisitor(Visitor visitor) {
52         fallbackVisitor = visitor;
53     }
54 
55     /**
56      * Sets {@code visitor} as the visitor for all string instructions.
57      */
setStringVisitor(Visitor visitor)58     public void setStringVisitor(Visitor visitor) {
59         stringVisitor = visitor;
60     }
61 
62     /**
63      * Sets {@code visitor} as the visitor for all type instructions.
64      */
setTypeVisitor(Visitor visitor)65     public void setTypeVisitor(Visitor visitor) {
66         typeVisitor = visitor;
67     }
68 
69     /**
70      * Sets {@code visitor} as the visitor for all field instructions.
71      */
setFieldVisitor(Visitor visitor)72     public void setFieldVisitor(Visitor visitor) {
73         fieldVisitor = visitor;
74     }
75 
76     /**
77      * Sets {@code visitor} as the visitor for all method instructions.
78      */
setMethodVisitor(Visitor visitor)79     public void setMethodVisitor(Visitor visitor) {
80         methodVisitor = visitor;
81     }
82 
83     /** Sets {@code visitor} as the visitor for all method and proto instructions. */
setMethodAndProtoVisitor(Visitor visitor)84     public void setMethodAndProtoVisitor(Visitor visitor) {
85         methodAndProtoVisitor = visitor;
86     }
87 
88     /** Sets {@code visitor} as the visitor for all call site instructions. */
setCallSiteVisitor(Visitor visitor)89     public void setCallSiteVisitor(Visitor visitor) {
90         callSiteVisitor = visitor;
91     }
92 
visitAll(DecodedInstruction[] decodedInstructions)93     public void visitAll(DecodedInstruction[] decodedInstructions)
94             throws DexException {
95         int size = decodedInstructions.length;
96 
97         for (int i = 0; i < size; i++) {
98             DecodedInstruction one = decodedInstructions[i];
99             if (one == null) {
100                 continue;
101             }
102 
103             callVisit(decodedInstructions, one);
104         }
105     }
106 
visitAll(short[] encodedInstructions)107     public void visitAll(short[] encodedInstructions) throws DexException {
108         DecodedInstruction[] decodedInstructions =
109             DecodedInstruction.decodeAll(encodedInstructions);
110         visitAll(decodedInstructions);
111     }
112 
callVisit(DecodedInstruction[] all, DecodedInstruction one)113     private void callVisit(DecodedInstruction[] all, DecodedInstruction one) {
114         Visitor visitor = null;
115 
116         switch (OpcodeInfo.getIndexType(one.getOpcode())) {
117             case STRING_REF:           visitor = stringVisitor;         break;
118             case TYPE_REF:             visitor = typeVisitor;           break;
119             case FIELD_REF:            visitor = fieldVisitor;          break;
120             case METHOD_REF:           visitor = methodVisitor;         break;
121             case METHOD_AND_PROTO_REF: visitor = methodAndProtoVisitor; break;
122             case CALL_SITE_REF:        visitor = callSiteVisitor;       break;
123         }
124 
125         if (visitor == null) {
126             visitor = fallbackVisitor;
127         }
128 
129         if (visitor != null) {
130             visitor.visit(all, one);
131         }
132     }
133 
134     public interface Visitor {
visit(DecodedInstruction[] all, DecodedInstruction one)135         void visit(DecodedInstruction[] all, DecodedInstruction one);
136     }
137 }
138