1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "codegen/ts_code_emitter.h"
17
18 #include <cctype>
19 #include <cstdio>
20 #include <algorithm>
21
22 #include "securec.h"
23 #include "util/file.h"
24 #include "util/logger.h"
25
26 namespace OHOS {
27 namespace Idl {
28 namespace {
29 const std::string PROXY = "proxy";
30 const std::string THIS_PROXY = "this.proxy";
31 static const char* TAG = "TsCodeEmitter";
32 const std::string UNKNOWN_TYPE = "unknown type";
33 const String NEWLINE = "\n";
34 const String RETURN_VALUE = "returnValue";
35 const std::string ERR_CODE_TYPE = "errCode: number";
36 const String ERR_CODE = "errCode";
37 }
38
EmitInterface()39 void TsCodeEmitter::EmitInterface()
40 {
41 if (!CheckInterfaceType()) {
42 return;
43 }
44 String filePath = String::Format("%s/%s.ts", directory_.string(), FileName(interfaceName_).string());
45 File file(filePath, File::WRITE);
46
47 StringBuilder stringBuilder;
48
49 EmitLicense(stringBuilder);
50 stringBuilder.Append(NEWLINE);
51 EmitInterfaceSelfDefinedTypeImports(stringBuilder);
52 stringBuilder.Append(NEWLINE);
53 EmitInterfaceDefinition(stringBuilder);
54 stringBuilder.Append(NEWLINE);
55
56 String data = stringBuilder.ToString();
57 file.WriteData(data.string(), data.GetLength());
58 file.Flush();
59 file.Close();
60 }
61
EmitInterfaceImports(StringBuilder & stringBuilder)62 void TsCodeEmitter::EmitInterfaceImports(StringBuilder& stringBuilder)
63 {
64 for (const auto &item : methods_) {
65 if (item.callbackName_.size() > 0) {
66 stringBuilder.AppendFormat("import {%s} from \"./%s\";\n",
67 item.callbackName_.c_str(), FileName(interfaceName_).string());
68 }
69 }
70 stringBuilder.AppendFormat("import %s from \"./%s\";\n", metaInterface_->name_, FileName(interfaceName_).string());
71 stringBuilder.Append("import rpc from \"@ohos.rpc\";\n");
72 EmitInterfaceSelfDefinedTypeImports(stringBuilder);
73
74 for (int index = 0; index < metaComponent_->interfaceNumber_; index++) {
75 MetaInterface* mi = metaComponent_->interfaces_[index];
76 if (!interfaceName_.Equals(mi->name_)) {
77 String dependInterface = mi->name_;
78 String dependStubName = dependInterface.StartsWith("I") ?
79 dependInterface.Substring(1) + "Stub" : dependInterface + "Stub";
80 stringBuilder.AppendFormat("import %s from \"./%s\";\n", dependStubName.string(),
81 FileName(dependStubName).string());
82 }
83 }
84 }
85
EmitInterfaceSelfDefinedTypeImports(StringBuilder & stringBuilder)86 void TsCodeEmitter::EmitInterfaceSelfDefinedTypeImports(StringBuilder& stringBuilder)
87 {
88 for (int index = 0; index < metaComponent_->sequenceableNumber_; index++) {
89 MetaSequenceable* mp = metaComponent_->sequenceables_[index];
90 stringBuilder.AppendFormat("import %s from \"./%s\";\n", mp->name_, FileName(mp->name_).string());
91 }
92
93 for (int index = 0; index < metaComponent_->interfaceNumber_; index++) {
94 MetaInterface* mi = metaComponent_->interfaces_[index];
95 if (mi->external_) {
96 stringBuilder.AppendFormat("import %s from \"./%s\";\n", mi->name_, FileName(mi->name_).string());
97 }
98 }
99 }
100
EmitInterfaceDefinition(StringBuilder & stringBuilder)101 void TsCodeEmitter::EmitInterfaceDefinition(StringBuilder& stringBuilder)
102 {
103 stringBuilder.AppendFormat("export default interface %s {\n", metaInterface_->name_);
104 EmitInterfaceMethods(stringBuilder, TAB);
105 stringBuilder.Append("}\n");
106
107 for (const auto &item : methods_) {
108 if (item.callbackName_.size() > 0) {
109 stringBuilder.AppendFormat("%s\n", item.exportFunction_.c_str());
110 }
111 }
112 }
113
EmitInterfaceMethods(StringBuilder & stringBuilder,const String & prefix)114 void TsCodeEmitter::EmitInterfaceMethods(StringBuilder& stringBuilder, const String& prefix)
115 {
116 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
117 MetaMethod* metaMethod = metaInterface_->methods_[index];
118 EmitInterfaceMethod(metaMethod, stringBuilder, prefix);
119 }
120 }
121
EmitInterfaceMethod(MetaMethod * metaMethod,StringBuilder & stringBuilder,const String & prefix)122 void TsCodeEmitter::EmitInterfaceMethod(MetaMethod* metaMethod, StringBuilder& stringBuilder, const String& prefix)
123 {
124 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
125 Method method;
126 method.properties_ = metaMethod->properties_;
127 StringBuilder callbackName;
128 callbackName.AppendFormat("%sCallback", MethodName(metaMethod->name_).string());
129 method.callbackName_ = callbackName.ToString();
130 method.exportFunction_ = "export type " + callbackName.ToString() + " = (" + ERR_CODE_TYPE.c_str();
131
132 bool haveOutPara = false;
133 StringBuilder methodStr;
134 if (returnType->kind_ != TypeKind::Void) {
135 method.retParameter_.name_ = RETURN_VALUE.string();
136 method.retParameter_.type_ = EmitType(returnType).string();
137 }
138 methodStr.Append(prefix).AppendFormat("%s(", MethodName(metaMethod->name_).string());
139 method.name_ = MethodName(metaMethod->name_).string();
140
141 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
142 MetaParameter* mp = metaMethod->parameters_[index];
143 MetaType* paraType = metaComponent_->types_[mp->typeIndex_];
144 Parameter para;
145 para.attr_ = mp->attributes_;
146 para.name_ = mp->name_;
147 para.type_ = EmitType(paraType).string();
148 if ((mp->attributes_ & ATTR_OUT) != 0) {
149 haveOutPara = true;
150 }
151 method.parameters_.emplace_back(para);
152 }
153
154 bool isLastParaTypeIn = false;
155 for (size_t index = 0; index < method.parameters_.size(); index++) {
156 if ((method.parameters_[index].attr_ & ATTR_IN) != 0) {
157 EmitMethodInParameter(methodStr, method.parameters_[index].name_, method.parameters_[index].type_,
158 prefix + TAB);
159 if (index != method.parameters_.size() - 1) {
160 methodStr.Append(", ");
161 } else {
162 isLastParaTypeIn = true;
163 }
164 }
165 }
166 std::sort(method.parameters_.begin(), method.parameters_.end());
167 if (method.callbackName_.size() > 0) {
168 if (!isLastParaTypeIn) {
169 methodStr.AppendFormat("callback: %s", method.callbackName_.c_str());
170 } else {
171 methodStr.AppendFormat(", callback: %s", method.callbackName_.c_str());
172 }
173 if (method.retParameter_.name_.size() > 0) {
174 if (!haveOutPara) {
175 method.exportFunction_ +=
176 (", " + method.retParameter_.name_ + ": " + method.retParameter_.type_ + ") => void;");
177 } else {
178 method.exportFunction_ +=
179 (", " + method.retParameter_.name_ + ": " + method.retParameter_.type_ + ", ");
180 }
181 } else {
182 if (!haveOutPara) {
183 method.exportFunction_ += ") => void;";
184 } else {
185 method.exportFunction_ += ", ";
186 }
187 }
188 for (size_t index = 0; index < method.parameters_.size(); index++) {
189 bool isLast = (index == method.parameters_.size() - 1) ? true : false;
190 if ((method.parameters_[index].attr_ & ATTR_OUT) != 0) {
191 EmitInterfaceMethodExportCallback(method, method.parameters_[index], isLast);
192 }
193 }
194 }
195 methodStr.Append("): void;\n");
196 stringBuilder.Append(methodStr.ToString());
197 methods_.emplace_back(method);
198 }
199
EmitInterfaceMethodParameter(MetaParameter * mp,StringBuilder & stringBuilder,const String & prefix)200 void TsCodeEmitter::EmitInterfaceMethodParameter(MetaParameter* mp, StringBuilder& stringBuilder, const String& prefix)
201 {
202 MetaType* paraType = metaComponent_->types_[mp->typeIndex_];
203 stringBuilder.AppendFormat("%s: %s", mp->name_, EmitType(paraType).string());
204 }
205
EmitMethodInParameter(StringBuilder & stringBuilder,const std::string & name,const std::string & type,const String & prefix)206 void TsCodeEmitter::EmitMethodInParameter(StringBuilder& stringBuilder, const std::string& name,
207 const std::string& type, const String& prefix)
208 {
209 stringBuilder.AppendFormat("%s: %s", name.c_str(), type.c_str());
210 }
211
EmitInterfaceMethodExportCallback(Method & m,const Parameter & para,bool isLast)212 void TsCodeEmitter::EmitInterfaceMethodExportCallback(Method& m, const Parameter& para, bool isLast)
213 {
214 StringBuilder exportCallback;
215 exportCallback.Append(m.exportFunction_.c_str());
216 if (isLast) {
217 exportCallback.AppendFormat("%s: %s) => void;", para.name_.c_str(), para.type_.c_str());
218 } else {
219 exportCallback.AppendFormat("%s: %s, ", para.name_.c_str(), para.type_.c_str());
220 }
221 m.exportFunction_ = exportCallback.ToString();
222 }
223
EmitInterfaceProxy()224 void TsCodeEmitter::EmitInterfaceProxy()
225 {
226 if (!CheckInterfaceType()) {
227 return;
228 }
229 String filePath = String::Format("%s/%s.ts", directory_.string(), FileName(proxyName_).string());
230 File file(filePath, File::WRITE);
231
232 StringBuilder stringBuilder;
233
234 EmitLicense(stringBuilder);
235 stringBuilder.Append(NEWLINE);
236 EmitInterfaceImports(stringBuilder);
237 stringBuilder.Append(NEWLINE);
238 EmitInterfaceProxyImpl(stringBuilder);
239 stringBuilder.Append(NEWLINE);
240
241 String data = stringBuilder.ToString();
242 file.WriteData(data.string(), data.GetLength());
243 file.Flush();
244 file.Close();
245 }
246
EmitInterfaceProxyImpl(StringBuilder & stringBuilder)247 void TsCodeEmitter::EmitInterfaceProxyImpl(StringBuilder& stringBuilder)
248 {
249 stringBuilder.AppendFormat("export default class %s implements %s {\n", proxyName_.string(),
250 interfaceName_.string());
251 EmitInterfaceProxyConstructor(stringBuilder, TAB);
252 stringBuilder.Append(NEWLINE);
253 EmitInterfaceProxyMethodImpls(stringBuilder, TAB);
254 stringBuilder.Append(NEWLINE);
255 EmitInterfaceMethodCommands(stringBuilder);
256 stringBuilder.Append(TAB).AppendFormat("private %s", PROXY.c_str());
257 stringBuilder.Append(NEWLINE);
258 stringBuilder.Append("}\n");
259 }
260
EmitInterfaceProxyConstructor(StringBuilder & stringBuilder,const String & prefix)261 void TsCodeEmitter::EmitInterfaceProxyConstructor(StringBuilder& stringBuilder, const String& prefix)
262 {
263 stringBuilder.Append(prefix).AppendFormat("constructor(%s) {\n", PROXY.c_str());
264 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s = %s;\n", THIS_PROXY.c_str(), PROXY.c_str());
265 stringBuilder.Append(prefix).Append("}\n");
266 }
267
EmitInterfaceProxyMethodImpls(StringBuilder & stringBuilder,const String & prefix)268 void TsCodeEmitter::EmitInterfaceProxyMethodImpls(StringBuilder& stringBuilder, const String& prefix)
269 {
270 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
271 MetaMethod* metaMethod = metaInterface_->methods_[index];
272 EmitInterfaceProxyMethodImpl(metaMethod, index, stringBuilder, prefix);
273 if (index != metaInterface_->methodNumber_ - 1) {
274 stringBuilder.Append(NEWLINE);
275 }
276 }
277 }
278
EmitInterfaceProxyMethodImpl(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix)279 void TsCodeEmitter::EmitInterfaceProxyMethodImpl(MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder,
280 const String& prefix)
281 {
282 stringBuilder.Append(prefix).AppendFormat("%s(", MethodName(metaMethod->name_).string());
283 bool isLastParaTypeIn = false;
284 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
285 MetaParameter* mp = metaMethod->parameters_[index];
286 if ((mp->attributes_ & ATTR_IN) != 0) {
287 EmitInterfaceMethodParameter(mp, stringBuilder, prefix + TAB);
288 if (index != metaMethod->parameterNumber_ - 1) {
289 stringBuilder.Append(", ");
290 } else {
291 isLastParaTypeIn = true;
292 }
293 }
294 }
295 if (methods_[methodIndex].callbackName_.size() > 0) {
296 if (!isLastParaTypeIn) {
297 stringBuilder.AppendFormat("callback: %s", methods_[methodIndex].callbackName_.c_str());
298 } else {
299 stringBuilder.AppendFormat(", callback: %s", methods_[methodIndex].callbackName_.c_str());
300 }
301 }
302 stringBuilder.Append("): void\n");
303 EmitInterfaceProxyMethodBody(metaMethod, methodIndex, stringBuilder, prefix);
304 }
305
EmitInterfaceProxyMethodBody(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix)306 void TsCodeEmitter::EmitInterfaceProxyMethodBody(MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder,
307 const String& prefix)
308 {
309 bool haveOutPara = false;
310 stringBuilder.Append(prefix).Append("{\n");
311 stringBuilder.Append(prefix).Append(TAB).AppendFormat("let _option = new rpc.MessageOption();\n");
312 if ((metaMethod->properties_ & METHOD_PROPERTY_ONEWAY) || (metaInterface_->properties_ & METHOD_PROPERTY_ONEWAY)) {
313 stringBuilder.Append(prefix).Append(TAB).AppendFormat("_option.setFlags(_option.TF_ASYNC);\n");
314 }
315 stringBuilder.Append(prefix).Append(TAB).Append("let _data = new rpc.MessageParcel();\n");
316 stringBuilder.Append(prefix).Append(TAB).Append("let _reply = new rpc.MessageParcel();\n");
317
318 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
319 MetaParameter* mp = metaMethod->parameters_[index];
320 if ((mp->attributes_ & ATTR_IN) != 0) {
321 EmitWriteMethodParameter(mp, "_data", stringBuilder, prefix + TAB);
322 }
323 if ((mp->attributes_ & ATTR_OUT) != 0) {
324 haveOutPara = true;
325 }
326 }
327 stringBuilder.Append(prefix).Append(TAB).AppendFormat(
328 "%s.sendRequest(%s.COMMAND_%s, _data, _reply, _option).then(function(result) {\n", THIS_PROXY.c_str(),
329 proxyName_.string(), ConstantName(metaMethod->name_).string());
330 stringBuilder.Append(prefix).Append(TAB).Append(TAB).AppendFormat("if (result.errCode === 0) {\n");
331 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
332 // emit errCode
333 MetaType errCode;
334 errCode.kind_ = TypeKind::Integer;
335 EmitReadOutVariable("result.reply", UnderlineAdded(ERR_CODE).c_str(), &errCode, stringBuilder,
336 prefix + TAB + TAB + TAB);
337
338 if (returnType->kind_ != TypeKind::Void || haveOutPara) {
339 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).AppendFormat(
340 "if (%s != 0) {\n", UnderlineAdded(ERR_CODE).c_str());
341 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
342 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
343 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).AppendFormat(
344 "let %s = undefined;\n", UnderlineAdded(
345 methods_[methodIndex].parameters_[index].name_.c_str()).c_str());
346 }
347 }
348 if (returnType->kind_ != TypeKind::Void) {
349 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).AppendFormat(
350 "let %s = undefined;\n", UnderlineAdded(RETURN_VALUE).c_str());
351 }
352 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).AppendFormat("callback(");
353 stringBuilder.AppendFormat("%s", UnderlineAdded(ERR_CODE).c_str());
354 if (methods_[methodIndex].retParameter_.name_.size() > 0) {
355 if (haveOutPara) {
356 stringBuilder.AppendFormat(", %s, ", UnderlineAdded(RETURN_VALUE).c_str());
357 } else {
358 stringBuilder.AppendFormat(", %s", UnderlineAdded(RETURN_VALUE).c_str());
359 }
360 } else {
361 if (haveOutPara) {
362 stringBuilder.Append(",");
363 }
364 }
365 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
366 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
367 stringBuilder.AppendFormat("%s",
368 UnderlineAdded(methods_[methodIndex].parameters_[index].name_.c_str()).c_str());
369 if (index != methods_[methodIndex].parameters_.size() - 1) {
370 stringBuilder.Append(", ");
371 }
372 }
373 }
374 stringBuilder.Append(");\n");
375 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).Append("return;\n");
376 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append("}\n");
377 }
378 // emit return
379 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
380 MetaParameter* mp = metaMethod->parameters_[index];
381 if ((mp->attributes_ & ATTR_OUT) != 0) {
382 EmitReadMethodParameter(mp, "result.reply", stringBuilder, prefix + TAB + TAB + TAB);
383 }
384 }
385 if (returnType->kind_ != TypeKind::Void) {
386 String parcelName = "result.reply";
387 EmitReadOutVariable(parcelName, UnderlineAdded(RETURN_VALUE), returnType, stringBuilder,
388 prefix + TAB + TAB + TAB);
389 }
390 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).AppendFormat("callback(");
391 stringBuilder.AppendFormat("%s", UnderlineAdded(ERR_CODE).c_str());
392 if (methods_[methodIndex].retParameter_.name_.size() > 0) {
393 if (haveOutPara) {
394 stringBuilder.AppendFormat(", %s, ", UnderlineAdded(RETURN_VALUE).c_str());
395 } else {
396 stringBuilder.AppendFormat(", %s", UnderlineAdded(RETURN_VALUE).c_str());
397 }
398 } else {
399 if (haveOutPara) {
400 stringBuilder.Append(",");
401 }
402 }
403 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
404 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
405 stringBuilder.AppendFormat("%s",
406 UnderlineAdded(methods_[methodIndex].parameters_[index].name_.c_str()).c_str());
407 if (index != methods_[methodIndex].parameters_.size() - 1) {
408 stringBuilder.Append(", ");
409 }
410 }
411 }
412 stringBuilder.Append(");\n");
413 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("} else {\n");
414 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(
415 "console.log(\"sendRequest failed, errCode: \" + result.errCode);\n");
416 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
417 stringBuilder.Append(prefix).Append(TAB).Append("})\n");
418 stringBuilder.Append(prefix).Append("}\n");
419 }
420
EmitWriteMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & stringBuilder,const String & prefix)421 void TsCodeEmitter::EmitWriteMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& stringBuilder,
422 const String& prefix)
423 {
424 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
425 std::string name = mp->name_;
426 EmitWriteVariable(parcelName, name, mt, stringBuilder, prefix);
427 }
428
EmitReadMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & stringBuilder,const String & prefix)429 void TsCodeEmitter::EmitReadMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& stringBuilder,
430 const String& prefix)
431 {
432 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
433 std::string name = UnderlineAdded(mp->name_);
434 EmitReadOutVariable(parcelName, name, mt, stringBuilder, prefix);
435 }
436
EmitInterfaceStub()437 void TsCodeEmitter::EmitInterfaceStub()
438 {
439 if (!CheckInterfaceType()) {
440 return;
441 }
442 String filePath = String::Format("%s/%s.ts", directory_.string(), FileName(stubName_).string());
443 File file(filePath, File::WRITE);
444
445 StringBuilder stringBuilder;
446 EmitLicense(stringBuilder);
447 stringBuilder.Append(NEWLINE);
448 EmitInterfaceImports(stringBuilder);
449 stringBuilder.Append(NEWLINE);
450 EmitInterfaceStubImpl(stringBuilder);
451 stringBuilder.Append(NEWLINE);
452
453 String data = stringBuilder.ToString();
454 file.WriteData(data.string(), data.GetLength());
455 file.Flush();
456 file.Close();
457 }
458
EmitInterfaceStubImpl(StringBuilder & stringBuilder)459 void TsCodeEmitter::EmitInterfaceStubImpl(StringBuilder& stringBuilder)
460 {
461 stringBuilder.AppendFormat("export default class %s extends rpc.RemoteObject implements %s {\n",
462 stubName_.string(), interfaceName_.string());
463 EmitInterfaceStubMethodImpls(stringBuilder, TAB);
464 stringBuilder.Append(NEWLINE);
465 EmitInterfaceMethodCommands(stringBuilder);
466 stringBuilder.Append("}\n");
467 }
468
EmitInterfaceStubConstructor(StringBuilder & stringBuilder,const String & prefix)469 void TsCodeEmitter::EmitInterfaceStubConstructor(StringBuilder& stringBuilder, const String& prefix)
470 {
471 stringBuilder.Append(prefix).Append("constructor(des: string) {\n");
472 stringBuilder.Append(prefix).Append(TAB).Append("super(des);\n");
473 stringBuilder.Append(prefix).Append("}\n");
474 }
475
EmitInterfaceStubMethodImpls(StringBuilder & stringBuilder,const String & prefix)476 void TsCodeEmitter::EmitInterfaceStubMethodImpls(StringBuilder& stringBuilder, const String& prefix)
477 {
478 EmitInterfaceStubConstructor(stringBuilder, prefix);
479 stringBuilder.Append(prefix).Append(NEWLINE);
480 stringBuilder.Append(prefix).AppendFormat("onRemoteRequest(code: number, data, reply, option): boolean {\n");
481 stringBuilder.Append(prefix).Append(TAB).Append("console.log(\"onRemoteRequest called, code = \" + code);\n");
482 stringBuilder.Append(prefix).Append(TAB).Append("switch(code) {\n");
483 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
484 MetaMethod* metaMethod = metaInterface_->methods_[index];
485 EmitInterfaceStubMethodImpl(metaMethod, index, stringBuilder, prefix + TAB + TAB);
486 }
487 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("default: {\n");
488 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(
489 "console.log(\"invalid request code\" + code);\n");
490 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append("break;\n");
491 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
492 stringBuilder.Append(prefix).Append(TAB).Append("}\n");
493 stringBuilder.Append(prefix).Append(TAB).Append("return false;\n");
494 stringBuilder.Append(prefix).Append("}\n");
495 stringBuilder.Append(prefix).Append(NEWLINE);
496
497 // emit empty method
498 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
499 bool isLastParaTypeIn = false;
500 MetaMethod* metaMethod = metaInterface_->methods_[index];
501 stringBuilder.Append(prefix).AppendFormat("%s(", MethodName(metaMethod->name_).string());
502 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
503 MetaParameter* mp = metaMethod->parameters_[index];
504 if ((mp->attributes_ & ATTR_IN) != 0) {
505 EmitInterfaceMethodParameter(mp, stringBuilder, prefix + TAB);
506 if (index != metaMethod->parameterNumber_ - 1) {
507 stringBuilder.Append(", ");
508 } else {
509 isLastParaTypeIn = true;
510 }
511 }
512 }
513 if (!isLastParaTypeIn) {
514 stringBuilder.AppendFormat("callback: %s", methods_[index].callbackName_.c_str());
515 } else {
516 stringBuilder.AppendFormat(", callback: %s", methods_[index].callbackName_.c_str());
517 }
518 stringBuilder.Append("): void{}\n");
519 }
520 }
521
EmitInterfaceStubMethodImpl(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix)522 void TsCodeEmitter::EmitInterfaceStubMethodImpl(MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder,
523 const String& prefix)
524 {
525 bool haveOutPara = false;
526 stringBuilder.Append(prefix).AppendFormat("case %s.COMMAND_%s: {\n", stubName_.string(),
527 ConstantName(metaMethod->name_).string());
528 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
529 MetaParameter* mp = metaMethod->parameters_[index];
530 if ((mp->attributes_ & ATTR_IN) != 0) {
531 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
532 EmitReadVariable("data", UnderlineAdded(mp->name_), mt, ATTR_IN, stringBuilder, prefix + TAB);
533 }
534 if ((mp->attributes_ & ATTR_OUT) != 0) {
535 haveOutPara = true;
536 }
537 }
538 stringBuilder.Append(prefix).Append(TAB).AppendFormat("this.%s(", MethodName(metaMethod->name_).string());
539 bool isLastParaTypeIn = false;
540 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
541 MetaParameter* mp = metaMethod->parameters_[index];
542 if ((mp->attributes_ & ATTR_IN) != 0) {
543 stringBuilder.Append(UnderlineAdded(mp->name_).c_str());
544 if (index != metaMethod->parameterNumber_ - 1) {
545 stringBuilder.Append(", ");
546 } else {
547 isLastParaTypeIn = true;
548 }
549 }
550 }
551 if (!isLastParaTypeIn) {
552 stringBuilder.Append("(");
553 } else {
554 stringBuilder.Append(", (");
555 }
556 stringBuilder.Append(ERR_CODE);
557 if (methods_[methodIndex].retParameter_.name_.size() > 0) {
558 if (!haveOutPara) {
559 stringBuilder.AppendFormat(", %s", RETURN_VALUE.string());
560 } else {
561 stringBuilder.AppendFormat(", %s", RETURN_VALUE.string()).Append(", ");
562 }
563 } else {
564 if (haveOutPara) {
565 stringBuilder.Append(", ");
566 }
567 }
568 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
569 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
570 stringBuilder.Append(methods_[methodIndex].parameters_[index].name_.c_str());
571 if (index != methods_[methodIndex].parameters_.size() - 1) {
572 stringBuilder.Append(", ");
573 }
574 }
575 }
576
577 stringBuilder.Append(") => {\n");
578 MetaType errCode;
579 errCode.kind_ = TypeKind::Integer;
580 EmitWriteVariable("reply", ERR_CODE.string(), &errCode, stringBuilder, prefix + TAB + TAB);
581 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
582
583 if (returnType->kind_ != TypeKind::Void || haveOutPara) {
584 stringBuilder.Append(prefix).Append(TAB).Append(TAB).AppendFormat("if (%s == 0) {\n", ERR_CODE.string());
585 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
586 MetaParameter* mp = metaMethod->parameters_[index];
587 if ((mp->attributes_ & ATTR_OUT) != 0) {
588 EmitWriteMethodParameter(mp, "reply", stringBuilder, prefix + TAB + TAB + TAB);
589 }
590 }
591 if (returnType->kind_ != TypeKind::Void) {
592 EmitWriteVariable("reply", RETURN_VALUE.string(), returnType, stringBuilder, prefix + TAB + TAB + TAB);
593 }
594 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
595 }
596 stringBuilder.Append(prefix).Append(TAB).Append("}");
597 stringBuilder.Append(");\n");
598 stringBuilder.Append(prefix).Append(TAB).Append("return true;\n");
599 stringBuilder.Append(prefix).Append("}\n");
600 }
601
EmitInterfaceMethodCommands(StringBuilder & stringBuilder)602 void TsCodeEmitter::EmitInterfaceMethodCommands(StringBuilder& stringBuilder)
603 {
604 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
605 MetaMethod* metaMethod = metaInterface_->methods_[index];
606 stringBuilder.Append(TAB).AppendFormat("static readonly COMMAND_%s = %d;\n",
607 ConstantName(metaMethod->name_).string(), index + 1);
608 }
609 }
610
EmitLicense(StringBuilder & stringBuilder)611 void TsCodeEmitter::EmitLicense(StringBuilder& stringBuilder)
612 {
613 stringBuilder.Append(metaInterface_->license_).Append(NEWLINE);
614 }
615
EmitWriteVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)616 void TsCodeEmitter::EmitWriteVariable(const String& parcelName, const std::string& name, MetaType* mt,
617 StringBuilder& stringBuilder,
618 const String& prefix)
619 {
620 switch (mt->kind_) {
621 case TypeKind::Boolean:
622 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s ? 1 : 0);\n", parcelName.string(), name.c_str());
623 break;
624 case TypeKind::Char:
625 case TypeKind::Byte:
626 case TypeKind::Short:
627 case TypeKind::Integer:
628 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s);\n", parcelName.string(), name.c_str());
629 break;
630 case TypeKind::Long:
631 stringBuilder.Append(prefix).AppendFormat("%s.writeLong(%s);\n", parcelName.string(), name.c_str());
632 break;
633 case TypeKind::Float:
634 stringBuilder.Append(prefix).AppendFormat("%s.writeFloat(%s);\n", parcelName.string(), name.c_str());
635 break;
636 case TypeKind::Double:
637 stringBuilder.Append(prefix).AppendFormat("%s.writeDouble(%s);\n", parcelName.string(), name.c_str());
638 break;
639 case TypeKind::String:
640 stringBuilder.Append(prefix).AppendFormat("%s.writeString(%s);\n", parcelName.string(), name.c_str());
641 break;
642 case TypeKind::Sequenceable:
643 if (EmitType(mt).Equals("IRemoteObject")) {
644 stringBuilder.Append(prefix).AppendFormat("%s.writeRemoteObject(%s);\n", parcelName.string(),
645 name.c_str());
646 break;
647 }
648 stringBuilder.Append(prefix).AppendFormat("%s.writeSequenceable(%s);\n", parcelName.string(),
649 name.c_str());
650 break;
651 case TypeKind::Interface:
652 stringBuilder.Append(prefix).AppendFormat("%s.writeRemoteObject(%s as %s);\n", parcelName.string(),
653 name.c_str(), StubName(EmitType(mt)).string());
654 break;
655 case TypeKind::List: {
656 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
657 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s.size());\n", parcelName.string(), name.c_str());
658 stringBuilder.Append(prefix).AppendFormat("for (%s element : %s) {\n",
659 EmitType(innerType).string(), name.c_str());
660 EmitWriteVariable(parcelName, "element", innerType, stringBuilder, prefix + TAB);
661 stringBuilder.Append(prefix).Append("}\n");
662 break;
663 }
664 case TypeKind::Map: {
665 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
666 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
667 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s.size);\n", parcelName.string(), name.c_str());
668 stringBuilder.Append(prefix).AppendFormat("for (let [key, value] of %s) {\n", name.c_str());
669 EmitWriteVariable(parcelName, "key", keyType, stringBuilder, prefix + TAB);
670 EmitWriteVariable(parcelName, "value", valueType, stringBuilder, prefix + TAB);
671 stringBuilder.Append(prefix).Append("}\n");
672 break;
673 }
674 case TypeKind::Array: {
675 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
676 EmitWriteArrayVariable(parcelName, name, innerType, stringBuilder, prefix);
677 break;
678 }
679 default:
680 break;
681 }
682 }
683
EmitWriteArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)684 void TsCodeEmitter::EmitWriteArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
685 StringBuilder& stringBuilder,
686 const String& prefix)
687 {
688 switch (mt->kind_) {
689 case TypeKind::Boolean:
690 stringBuilder.Append(prefix).AppendFormat("%s.writeBooleanArray(%s);\n", parcelName.string(),
691 name.c_str());
692 break;
693 case TypeKind::Char:
694 stringBuilder.Append(prefix).AppendFormat("%s.writeCharArray(%s);\n", parcelName.string(), name.c_str());
695 break;
696 case TypeKind::Byte:
697 stringBuilder.Append(prefix).AppendFormat("%s.writeByteArray(%s);\n",
698 parcelName.string(), name.c_str());
699 break;
700 case TypeKind::Short:
701 stringBuilder.Append(prefix).AppendFormat("%s.writeShortArray(%s);\n", parcelName.string(), name.c_str());
702 break;
703 case TypeKind::Integer:
704 stringBuilder.Append(prefix).AppendFormat("%s.writeIntArray(%s);\n", parcelName.string(), name.c_str());
705 break;
706 case TypeKind::Long:
707 stringBuilder.Append(prefix).AppendFormat("%s.writeLongArray(%s);\n", parcelName.string(), name.c_str());
708 break;
709 case TypeKind::Float:
710 stringBuilder.Append(prefix).AppendFormat("%s.writeFloatArray(%s);\n", parcelName.string(), name.c_str());
711 break;
712 case TypeKind::Double:
713 stringBuilder.Append(prefix).AppendFormat("%s.writeDoubleArray(%s);\n", parcelName.string(), name.c_str());
714 break;
715 case TypeKind::String:
716 stringBuilder.Append(prefix).AppendFormat("%s.writeStringArray(%s);\n", parcelName.string(), name.c_str());
717 break;
718 case TypeKind::Sequenceable: {
719 String typeName = EmitType(mt).EndsWith("]") ?
720 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
721 stringBuilder.Append(prefix).AppendFormat("let %sArray:Array<%s> = %s;\n", name.c_str(), typeName.string(),
722 name.c_str());
723 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%sArray.length);\n", parcelName.string(),
724 name.c_str());
725 stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sArray.length; index++) {\n",
726 name.c_str());
727 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.writeSequenceable(%s[index]);\n",
728 parcelName.string(), name.c_str());
729 stringBuilder.Append(prefix).AppendFormat("}\n");
730 }
731 break;
732 default:
733 break;
734 }
735 }
736
EmitReadVariable(const String & parcelName,const std::string & name,MetaType * mt,unsigned int attributes,StringBuilder & stringBuilder,const String & prefix)737 void TsCodeEmitter::EmitReadVariable(const String& parcelName, const std::string& name, MetaType* mt,
738 unsigned int attributes,
739 StringBuilder& stringBuilder,
740 const String& prefix)
741 {
742 switch (mt->kind_) {
743 case TypeKind::Boolean:
744 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt() == 1 ? true : false;\n", name.c_str(),
745 parcelName.string());
746 break;
747 case TypeKind::Char:
748 case TypeKind::Byte:
749 case TypeKind::Short:
750 case TypeKind::Integer:
751 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt();\n", name.c_str(), parcelName.string());
752 break;
753 case TypeKind::Long:
754 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLong();\n", name.c_str(), parcelName.string());
755 break;
756 case TypeKind::Float:
757 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloat();\n", name.c_str(), parcelName.string());
758 break;
759 case TypeKind::Double:
760 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDouble();\n", name.c_str(), parcelName.string());
761 break;
762 case TypeKind::String:
763 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readString();\n", name.c_str(), parcelName.string());
764 break;
765 case TypeKind::Sequenceable:
766 if ((attributes & ATTR_OUT) == 0 && EmitType(mt).Equals("IRemoteObject")) {
767 stringBuilder.Append(prefix).AppendFormat("IRemoteObject %s = %s.readRemoteObject();\n",
768 name.c_str(), parcelName.string());
769 break;
770 }
771 if ((attributes & ATTR_OUT) == 0) {
772 stringBuilder.Append(prefix).AppendFormat("let %s = new %s();\n", name.c_str(), EmitType(mt).string());
773 }
774 stringBuilder.Append(prefix).AppendFormat("%s.readSequenceable(%s);\n", parcelName.string(), name.c_str());
775
776 break;
777 case TypeKind::Interface:
778 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readRemoteObject();\n", name.c_str(),
779 parcelName.string());
780 break;
781
782 case TypeKind::Map: {
783 stringBuilder.Append(prefix).AppendFormat("let %s = new Map();\n", name.c_str());
784 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
785 parcelName.string());
786 stringBuilder.Append(prefix).AppendFormat("for (let i = 0; i < %sSize; ++i) {\n", name.c_str());
787 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
788 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
789 EmitReadVariable(parcelName, "key", keyType, ATTR_IN, stringBuilder, prefix + TAB);
790 EmitReadVariable(parcelName, "value", valueType, ATTR_IN, stringBuilder, prefix + TAB);
791 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.set(key, value);\n", name.c_str());
792 stringBuilder.Append(prefix).Append("}\n");
793 break;
794 }
795 case TypeKind::Array: {
796 if ((attributes & ATTR_MASK) == ATTR_OUT) {
797 EmitReadOutArrayVariable(parcelName, name, mt, stringBuilder, prefix);
798 } else {
799 EmitReadArrayVariable(parcelName, name, mt, attributes, stringBuilder, prefix);
800 }
801 break;
802 }
803 default:
804 break;
805 }
806 }
807
EmitReadArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,unsigned int attributes,StringBuilder & stringBuilder,const String & prefix)808 void TsCodeEmitter::EmitReadArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
809 unsigned int attributes, StringBuilder& stringBuilder, const String& prefix)
810 {
811 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
812 switch (innerType->kind_) {
813 case TypeKind::Boolean:
814 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readBooleanArray();\n", name.c_str(),
815 parcelName.string());
816 break;
817 case TypeKind::Char:
818 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readCharArray();\n", name.c_str(),
819 parcelName.string());
820 break;
821 case TypeKind::Byte:
822 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readByteArray();\n", name.c_str(),
823 parcelName.string());
824 break;
825 case TypeKind::Short:
826 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readShortArray();\n", name.c_str(),
827 parcelName.string());
828 break;
829 case TypeKind::Integer:
830 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readIntArray();\n", name.c_str(),
831 parcelName.string());
832 break;
833 case TypeKind::Long:
834 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLongArray();\n", name.c_str(),
835 parcelName.string());
836 break;
837 case TypeKind::Float:
838 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloatArray();\n", name.c_str(),
839 parcelName.string());
840 break;
841 case TypeKind::Double:
842 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDoubleArray();\n", name.c_str(),
843 parcelName.string());
844 break;
845 case TypeKind::String:
846 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readStringArray();\n", name.c_str(),
847 parcelName.string());
848 break;
849 case TypeKind::Sequenceable: {
850 String typeName = EmitType(mt).EndsWith("]") ?
851 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
852 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
853 parcelName.string());
854 stringBuilder.Append(prefix).AppendFormat("let %s:Array<%s> = [];\n", name.c_str(), typeName.string());
855 stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sSize; index++) {\n",
856 name.c_str());
857 stringBuilder.Append(prefix).Append(TAB).AppendFormat("let %sValue = new %s();\n",
858 name.c_str(), typeName.string());
859 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.readSequenceable(%sValue);\n",
860 parcelName.string(), name.c_str());
861 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.push(%sValue);\n", name.c_str(),
862 name.c_str());
863 stringBuilder.Append(prefix).AppendFormat("}\n");
864 }
865 break;
866 default:
867 break;
868 }
869 }
870
EmitReadOutArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)871 void TsCodeEmitter::EmitReadOutArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
872 StringBuilder& stringBuilder,
873 const String& prefix)
874 {
875 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
876 switch (innerType->kind_) {
877 case TypeKind::Boolean:
878 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readBooleanArray();\n", name.c_str(),
879 parcelName.string());
880 break;
881 case TypeKind::Char:
882 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readCharArray();\n", name.c_str(),
883 parcelName.string());
884 break;
885 case TypeKind::Byte:
886 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readByteArray();\n", name.c_str(),
887 parcelName.string());
888 break;
889 case TypeKind::Short:
890 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readShortArray();\n", name.c_str(),
891 parcelName.string());
892 break;
893 case TypeKind::Integer:
894 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readIntArray();\n", name.c_str(),
895 parcelName.string());
896 break;
897 case TypeKind::Long:
898 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLongArray();\n", name.c_str(),
899 parcelName.string());
900 break;
901 case TypeKind::Float:
902 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloatArray();\n", name.c_str(),
903 parcelName.string());
904 break;
905 case TypeKind::Double:
906 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDoubleArray();\n", name.c_str(),
907 parcelName.string());
908 break;
909 case TypeKind::String:
910 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readStringArray();\n", name.c_str(),
911 parcelName.string());
912 break;
913 case TypeKind::Sequenceable: {
914 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
915 parcelName.string());
916 String typeName = EmitType(mt).EndsWith("]") ?
917 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
918 stringBuilder.Append(prefix).AppendFormat("let %s:Array<%s> = [];\n", name.c_str(), typeName.string());
919 stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sSize; index++) {\n",
920 name.c_str());
921 stringBuilder.Append(prefix).Append(TAB).AppendFormat("let %sValue = new %s();\n",
922 name.c_str(), typeName.string());
923 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.readSequenceable(%sValue);\n",
924 parcelName.string(), name.c_str());
925 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.push(%sValue);\n", name.c_str(),
926 name.c_str());
927 stringBuilder.Append(prefix).AppendFormat("}\n");
928 }
929 break;
930 default:
931 break;
932 }
933 }
934
EmitReadOutVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)935 void TsCodeEmitter::EmitReadOutVariable(const String& parcelName, const std::string& name, MetaType* mt,
936 StringBuilder& stringBuilder,
937 const String& prefix)
938 {
939 switch (mt->kind_) {
940 case TypeKind::Boolean:
941 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt() == 1 ? true : false;\n",
942 name.c_str(), parcelName.string());
943 break;
944 case TypeKind::Char:
945 case TypeKind::Byte:
946 case TypeKind::Short:
947 case TypeKind::Integer:
948 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt();\n", name.c_str(), parcelName.string());
949 break;
950 case TypeKind::Long:
951 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLong();\n", name.c_str(), parcelName.string());
952 break;
953 case TypeKind::Float:
954 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloat();\n", name.c_str(), parcelName.string());
955 break;
956 case TypeKind::Double:
957 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDouble();\n", name.c_str(), parcelName.string());
958 break;
959 case TypeKind::String:
960 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readString();\n", name.c_str(), parcelName.string());
961 break;
962 case TypeKind::Sequenceable:
963 if (EmitType(mt).Equals("IRemoteObject")) {
964 stringBuilder.Append(prefix).AppendFormat("%s = %s.readRemoteObject();\n", name.c_str(),
965 parcelName.string());
966 break;
967 }
968 stringBuilder.Append(prefix).AppendFormat("let %s = new %s();\n", name.c_str(), EmitType(mt).string());
969 stringBuilder.Append(prefix).AppendFormat("%s.readSequenceable(%s);\n", parcelName.string(), name.c_str());
970 break;
971 case TypeKind::Interface:
972 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readRemoteObject();\n", name.c_str(),
973 parcelName.string());
974 break;
975 case TypeKind::List: {
976 stringBuilder.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(),
977 parcelName.string());
978 stringBuilder.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
979 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
980 EmitReadVariable(parcelName, "value", innerType, ATTR_IN, stringBuilder, prefix + TAB);
981 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.add(value);\n", name.c_str());
982 stringBuilder.Append(prefix).Append("}\n");
983 break;
984 }
985 case TypeKind::Map: {
986 stringBuilder.Append(prefix).AppendFormat("let %s = new Map();\n", name.c_str());
987 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
988 parcelName.string());
989 stringBuilder.Append(prefix).AppendFormat("for (let i = 0; i < %sSize; ++i) {\n", name.c_str());
990 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
991 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
992 EmitReadVariable(parcelName, "key", keyType, ATTR_IN, stringBuilder, prefix + TAB);
993 EmitReadVariable(parcelName, "value", valueType, ATTR_IN, stringBuilder, prefix + TAB);
994 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.set(key, value);\n", name.c_str());
995 stringBuilder.Append(prefix).Append("}\n");
996 break;
997 }
998 case TypeKind::Array: {
999 EmitReadOutArrayVariable(parcelName, name, mt, stringBuilder, prefix);
1000 break;
1001 }
1002 default:
1003 break;
1004 }
1005 }
1006
EmitType(MetaType * mt)1007 String TsCodeEmitter::EmitType(MetaType* mt)
1008 {
1009 switch (mt->kind_) {
1010 case TypeKind::Boolean:
1011 return "boolean";
1012 case TypeKind::Byte:
1013 return "number";
1014 case TypeKind::Short:
1015 return "number";
1016 case TypeKind::Integer:
1017 return "number";
1018 case TypeKind::Long:
1019 return "number";
1020 case TypeKind::Float:
1021 return "number";
1022 case TypeKind::Double:
1023 return "number";
1024 case TypeKind::String:
1025 return "string";
1026 case TypeKind::Void:
1027 return "void";
1028 case TypeKind::Sequenceable: {
1029 MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
1030 return mp->name_;
1031 }
1032 case TypeKind::Interface: {
1033 MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
1034 return mi->name_;
1035 }
1036 case TypeKind::Map: {
1037 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1038 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1039 if (EmitType(keyType).string() == UNKNOWN_TYPE || EmitType(valueType).string() == UNKNOWN_TYPE) {
1040 return String(UNKNOWN_TYPE.c_str());
1041 }
1042 return String::Format("Map<%s, %s>", EmitType(keyType).string(), EmitType(valueType).string());
1043 }
1044 case TypeKind::Array: {
1045 MetaType* elementType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1046 if (EmitType(elementType).string() == UNKNOWN_TYPE) {
1047 return String(UNKNOWN_TYPE.c_str());
1048 }
1049 return String::Format("%s[]", EmitType(elementType).string());
1050 }
1051 default:
1052 return String(UNKNOWN_TYPE.c_str());
1053 }
1054 }
1055
FileName(const String & name)1056 String TsCodeEmitter::FileName(const String& name)
1057 {
1058 if (name.IsEmpty()) {
1059 return name;
1060 }
1061
1062 StringBuilder stringBuilder;
1063 for (int index = 0; index < name.GetLength(); index++) {
1064 char c = name[index];
1065 if (isupper(c) != 0) {
1066 if (index > 0) {
1067 stringBuilder.Append('_');
1068 }
1069 stringBuilder.Append(tolower(c));
1070 } else {
1071 stringBuilder.Append(c);
1072 }
1073 }
1074 return stringBuilder.ToString().Replace('.', '/');
1075 }
1076
MethodName(const String & name)1077 String TsCodeEmitter::MethodName(const String& name)
1078 {
1079 if (name.IsEmpty() || islower(name[0])) {
1080 return name;
1081 }
1082 return String::Format("%c%s", tolower(name[0]), name.Substring(1).string());
1083 }
1084
ConstantName(const String & name)1085 String TsCodeEmitter::ConstantName(const String& name)
1086 {
1087 if (name.IsEmpty()) {
1088 return name;
1089 }
1090
1091 StringBuilder stringBuilder;
1092
1093 for (int index = 0; index < name.GetLength(); index++) {
1094 char c = name[index];
1095 if (isupper(c) != 0) {
1096 if (index > 1) {
1097 stringBuilder.Append('_');
1098 }
1099 stringBuilder.Append(c);
1100 } else {
1101 stringBuilder.Append(toupper(c));
1102 }
1103 }
1104
1105 return stringBuilder.ToString();
1106 }
1107
StubName(const String & name)1108 String TsCodeEmitter::StubName(const String& name)
1109 {
1110 return name.StartsWith("I") ? (name.Substring(1) + "Stub") : (name + "Stub");
1111 }
1112
UnderlineAdded(const String & originName)1113 const std::string TsCodeEmitter::UnderlineAdded(const String& originName)
1114 {
1115 std::string underline("_");
1116 return underline + std::string(originName.string());
1117 }
1118
CheckInterfaceType()1119 bool TsCodeEmitter::CheckInterfaceType()
1120 {
1121 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
1122 MetaMethod* metaMethod = metaInterface_->methods_[index];
1123 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
1124 std::string returnTypeStr = EmitType(returnType).string();
1125 if (returnTypeStr == UNKNOWN_TYPE) {
1126 Logger::E(TAG, "unsupported type in .idl file");
1127 return false;
1128 }
1129 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
1130 MetaParameter* mp = metaMethod->parameters_[index];
1131 MetaType* paraType = metaComponent_->types_[mp->typeIndex_];
1132 std::string paraTypeStr = EmitType(paraType).string();
1133 if (paraTypeStr == UNKNOWN_TYPE) {
1134 Logger::E(TAG, "unsupported type in .idl file");
1135 return false;
1136 }
1137 }
1138 }
1139 return true;
1140 }
1141 } // namespace Idl
1142 } // namespace OHOS
1143