blob: 80c8223f23b5315222a34e5db9cf32dc845cb696 [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;
Victor Hsiehd8a0d182010-07-07 19:22:33 +080031
Shih-wei Liao462aefd2010-06-04 15:32:04 -070032 static const char* const Import[];
33
Shih-wei Liao462aefd2010-06-04 15:32:04 -070034 bool mVerbose;
35
Ying Wang4e348442010-08-18 10:29:12 -070036 std::string mInputRSFile;
37
Shih-wei Liao462aefd2010-06-04 15:32:04 -070038 std::string mPackageName;
39 std::string mResourceId;
40
41 std::string mClassName;
42
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070043 std::string mLicenseNote;
44
Shih-wei Liao462aefd2010-06-04 15:32:04 -070045 std::string mIndent;
46
47 int mPaddingFieldIndex;
48
49 int mNextExportVarSlot;
50 int mNextExportFuncSlot;
51
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070052 /*
53 * A mapping from a field in a record type to its index in the rsType instance.
54 * Only used when generates TypeClass (ScriptField_*).
55 */
56 typedef std::map<const RSExportRecordType::Field*, unsigned> FieldIndexMapTy;
57 FieldIndexMapTy mFieldIndexMap;
58 /* Field index of current processing TypeClass. */
59 unsigned mFieldIndex;
60
Shih-wei Liao462aefd2010-06-04 15:32:04 -070061 inline void clear() {
62 mClassName = "";
63 mIndent = "";
64 mPaddingFieldIndex = 1;
65 mNextExportVarSlot = 0;
66 mNextExportFuncSlot = 0;
67 return;
68 }
69
70 public:
71 typedef enum {
72 AM_Public,
73 AM_Protected,
74 AM_Private
75 } AccessModifier;
76
Shih-wei Liao6de89272010-07-15 15:26:20 -070077 bool mUseStdout;
78 mutable std::ofstream mOF;
79
Shih-wei Liao462aefd2010-06-04 15:32:04 -070080 static const char* AccessModifierStr(AccessModifier AM);
81
Ying Wang4e348442010-08-18 10:29:12 -070082 Context(const std::string& InputRSFile, const std::string& PackageName, const std::string& ResourceId, bool UseStdout) :
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070083 mVerbose(true),
Ying Wang4e348442010-08-18 10:29:12 -070084 mInputRSFile(InputRSFile),
Shih-wei Liao462aefd2010-06-04 15:32:04 -070085 mPackageName(PackageName),
86 mResourceId(ResourceId),
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070087 mLicenseNote(ApacheLicenseNote),
88 mUseStdout(UseStdout)
Shih-wei Liao9e86e192010-06-18 20:42:28 -070089 {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070090 clear();
Shih-wei Liao9e86e192010-06-18 20:42:28 -070091 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070092 }
93
94 inline std::ostream& out() const { if(mUseStdout) return std::cout; else return mOF; }
Shih-wei Liao9e86e192010-06-18 20:42:28 -070095 inline std::ostream& indent() const {
96 out() << mIndent;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070097 return out();
98 }
99
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700100 inline void incIndentLevel() {
101 mIndent.append(4, ' ');
102 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700103 }
104
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700105 inline void decIndentLevel() {
106 assert(getIndentLevel() > 0 && "No indent");
107 mIndent.erase(0, 4);
108 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700109 }
110
111 inline int getIndentLevel() {
112 return (mIndent.length() >> 2);
113 }
114
115 inline int getNextExportVarSlot() {
116 return mNextExportVarSlot++;
117 }
118
119 inline int getNextExportFuncSlot() {
120 return mNextExportFuncSlot++;
121 }
122
123 /* Will remove later due to field name information is not necessary for C-reflect-to-Java */
124 inline std::string createPaddingField() {
125 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
126 }
127
Victor Hsiehd8a0d182010-07-07 19:22:33 +0800128 inline void setLicenseNote(const std::string& LicenseNote) {
129 mLicenseNote = LicenseNote;
130 }
131
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700132 bool startClass(AccessModifier AM, bool IsStatic, const std::string& ClassName, const char* SuperClassName, std::string& ErrorMsg);
133 void endClass();
134
135 void startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, int Argc, ...);
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700136
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700137 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
138 void startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, const ArgTy& Args);
139 void endFunction();
140
141 void startBlock(bool ShouldIndent = false);
142 void endBlock();
143
144 inline const std::string& getPackageName() const { return mPackageName; }
145 inline const std::string& getClassName() const { return mClassName; }
146 inline const std::string& getResourceId() const { return mResourceId; }
147
148 void startTypeClass(const std::string& ClassName);
149 void endTypeClass();
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700150
151 inline void incFieldIndex() {
152 mFieldIndex++;
153 }
154
155 inline void resetFieldIndex() {
156 mFieldIndex = 0;
157 }
158
159 inline void addFieldIndexMapping(const RSExportRecordType::Field* F) {
160 assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) && "Nested structure never occurs in C language.");
161 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
162 }
163
164 inline unsigned getFieldIndex(const RSExportRecordType::Field* F) const {
165 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
166 assert((I != mFieldIndexMap.end()) && "Requesting field is out of scope.");
167 return I->second;
168 }
169
170 inline void clearFieldIndexMap() {
171 mFieldIndexMap.clear();
172 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700173 };
174
Shih-wei Liao8b1d0dd2010-07-15 18:56:55 -0700175 bool openScriptFile(Context& C, const std::string& ClassName, std::string& ErrorMsg);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700176 bool genScriptClass(Context& C, const std::string& ClassName, std::string& ErrorMsg);
177 void genScriptClassConstructor(Context& C);
178
Shih-wei Liao48bac232010-07-03 22:29:41 -0700179 void genInitBoolExportVariable(Context& C, const std::string& VarName, const APValue& Val);
Shih-wei Liao324c0472010-06-21 13:15:11 -0700180 void genInitPrimitiveExportVariable(Context& C, const std::string& VarName, const APValue& Val);
181 void genInitExportVariable(Context& C, const RSExportType* ET, const std::string& VarName, const APValue& Val);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700182 void genExportVariable(Context& C, const RSExportVar* EV);
183 void genPrimitiveTypeExportVariable(Context& C, const RSExportVar* EV);
184 void genPointerTypeExportVariable(Context& C, const RSExportVar* EV);
185 void genVectorTypeExportVariable(Context& C, const RSExportVar* EV);
186 void genRecordTypeExportVariable(Context& C, const RSExportVar* EV);
187 void genGetExportVariable(Context& C, const std::string& TypeName, const std::string& VarName);
188
189 void genExportFunction(Context& C, const RSExportFunc* EF);
190
191 bool genTypeClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg);
192 bool genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg);
193 void genTypeClassConstructor(Context& C, const RSExportRecordType* ERT);
194 void genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT);
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700195 void genTypeClassItemSetter(Context& C, const RSExportRecordType* ERT);
196 void genTypeClassItemGetter(Context& C, const RSExportRecordType* ERT);
197 void genTypeClassComponentSetter(Context& C, const RSExportRecordType* ERT);
198 void genTypeClassComponentGetter(Context& C, const RSExportRecordType* ERT);
199 void genTypeClassCopyAll(Context& C, const RSExportRecordType* ERT);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700200
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700201 void genBuildElement(Context& C, const RSExportRecordType* ERT, const char* RenderScriptVar);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700202 void genAddElementToElementBuilder(Context& C, const RSExportType* ERT, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar);
203 void genAddPaddingToElementBuiler(Context& C, size_t PaddingSize, const char* ElementBuilderName, const char* RenderScriptVar);
204
205 bool genCreateFieldPacker(Context& C, const RSExportType* T, const char* FieldPackerName);
206 void genPackVarOfType(Context& C, const RSExportType* T, const char* VarName, const char* FieldPackerName);
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700207 void genNewItemBufferIfNull(Context& C, const char* Index);
208 void genNewItemBufferPackerIfNull(Context& C);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700209
210public:
211 RSReflection(const RSContext* Context) :
212 mRSContext(Context),
213 mLastError("")
214 {
215 return;
216 }
217
218 bool reflect(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName);
219
220 inline const char* getLastError() const {
221 if(mLastError.empty())
222 return NULL;
223 else
224 return mLastError.c_str();
225 }
226}; /* class RSReflection */
227
228} /* namespace slang */
229
230#endif /* _SLANG_COMPILER_RS_REFLECTION_HPP */