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