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