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