blob: deae276f6e98c3eab3e81beaf3c283812b1cfbd0 [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#ifndef _SLANG_COMPILER_RS_REFLECTION_H
2#define _SLANG_COMPILER_RS_REFLECTION_H
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07003
Shih-wei Liao462aefd2010-06-04 15:32:04 -07004#include <map>
5#include <vector>
6#include <string>
7#include <cassert>
8#include <fstream>
9#include <iostream>
10
zonr6315f762010-10-05 15:35:14 +080011#include "llvm/ADT/StringExtras.h"
12
13#include "slang_rs_export_type.h"
14
Shih-wei Liao462aefd2010-06-04 15:32:04 -070015namespace slang {
16
zonr6315f762010-10-05 15:35:14 +080017 class RSContext;
18 class RSExportVar;
19 class RSExportFunc;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020
21class RSReflection {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070022 private:
23 const RSContext *mRSContext;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070024
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070025 std::string mLastError;
26 inline void setError(const std::string &Error) { mLastError = Error; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070027
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070028 class Context {
29 private:
30 static const char *const ApacheLicenseNote;
Victor Hsiehd8a0d182010-07-07 19:22:33 +080031
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070032 static const char *const Import[];
Shih-wei Liao462aefd2010-06-04 15:32:04 -070033
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070034 bool mVerbose;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070035
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070036 std::string mInputRSFile;
Ying Wang4e348442010-08-18 10:29:12 -070037
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070038 std::string mPackageName;
39 std::string mResourceId;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070040
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070041 std::string mClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070042
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070043 std::string mLicenseNote;
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070044
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070045 std::string mIndent;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070046
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070047 int mPaddingFieldIndex;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070048
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070049 int mNextExportVarSlot;
50 int mNextExportFuncSlot;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070051
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070052 // A mapping from a field in a record type to its index in the rsType
53 // instance. Only used when generates TypeClass (ScriptField_*).
54 typedef std::map<const RSExportRecordType::Field*, unsigned> FieldIndexMapTy;
55 FieldIndexMapTy mFieldIndexMap;
56 // Field index of current processing TypeClass.
57 unsigned mFieldIndex;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070058
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070059 inline void clear() {
60 mClassName = "";
61 mIndent = "";
62 mPaddingFieldIndex = 1;
63 mNextExportVarSlot = 0;
64 mNextExportFuncSlot = 0;
65 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070066 }
67
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070068 public:
69 typedef enum {
70 AM_Public,
71 AM_Protected,
72 AM_Private
73 } AccessModifier;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070074
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070075 bool mUseStdout;
76 mutable std::ofstream mOF;
77
78 static const char *AccessModifierStr(AccessModifier AM);
79
80 Context(const std::string &InputRSFile,
81 const std::string &PackageName,
82 const std::string &ResourceId,
83 bool UseStdout)
84 : mVerbose(true),
85 mInputRSFile(InputRSFile),
86 mPackageName(PackageName),
87 mResourceId(ResourceId),
88 mLicenseNote(ApacheLicenseNote),
89 mUseStdout(UseStdout) {
90 clear();
91 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070092 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070093
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070094 inline std::ostream &out() const {
zonr6315f762010-10-05 15:35:14 +080095 return ((mUseStdout) ? std::cout : mOF);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070096 }
97 inline std::ostream &indent() const {
98 out() << mIndent;
99 return out();
100 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700101
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700102 inline void incIndentLevel() {
103 mIndent.append(4, ' ');
104 return;
105 }
106
107 inline void decIndentLevel() {
108 assert(getIndentLevel() > 0 && "No indent");
109 mIndent.erase(0, 4);
110 return;
111 }
112
113 inline int getIndentLevel() {
114 return (mIndent.length() >> 2);
115 }
116
117 inline int getNextExportVarSlot() {
118 return mNextExportVarSlot++;
119 }
120
121 inline int getNextExportFuncSlot() {
122 return mNextExportFuncSlot++;
123 }
124
125 // Will remove later due to field name information is not necessary for
126 // C-reflect-to-Java
127 inline std::string createPaddingField() {
128 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
129 }
130
131 inline void setLicenseNote(const std::string &LicenseNote) {
132 mLicenseNote = LicenseNote;
133 }
134
135 bool startClass(AccessModifier AM,
136 bool IsStatic,
137 const std::string &ClassName,
138 const char *SuperClassName,
139 std::string &ErrorMsg);
140 void endClass();
141
142 void startFunction(AccessModifier AM,
143 bool IsStatic,
144 const char *ReturnType,
145 const std::string &FunctionName,
146 int Argc, ...);
147
148 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
149 void startFunction(AccessModifier AM,
150 bool IsStatic,
151 const char *ReturnType,
152 const std::string &FunctionName,
153 const ArgTy &Args);
154 void endFunction();
155
156 void startBlock(bool ShouldIndent = false);
157 void endBlock();
158
159 inline const std::string &getPackageName() const { return mPackageName; }
160 inline const std::string &getClassName() const { return mClassName; }
161 inline const std::string &getResourceId() const { return mResourceId; }
162
163 void startTypeClass(const std::string &ClassName);
164 void endTypeClass();
165
166 inline void incFieldIndex() {
167 mFieldIndex++;
168 }
169
170 inline void resetFieldIndex() {
171 mFieldIndex = 0;
172 }
173
174 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
175 assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
176 "Nested structure never occurs in C language.");
177 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
178 }
179
180 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
181 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
182 assert((I != mFieldIndexMap.end()) &&
183 "Requesting field is out of scope.");
184 return I->second;
185 }
186
187 inline void clearFieldIndexMap() {
188 mFieldIndexMap.clear();
189 }
190 };
191
192 bool openScriptFile(Context &C,
193 const std::string &ClassName,
194 std::string &ErrorMsg);
195 bool genScriptClass(Context &C,
196 const std::string &ClassName,
197 std::string &ErrorMsg);
198 void genScriptClassConstructor(Context &C);
199
200 void genInitBoolExportVariable(Context &C,
201 const std::string &VarName,
202 const clang::APValue &Val);
203 void genInitPrimitiveExportVariable(Context &C,
zonr6315f762010-10-05 15:35:14 +0800204 const std::string &VarName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700205 const clang::APValue &Val);
206 void genInitExportVariable(Context &C,
207 const RSExportType *ET,
208 const std::string &VarName,
209 const clang::APValue &Val);
210 void genExportVariable(Context &C, const RSExportVar *EV);
211 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
212 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
213 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
214 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
215 void genGetExportVariable(Context &C,
216 const std::string &TypeName,
217 const std::string &VarName);
218
219 void genExportFunction(Context &C,
220 const RSExportFunc *EF);
221
222 bool genTypeClass(Context &C,
223 const RSExportRecordType *ERT,
224 std::string &ErrorMsg);
225 bool genTypeItemClass(Context &C,
226 const RSExportRecordType *ERT,
227 std::string &ErrorMsg);
228 void genTypeClassConstructor(Context &C,
229 const RSExportRecordType *ERT);
230 void genTypeClassCopyToArray(Context &C,
231 const RSExportRecordType *ERT);
232 void genTypeClassItemSetter(Context &C,
233 const RSExportRecordType *ERT);
234 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
235 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
236 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
237 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
238
239 void genBuildElement(Context &C,
240 const RSExportRecordType *ERT,
241 const char *RenderScriptVar);
242 void genAddElementToElementBuilder(Context &C,
243 const RSExportType *ERT,
244 const std::string &VarName,
245 const char *ElementBuilderName,
246 const char *RenderScriptVar);
247 void genAddPaddingToElementBuiler(Context &C,
248 int PaddingSize,
249 const char *ElementBuilderName,
250 const char *RenderScriptVar);
251
252 bool genCreateFieldPacker(Context &C,
253 const RSExportType *T,
254 const char *FieldPackerName);
255 void genPackVarOfType(Context &C,
256 const RSExportType *T,
257 const char *VarName,
258 const char *FieldPackerName);
259 void genNewItemBufferIfNull(Context &C, const char *Index);
260 void genNewItemBufferPackerIfNull(Context &C);
261
262 public:
zonr6315f762010-10-05 15:35:14 +0800263 explicit RSReflection(const RSContext *Context)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700264 : mRSContext(Context),
265 mLastError("") {
266 return;
267 }
268
269 bool reflect(const char *OutputPackageName,
270 const std::string &InputFileName,
271 const std::string &OutputBCFileName);
272
273 inline const char *getLastError() const {
274 if (mLastError.empty())
275 return NULL;
276 else
277 return mLastError.c_str();
278 }
279}; // class RSReflection
280
281} // namespace slang
282
zonr6315f762010-10-05 15:35:14 +0800283#endif // _SLANG_COMPILER_RS_REFLECTION_H