slang_rs_reflection.h revision 1f6c331d622ac645ab68a016aa4c577998547373
1/* 2 * Copyright 2010-2011, 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 <set> 24#include <string> 25#include <vector> 26 27#include "llvm/ADT/StringExtras.h" 28 29#include "slang_assert.h" 30#include "slang_rs_export_type.h" 31 32namespace slang { 33 34 class RSContext; 35 class RSExportVar; 36 class RSExportFunc; 37 class RSExportForEach; 38 39class RSReflection { 40 private: 41 const RSContext *mRSContext; 42 43 std::string mLastError; 44 std::vector<std::string> *mGeneratedFileNames; 45 46 inline void setError(const std::string &Error) { mLastError = Error; } 47 48 class Context { 49 private: 50 static const char *const ApacheLicenseNote; 51 52 static const char *const Import[]; 53 54 bool mVerbose; 55 56 std::string mOutputPathBase; 57 58 std::string mInputRSFile; 59 60 std::string mPackageName; 61 std::string mResourceId; 62 std::string mPaddingPrefix; 63 64 std::string mClassName; 65 66 std::string mLicenseNote; 67 68 std::string mIndent; 69 70 int mPaddingFieldIndex; 71 72 int mNextExportVarSlot; 73 int mNextExportFuncSlot; 74 int mNextExportForEachSlot; 75 76 // A mapping from a field in a record type to its index in the rsType 77 // instance. Only used when generates TypeClass (ScriptField_*). 78 typedef std::map<const RSExportRecordType::Field*, unsigned> 79 FieldIndexMapTy; 80 FieldIndexMapTy mFieldIndexMap; 81 // Field index of current processing TypeClass. 82 unsigned mFieldIndex; 83 84 inline void clear() { 85 mClassName = ""; 86 mIndent = ""; 87 mPaddingFieldIndex = 1; 88 mNextExportVarSlot = 0; 89 mNextExportFuncSlot = 0; 90 mNextExportForEachSlot = 0; 91 return; 92 } 93 94 bool openClassFile(const std::string &ClassName, 95 std::string &ErrorMsg); 96 97 public: 98 typedef enum { 99 AM_Public, 100 AM_Protected, 101 AM_Private, 102 AM_PublicSynchronized 103 } AccessModifier; 104 105 bool mUseStdout; 106 mutable std::ofstream mOF; 107 108 // Generated RS Elements for type-checking code. 109 std::set<std::string> mTypesToCheck; 110 111 // Generated FieldPackers for unsigned setters/validation. 112 std::set<std::string> mFieldPackerTypes; 113 114 bool addTypeNameForElement(const std::string &TypeName); 115 bool addTypeNameForFieldPacker(const std::string &TypeName); 116 117 static const char *AccessModifierStr(AccessModifier AM); 118 119 Context(const std::string &OutputPathBase, 120 const std::string &InputRSFile, 121 const std::string &PackageName, 122 const std::string &ResourceId, 123 const std::string &PaddingPrefix, 124 bool UseStdout) 125 : mVerbose(true), 126 mOutputPathBase(OutputPathBase), 127 mInputRSFile(InputRSFile), 128 mPackageName(PackageName), 129 mResourceId(ResourceId), 130 mPaddingPrefix(PaddingPrefix), 131 mLicenseNote(ApacheLicenseNote), 132 mUseStdout(UseStdout) { 133 clear(); 134 resetFieldIndex(); 135 clearFieldIndexMap(); 136 return; 137 } 138 139 inline std::ostream &out() const { 140 return ((mUseStdout) ? std::cout : mOF); 141 } 142 inline std::ostream &indent() const { 143 out() << mIndent; 144 return out(); 145 } 146 147 inline void incIndentLevel() { 148 mIndent.append(4, ' '); 149 return; 150 } 151 152 inline void decIndentLevel() { 153 slangAssert(getIndentLevel() > 0 && "No indent"); 154 mIndent.erase(0, 4); 155 return; 156 } 157 158 inline int getIndentLevel() { return (mIndent.length() >> 2); } 159 160 inline int getNextExportVarSlot() { return mNextExportVarSlot++; } 161 162 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; } 163 inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; } 164 165 // Will remove later due to field name information is not necessary for 166 // C-reflect-to-Java 167 inline std::string createPaddingField() { 168 return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++); 169 } 170 171 inline void setLicenseNote(const std::string &LicenseNote) { 172 mLicenseNote = LicenseNote; 173 } 174 175 bool startClass(AccessModifier AM, 176 bool IsStatic, 177 const std::string &ClassName, 178 const char *SuperClassName, 179 std::string &ErrorMsg); 180 void endClass(); 181 182 void startFunction(AccessModifier AM, 183 bool IsStatic, 184 const char *ReturnType, 185 const std::string &FunctionName, 186 int Argc, ...); 187 188 typedef std::vector<std::pair<std::string, std::string> > ArgTy; 189 void startFunction(AccessModifier AM, 190 bool IsStatic, 191 const char *ReturnType, 192 const std::string &FunctionName, 193 const ArgTy &Args); 194 void endFunction(); 195 196 void startBlock(bool ShouldIndent = false); 197 void endBlock(); 198 199 inline const std::string &getPackageName() const { return mPackageName; } 200 inline const std::string &getClassName() const { return mClassName; } 201 inline const std::string &getResourceId() const { return mResourceId; } 202 203 void startTypeClass(const std::string &ClassName); 204 void endTypeClass(); 205 206 inline void incFieldIndex() { mFieldIndex++; } 207 208 inline void resetFieldIndex() { mFieldIndex = 0; } 209 210 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) { 211 slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) && 212 "Nested structure never occurs in C language."); 213 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex)); 214 } 215 216 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const { 217 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F); 218 slangAssert((I != mFieldIndexMap.end()) && 219 "Requesting field is out of scope."); 220 return I->second; 221 } 222 223 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); } 224 }; 225 226 bool genScriptClass(Context &C, 227 const std::string &ClassName, 228 std::string &ErrorMsg); 229 void genScriptClassConstructor(Context &C); 230 231 static void genInitBoolExportVariable(Context &C, 232 const std::string &VarName, 233 const clang::APValue &Val); 234 static void genInitPrimitiveExportVariable(Context &C, 235 const std::string &VarName, 236 const clang::APValue &Val); 237 static void genInitExportVariable(Context &C, 238 const RSExportType *ET, 239 const std::string &VarName, 240 const clang::APValue &Val); 241 static void genInitValue(Context &C, const clang::APValue &Val); 242 void genExportVariable(Context &C, const RSExportVar *EV); 243 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV); 244 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV); 245 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV); 246 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV); 247 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV); 248 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV); 249 void genPrivateExportVariable(Context &C, 250 const std::string &TypeName, 251 const std::string &VarName); 252 void genSetExportVariable(Context &C, 253 const std::string &TypeName, 254 const RSExportVar *EV); 255 void genGetExportVariable(Context &C, 256 const std::string &TypeName, 257 const std::string &VarName); 258 259 void genExportFunction(Context &C, 260 const RSExportFunc *EF); 261 262 void genExportForEach(Context &C, 263 const RSExportForEach *EF); 264 265 static void genTypeCheck(Context &C, 266 const RSExportType *ET, 267 const char *VarName); 268 269 static void genTypeInstanceFromPointer(Context &C, 270 const RSExportType *ET); 271 272 static void genTypeInstance(Context &C, 273 const RSExportType *ET); 274 275 static void genFieldPackerInstance(Context &C, 276 const RSExportType *ET); 277 278 bool genTypeClass(Context &C, 279 const RSExportRecordType *ERT, 280 std::string &ErrorMsg); 281 void genTypeItemClass(Context &C, const RSExportRecordType *ERT); 282 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT); 283 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT); 284 void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT); 285 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT); 286 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT); 287 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT); 288 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT); 289 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT); 290 void genTypeClassResize(Context &C); 291 292 void genBuildElement(Context &C, 293 const char *ElementBuilderName, 294 const RSExportRecordType *ERT, 295 const char *RenderScriptVar, 296 bool IsInline); 297 void genAddElementToElementBuilder(Context &C, 298 const RSExportType *ERT, 299 const std::string &VarName, 300 const char *ElementBuilderName, 301 const char *RenderScriptVar, 302 unsigned ArraySize); 303 void genAddPaddingToElementBuiler(Context &C, 304 int PaddingSize, 305 const char *ElementBuilderName, 306 const char *RenderScriptVar); 307 308 bool genCreateFieldPacker(Context &C, 309 const RSExportType *T, 310 const char *FieldPackerName); 311 void genPackVarOfType(Context &C, 312 const RSExportType *T, 313 const char *VarName, 314 const char *FieldPackerName); 315 void genAllocateVarOfType(Context &C, 316 const RSExportType *T, 317 const std::string &VarName); 318 void genNewItemBufferIfNull(Context &C, const char *Index); 319 void genNewItemBufferPackerIfNull(Context &C); 320 321 public: 322 explicit RSReflection(const RSContext *Context, 323 std::vector<std::string> *GeneratedFileNames) 324 : mRSContext(Context), 325 mLastError(""), 326 mGeneratedFileNames(GeneratedFileNames) { 327 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames"); 328 return; 329 } 330 331 bool reflect(const std::string &OutputPathBase, 332 const std::string &OutputPackageName, 333 const std::string &InputFileName, 334 const std::string &OutputBCFileName); 335 336 inline const char *getLastError() const { 337 if (mLastError.empty()) 338 return NULL; 339 else 340 return mLastError.c_str(); 341 } 342}; // class RSReflection 343 344} // namespace slang 345 346#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT 347