33
44use crate :: compile:: { self , compile, core, std} ;
55use miette:: Diagnostic ;
6+ use qsc_ast:: ast;
67use qsc_data_structures:: language_features:: LanguageFeatures ;
78use qsc_frontend:: {
89 compile:: { OpenPackageStore , PackageStore , SourceMap , TargetCapabilityFlags } ,
@@ -80,6 +81,24 @@ impl Compiler {
8081 } )
8182 }
8283
84+ pub fn from (
85+ store : PackageStore ,
86+ source_package_id : PackageId ,
87+ capabilities : TargetCapabilityFlags ,
88+ language_features : LanguageFeatures ,
89+ ) -> Result < Self , Errors > {
90+ let frontend =
91+ qsc_frontend:: incremental:: Compiler :: new ( & store, [ ] , capabilities, language_features) ;
92+ let store = store. open ( ) ;
93+
94+ Ok ( Self {
95+ store,
96+ source_package_id,
97+ frontend,
98+ passes : PassContext :: new ( capabilities) ,
99+ } )
100+ }
101+
83102 /// Compiles Q# fragments. Fragments are Q# code that can contain
84103 /// top-level statements as well as namespaces. A notebook cell
85104 /// or an interpreter entry is an example of fragments.
@@ -99,6 +118,26 @@ impl Compiler {
99118 self . compile_fragments ( source_name, source_contents, fail_on_error)
100119 }
101120
121+ /// Compiles Q# ast fragments. Fragments are Q# code that can contain
122+ /// top-level statements as well as namespaces. A notebook cell
123+ /// or an interpreter entry is an example of fragments.
124+ ///
125+ /// This method returns the AST and HIR packages that were created as a result of
126+ /// the compilation, however it does *not* update the current compilation.
127+ ///
128+ /// The caller can use the returned packages to perform passes,
129+ /// get information about the newly added items, or do other modifications.
130+ /// It is then the caller's responsibility to merge
131+ /// these packages into the current `CompileUnit` using the `update()` method.
132+ pub fn compile_ast_fragments_fail_fast (
133+ & mut self ,
134+ source_name : & str ,
135+ source_contents : & str ,
136+ package : ast:: Package ,
137+ ) -> Result < Increment , Errors > {
138+ self . compile_ast_fragments ( source_name, source_contents, package, fail_on_error)
139+ }
140+
102141 /// Compiles Q# fragments. See [`compile_fragments_fail_fast`] for more details.
103142 ///
104143 /// This method calls an accumulator function with any errors returned
@@ -140,6 +179,52 @@ impl Compiler {
140179 Ok ( increment)
141180 }
142181
182+ /// Compiles Q# ast fragments. See [`compile_ast_fragments_fail_fast`] for more details.
183+ ///
184+ /// This method calls an accumulator function with any errors returned
185+ /// from each of the stages (parsing, lowering).
186+ /// If the accumulator succeeds, compilation continues.
187+ /// If the accumulator returns an error, compilation stops and the
188+ /// error is returned to the caller.
189+ pub fn compile_ast_fragments < F > (
190+ & mut self ,
191+ source_name : & str ,
192+ source_contents : & str ,
193+ package : ast:: Package ,
194+ mut accumulate_errors : F ,
195+ ) -> Result < Increment , Errors >
196+ where
197+ F : FnMut ( Errors ) -> Result < ( ) , Errors > ,
198+ {
199+ let ( core, unit) = self . store . get_open_mut ( ) ;
200+
201+ let mut errors = false ;
202+ let mut increment = self . frontend . compile_ast_fragments (
203+ unit,
204+ source_name,
205+ source_contents,
206+ package,
207+ |e| {
208+ errors = errors || !e. is_empty ( ) ;
209+ accumulate_errors ( into_errors ( e) )
210+ } ,
211+ ) ?;
212+
213+ // Even if we don't fail fast, skip passes if there were compilation errors.
214+ if !errors {
215+ let pass_errors = self . passes . run_default_passes (
216+ & mut increment. hir ,
217+ & mut unit. assigner ,
218+ core,
219+ PackageType :: Lib ,
220+ ) ;
221+
222+ accumulate_errors ( into_errors_with_source ( pass_errors, & unit. sources ) ) ?;
223+ }
224+
225+ Ok ( increment)
226+ }
227+
143228 /// Compiles an entry expression.
144229 ///
145230 /// This method returns the AST and HIR packages that were created as a result of
0 commit comments