-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslang_rs_reflection.h
351 lines (287 loc) · 12 KB
/
slang_rs_reflection.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
/*
* Copyright 2010-2012, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ // NOLINT
#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_
#include <fstream>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
#include "llvm/ADT/StringExtras.h"
#include "slang_assert.h"
#include "slang_rs_export_type.h"
namespace slang {
class RSContext;
class RSExportVar;
class RSExportFunc;
class RSExportForEach;
class RSReflection {
private:
const RSContext *mRSContext;
std::string mLastError;
std::vector<std::string> *mGeneratedFileNames;
inline void setError(const std::string &Error) { mLastError = Error; }
class Context {
private:
static const char *const ApacheLicenseNote;
bool mVerbose;
std::string mOutputPathBase;
std::string mInputRSFile;
std::string mPackageName;
std::string mRSPackageName;
std::string mResourceId;
std::string mPaddingPrefix;
std::string mClassName;
std::string mLicenseNote;
std::string mIndent;
int mPaddingFieldIndex;
int mNextExportVarSlot;
int mNextExportFuncSlot;
int mNextExportForEachSlot;
// A mapping from a field in a record type to its index in the rsType
// instance. Only used when generates TypeClass (ScriptField_*).
typedef std::map<const RSExportRecordType::Field*, unsigned>
FieldIndexMapTy;
FieldIndexMapTy mFieldIndexMap;
// Field index of current processing TypeClass.
unsigned mFieldIndex;
inline void clear() {
mClassName = "";
mIndent = "";
mPaddingFieldIndex = 1;
mNextExportVarSlot = 0;
mNextExportFuncSlot = 0;
mNextExportForEachSlot = 0;
return;
}
bool openClassFile(const std::string &ClassName,
std::string &ErrorMsg);
public:
typedef enum {
AM_Public,
AM_Protected,
AM_Private,
AM_PublicSynchronized
} AccessModifier;
bool mUseStdout;
mutable std::ofstream mOF;
// Generated RS Elements for type-checking code.
std::set<std::string> mTypesToCheck;
// Generated FieldPackers for unsigned setters/validation.
std::set<std::string> mFieldPackerTypes;
bool addTypeNameForElement(const std::string &TypeName);
bool addTypeNameForFieldPacker(const std::string &TypeName);
static const char *AccessModifierStr(AccessModifier AM);
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)
: mVerbose(true),
mOutputPathBase(OutputPathBase),
mInputRSFile(InputRSFile),
mPackageName(PackageName),
mRSPackageName(RSPackageName),
mResourceId(ResourceId),
mPaddingPrefix(PaddingPrefix),
mLicenseNote(ApacheLicenseNote),
mUseStdout(UseStdout) {
clear();
resetFieldIndex();
clearFieldIndexMap();
return;
}
inline std::ostream &out() const {
return ((mUseStdout) ? std::cout : mOF);
}
inline std::ostream &indent() const {
out() << mIndent;
return out();
}
inline void incIndentLevel() {
mIndent.append(4, ' ');
return;
}
inline void decIndentLevel() {
slangAssert(getIndentLevel() > 0 && "No indent");
mIndent.erase(0, 4);
return;
}
inline int getIndentLevel() { return (mIndent.length() >> 2); }
inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }
// Will remove later due to field name information is not necessary for
// C-reflect-to-Java
inline std::string createPaddingField() {
return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++);
}
inline void setLicenseNote(const std::string &LicenseNote) {
mLicenseNote = LicenseNote;
}
bool startClass(AccessModifier AM,
bool IsStatic,
const std::string &ClassName,
const char *SuperClassName,
std::string &ErrorMsg);
void endClass();
void startFunction(AccessModifier AM,
bool IsStatic,
const char *ReturnType,
const std::string &FunctionName,
int Argc, ...);
typedef std::vector<std::pair<std::string, std::string> > ArgTy;
void startFunction(AccessModifier AM,
bool IsStatic,
const char *ReturnType,
const std::string &FunctionName,
const ArgTy &Args);
void endFunction();
void startBlock(bool ShouldIndent = false);
void endBlock();
inline const std::string &getPackageName() const { return mPackageName; }
inline const std::string &getRSPackageName() const {
return mRSPackageName;
}
inline const std::string &getClassName() const { return mClassName; }
inline const std::string &getResourceId() const { return mResourceId; }
void startTypeClass(const std::string &ClassName);
void endTypeClass();
inline void incFieldIndex() { mFieldIndex++; }
inline void resetFieldIndex() { mFieldIndex = 0; }
inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
"Nested structure never occurs in C language.");
mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
}
inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
slangAssert((I != mFieldIndexMap.end()) &&
"Requesting field is out of scope.");
return I->second;
}
inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
};
bool genScriptClass(Context &C,
const std::string &ClassName,
std::string &ErrorMsg);
void genScriptClassConstructor(Context &C);
static void genInitBoolExportVariable(Context &C,
const std::string &VarName,
const clang::APValue &Val);
static void genInitPrimitiveExportVariable(Context &C,
const std::string &VarName,
const clang::APValue &Val);
static void genInitExportVariable(Context &C,
const RSExportType *ET,
const std::string &VarName,
const clang::APValue &Val);
static void genInitValue(Context &C, const clang::APValue &Val);
void genExportVariable(Context &C, const RSExportVar *EV);
void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
void genPrivateExportVariable(Context &C,
const std::string &TypeName,
const std::string &VarName);
void genSetExportVariable(Context &C,
const std::string &TypeName,
const RSExportVar *EV);
void genGetExportVariable(Context &C,
const std::string &TypeName,
const std::string &VarName);
void genExportFunction(Context &C,
const RSExportFunc *EF);
void genExportForEach(Context &C,
const RSExportForEach *EF);
static void genTypeCheck(Context &C,
const RSExportType *ET,
const char *VarName);
static void genTypeInstanceFromPointer(Context &C,
const RSExportType *ET);
static void genTypeInstance(Context &C,
const RSExportType *ET);
static void genFieldPackerInstance(Context &C,
const RSExportType *ET);
bool genTypeClass(Context &C,
const RSExportRecordType *ERT,
std::string &ErrorMsg);
void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT);
void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
void genTypeClassResize(Context &C);
void genBuildElement(Context &C,
const char *ElementBuilderName,
const RSExportRecordType *ERT,
const char *RenderScriptVar,
bool IsInline);
void genAddElementToElementBuilder(Context &C,
const RSExportType *ERT,
const std::string &VarName,
const char *ElementBuilderName,
const char *RenderScriptVar,
unsigned ArraySize);
void genAddPaddingToElementBuiler(Context &C,
int PaddingSize,
const char *ElementBuilderName,
const char *RenderScriptVar);
bool genCreateFieldPacker(Context &C,
const RSExportType *T,
const char *FieldPackerName);
void genPackVarOfType(Context &C,
const RSExportType *T,
const char *VarName,
const char *FieldPackerName);
void genAllocateVarOfType(Context &C,
const RSExportType *T,
const std::string &VarName);
void genNewItemBufferIfNull(Context &C, const char *Index);
void genNewItemBufferPackerIfNull(Context &C);
public:
explicit RSReflection(const RSContext *Context,
std::vector<std::string> *GeneratedFileNames)
: mRSContext(Context),
mLastError(""),
mGeneratedFileNames(GeneratedFileNames) {
slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
return;
}
bool reflect(const std::string &OutputPathBase,
const std::string &OutputPackageName,
const std::string &RSPackageName,
const std::string &InputFileName,
const std::string &OutputBCFileName);
inline const char *getLastError() const {
if (mLastError.empty())
return NULL;
else
return mLastError.c_str();
}
}; // class RSReflection
} // namespace slang
#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT