slang_rs_reflection.h revision 66aa299de2b5e0b0c7bfae7628e29a3961247aed
1#ifndef _SLANG_COMPILER_RS_REFLECTION_H 2#define _SLANG_COMPILER_RS_REFLECTION_H 3 4#include <map> 5#include <vector> 6#include <string> 7#include <cassert> 8#include <fstream> 9#include <iostream> 10 11#include "llvm/ADT/StringExtras.h" 12 13#include "slang_rs_export_type.h" 14 15namespace slang { 16 17 class RSContext; 18 class RSExportVar; 19 class RSExportFunc; 20 21class RSReflection { 22 private: 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: 30 static const char *const ApacheLicenseNote; 31 32 static const char *const Import[]; 33 34 bool mVerbose; 35 36 std::string mInputRSFile; 37 38 std::string mPackageName; 39 std::string mResourceId; 40 41 std::string mClassName; 42 43 std::string mLicenseNote; 44 45 std::string mIndent; 46 47 int mPaddingFieldIndex; 48 49 int mNextExportVarSlot; 50 int mNextExportFuncSlot; 51 52 // 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; 58 59 inline void clear() { 60 mClassName = ""; 61 mIndent = ""; 62 mPaddingFieldIndex = 1; 63 mNextExportVarSlot = 0; 64 mNextExportFuncSlot = 0; 65 return; 66 } 67 68 public: 69 typedef enum { 70 AM_Public, 71 AM_Protected, 72 AM_Private 73 } AccessModifier; 74 75 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(); 91 resetFieldIndex(); 92 clearFieldIndexMap(); 93 return; 94 } 95 96 inline std::ostream &out() const { 97 return ((mUseStdout) ? std::cout : mOF); 98 } 99 inline std::ostream &indent() const { 100 out() << mIndent; 101 return out(); 102 } 103 104 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, 206 const std::string &VarName, 207 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: 265 explicit RSReflection(const RSContext *Context) 266 : 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 285#endif // _SLANG_COMPILER_RS_REFLECTION_H 286