slang_rs_reflection.h revision b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5d
1/* 2 * Copyright 2010, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ // NOLINT 18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ 19 20#include <fstream> 21#include <iostream> 22#include <map> 23#include <string> 24#include <vector> 25 26#include "llvm/ADT/StringExtras.h" 27 28#include "slang_assert.h" 29#include "slang_rs_export_type.h" 30 31namespace slang { 32 33 class RSContext; 34 class RSExportVar; 35 class RSExportFunc; 36 class RSExportForEach; 37 38class RSReflection { 39 private: 40 const RSContext *mRSContext; 41 42 std::string mLastError; 43 std::vector<std::string> *mGeneratedFileNames; 44 45 inline void setError(const std::string &Error) { mLastError = Error; } 46 47 class Context { 48 private: 49 static const char *const ApacheLicenseNote; 50 51 static const char *const Import[]; 52 53 bool mVerbose; 54 55 std::string mOutputPathBase; 56 57 std::string mInputRSFile; 58 59 std::string mPackageName; 60 std::string mResourceId; 61 62 std::string mClassName; 63 64 std::string mLicenseNote; 65 66 std::string mIndent; 67 68 int mPaddingFieldIndex; 69 70 int mNextExportVarSlot; 71 int mNextExportFuncSlot; 72 int mNextExportForEachSlot; 73 74 // A mapping from a field in a record type to its index in the rsType 75 // instance. Only used when generates TypeClass (ScriptField_*). 76 typedef std::map<const RSExportRecordType::Field*, unsigned> 77 FieldIndexMapTy; 78 FieldIndexMapTy mFieldIndexMap; 79 // Field index of current processing TypeClass. 80 unsigned mFieldIndex; 81 82 inline void clear() { 83 mClassName = ""; 84 mIndent = ""; 85 mPaddingFieldIndex = 1; 86 mNextExportVarSlot = 0; 87 mNextExportFuncSlot = 0; 88 mNextExportForEachSlot = 0; 89 return; 90 } 91 92 bool openClassFile(const std::string &ClassName, 93 std::string &ErrorMsg); 94 95 public: 96 typedef enum { 97 AM_Public, 98 AM_Protected, 99 AM_Private 100 } AccessModifier; 101 102 bool mUseStdout; 103 mutable std::ofstream mOF; 104 105 static const char *AccessModifierStr(AccessModifier AM); 106 107 Context(const std::string &OutputPathBase, 108 const std::string &InputRSFile, 109 const std::string &PackageName, 110 const std::string &ResourceId, 111 bool UseStdout) 112 : mVerbose(true), 113 mOutputPathBase(OutputPathBase), 114 mInputRSFile(InputRSFile), 115 mPackageName(PackageName), 116 mResourceId(ResourceId), 117 mLicenseNote(ApacheLicenseNote), 118 mUseStdout(UseStdout) { 119 clear(); 120 resetFieldIndex(); 121 clearFieldIndexMap(); 122 return; 123 } 124 125 inline std::ostream &out() const { 126 return ((mUseStdout) ? std::cout : mOF); 127 } 128 inline std::ostream &indent() const { 129 out() << mIndent; 130 return out(); 131 } 132 133 inline void incIndentLevel() { 134 mIndent.append(4, ' '); 135 return; 136 } 137 138 inline void decIndentLevel() { 139 slangAssert(getIndentLevel() > 0 && "No indent"); 140 mIndent.erase(0, 4); 141 return; 142 } 143 144 inline int getIndentLevel() { return (mIndent.length() >> 2); } 145 146 inline int getNextExportVarSlot() { return mNextExportVarSlot++; } 147 148 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; } 149 inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; } 150 151 // Will remove later due to field name information is not necessary for 152 // C-reflect-to-Java 153 inline std::string createPaddingField() { 154 return "#padding_" + llvm::itostr(mPaddingFieldIndex++); 155 } 156 157 inline void setLicenseNote(const std::string &LicenseNote) { 158 mLicenseNote = LicenseNote; 159 } 160 161 bool startClass(AccessModifier AM, 162 bool IsStatic, 163 const std::string &ClassName, 164 const char *SuperClassName, 165 std::string &ErrorMsg); 166 void endClass(); 167 168 void startFunction(AccessModifier AM, 169 bool IsStatic, 170 const char *ReturnType, 171 const std::string &FunctionName, 172 int Argc, ...); 173 174 typedef std::vector<std::pair<std::string, std::string> > ArgTy; 175 void startFunction(AccessModifier AM, 176 bool IsStatic, 177 const char *ReturnType, 178 const std::string &FunctionName, 179 const ArgTy &Args); 180 void endFunction(); 181 182 void startBlock(bool ShouldIndent = false); 183 void endBlock(); 184 185 inline const std::string &getPackageName() const { return mPackageName; } 186 inline const std::string &getClassName() const { return mClassName; } 187 inline const std::string &getResourceId() const { return mResourceId; } 188 189 void startTypeClass(const std::string &ClassName); 190 void endTypeClass(); 191 192 inline void incFieldIndex() { mFieldIndex++; } 193 194 inline void resetFieldIndex() { mFieldIndex = 0; } 195 196 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) { 197 slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) && 198 "Nested structure never occurs in C language."); 199 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex)); 200 } 201 202 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const { 203 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F); 204 slangAssert((I != mFieldIndexMap.end()) && 205 "Requesting field is out of scope."); 206 return I->second; 207 } 208 209 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); } 210 }; 211 212 bool genScriptClass(Context &C, 213 const std::string &ClassName, 214 std::string &ErrorMsg); 215 void genScriptClassConstructor(Context &C); 216 217 void genInitBoolExportVariable(Context &C, 218 const std::string &VarName, 219 const clang::APValue &Val); 220 void genInitPrimitiveExportVariable(Context &C, 221 const std::string &VarName, 222 const clang::APValue &Val); 223 void genInitExportVariable(Context &C, 224 const RSExportType *ET, 225 const std::string &VarName, 226 const clang::APValue &Val); 227 void genExportVariable(Context &C, const RSExportVar *EV); 228 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV); 229 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV); 230 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV); 231 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV); 232 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV); 233 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV); 234 void genGetExportVariable(Context &C, 235 const std::string &TypeName, 236 const std::string &VarName); 237 238 void genExportFunction(Context &C, 239 const RSExportFunc *EF); 240 241 void genExportForEach(Context &C, 242 const RSExportForEach *EF); 243 244 void genTypeCheck(Context &C, 245 const RSExportType *ET, 246 const char *VarName); 247 248 bool genTypeClass(Context &C, 249 const RSExportRecordType *ERT, 250 std::string &ErrorMsg); 251 void genTypeItemClass(Context &C, const RSExportRecordType *ERT); 252 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT); 253 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT); 254 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT); 255 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT); 256 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT); 257 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT); 258 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT); 259 void genTypeClassResize(Context &C); 260 261 void genBuildElement(Context &C, 262 const char *ElementBuilderName, 263 const RSExportRecordType *ERT, 264 const char *RenderScriptVar, 265 bool IsInline); 266 void genAddElementToElementBuilder(Context &C, 267 const RSExportType *ERT, 268 const std::string &VarName, 269 const char *ElementBuilderName, 270 const char *RenderScriptVar, 271 unsigned ArraySize); 272 void genAddPaddingToElementBuiler(Context &C, 273 int PaddingSize, 274 const char *ElementBuilderName, 275 const char *RenderScriptVar); 276 277 bool genCreateFieldPacker(Context &C, 278 const RSExportType *T, 279 const char *FieldPackerName); 280 void genPackVarOfType(Context &C, 281 const RSExportType *T, 282 const char *VarName, 283 const char *FieldPackerName); 284 void genAllocateVarOfType(Context &C, 285 const RSExportType *T, 286 const std::string &VarName); 287 void genNewItemBufferIfNull(Context &C, const char *Index); 288 void genNewItemBufferPackerIfNull(Context &C); 289 290 public: 291 explicit RSReflection(const RSContext *Context, 292 std::vector<std::string> *GeneratedFileNames) 293 : mRSContext(Context), 294 mLastError(""), 295 mGeneratedFileNames(GeneratedFileNames) { 296 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames"); 297 return; 298 } 299 300 bool reflect(const std::string &OutputPathBase, 301 const std::string &OutputPackageName, 302 const std::string &InputFileName, 303 const std::string &OutputBCFileName); 304 305 inline const char *getLastError() const { 306 if (mLastError.empty()) 307 return NULL; 308 else 309 return mLastError.c_str(); 310 } 311}; // class RSReflection 312 313} // namespace slang 314 315#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT 316