• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.google.turbine.bytecode.sig;
18 
19 import com.google.turbine.bytecode.sig.Sig.ArrayTySig;
20 import com.google.turbine.bytecode.sig.Sig.BaseTySig;
21 import com.google.turbine.bytecode.sig.Sig.ClassSig;
22 import com.google.turbine.bytecode.sig.Sig.ClassTySig;
23 import com.google.turbine.bytecode.sig.Sig.LowerBoundTySig;
24 import com.google.turbine.bytecode.sig.Sig.MethodSig;
25 import com.google.turbine.bytecode.sig.Sig.SimpleClassTySig;
26 import com.google.turbine.bytecode.sig.Sig.TyParamSig;
27 import com.google.turbine.bytecode.sig.Sig.TySig;
28 import com.google.turbine.bytecode.sig.Sig.TyVarSig;
29 import com.google.turbine.bytecode.sig.Sig.UpperBoundTySig;
30 import com.google.turbine.bytecode.sig.Sig.WildTySig;
31 
32 /** Writes {@link Sig}s to their serialized string equivalents. */
33 public class SigWriter {
34 
35   /** Writes a {@link ClassSig} to a string. */
classSig(ClassSig classSig)36   public static String classSig(ClassSig classSig) {
37     SigWriter writer = new SigWriter();
38     writer.printClassSig(classSig);
39     return writer.toString();
40   }
41 
42   /** Writes a {@link TySig} to a string. */
type(TySig tySig)43   public static String type(TySig tySig) {
44     SigWriter writer = new SigWriter();
45     writer.writeTySig(tySig);
46     return writer.toString();
47   }
48 
49   /** Writes a {@link MethodSig} to a string. */
method(MethodSig methodSig)50   public static String method(MethodSig methodSig) {
51     SigWriter writer = new SigWriter();
52     writer.writeMethodSig(methodSig);
53     return writer.toString();
54   }
55 
56   private final StringBuilder sb = new StringBuilder();
57 
58   @Override
toString()59   public String toString() {
60     return sb.toString();
61   }
62 
writeFormalTyParamSig(TyParamSig tyParamSig)63   private void writeFormalTyParamSig(TyParamSig tyParamSig) {
64     sb.append(tyParamSig.name());
65     sb.append(':');
66     if (tyParamSig.classBound() != null) {
67       writeTySig(tyParamSig.classBound());
68     }
69     for (Sig.TySig f : tyParamSig.interfaceBounds()) {
70       sb.append(':');
71       writeTySig(f);
72     }
73   }
74 
writeClassTySig(ClassTySig classTySig)75   private void writeClassTySig(ClassTySig classTySig) {
76     sb.append('L');
77     if (!classTySig.pkg().isEmpty()) {
78       sb.append(classTySig.pkg()).append('/');
79     }
80     boolean first = true;
81     for (SimpleClassTySig c : classTySig.classes()) {
82       if (first) {
83         first = false;
84       } else {
85         sb.append('.');
86       }
87       writeSimpleClassTySig(c);
88     }
89     sb.append(';');
90   }
91 
writeSimpleClassTySig(SimpleClassTySig simpleClassTySig)92   public void writeSimpleClassTySig(SimpleClassTySig simpleClassTySig) {
93     sb.append(simpleClassTySig.simpleName());
94     if (!simpleClassTySig.tyArgs().isEmpty()) {
95       sb.append('<');
96       for (Sig.TySig x : simpleClassTySig.tyArgs()) {
97         writeTySig(x);
98       }
99       sb.append('>');
100     }
101   }
102 
wildTyArgSig(WildTySig sig)103   private void wildTyArgSig(WildTySig sig) {
104     switch (sig.boundKind()) {
105       case NONE:
106         sb.append('*');
107         break;
108       case LOWER:
109         sb.append('-');
110         writeTySig(((LowerBoundTySig) sig).bound());
111         break;
112       case UPPER:
113         sb.append('+');
114         writeTySig(((UpperBoundTySig) sig).bound());
115         break;
116     }
117   }
118 
writeArrayTySig(ArrayTySig arrayTySig)119   public void writeArrayTySig(ArrayTySig arrayTySig) {
120     sb.append('[');
121     writeTySig(arrayTySig.elementType());
122   }
123 
writeTyVarSig(TyVarSig tyVarSig)124   public void writeTyVarSig(TyVarSig tyVarSig) {
125     sb.append('T').append(tyVarSig.name()).append(';');
126   }
127 
writePrimitiveTySig(BaseTySig ty)128   public void writePrimitiveTySig(BaseTySig ty) {
129     switch (ty.type()) {
130       case BYTE:
131         sb.append('B');
132         break;
133       case CHAR:
134         sb.append('C');
135         break;
136       case DOUBLE:
137         sb.append('D');
138         break;
139       case FLOAT:
140         sb.append('F');
141         break;
142       case INT:
143         sb.append('I');
144         break;
145       case LONG:
146         sb.append('J');
147         break;
148       case SHORT:
149         sb.append('S');
150         break;
151       case BOOLEAN:
152         sb.append('Z');
153         break;
154       default:
155         throw new AssertionError(ty.type());
156     }
157   }
158 
writeMethodSig(MethodSig methodSig)159   private void writeMethodSig(MethodSig methodSig) {
160     if (!methodSig.tyParams().isEmpty()) {
161       sb.append('<');
162       for (TyParamSig x : methodSig.tyParams()) {
163         writeFormalTyParamSig(x);
164       }
165       sb.append('>');
166     }
167     sb.append('(');
168     for (TySig p : methodSig.params()) {
169       writeTySig(p);
170     }
171     sb.append(')');
172     writeTySig(methodSig.returnType());
173     for (TySig e : methodSig.exceptions()) {
174       sb.append('^');
175       writeTySig(e);
176     }
177   }
178 
writeTySig(TySig p)179   private void writeTySig(TySig p) {
180     switch (p.kind()) {
181       case VOID_TY_SIG:
182         sb.append('V');
183         break;
184       case BASE_TY_SIG:
185         writePrimitiveTySig((BaseTySig) p);
186         break;
187       case CLASS_TY_SIG:
188         writeClassTySig((ClassTySig) p);
189         break;
190       case ARRAY_TY_SIG:
191         writeArrayTySig((ArrayTySig) p);
192         break;
193       case TY_VAR_SIG:
194         writeTyVarSig((TyVarSig) p);
195         break;
196       case WILD_TY_SIG:
197         wildTyArgSig((WildTySig) p);
198         break;
199     }
200   }
201 
printClassSig(ClassSig classSig)202   private void printClassSig(ClassSig classSig) {
203     if (!classSig.tyParams().isEmpty()) {
204       sb.append('<');
205       for (TyParamSig x : classSig.tyParams()) {
206         writeFormalTyParamSig(x);
207       }
208       sb.append('>');
209     }
210     writeClassTySig(classSig.superClass());
211     for (ClassTySig i : classSig.interfaces()) {
212       writeClassTySig(i);
213     }
214   }
215 }
216