blob: 7d61b28f3aa1fbc724f7900c4ff1b8ef0056fd1c [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;
20class RSExportRecordType;
21
22class RSReflection {
23private:
24 const RSContext* mRSContext;
25
26 std::string mLastError;
27 inline void setError(const std::string& Error) { mLastError = Error; }
28
29 class Context {
30 private:
31 static const char* const LicenseNote;
32 static const char* const Import[];
33
34 bool mUseStdout;
35 mutable std::ofstream mOF;
36
37 bool mVerbose;
38
39 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
51 inline void clear() {
52 mClassName = "";
53 mIndent = "";
54 mPaddingFieldIndex = 1;
55 mNextExportVarSlot = 0;
56 mNextExportFuncSlot = 0;
57 return;
58 }
59
60 public:
61 typedef enum {
62 AM_Public,
63 AM_Protected,
64 AM_Private
65 } AccessModifier;
66
67 static const char* AccessModifierStr(AccessModifier AM);
68
69 Context(const std::string& PackageName, const std::string& ResourceId, bool UseStdout) :
70 mPackageName(PackageName),
71 mResourceId(ResourceId),
72 mUseStdout(UseStdout),
73 mVerbose(true)
74 {
75 clear();
76 return;
77 }
78
79 inline std::ostream& out() const { if(mUseStdout) return std::cout; else return mOF; }
80 inline std::ostream& indent() const {
81 out() << mIndent;
82 return out();
83 }
84
85 inline void incIndentLevel() {
86 mIndent.append(4, ' ');
87 return;
88 }
89
90 inline void decIndentLevel() {
91 assert(getIndentLevel() > 0 && "No indent");
92 mIndent.erase(0, 4);
93 return;
94 }
95
96 inline int getIndentLevel() {
97 return (mIndent.length() >> 2);
98 }
99
100 inline int getNextExportVarSlot() {
101 return mNextExportVarSlot++;
102 }
103
104 inline int getNextExportFuncSlot() {
105 return mNextExportFuncSlot++;
106 }
107
108 /* Will remove later due to field name information is not necessary for C-reflect-to-Java */
109 inline std::string createPaddingField() {
110 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
111 }
112
113 bool startClass(AccessModifier AM, bool IsStatic, const std::string& ClassName, const char* SuperClassName, std::string& ErrorMsg);
114 void endClass();
115
116 void startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, int Argc, ...);
117
118 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
119 void startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, const ArgTy& Args);
120 void endFunction();
121
122 void startBlock(bool ShouldIndent = false);
123 void endBlock();
124
125 inline const std::string& getPackageName() const { return mPackageName; }
126 inline const std::string& getClassName() const { return mClassName; }
127 inline const std::string& getResourceId() const { return mResourceId; }
128
129 void startTypeClass(const std::string& ClassName);
130 void endTypeClass();
131 };
132
133 bool genScriptClass(Context& C, const std::string& ClassName, std::string& ErrorMsg);
134 void genScriptClassConstructor(Context& C);
135
136 void genExportVariable(Context& C, const RSExportVar* EV);
137 void genPrimitiveTypeExportVariable(Context& C, const RSExportVar* EV);
138 void genPointerTypeExportVariable(Context& C, const RSExportVar* EV);
139 void genVectorTypeExportVariable(Context& C, const RSExportVar* EV);
140 void genRecordTypeExportVariable(Context& C, const RSExportVar* EV);
141 void genGetExportVariable(Context& C, const std::string& TypeName, const std::string& VarName);
142
143 void genExportFunction(Context& C, const RSExportFunc* EF);
144
145 bool genTypeClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg);
146 bool genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg);
147 void genTypeClassConstructor(Context& C, const RSExportRecordType* ERT);
148 void genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT);
149 void genTypeClasSet(Context& C, const RSExportRecordType* ERT);
150 void genTypeClasCopyAll(Context& C, const RSExportRecordType* ERT);
151
152 void genBuildElement(Context& C, const RSExportRecordType* ERT, const char* ElementName, const char* RenderScriptVar);
153 void genAddElementToElementBuilder(Context& C, const RSExportType* ERT, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar);
154 void genAddPaddingToElementBuiler(Context& C, size_t PaddingSize, const char* ElementBuilderName, const char* RenderScriptVar);
155
156 bool genCreateFieldPacker(Context& C, const RSExportType* T, const char* FieldPackerName);
157 void genPackVarOfType(Context& C, const RSExportType* T, const char* VarName, const char* FieldPackerName);
158
159public:
160 RSReflection(const RSContext* Context) :
161 mRSContext(Context),
162 mLastError("")
163 {
164 return;
165 }
166
167 bool reflect(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName);
168
169 inline const char* getLastError() const {
170 if(mLastError.empty())
171 return NULL;
172 else
173 return mLastError.c_str();
174 }
175}; /* class RSReflection */
176
177} /* namespace slang */
178
179#endif /* _SLANG_COMPILER_RS_REFLECTION_HPP */