blob: dc92dcdc971570149cd90167f7df657fafda76c6 [file] [log] [blame]
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001#ifndef _SLANG_COMPILER_RS_REFLECTION_HPP
2# define _SLANG_COMPILER_RS_REFLECTION_HPP
3
4#include <map>
5#include <vector>
6#include <string>
7#include <cassert>
8#include <fstream>
9#include <iostream>
10
11#include "slang_rs_export_type.hpp"
12
13#include "llvm/ADT/StringExtras.h" /* for function llvm::utostr_32() and llvm::itostr() */
14
15namespace slang {
16
17class RSContext;
18class RSExportVar;
19class RSExportFunc;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020
21class RSReflection {
22private:
23 const RSContext* mRSContext;
24
25 std::string mLastError;
26 inline void setError(const std::string& Error) { mLastError = Error; }
27
28 class Context {
29 private:
Victor Hsiehd8a0d182010-07-07 19:22:33 +080030 static const char* const ApacheLicenseNote;
31 std::string mLicenseNote;
32
Shih-wei Liao462aefd2010-06-04 15:32:04 -070033 static const char* const Import[];
34
Shih-wei Liao462aefd2010-06-04 15:32:04 -070035 bool mVerbose;
36
Ying Wang4e348442010-08-18 10:29:12 -070037 std::string mInputRSFile;
38
Shih-wei Liao462aefd2010-06-04 15:32:04 -070039 std::string mPackageName;
40 std::string mResourceId;
41
42 std::string mClassName;
43
44 std::string mIndent;
45
46 int mPaddingFieldIndex;
47
48 int mNextExportVarSlot;
49 int mNextExportFuncSlot;
50
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070051 /*
52 * A mapping from a field in a record type to its index in the rsType instance.
53 * Only used when generates TypeClass (ScriptField_*).
54 */
55 typedef std::map<const RSExportRecordType::Field*, unsigned> FieldIndexMapTy;
56 FieldIndexMapTy mFieldIndexMap;
57 /* Field index of current processing TypeClass. */
58 unsigned mFieldIndex;
59
Shih-wei Liao462aefd2010-06-04 15:32:04 -070060 inline void clear() {
61 mClassName = "";
62 mIndent = "";
63 mPaddingFieldIndex = 1;
64 mNextExportVarSlot = 0;
65 mNextExportFuncSlot = 0;
66 return;
67 }
68
69 public:
70 typedef enum {
71 AM_Public,
72 AM_Protected,
73 AM_Private
74 } AccessModifier;
75
Shih-wei Liao6de89272010-07-15 15:26:20 -070076 bool mUseStdout;
77 mutable std::ofstream mOF;
78
Shih-wei Liao462aefd2010-06-04 15:32:04 -070079 static const char* AccessModifierStr(AccessModifier AM);
80
Ying Wang4e348442010-08-18 10:29:12 -070081 Context(const std::string& InputRSFile, const std::string& PackageName, const std::string& ResourceId, bool UseStdout) :
Victor Hsiehd8a0d182010-07-07 19:22:33 +080082 mLicenseNote(ApacheLicenseNote),
Ying Wang4e348442010-08-18 10:29:12 -070083 mInputRSFile(InputRSFile),
Shih-wei Liao462aefd2010-06-04 15:32:04 -070084 mPackageName(PackageName),
85 mResourceId(ResourceId),
86 mUseStdout(UseStdout),
87 mVerbose(true)
Shih-wei Liao9e86e192010-06-18 20:42:28 -070088 {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070089 clear();
Shih-wei Liao9e86e192010-06-18 20:42:28 -070090 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070091 }
92
93 inline std::ostream& out() const { if(mUseStdout) return std::cout; else return mOF; }
Shih-wei Liao9e86e192010-06-18 20:42:28 -070094 inline std::ostream& indent() const {
95 out() << mIndent;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070096 return out();
97 }
98
Shih-wei Liao9e86e192010-06-18 20:42:28 -070099 inline void incIndentLevel() {
100 mIndent.append(4, ' ');
101 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700102 }
103
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700104 inline void decIndentLevel() {
105 assert(getIndentLevel() > 0 && "No indent");
106 mIndent.erase(0, 4);
107 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700108 }
109
110 inline int getIndentLevel() {
111 return (mIndent.length() >> 2);
112 }
113
114 inline int getNextExportVarSlot() {
115 return mNextExportVarSlot++;
116 }
117
118 inline int getNextExportFuncSlot() {
119 return mNextExportFuncSlot++;
120 }
121
122 /* Will remove later due to field name information is not necessary for C-reflect-to-Java */
123 inline std::string createPaddingField() {
124 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
125 }
126
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800127 inline void setLicenseNote(const std::string& LicenseNote) {
128 mLicenseNote = LicenseNote;
129 }
130
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700131 bool startClass(AccessModifier AM, bool IsStatic, const std::string& ClassName, const char* SuperClassName, std::string& ErrorMsg);
132 void endClass();
133
134 void startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, int Argc, ...);
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700135
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700136 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
137 void startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, const ArgTy& Args);
138 void endFunction();
139
140 void startBlock(bool ShouldIndent = false);
141 void endBlock();
142
143 inline const std::string& getPackageName() const { return mPackageName; }
144 inline const std::string& getClassName() const { return mClassName; }
145 inline const std::string& getResourceId() const { return mResourceId; }
146
147 void startTypeClass(const std::string& ClassName);
148 void endTypeClass();
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700149
150 inline void incFieldIndex() {
151 mFieldIndex++;
152 }
153
154 inline void resetFieldIndex() {
155 mFieldIndex = 0;
156 }
157
158 inline void addFieldIndexMapping(const RSExportRecordType::Field* F) {
159 assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) && "Nested structure never occurs in C language.");
160 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
161 }
162
163 inline unsigned getFieldIndex(const RSExportRecordType::Field* F) const {
164 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
165 assert((I != mFieldIndexMap.end()) && "Requesting field is out of scope.");
166 return I->second;
167 }
168
169 inline void clearFieldIndexMap() {
170 mFieldIndexMap.clear();
171 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700172 };
173
Shih-wei Liao8b1d0dd2010-07-15 18:56:55 -0700174 bool openScriptFile(Context& C, const std::string& ClassName, std::string& ErrorMsg);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700175 bool genScriptClass(Context& C, const std::string& ClassName, std::string& ErrorMsg);
176 void genScriptClassConstructor(Context& C);
177
Shih-wei Liao48bac232010-07-03 22:29:41 -0700178 void genInitBoolExportVariable(Context& C, const std::string& VarName, const APValue& Val);
Shih-wei Liao324c0472010-06-21 13:15:11 -0700179 void genInitPrimitiveExportVariable(Context& C, const std::string& VarName, const APValue& Val);
180 void genInitExportVariable(Context& C, const RSExportType* ET, const std::string& VarName, const APValue& Val);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700181 void genExportVariable(Context& C, const RSExportVar* EV);
182 void genPrimitiveTypeExportVariable(Context& C, const RSExportVar* EV);
183 void genPointerTypeExportVariable(Context& C, const RSExportVar* EV);
184 void genVectorTypeExportVariable(Context& C, const RSExportVar* EV);
185 void genRecordTypeExportVariable(Context& C, const RSExportVar* EV);
186 void genGetExportVariable(Context& C, const std::string& TypeName, const std::string& VarName);
187
188 void genExportFunction(Context& C, const RSExportFunc* EF);
189
190 bool genTypeClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg);
191 bool genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg);
192 void genTypeClassConstructor(Context& C, const RSExportRecordType* ERT);
193 void genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT);
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700194 void genTypeClassItemSetter(Context& C, const RSExportRecordType* ERT);
195 void genTypeClassItemGetter(Context& C, const RSExportRecordType* ERT);
196 void genTypeClassComponentSetter(Context& C, const RSExportRecordType* ERT);
197 void genTypeClassComponentGetter(Context& C, const RSExportRecordType* ERT);
198 void genTypeClassCopyAll(Context& C, const RSExportRecordType* ERT);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700199
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700200 void genBuildElement(Context& C, const RSExportRecordType* ERT, const char* RenderScriptVar);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700201 void genAddElementToElementBuilder(Context& C, const RSExportType* ERT, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar);
202 void genAddPaddingToElementBuiler(Context& C, size_t PaddingSize, const char* ElementBuilderName, const char* RenderScriptVar);
203
204 bool genCreateFieldPacker(Context& C, const RSExportType* T, const char* FieldPackerName);
205 void genPackVarOfType(Context& C, const RSExportType* T, const char* VarName, const char* FieldPackerName);
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700206 void genNewItemBufferIfNull(Context& C, const char* Index);
207 void genNewItemBufferPackerIfNull(Context& C);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700208
209public:
210 RSReflection(const RSContext* Context) :
211 mRSContext(Context),
212 mLastError("")
213 {
214 return;
215 }
216
217 bool reflect(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName);
218
219 inline const char* getLastError() const {
220 if(mLastError.empty())
221 return NULL;
222 else
223 return mLastError.c_str();
224 }
225}; /* class RSReflection */
226
227} /* namespace slang */
228
229#endif /* _SLANG_COMPILER_RS_REFLECTION_HPP */