• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
setError(const std::string & Error)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 
clear()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 
Context(const std::string & OutputPathBase,const std::string & InputRSFile,const std::string & PackageName,const std::string & ResourceId,bool UseStdout)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 
out()129     inline std::ostream &out() const {
130       return ((mUseStdout) ? std::cout : mOF);
131     }
indent()132     inline std::ostream &indent() const {
133       out() << mIndent;
134       return out();
135     }
136 
incIndentLevel()137     inline void incIndentLevel() {
138       mIndent.append(4, ' ');
139       return;
140     }
141 
decIndentLevel()142     inline void decIndentLevel() {
143       slangAssert(getIndentLevel() > 0 && "No indent");
144       mIndent.erase(0, 4);
145       return;
146     }
147 
getIndentLevel()148     inline int getIndentLevel() { return (mIndent.length() >> 2); }
149 
getNextExportVarSlot()150     inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
151 
getNextExportFuncSlot()152     inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
getNextExportForEachSlot()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
createPaddingField()157     inline std::string createPaddingField() {
158       return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
159     }
160 
setLicenseNote(const std::string & LicenseNote)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 
getPackageName()189     inline const std::string &getPackageName() const { return mPackageName; }
getClassName()190     inline const std::string &getClassName() const { return mClassName; }
getResourceId()191     inline const std::string &getResourceId() const { return mResourceId; }
192 
193     void startTypeClass(const std::string &ClassName);
194     void endTypeClass();
195 
incFieldIndex()196     inline void incFieldIndex() { mFieldIndex++; }
197 
resetFieldIndex()198     inline void resetFieldIndex() { mFieldIndex = 0; }
199 
addFieldIndexMapping(const RSExportRecordType::Field * F)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 
getFieldIndex(const RSExportRecordType::Field * F)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 
clearFieldIndexMap()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:
RSReflection(const RSContext * Context,std::vector<std::string> * GeneratedFileNames)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 
getLastError()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