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