slang_rs_reflection.h revision 6315f76e3cc6ff2d012d1183a0b030d4ff0dc808
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 return; 92 } 93 94 inline std::ostream &out() const { 95 return ((mUseStdout) ? std::cout : mOF); 96 } 97 inline std::ostream &indent() const { 98 out() << mIndent; 99 return out(); 100 } 101 102 inline void incIndentLevel() { 103 mIndent.append(4, ' '); 104 return; 105 } 106 107 inline void decIndentLevel() { 108 assert(getIndentLevel() > 0 && "No indent"); 109 mIndent.erase(0, 4); 110 return; 111 } 112 113 inline int getIndentLevel() { 114 return (mIndent.length() >> 2); 115 } 116 117 inline int getNextExportVarSlot() { 118 return mNextExportVarSlot++; 119 } 120 121 inline int getNextExportFuncSlot() { 122 return mNextExportFuncSlot++; 123 } 124 125 // Will remove later due to field name information is not necessary for 126 // C-reflect-to-Java 127 inline std::string createPaddingField() { 128 return "#padding_" + llvm::itostr(mPaddingFieldIndex++); 129 } 130 131 inline void setLicenseNote(const std::string &LicenseNote) { 132 mLicenseNote = LicenseNote; 133 } 134 135 bool startClass(AccessModifier AM, 136 bool IsStatic, 137 const std::string &ClassName, 138 const char *SuperClassName, 139 std::string &ErrorMsg); 140 void endClass(); 141 142 void startFunction(AccessModifier AM, 143 bool IsStatic, 144 const char *ReturnType, 145 const std::string &FunctionName, 146 int Argc, ...); 147 148 typedef std::vector<std::pair<std::string, std::string> > ArgTy; 149 void startFunction(AccessModifier AM, 150 bool IsStatic, 151 const char *ReturnType, 152 const std::string &FunctionName, 153 const ArgTy &Args); 154 void endFunction(); 155 156 void startBlock(bool ShouldIndent = false); 157 void endBlock(); 158 159 inline const std::string &getPackageName() const { return mPackageName; } 160 inline const std::string &getClassName() const { return mClassName; } 161 inline const std::string &getResourceId() const { return mResourceId; } 162 163 void startTypeClass(const std::string &ClassName); 164 void endTypeClass(); 165 166 inline void incFieldIndex() { 167 mFieldIndex++; 168 } 169 170 inline void resetFieldIndex() { 171 mFieldIndex = 0; 172 } 173 174 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) { 175 assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) && 176 "Nested structure never occurs in C language."); 177 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex)); 178 } 179 180 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const { 181 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F); 182 assert((I != mFieldIndexMap.end()) && 183 "Requesting field is out of scope."); 184 return I->second; 185 } 186 187 inline void clearFieldIndexMap() { 188 mFieldIndexMap.clear(); 189 } 190 }; 191 192 bool openScriptFile(Context &C, 193 const std::string &ClassName, 194 std::string &ErrorMsg); 195 bool genScriptClass(Context &C, 196 const std::string &ClassName, 197 std::string &ErrorMsg); 198 void genScriptClassConstructor(Context &C); 199 200 void genInitBoolExportVariable(Context &C, 201 const std::string &VarName, 202 const clang::APValue &Val); 203 void genInitPrimitiveExportVariable(Context &C, 204 const std::string &VarName, 205 const clang::APValue &Val); 206 void genInitExportVariable(Context &C, 207 const RSExportType *ET, 208 const std::string &VarName, 209 const clang::APValue &Val); 210 void genExportVariable(Context &C, const RSExportVar *EV); 211 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV); 212 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV); 213 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV); 214 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV); 215 void genGetExportVariable(Context &C, 216 const std::string &TypeName, 217 const std::string &VarName); 218 219 void genExportFunction(Context &C, 220 const RSExportFunc *EF); 221 222 bool genTypeClass(Context &C, 223 const RSExportRecordType *ERT, 224 std::string &ErrorMsg); 225 bool genTypeItemClass(Context &C, 226 const RSExportRecordType *ERT, 227 std::string &ErrorMsg); 228 void genTypeClassConstructor(Context &C, 229 const RSExportRecordType *ERT); 230 void genTypeClassCopyToArray(Context &C, 231 const RSExportRecordType *ERT); 232 void genTypeClassItemSetter(Context &C, 233 const RSExportRecordType *ERT); 234 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT); 235 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT); 236 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT); 237 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT); 238 239 void genBuildElement(Context &C, 240 const RSExportRecordType *ERT, 241 const char *RenderScriptVar); 242 void genAddElementToElementBuilder(Context &C, 243 const RSExportType *ERT, 244 const std::string &VarName, 245 const char *ElementBuilderName, 246 const char *RenderScriptVar); 247 void genAddPaddingToElementBuiler(Context &C, 248 int PaddingSize, 249 const char *ElementBuilderName, 250 const char *RenderScriptVar); 251 252 bool genCreateFieldPacker(Context &C, 253 const RSExportType *T, 254 const char *FieldPackerName); 255 void genPackVarOfType(Context &C, 256 const RSExportType *T, 257 const char *VarName, 258 const char *FieldPackerName); 259 void genNewItemBufferIfNull(Context &C, const char *Index); 260 void genNewItemBufferPackerIfNull(Context &C); 261 262 public: 263 explicit RSReflection(const RSContext *Context) 264 : mRSContext(Context), 265 mLastError("") { 266 return; 267 } 268 269 bool reflect(const char *OutputPackageName, 270 const std::string &InputFileName, 271 const std::string &OutputBCFileName); 272 273 inline const char *getLastError() const { 274 if (mLastError.empty()) 275 return NULL; 276 else 277 return mLastError.c_str(); 278 } 279}; // class RSReflection 280 281} // namespace slang 282 283#endif // _SLANG_COMPILER_RS_REFLECTION_H 284