• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/torque/torque-compiler.h"
6 
7 #include <fstream>
8 #include "src/torque/declarable.h"
9 #include "src/torque/declaration-visitor.h"
10 #include "src/torque/global-context.h"
11 #include "src/torque/implementation-visitor.h"
12 #include "src/torque/torque-parser.h"
13 #include "src/torque/type-oracle.h"
14 
15 namespace v8 {
16 namespace internal {
17 namespace torque {
18 
19 namespace {
20 
ReadFile(const std::string & path)21 base::Optional<std::string> ReadFile(const std::string& path) {
22   std::ifstream file_stream(path);
23   if (!file_stream.good()) return base::nullopt;
24 
25   return std::string{std::istreambuf_iterator<char>(file_stream),
26                      std::istreambuf_iterator<char>()};
27 }
28 
ReadAndParseTorqueFile(const std::string & path)29 void ReadAndParseTorqueFile(const std::string& path) {
30   SourceId source_id = SourceFileMap::AddSource(path);
31   CurrentSourceFile::Scope source_id_scope(source_id);
32 
33   // path might be either a normal file path or an encoded URI.
34   auto maybe_content = ReadFile(SourceFileMap::AbsolutePath(source_id));
35   if (!maybe_content) {
36     if (auto maybe_path = FileUriDecode(path)) {
37       maybe_content = ReadFile(*maybe_path);
38     }
39   }
40 
41   if (!maybe_content) {
42     Error("Cannot open file path/uri: ", path).Throw();
43   }
44 
45   ParseTorque(*maybe_content);
46 }
47 
CompileCurrentAst(TorqueCompilerOptions options)48 void CompileCurrentAst(TorqueCompilerOptions options) {
49   GlobalContext::Scope global_context(std::move(CurrentAst::Get()));
50   if (options.collect_language_server_data) {
51     GlobalContext::SetCollectLanguageServerData();
52   }
53   if (options.collect_kythe_data) {
54     GlobalContext::SetCollectKytheData();
55   }
56   if (options.force_assert_statements) {
57     GlobalContext::SetForceAssertStatements();
58   }
59   if (options.annotate_ir) {
60     GlobalContext::SetAnnotateIR();
61   }
62   TargetArchitecture::Scope target_architecture(options.force_32bit_output);
63   TypeOracle::Scope type_oracle;
64   CurrentScope::Scope current_namespace(GlobalContext::GetDefaultNamespace());
65 
66   // Two-step process of predeclaration + resolution allows to resolve type
67   // declarations independent of the order they are given.
68   PredeclarationVisitor::Predeclare(GlobalContext::ast());
69   PredeclarationVisitor::ResolvePredeclarations();
70 
71   // Process other declarations.
72   DeclarationVisitor::Visit(GlobalContext::ast());
73 
74   // A class types' fields are resolved here, which allows two class fields to
75   // mutually refer to each others.
76   TypeOracle::FinalizeAggregateTypes();
77 
78   std::string output_directory = options.output_directory;
79 
80   ImplementationVisitor implementation_visitor;
81   implementation_visitor.SetDryRun(output_directory.length() == 0);
82 
83   implementation_visitor.GenerateInstanceTypes(output_directory);
84   implementation_visitor.BeginGeneratedFiles();
85   implementation_visitor.BeginDebugMacrosFile();
86 
87   implementation_visitor.VisitAllDeclarables();
88 
89   ReportAllUnusedMacros();
90 
91   implementation_visitor.GenerateBuiltinDefinitionsAndInterfaceDescriptors(
92       output_directory);
93   implementation_visitor.GenerateVisitorLists(output_directory);
94   implementation_visitor.GenerateBitFields(output_directory);
95   implementation_visitor.GeneratePrintDefinitions(output_directory);
96   implementation_visitor.GenerateClassDefinitions(output_directory);
97   implementation_visitor.GenerateClassVerifiers(output_directory);
98   implementation_visitor.GenerateClassDebugReaders(output_directory);
99   implementation_visitor.GenerateEnumVerifiers(output_directory);
100   implementation_visitor.GenerateBodyDescriptors(output_directory);
101   implementation_visitor.GenerateExportedMacrosAssembler(output_directory);
102   implementation_visitor.GenerateCSATypes(output_directory);
103 
104   implementation_visitor.EndGeneratedFiles();
105   implementation_visitor.EndDebugMacrosFile();
106   implementation_visitor.GenerateImplementation(output_directory);
107 
108   if (GlobalContext::collect_language_server_data()) {
109     LanguageServerData::SetGlobalContext(std::move(GlobalContext::Get()));
110     LanguageServerData::SetTypeOracle(std::move(TypeOracle::Get()));
111   }
112 }
113 
114 }  // namespace
115 
CompileTorque(const std::string & source,TorqueCompilerOptions options)116 TorqueCompilerResult CompileTorque(const std::string& source,
117                                    TorqueCompilerOptions options) {
118   SourceFileMap::Scope source_map_scope(options.v8_root);
119   CurrentSourceFile::Scope no_file_scope(
120       SourceFileMap::AddSource("dummy-filename.tq"));
121   CurrentAst::Scope ast_scope;
122   TorqueMessages::Scope messages_scope;
123   LanguageServerData::Scope server_data_scope;
124 
125   TorqueCompilerResult result;
126   try {
127     ParseTorque(source);
128     CompileCurrentAst(options);
129   } catch (TorqueAbortCompilation&) {
130     // Do nothing. The relevant TorqueMessage is part of the
131     // TorqueMessages contextual.
132   }
133 
134   result.source_file_map = SourceFileMap::Get();
135   result.language_server_data = std::move(LanguageServerData::Get());
136   result.messages = std::move(TorqueMessages::Get());
137 
138   return result;
139 }
140 
CompileTorque(std::vector<std::string> files,TorqueCompilerOptions options)141 TorqueCompilerResult CompileTorque(std::vector<std::string> files,
142                                    TorqueCompilerOptions options) {
143   SourceFileMap::Scope source_map_scope(options.v8_root);
144   CurrentSourceFile::Scope unknown_source_file_scope(SourceId::Invalid());
145   CurrentAst::Scope ast_scope;
146   TorqueMessages::Scope messages_scope;
147   LanguageServerData::Scope server_data_scope;
148 
149   TorqueCompilerResult result;
150   try {
151     for (const auto& path : files) {
152       ReadAndParseTorqueFile(path);
153     }
154     CompileCurrentAst(options);
155   } catch (TorqueAbortCompilation&) {
156     // Do nothing. The relevant TorqueMessage is part of the
157     // TorqueMessages contextual.
158   }
159 
160   result.source_file_map = SourceFileMap::Get();
161   result.language_server_data = std::move(LanguageServerData::Get());
162   result.messages = std::move(TorqueMessages::Get());
163 
164   return result;
165 }
166 
CompileTorqueForKythe(std::vector<TorqueCompilationUnit> units,TorqueCompilerOptions options,KytheConsumer * consumer)167 TorqueCompilerResult CompileTorqueForKythe(
168     std::vector<TorqueCompilationUnit> units, TorqueCompilerOptions options,
169     KytheConsumer* consumer) {
170   SourceFileMap::Scope source_map_scope(options.v8_root);
171   CurrentSourceFile::Scope unknown_source_file_scope(SourceId::Invalid());
172   CurrentAst::Scope ast_scope;
173   TorqueMessages::Scope messages_scope;
174   LanguageServerData::Scope server_data_scope;
175   KytheData::Scope kythe_scope;
176 
177   KytheData::Get().SetConsumer(consumer);
178 
179   TorqueCompilerResult result;
180   try {
181     for (const auto& unit : units) {
182       SourceId source_id = SourceFileMap::AddSource(unit.source_file_path);
183       CurrentSourceFile::Scope source_id_scope(source_id);
184       ParseTorque(unit.file_content);
185     }
186     CompileCurrentAst(options);
187   } catch (TorqueAbortCompilation&) {
188     // Do nothing. The relevant TorqueMessage is part of the
189     // TorqueMessages contextual.
190   }
191 
192   result.source_file_map = SourceFileMap::Get();
193   result.language_server_data = std::move(LanguageServerData::Get());
194   result.messages = std::move(TorqueMessages::Get());
195 
196   return result;
197 }
198 
199 }  // namespace torque
200 }  // namespace internal
201 }  // namespace v8
202