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