1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "parser/parser.h"
10
11 #include <regex>
12
13 #include "ast/ast_array_type.h"
14 #include "ast/ast_enum_type.h"
15 #include "ast/ast_map_type.h"
16 #include "ast/ast_parameter.h"
17 #include "ast/ast_sequenceable_type.h"
18 #include "ast/ast_smq_type.h"
19 #include "ast/ast_struct_type.h"
20 #include "ast/ast_union_type.h"
21 #include "util/logger.h"
22 #include "util/string_builder.h"
23
24 #define RE_BIN_DIGIT "0[b][0|1]+" // binary digit
25 #define RE_OCT_DIGIT "0[0-7]+" // octal digit
26 #define RE_DEC_DIGIT "[0-9]+" // decimal digit
27 #define RE_HEX_DIFIT "0[xX][0-9a-fA-F]+" // hexadecimal digit
28 #define RE_DIGIT_SUFFIX "(u|l|ll|ul|ull|)$"
29 #define RE_IDENTIFIER "[a-zA-Z_][a-zA-Z0-9_]*"
30
31 #define RE_PACKAGE_NUM 3
32 #define RE_PACKAGE_INDEX 0
33 #define RE_PACKAGE_MAJOR_VER_INDEX 1
34 #define RE_PACKAGE_MINOR_VER_INDEX 2
35
36 namespace OHOS {
37 namespace HDI {
38 static const std::regex RE_PACKAGE(RE_IDENTIFIER "(?:\\." RE_IDENTIFIER ")*\\.[V|v]"
39 "(" RE_DEC_DIGIT ")_(" RE_DEC_DIGIT ")");
40 static const std::regex RE_IMPORT(
41 RE_IDENTIFIER "(?:\\." RE_IDENTIFIER ")*\\.[V|v]" RE_DEC_DIGIT "_" RE_DEC_DIGIT "." RE_IDENTIFIER);
42 static std::regex g_binaryNumRe(RE_BIN_DIGIT RE_DIGIT_SUFFIX, std::regex_constants::icase);
43 static std::regex g_octNumRe(RE_OCT_DIGIT RE_DIGIT_SUFFIX, std::regex_constants::icase);
44 static std::regex g_decNumRe(RE_DEC_DIGIT RE_DIGIT_SUFFIX, std::regex_constants::icase);
45 static std::regex g_hexNumRe(RE_HEX_DIFIT RE_DIGIT_SUFFIX, std::regex_constants::icase);
46
Parse(const std::vector<FileDetail> & fileDetails)47 bool Parser::Parse(const std::vector<FileDetail> &fileDetails)
48 {
49 for (const auto &fileDetail : fileDetails) {
50 if (!ParseOne(fileDetail.filePath_)) {
51 return false;
52 }
53 }
54
55 if (!PostProcess()) {
56 return false;
57 }
58
59 return true;
60 }
61
ParseOne(const std::string & sourceFile)62 bool Parser::ParseOne(const std::string &sourceFile)
63 {
64 if (!Reset(sourceFile)) {
65 return false;
66 }
67
68 bool ret = ParseFile();
69 ret = CheckIntegrity() && ret;
70 ret = AddAst(ast_) && ret;
71 if (!ret || !errors_.empty()) {
72 ShowError();
73 return false;
74 }
75
76 return true;
77 }
78
Reset(const std::string & sourceFile)79 bool Parser::Reset(const std::string &sourceFile)
80 {
81 bool ret = lexer_.Reset(sourceFile);
82 if (!ret) {
83 Logger::E(TAG, "Fail to open file '%s'.", sourceFile.c_str());
84 return false;
85 }
86
87 errors_.clear();
88 ast_ = nullptr;
89 return true;
90 }
91
ParseFile()92 bool Parser::ParseFile()
93 {
94 ast_ = new AST();
95 ast_->SetIdlFile(lexer_.GetFilePath());
96 ast_->SetLicense(ParseLicense());
97
98 if (!ParsePackage()) {
99 return false;
100 }
101
102 if (!ParseImports()) {
103 return false;
104 }
105
106 if (!ParseTypeDecls()) {
107 return false;
108 }
109
110 SetAstFileType();
111 return true;
112 }
113
ParseLicense()114 std::string Parser::ParseLicense()
115 {
116 Token token = lexer_.PeekToken(false);
117 if (token.kind == TokenType::COMMENT_BLOCK) {
118 lexer_.GetToken(false);
119 return token.value;
120 }
121
122 return std::string("");
123 }
124
ParsePackage()125 bool Parser::ParsePackage()
126 {
127 Token token = lexer_.PeekToken();
128 if (token.kind != TokenType::PACKAGE) {
129 LogError(token, StringHelper::Format("expected 'package' before '%s' token", token.value.c_str()));
130 return false;
131 }
132 lexer_.GetToken();
133
134 token = lexer_.PeekToken();
135 if (token.kind != TokenType::ID) {
136 LogError(token, StringHelper::Format("expected name of package before '%s' token", token.value.c_str()));
137 lexer_.SkipToken(TokenType::SEMICOLON);
138 return false;
139 }
140 std::string packageName = token.value;
141 lexer_.GetToken();
142
143 token = lexer_.PeekToken();
144 if (token.kind != TokenType::SEMICOLON) {
145 LogError(token, StringHelper::Format("expected ';' before '%s' token", token.value.c_str()));
146 return false;
147 }
148 lexer_.GetToken();
149
150 if (packageName.empty()) {
151 LogError(std::string("package name is not expected."));
152 return false;
153 } else if (!CheckPackageName(lexer_.GetFilePath(), packageName)) {
154 LogError(StringHelper::Format(
155 "package name '%s' does not match file apth '%s'.", packageName.c_str(), lexer_.GetFilePath().c_str()));
156 return false;
157 }
158
159 if (!ParserPackageInfo(packageName)) {
160 LogError(StringHelper::Format("parse package '%s' infomation failed.", packageName.c_str()));
161 return false;
162 }
163
164 return true;
165 }
166
ParserPackageInfo(const std::string & packageName)167 bool Parser::ParserPackageInfo(const std::string &packageName)
168 {
169 std::cmatch result;
170 if (!std::regex_match(packageName.c_str(), result, RE_PACKAGE)) {
171 return false;
172 }
173
174 if (result.size() < RE_PACKAGE_NUM) {
175 return false;
176 }
177
178 ast_->SetPackageName(result.str(RE_PACKAGE_INDEX).c_str());
179 size_t majorVersion = std::stoul(result.str(RE_PACKAGE_MAJOR_VER_INDEX));
180 size_t minorVersion = std::stoul(result.str(RE_PACKAGE_MINOR_VER_INDEX));
181 ast_->SetVersion(majorVersion, minorVersion);
182 return true;
183 }
184
ParseImports()185 bool Parser::ParseImports()
186 {
187 Token token = lexer_.PeekToken();
188 while (token.kind == TokenType::IMPORT || token.kind == TokenType::SEQ) {
189 TokenType kind = token.kind;
190 lexer_.GetToken();
191
192 token = lexer_.PeekToken();
193 if (token.kind != TokenType::ID) {
194 LogError(token, StringHelper::Format("expected identifier before '%s' token", token.value.c_str()));
195 lexer_.SkipToken(TokenType::SEMICOLON);
196 token = lexer_.PeekToken();
197 continue;
198 }
199
200 if (kind == TokenType::IMPORT) {
201 ParseImportInfo();
202 } else {
203 ParseSequenceableInfo();
204 }
205 lexer_.GetToken();
206
207 token = lexer_.PeekToken();
208 if (token.kind != TokenType::SEMICOLON) {
209 LogError(token, StringHelper::Format("expected ';' before '%s'.", token.value.c_str()));
210 return false;
211 }
212 lexer_.GetToken();
213
214 token = lexer_.PeekToken();
215 }
216
217 return true;
218 }
219
ParseImportInfo()220 void Parser::ParseImportInfo()
221 {
222 Token token = lexer_.PeekToken();
223 std::string importName = token.value;
224 if (importName.empty()) {
225 LogError(token, StringHelper::Format("import name is empty"));
226 return;
227 }
228
229 if (!CheckImport(importName)) {
230 LogError(token, StringHelper::Format("import name is illegal"));
231 return;
232 }
233
234 auto iter = allAsts_.find(importName);
235 AutoPtr<AST> importAst = (iter != allAsts_.end()) ? iter->second : nullptr;
236 if (importAst == nullptr) {
237 LogError(token, StringHelper::Format("can not find idl file from import name '%s'", importName.c_str()));
238 return;
239 }
240
241 if (!ast_->AddImport(importAst)) {
242 LogError(token, StringHelper::Format("multiple import of '%s'", importName.c_str()));
243 return;
244 }
245 }
246
ParseSequenceableInfo()247 void Parser::ParseSequenceableInfo()
248 {
249 Token token = lexer_.PeekToken();
250 std::string seqName = token.value;
251 if (seqName.empty()) {
252 LogError(token, StringHelper::Format("sequenceable name is empty"));
253 return;
254 }
255
256 AutoPtr<ASTSequenceableType> seqType = new ASTSequenceableType();
257 size_t index = seqName.rfind('.');
258 if (index != std::string::npos) {
259 seqType->SetName(seqName.substr(index + 1));
260 seqType->SetNamespace(ast_->ParseNamespace(seqName.substr(0, index)));
261 } else {
262 seqType->SetName(seqName);
263 }
264
265 AutoPtr<AST> seqAst = new AST();
266 seqAst->SetFullName(seqName);
267 seqAst->AddSequenceableDef(seqType);
268 seqAst->SetAStFileType(ASTFileType::AST_SEQUENCEABLE);
269 ast_->AddImport(seqAst);
270 AddAst(seqAst);
271 }
272
ParseTypeDecls()273 bool Parser::ParseTypeDecls()
274 {
275 Token token = lexer_.PeekToken();
276 while (token.kind != TokenType::END_OF_FILE) {
277 switch (token.kind) {
278 case TokenType::BRACKETS_LEFT:
279 ParseAttribute();
280 break;
281 case TokenType::INTERFACE:
282 ParseInterface();
283 break;
284 case TokenType::ENUM:
285 ParseEnumDeclaration();
286 break;
287 case TokenType::STRUCT:
288 ParseStructDeclaration();
289 break;
290 case TokenType::UNION:
291 ParseUnionDeclaration();
292 break;
293 default:
294 LogError(token, StringHelper::Format("'%s' is not expected", token.value.c_str()));
295 lexer_.SkipToken(TokenType::SEMICOLON);
296 break;
297 }
298 token = lexer_.PeekToken();
299 }
300 return true;
301 }
302
ParseAttribute()303 void Parser::ParseAttribute()
304 {
305 AttrSet attrs = ParseAttributeInfo();
306 Token token = lexer_.PeekToken();
307 switch (token.kind) {
308 case TokenType::INTERFACE:
309 ParseInterface(attrs);
310 break;
311 case TokenType::ENUM:
312 ParseEnumDeclaration(attrs);
313 break;
314 case TokenType::STRUCT:
315 ParseStructDeclaration(attrs);
316 break;
317 case TokenType::UNION:
318 ParseUnionDeclaration(attrs);
319 break;
320 default:
321 LogError(token, StringHelper::Format("'%s' is not expected", token.value.c_str()));
322 lexer_.SkipToken(token.kind);
323 break;
324 }
325 }
326
ParseAttributeInfo()327 AttrSet Parser::ParseAttributeInfo()
328 {
329 AttrSet attrs;
330 Token token = lexer_.PeekToken();
331 if (token.kind != TokenType::BRACKETS_LEFT) {
332 LogError(token, StringHelper::Format("expected '[' before '%s' token", token.value.c_str()));
333 lexer_.SkipToken(token.kind);
334 return attrs;
335 }
336 lexer_.GetToken();
337
338 token = lexer_.PeekToken();
339 while (token.kind != TokenType::BRACKETS_RIGHT && token.kind != TokenType::END_OF_FILE) {
340 if (!AprseAttrUnit(attrs)) {
341 return attrs;
342 }
343 token = lexer_.PeekToken();
344 if (token.kind == TokenType::COMMA) {
345 lexer_.GetToken();
346 token = lexer_.PeekToken();
347 continue;
348 }
349
350 if (token.kind == TokenType::BRACKETS_RIGHT) {
351 lexer_.GetToken();
352 break;
353 } else {
354 LogError(token, StringHelper::Format("expected ',' or ']' before '%s' token", token.value.c_str()));
355 lexer_.SkipToken(TokenType::BRACKETS_RIGHT);
356 break;
357 }
358 }
359
360 return attrs;
361 }
362
AprseAttrUnit(AttrSet & attrs)363 bool Parser::AprseAttrUnit(AttrSet &attrs)
364 {
365 Token token = lexer_.PeekToken();
366 switch (token.kind) {
367 case TokenType::FULL:
368 case TokenType::LITE:
369 case TokenType::MINI:
370 case TokenType::CALLBACK:
371 case TokenType::ONEWAY: {
372 if (attrs.find(token) != attrs.end()) {
373 LogError(token, StringHelper::Format("Duplicate declared attributes '%s'", token.value.c_str()));
374 } else {
375 attrs.insert(token);
376 }
377 lexer_.GetToken();
378 break;
379 }
380 default:
381 LogError(token, StringHelper::Format("'%s' is a illegal attribute", token.value.c_str()));
382 lexer_.SkipToken(TokenType::BRACKETS_RIGHT);
383 return false;
384 }
385 return true;
386 }
387
ParseInterface(const AttrSet & attrs)388 void Parser::ParseInterface(const AttrSet &attrs)
389 {
390 AutoPtr<ASTInterfaceType> interfaceType = new ASTInterfaceType;
391 AutoPtr<ASTAttr> astAttr = ParseInfAttrInfo(attrs);
392 interfaceType->SetAttribute(astAttr);
393
394 lexer_.GetToken();
395 Token token = lexer_.PeekToken();
396 if (token.kind != TokenType::ID) {
397 LogError(token, StringHelper::Format("expected interface name before '%s' token", token.value.c_str()));
398 } else {
399 interfaceType->SetName(token.value);
400 interfaceType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
401 interfaceType->SetLicense(ast_->GetLicense());
402 if (token.value != ast_->GetName()) {
403 LogError(
404 token, StringHelper::Format("interface name '%s' is not equal idl file name", token.value.c_str()));
405 }
406 lexer_.GetToken();
407 }
408
409 CheckInterfaceAttr(interfaceType, token);
410 ParseInterfaceExtends(interfaceType);
411 ParseInterfaceBody(interfaceType);
412 SetInterfaceVersion(interfaceType);
413 ast_->AddInterfaceDef(interfaceType);
414 }
415
ParseInfAttrInfo(const AttrSet & attrs)416 AutoPtr<ASTAttr> Parser::ParseInfAttrInfo(const AttrSet &attrs)
417 {
418 AutoPtr<ASTAttr> infAttr = new ASTAttr();
419 bool isFull = false;
420 bool isLite = false;
421 bool isMini = false;
422
423 for (const auto &attr : attrs) {
424 switch (attr.kind) {
425 case TokenType::FULL:
426 isFull = true;
427 break;
428 case TokenType::LITE:
429 isLite = true;
430 break;
431 case TokenType::MINI:
432 isMini = true;
433 break;
434 case TokenType::CALLBACK:
435 infAttr->SetValue(ASTAttr::CALLBACK);
436 break;
437 case TokenType::ONEWAY:
438 infAttr->SetValue(ASTAttr::ONEWAY);
439 break;
440 default:
441 LogError(attr, StringHelper::Format("illegal attribute of interface"));
442 break;
443 }
444 }
445
446 if (!isFull && !isLite && !isMini) {
447 infAttr->SetValue(ASTAttr::FULL | ASTAttr::LITE | ASTAttr::MINI);
448 } else {
449 if (isFull) {
450 infAttr->SetValue(ASTAttr::FULL);
451 }
452 if (isLite) {
453 infAttr->SetValue(ASTAttr::LITE);
454 }
455 if (isMini) {
456 infAttr->SetValue(ASTAttr::MINI);
457 }
458 }
459
460 return infAttr;
461 }
462
CheckInterfaceAttr(const AutoPtr<ASTInterfaceType> & interface,Token token)463 void Parser::CheckInterfaceAttr(const AutoPtr<ASTInterfaceType> &interface, Token token)
464 {
465 bool ret = true;
466 std::string systemName;
467 switch (Options::GetInstance().GetSystemLevel()) {
468 case SystemLevel::FULL:
469 systemName = "full";
470 ret = interface->IsFull();
471 break;
472 case SystemLevel::LITE:
473 systemName = "lite";
474 ret = interface->IsLite();
475 break;
476 case SystemLevel::MINI:
477 systemName = "mini";
478 ret = interface->IsMini();
479 break;
480 default:
481 break;
482 }
483
484 if (!ret) {
485 LogError(token, StringHelper::Format("the system option is '%s', but the '%s' interface has no '%s' attribute",
486 systemName.c_str(), interface->GetName().c_str(), systemName.c_str()));
487 }
488 }
489
ParseInterfaceBody(const AutoPtr<ASTInterfaceType> & interface)490 void Parser::ParseInterfaceBody(const AutoPtr<ASTInterfaceType> &interface)
491 {
492 Token token = lexer_.PeekToken();
493 if (token.kind != TokenType::BRACES_LEFT) {
494 LogError(token, StringHelper::Format("expected '{' before '%s' token", token.value.c_str()));
495 } else {
496 lexer_.GetToken();
497 }
498
499 token = lexer_.PeekToken();
500 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
501 AutoPtr<ASTMethod> method = ParseMethod(interface);
502 interface->AddMethod(method);
503 token = lexer_.PeekToken();
504 }
505
506 token = lexer_.PeekToken();
507 if (token.kind != TokenType::BRACES_RIGHT) {
508 LogError(token, StringHelper::Format("expected '{' before '%s' token", token.value.c_str()));
509 } else {
510 lexer_.GetToken();
511 }
512
513 token = lexer_.PeekToken();
514 if (token.kind == TokenType::SEMICOLON) {
515 lexer_.GetToken();
516 }
517
518 interface->AddVersionMethod(CreateGetVersionMethod());
519 }
520
ParseMethod(const AutoPtr<ASTInterfaceType> & interface)521 AutoPtr<ASTMethod> Parser::ParseMethod(const AutoPtr<ASTInterfaceType> &interface)
522 {
523 AutoPtr<ASTMethod> method = new ASTMethod();
524 method->SetAttribute(ParseMethodAttr());
525
526 Token token = lexer_.PeekToken();
527 if (token.kind != TokenType::ID) {
528 LogError(token, StringHelper::Format("expected method name before '%s' token", token.value.c_str()));
529 } else {
530 method->SetName(token.value);
531 lexer_.GetToken();
532 }
533
534 CheckMethodAttr(interface, method);
535 ParseMethodParamList(method);
536
537 token = lexer_.PeekToken();
538 if (token.kind != TokenType::SEMICOLON) {
539 LogError(token, StringHelper::Format("expected ';' before '%s' token", token.value.c_str()));
540 } else {
541 lexer_.GetToken();
542 }
543
544 return method;
545 }
546
ParseMethodAttr()547 AutoPtr<ASTAttr> Parser::ParseMethodAttr()
548 {
549 if (lexer_.PeekToken().kind != TokenType::BRACKETS_LEFT) {
550 return new ASTAttr();
551 }
552
553 AttrSet attrs = ParseAttributeInfo();
554 AutoPtr<ASTAttr> methodAttr = new ASTAttr();
555 bool isFull = false;
556 bool isLite = false;
557 bool isMini = false;
558
559 for (const auto &attr : attrs) {
560 switch (attr.kind) {
561 case TokenType::FULL:
562 isFull = true;
563 break;
564 case TokenType::LITE:
565 isLite = true;
566 break;
567 case TokenType::MINI:
568 isMini = true;
569 break;
570 case TokenType::ONEWAY:
571 methodAttr->SetValue(ASTAttr::ONEWAY);
572 break;
573 default:
574 LogError(attr, StringHelper::Format("illegal attribute of interface"));
575 break;
576 }
577 }
578
579 if (isFull) {
580 methodAttr->SetValue(ASTAttr::FULL);
581 }
582 if (isLite) {
583 methodAttr->SetValue(ASTAttr::LITE);
584 }
585 if (isMini) {
586 methodAttr->SetValue(ASTAttr::MINI);
587 }
588
589 return methodAttr;
590 }
591
CreateGetVersionMethod()592 AutoPtr<ASTMethod> Parser::CreateGetVersionMethod()
593 {
594 AutoPtr<ASTMethod> method = new ASTMethod();
595 method->SetName("GetVersion");
596
597 AutoPtr<ASTType> type = ast_->FindType("unsigned int");
598 if (type == nullptr) {
599 type = new ASTUintType();
600 }
601 AutoPtr<ASTParameter> majorParam = new ASTParameter("majorVer", ParamAttr::PARAM_OUT, type);
602 AutoPtr<ASTParameter> minorParam = new ASTParameter("minorVer", ParamAttr::PARAM_OUT, type);
603
604 method->AddParameter(majorParam);
605 method->AddParameter(minorParam);
606 return method;
607 }
608
CheckMethodAttr(const AutoPtr<ASTInterfaceType> & interface,const AutoPtr<ASTMethod> & method)609 void Parser::CheckMethodAttr(const AutoPtr<ASTInterfaceType> &interface, const AutoPtr<ASTMethod> &method)
610 {
611 // if the attribute of method is empty, the default value is attribute of interface
612 if (!method->IsMini() && !method->IsLite() && !method->IsFull()) {
613 method->GetAttribute()->SetValue(ASTAttr::FULL | ASTAttr::LITE | ASTAttr::MINI);
614 }
615
616 if (!interface->IsMini() && method->IsMini()) {
617 LogError(StringHelper::Format(
618 "the '%s' mehtod can not have 'mini' attribute, because the '%s' interface has no 'mini' attribute",
619 method->GetName().c_str(), interface->GetName().c_str()));
620 }
621
622 if (!interface->IsLite() && method->IsLite()) {
623 LogError(StringHelper::Format(
624 "the '%s' mehtod can not have 'lite' attribute, because the '%s' interface has no 'lite' attribute",
625 method->GetName().c_str(), interface->GetName().c_str()));
626 }
627
628 if (!interface->IsFull() && method->IsFull()) {
629 LogError(StringHelper::Format(
630 "the '%s' mehtod can not have 'full' attribute, because the '%s' interface has no 'full' attribute",
631 method->GetName().c_str(), interface->GetName().c_str()));
632 }
633
634 // the method has 'oneway' attribute if interface or method has 'oneway' attribute
635 if (interface->IsOneWay() || method->IsOneWay()) {
636 method->GetAttribute()->SetValue(ASTAttr::ONEWAY);
637 }
638 }
639
ParseMethodParamList(const AutoPtr<ASTMethod> & method)640 void Parser::ParseMethodParamList(const AutoPtr<ASTMethod> &method)
641 {
642 Token token = lexer_.PeekToken();
643 if (token.kind != TokenType::PARENTHESES_LEFT) {
644 LogError(token, StringHelper::Format("expected '(' before '%s' token", token.value.c_str()));
645 } else {
646 lexer_.GetToken();
647 }
648
649 token = lexer_.PeekToken();
650 if (token.kind == TokenType::PARENTHESES_RIGHT) {
651 lexer_.GetToken();
652 return;
653 }
654
655 while (token.kind != TokenType::PARENTHESES_RIGHT && token.kind != TokenType::END_OF_FILE) {
656 AutoPtr<ASTParameter> param = ParseParam();
657 if (method->IsOneWay() && param->GetAttribute() == ParamAttr::PARAM_OUT) {
658 LogError(token, StringHelper::Format("the '%s' parameter of '%s' method can not be 'out'",
659 param->GetName().c_str(), method->GetName().c_str()));
660 }
661 method->AddParameter(param);
662
663 token = lexer_.PeekToken();
664 if (token.kind == TokenType::COMMA) {
665 lexer_.GetToken();
666 token = lexer_.PeekToken();
667 if (token.kind == TokenType::PARENTHESES_RIGHT) {
668 LogError(token, StringHelper::Format(""));
669 }
670 continue;
671 }
672
673 if (token.kind == TokenType::PARENTHESES_RIGHT) {
674 lexer_.GetToken();
675 break;
676 } else {
677 LogError(token, StringHelper::Format("expected ',' or ')' before '%s' token", token.value.c_str()));
678 lexer_.SkipToken(TokenType::PARENTHESES_RIGHT);
679 break;
680 }
681 }
682 }
683
ParseParam()684 AutoPtr<ASTParameter> Parser::ParseParam()
685 {
686 AutoPtr<ASTParamAttr> paramAttr = ParseParamAttr();
687 AutoPtr<ASTType> paramType = ParseType();
688 std::string paramName = "";
689
690 Token token = lexer_.PeekToken();
691 if (token.kind != TokenType::ID) {
692 LogError(token, StringHelper::Format("expected param name before '%s' token", token.value.c_str()));
693 } else {
694 paramName = token.value;
695 lexer_.GetToken();
696 }
697
698 if (paramType != nullptr && paramType->IsInterfaceType()) {
699 AutoPtr<ASTInterfaceType> ifaceType = dynamic_cast<ASTInterfaceType *>(paramType.Get());
700 if (ifaceType->IsCallback() && paramAttr->value_ != ParamAttr::PARAM_IN) {
701 LogError(token, StringHelper::Format("'%s' parameter of callback interface type must be 'in' attribute",
702 paramName.c_str()));
703 } else if (!ifaceType->IsCallback() && paramAttr->value_ != ParamAttr::PARAM_OUT) {
704 LogError(token, StringHelper::Format("'%s' parameter of interface type must be 'out' attribute",
705 paramName.c_str()));
706 }
707 if (!ifaceType->IsCallback()) {
708 ifaceType->SetSerializable(true);
709 }
710 }
711
712 return new ASTParameter(paramName, paramAttr, paramType);
713 }
714
ParseParamAttr()715 AutoPtr<ASTParamAttr> Parser::ParseParamAttr()
716 {
717 AutoPtr<ASTParamAttr> attr = new ASTParamAttr(ParamAttr::PARAM_IN);
718 Token token = lexer_.PeekToken();
719 if (token.kind != TokenType::BRACKETS_LEFT) {
720 LogError(token, StringHelper::Format("expected '[' before '%s' token", token.value.c_str()));
721 } else {
722 lexer_.GetToken();
723 }
724
725 token = lexer_.PeekToken();
726 if (token.kind == TokenType::IN) {
727 attr->value_ = ParamAttr::PARAM_IN;
728 lexer_.GetToken();
729 } else if (token.kind == TokenType::OUT) {
730 attr->value_ = ParamAttr::PARAM_OUT;
731 lexer_.GetToken();
732 } else {
733 LogError(
734 token, StringHelper::Format("expected 'in' or 'out' attribute before '%s' token", token.value.c_str()));
735 }
736
737 token = lexer_.PeekToken();
738 if (token.kind != TokenType::BRACKETS_RIGHT) {
739 LogError(token, StringHelper::Format("expected ']' before '%s' token", token.value.c_str()));
740 } else {
741 lexer_.GetToken();
742 }
743
744 return attr;
745 }
746
ParseType()747 AutoPtr<ASTType> Parser::ParseType()
748 {
749 AutoPtr<ASTType> type = nullptr;
750 Token token = lexer_.PeekToken();
751 switch (token.kind) {
752 case TokenType::BOOLEAN:
753 case TokenType::BYTE:
754 case TokenType::SHORT:
755 case TokenType::INT:
756 case TokenType::LONG:
757 case TokenType::STRING:
758 case TokenType::FLOAT:
759 case TokenType::DOUBLE:
760 case TokenType::FD:
761 case TokenType::ASHMEM:
762 case TokenType::NATIVE_BUFFER:
763 case TokenType::POINTER:
764 case TokenType::UNSIGNED:
765 type = ParseBasicType();
766 break;
767 case TokenType::LIST:
768 type = ParseListType();
769 break;
770 case TokenType::MAP:
771 type = ParseMapType();
772 break;
773 case TokenType::SMQ:
774 type = ParseSmqType();
775 break;
776 case TokenType::ENUM:
777 case TokenType::STRUCT:
778 case TokenType::UNION:
779 case TokenType::ID:
780 case TokenType::SEQ:
781 type = ParseUserDefType();
782 break;
783 default:
784 LogError(token, StringHelper::Format("'%s' of type is illegal", token.value.c_str()));
785 return nullptr;
786 }
787 if (type == nullptr) {
788 LogError(token, StringHelper::Format("this type was not declared in this scope"));
789 }
790 if (!CheckType(token, type)) {
791 return nullptr;
792 }
793
794 while (lexer_.PeekToken().kind == TokenType::BRACKETS_LEFT) {
795 type = ParseArrayType(type);
796 }
797 return type;
798 }
799
ParseBasicType()800 AutoPtr<ASTType> Parser::ParseBasicType()
801 {
802 AutoPtr<ASTType> type = nullptr;
803 Token token = lexer_.PeekToken();
804 if (token.kind == TokenType::UNSIGNED) {
805 type = ParseUnsignedType();
806 } else {
807 type = ast_->FindType(token.value);
808 lexer_.GetToken();
809 }
810
811 ast_->AddType(type);
812 return type;
813 }
814
ParseUnsignedType()815 AutoPtr<ASTType> Parser::ParseUnsignedType()
816 {
817 AutoPtr<ASTType> type = nullptr;
818 std::string namePrefix = lexer_.GetToken().value;
819 Token token = lexer_.PeekToken();
820 switch (token.kind) {
821 case TokenType::CHAR:
822 case TokenType::SHORT:
823 case TokenType::INT:
824 case TokenType::LONG:
825 type = ast_->FindType(namePrefix + " " + token.value);
826 lexer_.GetToken();
827 break;
828 default:
829 LogError(
830 token, StringHelper::Format("'unsigned %s' was not declared in the idl file", token.value.c_str()));
831 break;
832 }
833
834 return type;
835 }
836
ParseArrayType(const AutoPtr<ASTType> & elementType)837 AutoPtr<ASTType> Parser::ParseArrayType(const AutoPtr<ASTType> &elementType)
838 {
839 lexer_.GetToken(); // '['
840
841 Token token = lexer_.PeekToken();
842 if (token.kind != TokenType::BRACKETS_RIGHT) {
843 LogError(token, StringHelper::Format("expected ']' before '%s' token", token.value.c_str()));
844 return nullptr;
845 }
846 lexer_.GetToken(); // ']'
847
848 if (elementType == nullptr) {
849 return nullptr;
850 }
851
852 AutoPtr<ASTArrayType> arrayType = new ASTArrayType();
853 arrayType->SetElementType(elementType);
854 AutoPtr<ASTType> retType = arrayType.Get();
855 ast_->AddType(retType);
856 return retType;
857 }
858
ParseListType()859 AutoPtr<ASTType> Parser::ParseListType()
860 {
861 lexer_.GetToken(); // List
862
863 Token token = lexer_.PeekToken();
864 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
865 LogError(token, StringHelper::Format("expected '<' before '%s' token", token.value.c_str()));
866 } else {
867 lexer_.GetToken(); // '<'
868 }
869
870 AutoPtr<ASTType> type = ParseType(); // element type
871 if (type == nullptr) {
872 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
873 return nullptr;
874 }
875
876 token = lexer_.PeekToken();
877 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
878 LogError(token, StringHelper::Format("expected '>' before '%s' token", token.value.c_str()));
879 } else {
880 lexer_.GetToken(); // '>'
881 }
882
883 AutoPtr<ASTListType> listType = new ASTListType();
884 listType->SetElementType(type);
885 AutoPtr<ASTType> retType = listType.Get();
886 ast_->AddType(retType);
887 return retType;
888 }
889
ParseMapType()890 AutoPtr<ASTType> Parser::ParseMapType()
891 {
892 lexer_.GetToken(); // 'Map'
893
894 Token token = lexer_.PeekToken();
895 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
896 LogError(token, StringHelper::Format("expected '<' before '%s' token", token.value.c_str()));
897 } else {
898 lexer_.GetToken(); // '<'
899 }
900
901 AutoPtr<ASTType> keyType = ParseType(); // key type
902 if (keyType == nullptr) {
903 LogError(token, StringHelper::Format("key type '%s' is illegal", token.value.c_str()));
904 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
905 return nullptr;
906 }
907
908 token = lexer_.PeekToken();
909 if (token.kind != TokenType::COMMA) {
910 LogError(token, StringHelper::Format("expected ',' before '%s' token", token.value.c_str()));
911 } else {
912 lexer_.GetToken(); // ','
913 }
914
915 AutoPtr<ASTType> valueType = ParseType();
916 if (valueType == nullptr) {
917 LogError(token, StringHelper::Format("key type '%s' is illegal", token.value.c_str()));
918 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
919 return nullptr;
920 }
921
922 token = lexer_.PeekToken();
923 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
924 LogError(token, StringHelper::Format("expected '>' before '%s' token", token.value.c_str()));
925 } else {
926 lexer_.GetToken();
927 }
928
929 AutoPtr<ASTMapType> mapType = new ASTMapType();
930 mapType->SetKeyType(keyType);
931 mapType->SetValueType(valueType);
932 AutoPtr<ASTType> retType = mapType.Get();
933 ast_->AddType(retType);
934 return retType;
935 }
936
ParseSmqType()937 AutoPtr<ASTType> Parser::ParseSmqType()
938 {
939 lexer_.GetToken(); // 'SharedMemQueue'
940
941 Token token = lexer_.PeekToken();
942 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
943 LogError(token, StringHelper::Format("expected '<' before '%s' token", token.value.c_str()));
944 } else {
945 lexer_.GetToken(); // '<'
946 }
947
948 AutoPtr<ASTType> innerType = ParseType();
949 if (innerType == nullptr) {
950 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
951 return nullptr;
952 }
953
954 token = lexer_.PeekToken();
955 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
956 LogError(token, StringHelper::Format("expected '>' before '%s' token", token.value.c_str()));
957 } else {
958 lexer_.GetToken(); // '>'
959 }
960
961 AutoPtr<ASTSmqType> smqType = new ASTSmqType();
962 smqType->SetInnerType(innerType);
963 AutoPtr<ASTType> retType = smqType.Get();
964 ast_->AddType(retType);
965 return retType;
966 }
967
ParseUserDefType()968 AutoPtr<ASTType> Parser::ParseUserDefType()
969 {
970 Token token = lexer_.GetToken();
971 if (token.kind == TokenType::ID) {
972 return ast_->FindType(token.value);
973 }
974
975 token = lexer_.PeekToken();
976 if (token.kind != TokenType::ID) {
977 LogError(token, StringHelper::Format("expected identifier before '%s' token", token.value.c_str()));
978 return nullptr;
979 } else {
980 lexer_.GetToken();
981 }
982
983 std::string typeName = token.value;
984 AutoPtr<ASTType> type = ast_->FindType(typeName);
985 ast_->AddType(type);
986 return type;
987 }
988
ParseEnumDeclaration(const AttrSet & attrs)989 void Parser::ParseEnumDeclaration(const AttrSet &attrs)
990 {
991 AutoPtr<ASTEnumType> enumType = new ASTEnumType;
992 enumType->SetAttribute(ParseUserDefTypeAttr(attrs));
993
994 lexer_.GetToken();
995 Token token = lexer_.PeekToken();
996 if (token.kind != TokenType::ID) {
997 LogError(token, StringHelper::Format("expected enum type name before '%s' token", token.value.c_str()));
998 } else {
999 lexer_.GetToken();
1000 enumType->SetName(token.value);
1001 }
1002
1003 token = lexer_.PeekToken();
1004 if (token.kind == TokenType::COLON || token.kind == TokenType::BRACES_LEFT) {
1005 enumType->SetBaseType(ParseEnumBaseType());
1006 } else {
1007 LogError(token, StringHelper::Format("expected ':' or '{' before '%s' token", token.value.c_str()));
1008 }
1009
1010 ParserEnumMember(enumType);
1011 token = lexer_.PeekToken();
1012 if (token.kind != TokenType::BRACES_RIGHT) {
1013 LogError(token, StringHelper::Format("expected '}' before '%s' token", token.value.c_str()));
1014 return;
1015 } else {
1016 lexer_.GetToken();
1017 }
1018
1019 token = lexer_.PeekToken();
1020 if (token.kind != TokenType::SEMICOLON) {
1021 LogError(token, StringHelper::Format("expected ';' before '%s' token", token.value.c_str()));
1022 } else {
1023 lexer_.GetToken();
1024 }
1025
1026 enumType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1027 ast_->AddTypeDefinition(enumType.Get());
1028 }
1029
ParseEnumBaseType()1030 AutoPtr<ASTType> Parser::ParseEnumBaseType()
1031 {
1032 AutoPtr<ASTType> baseType = nullptr;
1033 Token token = lexer_.PeekToken();
1034 if (token.kind != TokenType::COLON) {
1035 lexer_.GetToken();
1036 baseType = ast_->FindType("int");
1037 return baseType;
1038 }
1039
1040 lexer_.GetToken();
1041 token = lexer_.PeekToken();
1042 baseType = ParseType();
1043 if (baseType != nullptr) {
1044 switch (baseType->GetTypeKind()) {
1045 case TypeKind::TYPE_BYTE:
1046 case TypeKind::TYPE_SHORT:
1047 case TypeKind::TYPE_INT:
1048 case TypeKind::TYPE_LONG:
1049 case TypeKind::TYPE_UCHAR:
1050 case TypeKind::TYPE_USHORT:
1051 case TypeKind::TYPE_UINT:
1052 case TypeKind::TYPE_ULONG:
1053 break;
1054 default: {
1055 LogError(token, StringHelper::Format("illegal base type of enum", baseType->ToString().c_str()));
1056 lexer_.SkipUntilToken(TokenType::BRACES_LEFT);
1057 }
1058 }
1059 }
1060
1061 token = lexer_.PeekToken();
1062 if (token.kind != TokenType::BRACES_LEFT) {
1063 LogError(token, StringHelper::Format("expected '{' before '%s' token", token.value.c_str()));
1064 }
1065 lexer_.GetToken();
1066 return baseType;
1067 }
1068
ParserEnumMember(const AutoPtr<ASTEnumType> & enumType)1069 void Parser::ParserEnumMember(const AutoPtr<ASTEnumType> &enumType)
1070 {
1071 while (lexer_.PeekToken().kind == TokenType::ID) {
1072 Token token = lexer_.GetToken();
1073 AutoPtr<ASTEnumValue> enumValue = new ASTEnumValue(token.value);
1074
1075 token = lexer_.PeekToken();
1076 if (token.kind == TokenType::ASSIGN) {
1077 lexer_.GetToken();
1078 enumValue->SetExprValue(ParseExpr());
1079 }
1080
1081 enumValue->SetType(enumType->GetBaseType());
1082 enumType->AddMember(enumValue);
1083
1084 token = lexer_.PeekToken();
1085 if (token.kind == TokenType::COMMA) {
1086 lexer_.GetToken();
1087 continue;
1088 }
1089
1090 if (token.kind != TokenType::BRACES_RIGHT) {
1091 LogError(token, StringHelper::Format("expected ',' or '}' before '%s' token", token.value.c_str()));
1092 }
1093 }
1094 }
1095
ParseStructDeclaration(const AttrSet & attrs)1096 void Parser::ParseStructDeclaration(const AttrSet &attrs)
1097 {
1098 AutoPtr<ASTStructType> structType = new ASTStructType;
1099 structType->SetAttribute(ParseUserDefTypeAttr(attrs));
1100
1101 lexer_.GetToken();
1102 Token token = lexer_.PeekToken();
1103 if (token.kind != TokenType::ID) {
1104 LogError(token, StringHelper::Format("expected struct name before '%s' token", token.value.c_str()));
1105 } else {
1106 structType->SetName(token.value);
1107 lexer_.GetToken();
1108 }
1109
1110 token = lexer_.PeekToken();
1111 if (token.kind != TokenType::BRACES_LEFT) {
1112 LogError(token, StringHelper::Format("expected '{' before '%s' token", token.value.c_str()));
1113 } else {
1114 lexer_.GetToken();
1115 }
1116
1117 ParseStructMember(structType);
1118
1119 token = lexer_.PeekToken();
1120 if (token.kind != TokenType::BRACES_RIGHT) {
1121 LogError(token, StringHelper::Format("expected '}' before '%s' token", token.value.c_str()));
1122 } else {
1123 lexer_.GetToken();
1124 }
1125
1126 token = lexer_.PeekToken();
1127 if (token.kind != TokenType::SEMICOLON) {
1128 LogError(token, StringHelper::Format("expected ';' before '%s' token", token.value.c_str()));
1129 } else {
1130 lexer_.GetToken();
1131 }
1132
1133 structType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1134 ast_->AddTypeDefinition(structType.Get());
1135 }
1136
ParseStructMember(const AutoPtr<ASTStructType> & structType)1137 void Parser::ParseStructMember(const AutoPtr<ASTStructType> &structType)
1138 {
1139 Token token = lexer_.PeekToken();
1140 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1141 AutoPtr<ASTType> memberType = ParseType();
1142 if (memberType == nullptr) {
1143 lexer_.SkipToken(TokenType::SEMICOLON);
1144 token = lexer_.PeekToken();
1145 continue;
1146 }
1147
1148 token = lexer_.PeekToken();
1149 if (token.kind != TokenType::ID) {
1150 LogError(token, StringHelper::Format("expected member name before '%s' token", token.value.c_str()));
1151 lexer_.SkipToken(TokenType::SEMICOLON);
1152 token = lexer_.PeekToken();
1153 continue;
1154 }
1155
1156 lexer_.GetToken();
1157 std::string memberName = token.value;
1158 structType->AddMember(memberType, memberName);
1159
1160 token = lexer_.PeekToken();
1161 if (token.kind == TokenType::SEMICOLON) {
1162 lexer_.GetToken();
1163 token = lexer_.PeekToken();
1164 continue;
1165 }
1166
1167 if (token.kind != TokenType::BRACES_RIGHT) {
1168 LogError(token, StringHelper::Format("expected ',' or '}' before '%s' token", token.value.c_str()));
1169 }
1170 }
1171 }
1172
ParseUnionDeclaration(const AttrSet & attrs)1173 void Parser::ParseUnionDeclaration(const AttrSet &attrs)
1174 {
1175 AutoPtr<ASTUnionType> unionType = new ASTUnionType;
1176 unionType->SetAttribute(ParseUserDefTypeAttr(attrs));
1177
1178 lexer_.GetToken();
1179 Token token = lexer_.PeekToken();
1180 if (token.kind != TokenType::ID) {
1181 LogError(token, StringHelper::Format("expected struct name before '%s' token", token.value.c_str()));
1182 } else {
1183 unionType->SetName(token.value);
1184 lexer_.GetToken();
1185 }
1186
1187 token = lexer_.PeekToken();
1188 if (token.kind != TokenType::BRACES_LEFT) {
1189 LogError(token, StringHelper::Format("expected '{' before '%s' token", token.value.c_str()));
1190 } else {
1191 lexer_.GetToken();
1192 }
1193
1194 ParseUnionMember(unionType);
1195
1196 token = lexer_.PeekToken();
1197 if (token.kind != TokenType::BRACES_RIGHT) {
1198 LogError(token, StringHelper::Format("expected '}' before '%s' token", token.value.c_str()));
1199 } else {
1200 lexer_.GetToken();
1201 }
1202
1203 token = lexer_.PeekToken();
1204 if (token.kind != TokenType::SEMICOLON) {
1205 LogError(token, StringHelper::Format("expected ';' before '%s' token", token.value.c_str()));
1206 } else {
1207 lexer_.GetToken();
1208 }
1209
1210 unionType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1211 ast_->AddTypeDefinition(unionType.Get());
1212 }
1213
ParseUnionMember(const AutoPtr<ASTUnionType> & unionType)1214 void Parser::ParseUnionMember(const AutoPtr<ASTUnionType> &unionType)
1215 {
1216 Token token = lexer_.PeekToken();
1217 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1218 AutoPtr<ASTType> memberType = ParseType();
1219 if (memberType == nullptr) {
1220 lexer_.SkipToken(TokenType::SEMICOLON);
1221 token = lexer_.PeekToken();
1222 continue;
1223 }
1224
1225 token = lexer_.PeekToken();
1226 if (token.kind != TokenType::ID) {
1227 LogError(token, StringHelper::Format("expected member name before '%s' token", token.value.c_str()));
1228 lexer_.SkipToken(TokenType::SEMICOLON);
1229 token = lexer_.PeekToken();
1230 continue;
1231 }
1232 lexer_.GetToken();
1233
1234 std::string memberName = token.value;
1235 if (!AddUnionMember(unionType, memberType, memberName)) {
1236 LogError(token,
1237 StringHelper::Format(
1238 "union not support this type or name of member duplicate '%s'", token.value.c_str()));
1239 }
1240
1241 token = lexer_.PeekToken();
1242 if (token.kind == TokenType::SEMICOLON) {
1243 lexer_.GetToken();
1244 token = lexer_.PeekToken();
1245 continue;
1246 }
1247
1248 if (token.kind != TokenType::BRACES_RIGHT) {
1249 LogError(token, StringHelper::Format("expected ',' or '}' before '%s' token", token.value.c_str()));
1250 }
1251 }
1252 }
1253
AddUnionMember(const AutoPtr<ASTUnionType> & unionType,const AutoPtr<ASTType> & type,const std::string & name) const1254 bool Parser::AddUnionMember(
1255 const AutoPtr<ASTUnionType> &unionType, const AutoPtr<ASTType> &type, const std::string &name) const
1256 {
1257 for (size_t i = 0; i < unionType->GetMemberNumber(); i++) {
1258 std::string memberName = unionType->GetMemberName(i);
1259 if (name == memberName) {
1260 return false;
1261 }
1262 }
1263
1264 // Non pod type members are not allowed in the union
1265 if (!type->IsPod()) {
1266 return false;
1267 }
1268
1269 unionType->AddMember(type, name);
1270 return true;
1271 }
1272
ParseUserDefTypeAttr(const AttrSet & attrs)1273 AutoPtr<ASTAttr> Parser::ParseUserDefTypeAttr(const AttrSet &attrs)
1274 {
1275 AutoPtr<ASTAttr> attr = new ASTAttr();
1276 bool isFull = false;
1277 bool isLite = false;
1278 bool isMini = false;
1279
1280 for (const auto &token : attrs) {
1281 switch (token.kind) {
1282 case TokenType::FULL:
1283 isFull = true;
1284 break;
1285 case TokenType::LITE:
1286 isLite = true;
1287 break;
1288 case TokenType::MINI:
1289 isMini = true;
1290 break;
1291 default:
1292 LogError(token, StringHelper::Format("invalid attribute '%s' for type decl", token.value.c_str()));
1293 break;
1294 }
1295 }
1296
1297 if (!isFull && !isLite && !isMini) {
1298 attr->SetValue(ASTAttr::FULL | ASTAttr::LITE | ASTAttr::MINI);
1299 } else {
1300 if (isFull) {
1301 attr->SetValue(ASTAttr::FULL);
1302 }
1303 if (isLite) {
1304 attr->SetValue(ASTAttr::LITE);
1305 }
1306 if (isMini) {
1307 attr->SetValue(ASTAttr::MINI);
1308 }
1309 }
1310
1311 return attr;
1312 }
1313
ParseExpr()1314 AutoPtr<ASTExpr> Parser::ParseExpr()
1315 {
1316 lexer_.SetParseMode(Lexer::ParseMode::EXPR_MODE);
1317 AutoPtr<ASTExpr> value = ParseAndExpr();
1318 lexer_.SetParseMode(Lexer::ParseMode::DECL_MODE);
1319 return value;
1320 }
1321
ParseAndExpr()1322 AutoPtr<ASTExpr> Parser::ParseAndExpr()
1323 {
1324 AutoPtr<ASTExpr> left = ParseXorExpr();
1325 Token token = lexer_.PeekToken();
1326 while (token.kind == TokenType::AND) {
1327 lexer_.GetToken();
1328 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1329 expr->op_ = BinaryOpKind::AND;
1330 expr->lExpr_ = left;
1331 expr->rExpr_ = ParseXorExpr();
1332
1333 left = expr.Get();
1334 token = lexer_.PeekToken();
1335 }
1336 return left;
1337 }
1338
ParseXorExpr()1339 AutoPtr<ASTExpr> Parser::ParseXorExpr()
1340 {
1341 AutoPtr<ASTExpr> left = ParseOrExpr();
1342 Token token = lexer_.PeekToken();
1343 while (token.kind == TokenType::XOR) {
1344 lexer_.GetToken();
1345 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1346 expr->op_ = BinaryOpKind::XOR;
1347 expr->lExpr_ = left;
1348 expr->rExpr_ = ParseOrExpr();
1349
1350 left = expr.Get();
1351 token = lexer_.PeekToken();
1352 }
1353 return left;
1354 }
1355
ParseOrExpr()1356 AutoPtr<ASTExpr> Parser::ParseOrExpr()
1357 {
1358 AutoPtr<ASTExpr> left = ParseShiftExpr();
1359 Token token = lexer_.PeekToken();
1360 while (token.kind == TokenType::OR) {
1361 lexer_.GetToken();
1362 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1363 expr->op_ = BinaryOpKind::OR;
1364 expr->lExpr_ = left;
1365 expr->rExpr_ = ParseShiftExpr();
1366
1367 left = expr.Get();
1368 token = lexer_.PeekToken();
1369 }
1370 return left;
1371 }
1372
ParseShiftExpr()1373 AutoPtr<ASTExpr> Parser::ParseShiftExpr()
1374 {
1375 AutoPtr<ASTExpr> left = ParseAddExpr();
1376 Token token = lexer_.PeekToken();
1377 while (token.kind == TokenType::LEFT_SHIFT || token.kind == TokenType::RIGHT_SHIFT) {
1378 lexer_.GetToken();
1379 BinaryOpKind op = (token.kind == TokenType::LEFT_SHIFT) ? BinaryOpKind::LSHIFT : BinaryOpKind::RSHIFT;
1380 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1381 expr->op_ = op;
1382 expr->lExpr_ = left;
1383 expr->rExpr_ = ParseAddExpr();
1384
1385 left = expr.Get();
1386 token = lexer_.PeekToken();
1387 }
1388 return left;
1389 }
1390
ParseAddExpr()1391 AutoPtr<ASTExpr> Parser::ParseAddExpr()
1392 {
1393 AutoPtr<ASTExpr> left = ParseMulExpr();
1394 Token token = lexer_.PeekToken();
1395 while (token.kind == TokenType::ADD || token.kind == TokenType::SUB) {
1396 lexer_.GetToken();
1397 BinaryOpKind op = (token.kind == TokenType::ADD) ? BinaryOpKind::ADD : BinaryOpKind::SUB;
1398 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1399 expr->op_ = op;
1400 expr->lExpr_ = left;
1401 expr->rExpr_ = ParseMulExpr();
1402
1403 left = expr.Get();
1404 token = lexer_.PeekToken();
1405 }
1406 return left;
1407 }
1408
ParseMulExpr()1409 AutoPtr<ASTExpr> Parser::ParseMulExpr()
1410 {
1411 AutoPtr<ASTExpr> left = ParseUnaryExpr();
1412 Token token = lexer_.PeekToken();
1413 while (
1414 token.kind == TokenType::STAR || token.kind == TokenType::SLASH || token.kind == TokenType::PERCENT_SIGN) {
1415 lexer_.GetToken();
1416 BinaryOpKind op = BinaryOpKind::MUL;
1417 if (token.kind == TokenType::SLASH) {
1418 op = BinaryOpKind::DIV;
1419 } else if (token.kind == TokenType::PERCENT_SIGN) {
1420 op = BinaryOpKind::MOD;
1421 }
1422 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1423 expr->op_ = op;
1424 expr->lExpr_ = left;
1425 expr->rExpr_ = ParseUnaryExpr();
1426
1427 left = expr.Get();
1428 token = lexer_.PeekToken();
1429 }
1430 return left;
1431 }
1432
ParseUnaryExpr()1433 AutoPtr<ASTExpr> Parser::ParseUnaryExpr()
1434 {
1435 Token token = lexer_.PeekToken();
1436 switch (token.kind) {
1437 case TokenType::ADD:
1438 case TokenType::SUB:
1439 case TokenType::TILDE: {
1440 lexer_.GetToken();
1441 AutoPtr<ASTUnaryExpr> expr = new ASTUnaryExpr;
1442 expr->op_ = UnaryOpKind::PLUS;
1443 if (token.kind == TokenType::SUB) {
1444 expr->op_ = UnaryOpKind::MINUS;
1445 } else if (token.kind == TokenType::TILDE) {
1446 expr->op_ = UnaryOpKind::TILDE;
1447 }
1448
1449 expr->expr_ = ParseUnaryExpr();
1450 return expr.Get();
1451 }
1452 default:
1453 return ParsePrimaryExpr();
1454 }
1455 }
1456
ParsePrimaryExpr()1457 AutoPtr<ASTExpr> Parser::ParsePrimaryExpr()
1458 {
1459 Token token = lexer_.PeekToken();
1460 switch (token.kind) {
1461 case TokenType::PARENTHESES_LEFT: {
1462 lexer_.GetToken();
1463 AutoPtr<ASTExpr> expr = ParseExpr();
1464 token = lexer_.PeekToken();
1465 if (token.kind != TokenType::PARENTHESES_RIGHT) {
1466 LogError(token, StringHelper::Format("expected ')' before %s token", token.value.c_str()));
1467 } else {
1468 lexer_.GetToken();
1469 expr->isParenExpr = true;
1470 }
1471 return expr;
1472 }
1473 case TokenType::NUM:
1474 return ParseNumExpr();
1475 default:
1476 LogError(token, StringHelper::Format("this expression is not supported"));
1477 lexer_.SkipUntilToken(TokenType::COMMA);
1478 return nullptr;
1479 }
1480 }
1481
ParseNumExpr()1482 AutoPtr<ASTExpr> Parser::ParseNumExpr()
1483 {
1484 Token token = lexer_.GetToken();
1485 if (!CheckNumber(token.value)) {
1486 LogError(token, StringHelper::Format("unknown integer number: '%s'", token.value.c_str()));
1487 return nullptr;
1488 }
1489
1490 AutoPtr<ASTNumExpr> expr = new ASTNumExpr;
1491 expr->value_ = token.value;
1492 return expr.Get();
1493 }
1494
CheckNumber(const std::string & integerVal) const1495 bool Parser::CheckNumber(const std::string& integerVal) const
1496 {
1497 if (std::regex_match(integerVal, g_binaryNumRe)||
1498 std::regex_match(integerVal, g_octNumRe)||
1499 std::regex_match(integerVal, g_decNumRe)||
1500 std::regex_match(integerVal, g_hexNumRe)) {
1501 return true;
1502 }
1503 return false;
1504 }
1505
CheckType(const Token & token,const AutoPtr<ASTType> & type)1506 bool Parser::CheckType(const Token &token, const AutoPtr<ASTType> &type)
1507 {
1508 if (type == nullptr) {
1509 return false;
1510 }
1511
1512 if (!CheckTypeByMode(token, type)) {
1513 return false;
1514 }
1515
1516 if (Options::GetInstance().GetLanguage() == Language::C) {
1517 if (type->IsSequenceableType() || type->IsSmqType() || type->IsAshmemType()) {
1518 LogError(token, StringHelper::Format("The %s type is not supported by c language.",
1519 type->ToString().c_str()));
1520 return false;
1521 }
1522 } else if (Options::GetInstance().GetLanguage() == Language::JAVA) {
1523 switch (type->GetTypeKind()) {
1524 case TypeKind::TYPE_UCHAR:
1525 case TypeKind::TYPE_USHORT:
1526 case TypeKind::TYPE_UINT:
1527 case TypeKind::TYPE_ULONG:
1528 case TypeKind::TYPE_ENUM:
1529 case TypeKind::TYPE_STRUCT:
1530 case TypeKind::TYPE_UNION:
1531 case TypeKind::TYPE_SMQ:
1532 case TypeKind::TYPE_UNKNOWN:
1533 LogError(token,
1534 StringHelper::Format("The '%s' type is not supported by java language.", type->ToString().c_str()));
1535 return false;
1536 default:
1537 break;
1538 }
1539 }
1540
1541 return true;
1542 }
1543
CheckTypeByMode(const Token & token,const AutoPtr<ASTType> & type)1544 bool Parser::CheckTypeByMode(const Token &token, const AutoPtr<ASTType> &type)
1545 {
1546 if (!Options::GetInstance().DoPassthrough() && type->IsPointerType()) {
1547 LogError(token, StringHelper::Format("The %s type is only supported by passthrough mode.",
1548 type->ToString().c_str()));
1549 return false;
1550 }
1551
1552 if (Options::GetInstance().DoGenerateKernelCode()) {
1553 switch (type->GetTypeKind()) {
1554 case TypeKind::TYPE_FLOAT:
1555 case TypeKind::TYPE_DOUBLE:
1556 case TypeKind::TYPE_FILEDESCRIPTOR:
1557 case TypeKind::TYPE_INTERFACE:
1558 case TypeKind::TYPE_SMQ:
1559 case TypeKind::TYPE_ASHMEM:
1560 case TypeKind::TYPE_NATIVE_BUFFER:
1561 case TypeKind::TYPE_POINTER:
1562 LogError(token,
1563 StringHelper::Format(
1564 "The '%s' type is not supported by kernel mode.", type->ToString().c_str()));
1565 return false;
1566 default:
1567 break;
1568 }
1569 }
1570 return true;
1571 }
1572
SetAstFileType()1573 void Parser::SetAstFileType()
1574 {
1575 if (ast_->GetInterfaceDef() != nullptr) {
1576 if (ast_->GetInterfaceDef()->IsCallback()) {
1577 ast_->SetAStFileType(ASTFileType::AST_ICALLBACK);
1578 } else {
1579 ast_->SetAStFileType(ASTFileType::AST_IFACE);
1580 }
1581 } else {
1582 ast_->SetAStFileType(ASTFileType::AST_TYPES);
1583 }
1584 }
1585
CheckIntegrity()1586 bool Parser::CheckIntegrity()
1587 {
1588 if (ast_ == nullptr) {
1589 LogError(std::string("ast is nullptr."));
1590 return false;
1591 }
1592
1593 if (ast_->GetName().empty()) {
1594 LogError(std::string("ast's name is empty."));
1595 return false;
1596 }
1597
1598 if (ast_->GetPackageName().empty()) {
1599 LogError(std::string("ast's package name is empty."));
1600 return false;
1601 }
1602
1603 switch (ast_->GetASTFileType()) {
1604 case ASTFileType::AST_IFACE: {
1605 return CheckInterfaceAst();
1606 }
1607 case ASTFileType::AST_ICALLBACK: {
1608 return CheckCallbackAst();
1609 }
1610 case ASTFileType::AST_SEQUENCEABLE: {
1611 LogError(std::string("it's impossible that ast is sequenceable."));
1612 return false;
1613 }
1614 case ASTFileType::AST_TYPES: {
1615 if (ast_->GetInterfaceDef() != nullptr) {
1616 LogError(std::string("custom ast cannot has interface."));
1617 return false;
1618 }
1619 break;
1620 }
1621 default:
1622 break;
1623 }
1624
1625 return true;
1626 }
1627
CheckInterfaceAst()1628 bool Parser::CheckInterfaceAst()
1629 {
1630 AutoPtr<ASTInterfaceType> interface = ast_->GetInterfaceDef();
1631 if (interface == nullptr) {
1632 LogError(std::string("ast's interface is empty."));
1633 return false;
1634 }
1635
1636 if (ast_->GetTypeDefinitionNumber() > 0) {
1637 LogError(std::string("interface ast cannot has custom types."));
1638 return false;
1639 }
1640
1641 if (interface->GetMethodNumber() == 0) {
1642 LogError(std::string("interface ast has no method."));
1643 return false;
1644 }
1645 return true;
1646 }
1647
CheckCallbackAst()1648 bool Parser::CheckCallbackAst()
1649 {
1650 AutoPtr<ASTInterfaceType> interface = ast_->GetInterfaceDef();
1651 if (interface == nullptr) {
1652 LogError(std::string("ast's interface is empty."));
1653 return false;
1654 }
1655
1656 if (!interface->IsCallback()) {
1657 LogError(std::string("ast is callback, but ast's interface is not callback."));
1658 return false;
1659 }
1660 return true;
1661 }
1662
1663 /*
1664 * filePath: ./ohos/interface/foo/v1_0/IFoo.idl
1665 * package OHOS.Hdi.foo.v1_0;
1666 */
CheckPackageName(const std::string & filePath,const std::string & packageName) const1667 bool Parser::CheckPackageName(const std::string &filePath, const std::string &packageName) const
1668 {
1669 std::string pkgToPath = Options::GetInstance().GetPackagePath(packageName);
1670
1671 size_t index = filePath.rfind(SEPARATOR);
1672 if (index == std::string::npos) {
1673 return false;
1674 }
1675
1676 std::string parentDir = filePath.substr(0, index);
1677 return parentDir == pkgToPath;
1678 }
1679
CheckImport(const std::string & importName)1680 bool Parser::CheckImport(const std::string &importName)
1681 {
1682 if (!std::regex_match(importName.c_str(), RE_IMPORT)) {
1683 LogError(StringHelper::Format("invalid impirt name '%s'", importName.c_str()));
1684 return false;
1685 }
1686
1687 std::string idlFilePath = Options::GetInstance().GetImportFilePath(importName);
1688 if (!File::CheckValid(idlFilePath)) {
1689 LogError(StringHelper::Format("can not import '%s'", idlFilePath.c_str()));
1690 return false;
1691 }
1692 return true;
1693 }
1694
AddAst(const AutoPtr<AST> & ast)1695 bool Parser::AddAst(const AutoPtr<AST> &ast)
1696 {
1697 if (ast == nullptr) {
1698 LogError(std::string("ast is nullptr."));
1699 return false;
1700 }
1701
1702 allAsts_[ast->GetFullName()] = ast;
1703 return true;
1704 }
1705
LogError(const std::string & message)1706 void Parser::LogError(const std::string &message)
1707 {
1708 errors_.push_back(message);
1709 }
1710
LogError(const Token & token,const std::string & message)1711 void Parser::LogError(const Token &token, const std::string &message)
1712 {
1713 errors_.push_back(StringHelper::Format("[%s] error:%s", LocInfo(token).c_str(), message.c_str()));
1714 }
1715
ShowError()1716 void Parser::ShowError()
1717 {
1718 for (const auto &errMsg : errors_) {
1719 Logger::E(TAG, "%s", errMsg.c_str());
1720 }
1721 }
1722
ParseInterfaceExtends(AutoPtr<ASTInterfaceType> & interface)1723 void Parser::ParseInterfaceExtends(AutoPtr<ASTInterfaceType> &interface)
1724 {
1725 Token token = lexer_.PeekToken();
1726 if (token.kind != TokenType::EXTENDS) {
1727 return;
1728 }
1729 lexer_.GetToken();
1730 token = lexer_.PeekToken();
1731 if (token.kind != TokenType::ID) {
1732 LogError(
1733 token, StringHelper::Format("expected extends interface name before '%s' token", token.value.c_str()));
1734 lexer_.SkipToken(TokenType::BRACES_LEFT);
1735 return;
1736 }
1737 ParseExtendsInfo(interface);
1738 lexer_.GetToken();
1739 }
1740
ParseExtendsInfo(AutoPtr<ASTInterfaceType> & interfaceType)1741 void Parser::ParseExtendsInfo(AutoPtr<ASTInterfaceType> &interfaceType)
1742 {
1743 Token token = lexer_.PeekToken();
1744 std::string extendsInterfaceName = token.value;
1745 if (extendsInterfaceName.empty()) {
1746 LogError(token, StringHelper::Format("extends interface name is empty"));
1747 return;
1748 }
1749 if (!CheckImport(extendsInterfaceName)) {
1750 LogError(token, StringHelper::Format("extends interface name is illegal"));
1751 return;
1752 }
1753 auto iter = allAsts_.find(extendsInterfaceName);
1754 AutoPtr<AST> extendsAst = (iter != allAsts_.end()) ? iter->second : nullptr;
1755 if (extendsAst == nullptr) {
1756 LogError(token,
1757 StringHelper::Format("can not find idl file by extends interface name '%s', please check import info",
1758 extendsInterfaceName.c_str()));
1759 return;
1760 }
1761 if (!CheckExtendsName(interfaceType, extendsInterfaceName)) {
1762 LogError(token,
1763 StringHelper::Format(
1764 "extends interface name must same as current interface name '%s'", interfaceType->GetName().c_str()));
1765 return;
1766 }
1767 if (!CheckExtendsVersion(interfaceType, extendsInterfaceName, extendsAst)) {
1768 LogError(token, StringHelper::Format("extends interface version must less than current interface version"));
1769 return;
1770 }
1771 if (!interfaceType->AddExtendsInterface(extendsAst->GetInterfaceDef())) {
1772 LogError(token, StringHelper::Format("multiple extends of '%s'", interfaceType->GetName().c_str()));
1773 return;
1774 }
1775 }
1776
CheckExtendsName(AutoPtr<ASTInterfaceType> & interfaceType,const std::string & extendsInterfaceName)1777 bool Parser::CheckExtendsName(AutoPtr<ASTInterfaceType> &interfaceType, const std::string &extendsInterfaceName)
1778 {
1779 size_t index = extendsInterfaceName.rfind(".");
1780 std::string interfaceName = interfaceType->GetName();
1781 if (extendsInterfaceName.substr(index + 1).compare(interfaceName) != 0) {
1782 return false;
1783 }
1784 return true;
1785 }
1786
CheckExtendsVersion(AutoPtr<ASTInterfaceType> & interfaceType,const std::string & extendsName,AutoPtr<AST> extendsAst)1787 bool Parser::CheckExtendsVersion(
1788 AutoPtr<ASTInterfaceType> &interfaceType, const std::string &extendsName, AutoPtr<AST> extendsAst)
1789 {
1790 if (extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() >= ast_->GetMinorVer()) {
1791 return false;
1792 }
1793 return true;
1794 }
1795
SetInterfaceVersion(AutoPtr<ASTInterfaceType> & interfaceType)1796 void Parser::SetInterfaceVersion(AutoPtr<ASTInterfaceType> &interfaceType)
1797 {
1798 size_t majorVer = ast_->GetMajorVer();
1799 size_t minorVer = ast_->GetMinorVer();
1800 interfaceType->SetVersion(majorVer, minorVer);
1801 }
1802
PostProcess()1803 bool Parser::PostProcess()
1804 {
1805 Language language = Options::GetInstance().GetLanguage();
1806 if (language != Language::C) {
1807 return true;
1808 }
1809 if (!CheckExistExtends()) {
1810 return true;
1811 }
1812 std::vector<size_t> genVersion = {0, 0};
1813 std::string genPackageName;
1814 AutoPtr<ASTNamespace> ns;
1815 if (!GetGenVersion(genVersion, genPackageName)) {
1816 return false;
1817 }
1818 GetGenNamespace(ns);
1819 AstMergeMap mergeMap;
1820 SortAstByName(mergeMap, allAsts_);
1821 allAsts_.clear();
1822 MergeAsts(mergeMap);
1823 ModifyImport(allAsts_, genPackageName);
1824 ModifyPackageNameAndVersion(allAsts_, genPackageName, genVersion);
1825 ModifyInterfaceNamespace(ns);
1826
1827 return true;
1828 }
1829
CheckExistExtends()1830 bool Parser::CheckExistExtends()
1831 {
1832 return std::any_of(allAsts_.begin(), allAsts_.end(), [](const std::pair<std::string, AutoPtr<AST>> &astPair) {
1833 return astPair.second->GetInterfaceDef() != nullptr &&
1834 astPair.second->GetInterfaceDef()->GetExtendsInterface() != nullptr;
1835 });
1836 }
1837
GetGenVersion(std::vector<size_t> & version,std::string & genPackageName)1838 bool Parser::GetGenVersion(std::vector<size_t> &version, std::string &genPackageName)
1839 {
1840 std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
1841 for (const auto &ast : allAsts_) {
1842 if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) {
1843 if (genPackageName == "") {
1844 genPackageName = ast.second->GetPackageName();
1845 version[0] = ast.second->GetMajorVer();
1846 version[1] = ast.second->GetMinorVer();
1847 continue;
1848 }
1849 if (genPackageName != ast.second->GetPackageName() || version[0] != ast.second->GetMajorVer() ||
1850 version[1] != ast.second->GetMinorVer()) {
1851 LogError(StringHelper::Format("merge ast failed, source files must have same package and version"));
1852 return false;
1853 }
1854 }
1855 }
1856 return true;
1857 }
1858
GetGenNamespace(AutoPtr<ASTNamespace> & ns)1859 void Parser::GetGenNamespace(AutoPtr<ASTNamespace> &ns)
1860 {
1861 std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
1862 for (const auto &ast : allAsts_) {
1863 if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) {
1864 if (ast.second->GetInterfaceDef() != nullptr) {
1865 ns = ast.second->GetInterfaceDef()->GetNamespace();
1866 return;
1867 }
1868 }
1869 }
1870 }
1871
SortAstByName(AstMergeMap & mergeMap,StrAstMap & allAsts)1872 void Parser::SortAstByName(AstMergeMap &mergeMap, StrAstMap &allAsts)
1873 {
1874 for (const auto &astPair : allAsts) {
1875 AutoPtr<AST> ast = astPair.second;
1876 mergeMap[ast->GetName()].emplace(ast);
1877 }
1878 }
1879
MergeAsts(AstMergeMap & mergeMap)1880 void Parser::MergeAsts(AstMergeMap &mergeMap)
1881 {
1882 for (const auto &setPair : mergeMap) {
1883 auto astSet = setPair.second;
1884 AutoPtr<AST> targetAst = nullptr;
1885 for (const auto &ast : astSet) {
1886 MergeAst(targetAst, ast);
1887 }
1888 AddAst(targetAst);
1889 }
1890 }
1891
MergeAst(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)1892 void Parser::MergeAst(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
1893 {
1894 if (targetAst == nullptr) {
1895 targetAst = sourceAst;
1896 return;
1897 }
1898 MergeImport(targetAst, sourceAst);
1899 MergeInterfaceDef(targetAst, sourceAst);
1900 MergeTypeDefinitions(targetAst, sourceAst);
1901 MergeTypes(targetAst, sourceAst);
1902 MergeSequenceableDef(targetAst, sourceAst);
1903 }
1904
MergeImport(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)1905 void Parser::MergeImport(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
1906 {
1907 for (const auto &importPair : sourceAst->GetImports()) {
1908 AutoPtr<AST> importAst = importPair.second;
1909 targetAst->AddImport(importAst);
1910 }
1911 }
1912
MergeInterfaceDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)1913 void Parser::MergeInterfaceDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
1914 {
1915 AutoPtr<ASTInterfaceType> sourceInterface = sourceAst->GetInterfaceDef();
1916 if (sourceInterface == nullptr) {
1917 return;
1918 }
1919 AutoPtr<ASTInterfaceType> targetInterface = targetAst->GetInterfaceDef();
1920 if (targetInterface == nullptr) {
1921 targetInterface = sourceInterface;
1922 return;
1923 }
1924
1925 for (size_t i = 0; i < sourceInterface->GetMethodNumber(); i++) {
1926 targetInterface->AddMethod(sourceInterface->GetMethod(i));
1927 }
1928 targetInterface->SetSerializable(sourceInterface->IsSerializable());
1929 }
1930
MergeTypeDefinitions(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)1931 void Parser::MergeTypeDefinitions(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
1932 {
1933 for (size_t i = 0; i < sourceAst->GetTypeDefinitionNumber(); i++) {
1934 targetAst->AddTypeDefinition(sourceAst->GetTypeDefintion(i));
1935 }
1936 }
1937
MergeSequenceableDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)1938 void Parser::MergeSequenceableDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
1939 {
1940 if (sourceAst->GetSequenceableDef() != nullptr) {
1941 targetAst->AddSequenceableDef(sourceAst->GetSequenceableDef());
1942 }
1943 }
1944
MergeTypes(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)1945 void Parser::MergeTypes(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
1946 {
1947 for (const auto &typePair : sourceAst->GetTypes()) {
1948 targetAst->AddType(typePair.second);
1949 }
1950 }
1951
ModifyImport(StrAstMap & allAsts,std::string & genPackageName)1952 void Parser::ModifyImport(StrAstMap &allAsts, std::string &genPackageName)
1953 {
1954 for (const auto &astPair : allAsts) {
1955 StrAstMap modifiedImport;
1956 StrAstMap import = astPair.second->GetImports();
1957 for (const auto &importPair : import) {
1958 if (importPair.second->GetName() == astPair.second->GetName()) {
1959 continue;
1960 }
1961 modifiedImport[importPair.second->GetName()] = importPair.second;
1962 }
1963 astPair.second->ClearImport();
1964 for (const auto &importPair : modifiedImport) {
1965 importPair.second->SetPackageName(genPackageName);
1966 astPair.second->AddImport(importPair.second);
1967 }
1968 }
1969 }
1970
ModifyPackageNameAndVersion(StrAstMap & allAsts,std::string & genPackageName,std::vector<size_t> genVersion)1971 void Parser::ModifyPackageNameAndVersion(
1972 StrAstMap &allAsts, std::string &genPackageName, std::vector<size_t> genVersion)
1973 {
1974 for (const auto &astPair : allAsts) {
1975 astPair.second->SetPackageName(genPackageName);
1976 astPair.second->SetVersion(genVersion[0], genVersion[1]);
1977 }
1978 }
1979
ModifyInterfaceNamespace(AutoPtr<ASTNamespace> & ns)1980 void Parser::ModifyInterfaceNamespace(AutoPtr<ASTNamespace> &ns)
1981 {
1982 for (const auto &astPair : allAsts_) {
1983 AutoPtr<ASTInterfaceType> interface = astPair.second->GetInterfaceDef();
1984 if (interface != nullptr) {
1985 interface->SetNamespace(ns);
1986 }
1987 }
1988 }
1989 } // namespace HDI
1990 } // namespace OHOS
1991