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