Home | History | Annotate | Download | only in slang
      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 
     32 namespace slang {
     33 
     34   class RSContext;
     35   class RSExportVar;
     36   class RSExportFunc;
     37   class RSExportForEach;
     38 
     39 class 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     std::set<std::string> mTypesToCheck;
    109 
    110     static const char *AccessModifierStr(AccessModifier AM);
    111 
    112     Context(const std::string &OutputPathBase,
    113             const std::string &InputRSFile,
    114             const std::string &PackageName,
    115             const std::string &ResourceId,
    116             const std::string &PaddingPrefix,
    117             bool UseStdout)
    118         : mVerbose(true),
    119           mOutputPathBase(OutputPathBase),
    120           mInputRSFile(InputRSFile),
    121           mPackageName(PackageName),
    122           mResourceId(ResourceId),
    123           mPaddingPrefix(PaddingPrefix),
    124           mLicenseNote(ApacheLicenseNote),
    125           mUseStdout(UseStdout) {
    126       clear();
    127       resetFieldIndex();
    128       clearFieldIndexMap();
    129       return;
    130     }
    131 
    132     inline std::ostream &out() const {
    133       return ((mUseStdout) ? std::cout : mOF);
    134     }
    135     inline std::ostream &indent() const {
    136       out() << mIndent;
    137       return out();
    138     }
    139 
    140     inline void incIndentLevel() {
    141       mIndent.append(4, ' ');
    142       return;
    143     }
    144 
    145     inline void decIndentLevel() {
    146       slangAssert(getIndentLevel() > 0 && "No indent");
    147       mIndent.erase(0, 4);
    148       return;
    149     }
    150 
    151     inline int getIndentLevel() { return (mIndent.length() >> 2); }
    152 
    153     inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
    154 
    155     inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
    156     inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }
    157 
    158     // Will remove later due to field name information is not necessary for
    159     // C-reflect-to-Java
    160     inline std::string createPaddingField() {
    161       return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
    162     }
    163 
    164     inline void setLicenseNote(const std::string &LicenseNote) {
    165       mLicenseNote = LicenseNote;
    166     }
    167 
    168     bool startClass(AccessModifier AM,
    169                     bool IsStatic,
    170                     const std::string &ClassName,
    171                     const char *SuperClassName,
    172                     std::string &ErrorMsg);
    173     void endClass();
    174 
    175     void startFunction(AccessModifier AM,
    176                        bool IsStatic,
    177                        const char *ReturnType,
    178                        const std::string &FunctionName,
    179                        int Argc, ...);
    180 
    181     typedef std::vector<std::pair<std::string, std::string> > ArgTy;
    182     void startFunction(AccessModifier AM,
    183                        bool IsStatic,
    184                        const char *ReturnType,
    185                        const std::string &FunctionName,
    186                        const ArgTy &Args);
    187     void endFunction();
    188 
    189     void startBlock(bool ShouldIndent = false);
    190     void endBlock();
    191 
    192     inline const std::string &getPackageName() const { return mPackageName; }
    193     inline const std::string &getClassName() const { return mClassName; }
    194     inline const std::string &getResourceId() const { return mResourceId; }
    195 
    196     void startTypeClass(const std::string &ClassName);
    197     void endTypeClass();
    198 
    199     inline void incFieldIndex() { mFieldIndex++; }
    200 
    201     inline void resetFieldIndex() { mFieldIndex = 0; }
    202 
    203     inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
    204       slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
    205                   "Nested structure never occurs in C language.");
    206       mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
    207     }
    208 
    209     inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
    210       FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
    211       slangAssert((I != mFieldIndexMap.end()) &&
    212                   "Requesting field is out of scope.");
    213       return I->second;
    214     }
    215 
    216     inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
    217   };
    218 
    219   bool genScriptClass(Context &C,
    220                       const std::string &ClassName,
    221                       std::string &ErrorMsg);
    222   void genScriptClassConstructor(Context &C);
    223 
    224   static void genInitBoolExportVariable(Context &C,
    225                                         const std::string &VarName,
    226                                         const clang::APValue &Val);
    227   static void genInitPrimitiveExportVariable(Context &C,
    228                                              const std::string &VarName,
    229                                              const clang::APValue &Val);
    230   static void genInitExportVariable(Context &C,
    231                                     const RSExportType *ET,
    232                                     const std::string &VarName,
    233                                     const clang::APValue &Val);
    234   static void genInitValue(Context &C, const clang::APValue &Val);
    235   void genExportVariable(Context &C, const RSExportVar *EV);
    236   void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
    237   void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
    238   void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
    239   void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
    240   void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
    241   void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
    242   void genPrivateExportVariable(Context &C,
    243                                 const std::string &TypeName,
    244                                 const std::string &VarName);
    245   void genSetExportVariable(Context &C,
    246                             const std::string &TypeName,
    247                             const RSExportVar *EV);
    248   void genGetExportVariable(Context &C,
    249                             const std::string &TypeName,
    250                             const std::string &VarName);
    251 
    252   void genExportFunction(Context &C,
    253                          const RSExportFunc *EF);
    254 
    255   void genExportForEach(Context &C,
    256                         const RSExportForEach *EF);
    257 
    258   static void genTypeCheck(Context &C,
    259                            const RSExportType *ET,
    260                            const char *VarName);
    261 
    262   static void genTypeInstanceFromPointer(Context &C,
    263                                          const RSExportType *ET);
    264 
    265   static void genTypeInstance(Context &C,
    266                               const RSExportType *ET);
    267 
    268   bool genTypeClass(Context &C,
    269                     const RSExportRecordType *ERT,
    270                     std::string &ErrorMsg);
    271   void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
    272   void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
    273   void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
    274   void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT);
    275   void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
    276   void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
    277   void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
    278   void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
    279   void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
    280   void genTypeClassResize(Context &C);
    281 
    282   void genBuildElement(Context &C,
    283                        const char *ElementBuilderName,
    284                        const RSExportRecordType *ERT,
    285                        const char *RenderScriptVar,
    286                        bool IsInline);
    287   void genAddElementToElementBuilder(Context &C,
    288                                      const RSExportType *ERT,
    289                                      const std::string &VarName,
    290                                      const char *ElementBuilderName,
    291                                      const char *RenderScriptVar,
    292                                      unsigned ArraySize);
    293   void genAddPaddingToElementBuiler(Context &C,
    294                                     int PaddingSize,
    295                                     const char *ElementBuilderName,
    296                                     const char *RenderScriptVar);
    297 
    298   bool genCreateFieldPacker(Context &C,
    299                             const RSExportType *T,
    300                             const char *FieldPackerName);
    301   void genPackVarOfType(Context &C,
    302                         const RSExportType *T,
    303                         const char *VarName,
    304                         const char *FieldPackerName);
    305   void genAllocateVarOfType(Context &C,
    306                             const RSExportType *T,
    307                             const std::string &VarName);
    308   void genNewItemBufferIfNull(Context &C, const char *Index);
    309   void genNewItemBufferPackerIfNull(Context &C);
    310 
    311  public:
    312   explicit RSReflection(const RSContext *Context,
    313       std::vector<std::string> *GeneratedFileNames)
    314       : mRSContext(Context),
    315         mLastError(""),
    316         mGeneratedFileNames(GeneratedFileNames) {
    317     slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
    318     return;
    319   }
    320 
    321   bool reflect(const std::string &OutputPathBase,
    322                const std::string &OutputPackageName,
    323                const std::string &InputFileName,
    324                const std::string &OutputBCFileName);
    325 
    326   inline const char *getLastError() const {
    327     if (mLastError.empty())
    328       return NULL;
    329     else
    330       return mLastError.c_str();
    331   }
    332 };  // class RSReflection
    333 
    334 }   // namespace slang
    335 
    336 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  NOLINT
    337