blob: bc5a71aa621591aafa6a7f5f85eefb487fa404d2 [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();
Zonr Chang66aa2992010-10-05 15:56:31 +080091 resetFieldIndex();
92 clearFieldIndexMap();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070093 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070094 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070095
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070096 inline std::ostream &out() const {
zonr6315f762010-10-05 15:35:14 +080097 return ((mUseStdout) ? std::cout : mOF);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070098 }
99 inline std::ostream &indent() const {
100 out() << mIndent;
101 return out();
102 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700103
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700104 inline void incIndentLevel() {
105 mIndent.append(4, ' ');
106 return;
107 }
108
109 inline void decIndentLevel() {
110 assert(getIndentLevel() > 0 && "No indent");
111 mIndent.erase(0, 4);
112 return;
113 }
114
115 inline int getIndentLevel() {
116 return (mIndent.length() >> 2);
117 }
118
119 inline int getNextExportVarSlot() {
120 return mNextExportVarSlot++;
121 }
122
123 inline int getNextExportFuncSlot() {
124 return mNextExportFuncSlot++;
125 }
126
127 // Will remove later due to field name information is not necessary for
128 // C-reflect-to-Java
129 inline std::string createPaddingField() {
130 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
131 }
132
133 inline void setLicenseNote(const std::string &LicenseNote) {
134 mLicenseNote = LicenseNote;
135 }
136
137 bool startClass(AccessModifier AM,
138 bool IsStatic,
139 const std::string &ClassName,
140 const char *SuperClassName,
141 std::string &ErrorMsg);
142 void endClass();
143
144 void startFunction(AccessModifier AM,
145 bool IsStatic,
146 const char *ReturnType,
147 const std::string &FunctionName,
148 int Argc, ...);
149
150 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
151 void startFunction(AccessModifier AM,
152 bool IsStatic,
153 const char *ReturnType,
154 const std::string &FunctionName,
155 const ArgTy &Args);
156 void endFunction();
157
158 void startBlock(bool ShouldIndent = false);
159 void endBlock();
160
161 inline const std::string &getPackageName() const { return mPackageName; }
162 inline const std::string &getClassName() const { return mClassName; }
163 inline const std::string &getResourceId() const { return mResourceId; }
164
165 void startTypeClass(const std::string &ClassName);
166 void endTypeClass();
167
168 inline void incFieldIndex() {
169 mFieldIndex++;
170 }
171
172 inline void resetFieldIndex() {
173 mFieldIndex = 0;
174 }
175
176 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
177 assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
178 "Nested structure never occurs in C language.");
179 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
180 }
181
182 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
183 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
184 assert((I != mFieldIndexMap.end()) &&
185 "Requesting field is out of scope.");
186 return I->second;
187 }
188
189 inline void clearFieldIndexMap() {
190 mFieldIndexMap.clear();
191 }
192 };
193
194 bool openScriptFile(Context &C,
195 const std::string &ClassName,
196 std::string &ErrorMsg);
197 bool genScriptClass(Context &C,
198 const std::string &ClassName,
199 std::string &ErrorMsg);
200 void genScriptClassConstructor(Context &C);
201
202 void genInitBoolExportVariable(Context &C,
203 const std::string &VarName,
204 const clang::APValue &Val);
205 void genInitPrimitiveExportVariable(Context &C,
zonr6315f762010-10-05 15:35:14 +0800206 const std::string &VarName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700207 const clang::APValue &Val);
208 void genInitExportVariable(Context &C,
209 const RSExportType *ET,
210 const std::string &VarName,
211 const clang::APValue &Val);
212 void genExportVariable(Context &C, const RSExportVar *EV);
213 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
214 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
215 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
216 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
217 void genGetExportVariable(Context &C,
218 const std::string &TypeName,
219 const std::string &VarName);
220
221 void genExportFunction(Context &C,
222 const RSExportFunc *EF);
223
224 bool genTypeClass(Context &C,
225 const RSExportRecordType *ERT,
226 std::string &ErrorMsg);
227 bool genTypeItemClass(Context &C,
228 const RSExportRecordType *ERT,
229 std::string &ErrorMsg);
230 void genTypeClassConstructor(Context &C,
231 const RSExportRecordType *ERT);
232 void genTypeClassCopyToArray(Context &C,
233 const RSExportRecordType *ERT);
234 void genTypeClassItemSetter(Context &C,
235 const RSExportRecordType *ERT);
236 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
237 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
238 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
239 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
240
241 void genBuildElement(Context &C,
242 const RSExportRecordType *ERT,
243 const char *RenderScriptVar);
244 void genAddElementToElementBuilder(Context &C,
245 const RSExportType *ERT,
246 const std::string &VarName,
247 const char *ElementBuilderName,
248 const char *RenderScriptVar);
249 void genAddPaddingToElementBuiler(Context &C,
250 int PaddingSize,
251 const char *ElementBuilderName,
252 const char *RenderScriptVar);
253
254 bool genCreateFieldPacker(Context &C,
255 const RSExportType *T,
256 const char *FieldPackerName);
257 void genPackVarOfType(Context &C,
258 const RSExportType *T,
259 const char *VarName,
260 const char *FieldPackerName);
261 void genNewItemBufferIfNull(Context &C, const char *Index);
262 void genNewItemBufferPackerIfNull(Context &C);
263
264 public:
zonr6315f762010-10-05 15:35:14 +0800265 explicit RSReflection(const RSContext *Context)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700266 : mRSContext(Context),
267 mLastError("") {
268 return;
269 }
270
271 bool reflect(const char *OutputPackageName,
272 const std::string &InputFileName,
273 const std::string &OutputBCFileName);
274
275 inline const char *getLastError() const {
276 if (mLastError.empty())
277 return NULL;
278 else
279 return mLastError.c_str();
280 }
281}; // class RSReflection
282
283} // namespace slang
284
zonr6315f762010-10-05 15:35:14 +0800285#endif // _SLANG_COMPILER_RS_REFLECTION_H