• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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     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 
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     // 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 
Context(const std::string & OutputPathBase,const std::string & InputRSFile,const std::string & PackageName,const std::string & RSPackageName,const std::string & ResourceId,const std::string & PaddingPrefix,bool UseStdout)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 
out()140     inline std::ostream &out() const {
141       return ((mUseStdout) ? std::cout : mOF);
142     }
indent()143     inline std::ostream &indent() const {
144       out() << mIndent;
145       return out();
146     }
147 
incIndentLevel()148     inline void incIndentLevel() {
149       mIndent.append(4, ' ');
150       return;
151     }
152 
decIndentLevel()153     inline void decIndentLevel() {
154       slangAssert(getIndentLevel() > 0 && "No indent");
155       mIndent.erase(0, 4);
156       return;
157     }
158 
getIndentLevel()159     inline int getIndentLevel() { return (mIndent.length() >> 2); }
160 
getNextExportVarSlot()161     inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
162 
getNextExportFuncSlot()163     inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
getNextExportForEachSlot()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
createPaddingField()168     inline std::string createPaddingField() {
169       return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
170     }
171 
setLicenseNote(const std::string & LicenseNote)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 
getPackageName()200     inline const std::string &getPackageName() const { return mPackageName; }
getRSPackageName()201     inline const std::string &getRSPackageName() const {
202       return mRSPackageName;
203     }
getClassName()204     inline const std::string &getClassName() const { return mClassName; }
getResourceId()205     inline const std::string &getResourceId() const { return mResourceId; }
206 
207     void startTypeClass(const std::string &ClassName);
208     void endTypeClass();
209 
incFieldIndex()210     inline void incFieldIndex() { mFieldIndex++; }
211 
resetFieldIndex()212     inline void resetFieldIndex() { mFieldIndex = 0; }
213 
addFieldIndexMapping(const RSExportRecordType::Field * F)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 
getFieldIndex(const RSExportRecordType::Field * F)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 
clearFieldIndexMap()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   void genExportVariable(Context &C, const RSExportVar *EV);
246   void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
247   void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
248   void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
249   void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
250   void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
251   void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
252   void genPrivateExportVariable(Context &C,
253                                 const std::string &TypeName,
254                                 const std::string &VarName);
255   void genSetExportVariable(Context &C,
256                             const std::string &TypeName,
257                             const RSExportVar *EV);
258   void genGetExportVariable(Context &C,
259                             const std::string &TypeName,
260                             const std::string &VarName);
261   void genGetFieldID(Context &C,
262                      const std::string &VarName);
263 
264   void genExportFunction(Context &C,
265                          const RSExportFunc *EF);
266 
267   void genExportForEach(Context &C,
268                         const RSExportForEach *EF);
269 
270   static void genTypeCheck(Context &C,
271                            const RSExportType *ET,
272                            const char *VarName);
273 
274   static void genTypeInstanceFromPointer(Context &C,
275                                          const RSExportType *ET);
276 
277   static void genTypeInstance(Context &C,
278                               const RSExportType *ET);
279 
280   static void genFieldPackerInstance(Context &C,
281                                      const RSExportType *ET);
282 
283   bool genTypeClass(Context &C,
284                     const RSExportRecordType *ERT,
285                     std::string &ErrorMsg);
286   void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
287   void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
288   void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
289   void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT);
290   void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
291   void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
292   void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
293   void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
294   void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
295   void genTypeClassResize(Context &C);
296 
297   void genBuildElement(Context &C,
298                        const char *ElementBuilderName,
299                        const RSExportRecordType *ERT,
300                        const char *RenderScriptVar,
301                        bool IsInline);
302   void genAddElementToElementBuilder(Context &C,
303                                      const RSExportType *ERT,
304                                      const std::string &VarName,
305                                      const char *ElementBuilderName,
306                                      const char *RenderScriptVar,
307                                      unsigned ArraySize);
308   void genAddPaddingToElementBuiler(Context &C,
309                                     int PaddingSize,
310                                     const char *ElementBuilderName,
311                                     const char *RenderScriptVar);
312 
313   bool genCreateFieldPacker(Context &C,
314                             const RSExportType *T,
315                             const char *FieldPackerName);
316   void genPackVarOfType(Context &C,
317                         const RSExportType *T,
318                         const char *VarName,
319                         const char *FieldPackerName);
320   void genAllocateVarOfType(Context &C,
321                             const RSExportType *T,
322                             const std::string &VarName);
323   void genNewItemBufferIfNull(Context &C, const char *Index);
324   void genNewItemBufferPackerIfNull(Context &C);
325 
326  public:
RSReflection(const RSContext * Context,std::vector<std::string> * GeneratedFileNames)327   explicit RSReflection(const RSContext *Context,
328       std::vector<std::string> *GeneratedFileNames)
329       : mRSContext(Context),
330         mLastError(""),
331         mGeneratedFileNames(GeneratedFileNames) {
332     slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
333     return;
334   }
335 
336   bool reflect(const std::string &OutputPathBase,
337                const std::string &OutputPackageName,
338                const std::string &RSPackageName,
339                const std::string &InputFileName,
340                const std::string &OutputBCFileName);
341 
getLastError()342   inline const char *getLastError() const {
343     if (mLastError.empty())
344       return NULL;
345     else
346       return mLastError.c_str();
347   }
348 };  // class RSReflection
349 
350 }   // namespace slang
351 
352 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  NOLINT
353