• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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/module_parser.h"
10 #include <queue>
11 #include "parser/parser.h"
12 #include "util/logger.h"
13 
14 namespace OHOS {
15 namespace HDI {
16 const char* ModuleParser::TAG = "ModuleParser";
17 
Parse()18 AutoPtr<ASTModule> ModuleParser::Parse()
19 {
20     if (!ParserDependencies()) {
21         return nullptr;
22     }
23 
24     if (!CompileFiles()) {
25         return nullptr;
26     }
27 
28     return module_;
29 }
30 
ParserDependencies()31 bool ModuleParser::ParserDependencies()
32 {
33     if (option_.GetSourceFiles().size() == 1) {
34         if (!ParserAllImports(option_.GetSourceFiles()[0])) {
35             Logger::E(TAG, "Parsing all idl file failed.");
36             return false;
37         }
38     } else {
39         if (!ParserAllidlFile(option_.GetSourceFiles())) {
40             Logger::E(TAG, "Parsing all given idl file failed.");
41             return false;
42         }
43     }
44 
45     if (!CheckCircularReference()) {
46         Logger::E(TAG, "has circle reference.");
47         return false;
48     }
49 
50     return true;
51 }
52 
CompileFiles()53 bool ModuleParser::CompileFiles()
54 {
55     std::unique_ptr<Parser> parserPtr = std::make_unique<Parser>(option_, module_);
56 
57     for (const auto& filePath : compileFiles_) {
58         if (!parserPtr->Parse(filePath)) {
59             Logger::E(TAG, "parse %s failed", filePath.string());
60             return false;
61         }
62     }
63 
64     return true;
65 }
66 
ParserAllImports(const String & rootFilePath)67 bool ModuleParser::ParserAllImports(const String& rootFilePath)
68 {
69     std::unique_ptr<Parser> parserPtr = std::make_unique<Parser>(option_);
70     std::shared_ptr<FileDetail> fileInfo = nullptr;
71 
72     if (!parserPtr->Parse(rootFilePath, fileInfo)) {
73         return false;
74     }
75 
76     if (fileInfo == nullptr) {
77         return false;
78     }
79 
80     sourceFiles_[fileInfo->GetFullName()] = fileInfo;
81     return ParserAllImportsRecursion(fileInfo);
82 }
83 
ParserAllImportsRecursion(const std::shared_ptr<FileDetail> & fileInfo)84 bool ModuleParser::ParserAllImportsRecursion(const std::shared_ptr<FileDetail>& fileInfo)
85 {
86     for (const auto& importName : fileInfo->GetImports()) {
87         if (sourceFiles_.find(importName) != sourceFiles_.end()) {
88             continue;
89         }
90 
91         String filePath = FileDetail::ImportsToPath(importName);
92 
93         std::unique_ptr<Parser> parserPtr = std::make_unique<Parser>(option_);
94         std::shared_ptr<FileDetail> file = nullptr;
95         if (!parserPtr->Parse(filePath, file)) {
96             Logger::E(TAG, "Parsing %s failed.", filePath.string());
97             return false;
98         }
99 
100         if (file == nullptr) {
101             Logger::E(TAG, "Parsing %s failed, generator filedetail is nullptr.", filePath.string());
102             return false;
103         }
104 
105         sourceFiles_[file->GetFullName()] = file;
106 
107         if (!ParserAllImportsRecursion(file)) {
108             Logger::E(TAG, "Parsing %s file's import failed.", file->GetFilePath().string());
109             return false;
110         }
111     }
112 
113     return true;
114 }
115 
ParserAllidlFile(const std::vector<String> & idlSourceFile)116 bool ModuleParser::ParserAllidlFile(const std::vector<String>& idlSourceFile)
117 {
118     std::unique_ptr<Parser> parserPtr = std::make_unique<Parser>(option_);
119 
120     for (const auto& idlSourceFile : idlSourceFile) {
121         std::shared_ptr<FileDetail> fileInfo = nullptr;
122         if (!parserPtr->Parse(idlSourceFile, fileInfo)) {
123             return false;
124         }
125 
126         if (fileInfo == nullptr) {
127             return false;
128         }
129 
130         sourceFiles_[fileInfo->GetFullName()] = fileInfo;
131     }
132 
133     return true;
134 }
135 
CheckCircularReference()136 bool ModuleParser::CheckCircularReference()
137 {
138     std::queue<std::shared_ptr<FileDetail>> fileQueue;
139     for (const auto& filePair : sourceFiles_) {
140         std::shared_ptr<FileDetail> fileNode = filePair.second;
141         if (fileNode->GetImportSize() == 0) {
142             fileQueue.push(fileNode);
143         }
144     }
145 
146     compileFiles_.clear();
147     while (!fileQueue.empty()) {
148         std::shared_ptr<FileDetail> importFile = fileQueue.front();
149         fileQueue.pop();
150         compileFiles_.push_back(importFile->GetFilePath());
151 
152         for (const auto& filePair : sourceFiles_) {
153             std::shared_ptr<FileDetail> fileNode = filePair.second;
154             if (fileNode->GetImportSize() > 0) {
155                 fileNode->DelImport(importFile->GetFullName());
156                 if (fileNode->GetImportSize() == 0) {
157                     fileQueue.push(fileNode);
158                 }
159             }
160         }
161     }
162 
163     if (compileFiles_.size() < sourceFiles_.size()) {
164         return false;
165     }
166 
167     return true;
168 }
169 } // namespace HDI
170 } // namespace OHOS