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