@@ -18,6 +18,7 @@ use crate::workspace::document::EmbeddedLanguageSnippets;
1818use append_only_vec:: AppendOnlyVec ;
1919use biome_analyze:: { AnalyzerPluginVec , RuleCategory } ;
2020use biome_configuration:: bool:: Bool ;
21+ use biome_configuration:: max_size:: MaxSize ;
2122use biome_configuration:: plugins:: { PluginConfiguration , Plugins } ;
2223use biome_configuration:: vcs:: VcsClientKind ;
2324use biome_configuration:: { BiomeDiagnostic , Configuration , ConfigurationPathHint } ;
@@ -292,6 +293,11 @@ impl WorkspaceServer {
292293
293294 let mut source = document_file_source. unwrap_or ( DocumentFileSource :: from_path ( & path) ) ;
294295
296+ let settings = self
297+ . projects
298+ . get_settings_based_on_path ( project_key, & path)
299+ . ok_or_else ( WorkspaceError :: no_project) ?;
300+
295301 if let DocumentFileSource :: Js ( js) = & mut source {
296302 match path. extension ( ) {
297303 Some ( "js" ) => {
@@ -308,10 +314,6 @@ impl WorkspaceServer {
308314 _ => { }
309315 }
310316 if !js. is_typescript ( ) && !js. is_jsx ( ) {
311- let settings = self
312- . projects
313- . get_settings_based_on_path ( project_key, & biome_path)
314- . ok_or_else ( WorkspaceError :: no_project) ?;
315317 let jsx_everywhere = settings
316318 . languages
317319 . javascript
@@ -333,7 +335,7 @@ impl WorkspaceServer {
333335 let mut file_source_index = self . insert_source ( source) ;
334336
335337 let size = content. len ( ) ;
336- let limit = self . projects . get_max_file_size ( project_key , path. as_path ( ) ) ;
338+ let limit = settings . get_max_file_size ( & path) ;
337339
338340 let syntax = if size > limit {
339341 Some ( Err ( FileTooLarge { size, limit } ) )
@@ -342,9 +344,9 @@ impl WorkspaceServer {
342344 } else {
343345 let mut node_cache = NodeCache :: default ( ) ;
344346 let parsed = self . parse (
345- project_key,
346347 & path,
347348 & content,
349+ & settings,
348350 file_source_index,
349351 & mut node_cache,
350352 ) ?;
@@ -363,19 +365,14 @@ impl WorkspaceServer {
363365 Some ( Ok ( parsed. any_parse ) )
364366 } ;
365367
366- // Second-pass parsing for HTML files with embedded JavaScript and CSS content
367- let embedded_snippets = if let Some ( DocumentFileSource :: Html ( _) ) =
368- self . get_source ( file_source_index)
369- && let Some ( Ok ( any_parse) ) = & syntax
370- && let Some ( html_root) = biome_html_syntax:: HtmlRoot :: cast ( any_parse. syntax ( ) )
371- {
372- let mut node_cache = NodeCache :: default ( ) ;
368+ // Second-pass parsing for HTML files with embedded JavaScript and CSS
369+ // content.
370+ let embedded_snippets = if let Some ( Ok ( parse) ) = & syntax {
373371 self . parse_embedded_language_snippets (
374- project_key,
375372 & biome_path,
376- & source ,
377- & html_root ,
378- & mut node_cache ,
373+ parse ,
374+ & settings ,
375+ file_source_index ,
379376 |file_source| self . insert_source ( file_source) ,
380377 ) ?
381378 } else {
@@ -502,21 +499,26 @@ impl WorkspaceServer {
502499 /// parsing.
503500 fn parse_embedded_language_snippets (
504501 & self ,
505- project_key : ProjectKey ,
506502 path : & BiomePath ,
507- source : & DocumentFileSource ,
508- html_root : & HtmlRoot ,
509- cache : & mut NodeCache ,
503+ parse : & AnyParse ,
504+ settings : & Settings ,
505+ file_source_index : usize ,
510506 source_index_fn : impl Fn ( DocumentFileSource ) -> usize ,
511507 ) -> Result < EmbeddedLanguageSnippets , WorkspaceError > {
508+ let ( source, html_root) = match self . get_source ( file_source_index) {
509+ Some ( source @ DocumentFileSource :: Html ( _) ) => match HtmlRoot :: cast ( parse. syntax ( ) ) {
510+ Some ( html_root) => ( source, html_root) ,
511+ None => return Ok ( Default :: default ( ) ) ,
512+ } ,
513+ _ => return Ok ( Default :: default ( ) ) ,
514+ } ;
515+
512516 let mut scripts = Vec :: new ( ) ;
513517 let mut json = Vec :: new ( ) ;
514518 let mut styles = Vec :: new ( ) ;
515519
516- let settings = self
517- . projects
518- . get_settings_based_on_path ( project_key, path)
519- . ok_or_else ( WorkspaceError :: no_project) ?;
520+ let mut cache = NodeCache :: default ( ) ;
521+
520522 // Walk through all HTML elements looking for script and style tags
521523 for element in html_root. syntax ( ) . descendants ( ) {
522524 let Some ( element) = HtmlElement :: cast ( element) else {
@@ -527,34 +529,36 @@ impl WorkspaceServer {
527529
528530 if let Some ( script_type) = element. get_script_type ( ) {
529531 if script_type. is_javascript ( ) {
530- let options = settings. parse_options :: < JsLanguage > ( path, source) ;
532+ let options = settings. parse_options :: < JsLanguage > ( path, & source) ;
531533
532534 if let Some ( list) = parse_embedded_js_script (
533535 element,
534536 script_type,
535- cache,
537+ & mut cache,
536538 options,
537539 |file_source| source_index_fn ( file_source. into ( ) ) ,
538540 ) {
539541 scripts. extend ( list)
540542 }
541543 } else if script_type. is_json ( ) {
542- let options = settings. parse_options :: < JsonLanguage > ( path, source) ;
544+ let options = settings. parse_options :: < JsonLanguage > ( path, & source) ;
543545
544546 if let Some ( list) =
545- parse_embedded_json ( element, cache, options, |file_source| {
547+ parse_embedded_json ( element, & mut cache, options, |file_source| {
546548 source_index_fn ( file_source. into ( ) )
547549 } )
548550 {
549551 json. extend ( list)
550552 }
551553 }
552554 } else if element. is_style_tag ( ) {
553- let options = settings. parse_options :: < CssLanguage > ( path, source) ;
555+ let options = settings. parse_options :: < CssLanguage > ( path, & source) ;
554556
555- if let Some ( list) = parse_embedded_style ( element, cache, options, |file_source| {
556- source_index_fn ( file_source. into ( ) )
557- } ) {
557+ if let Some ( list) =
558+ parse_embedded_style ( element, & mut cache, options, |file_source| {
559+ source_index_fn ( file_source. into ( ) )
560+ } )
561+ {
558562 styles. extend ( list)
559563 }
560564 }
@@ -569,9 +573,9 @@ impl WorkspaceServer {
569573
570574 fn parse (
571575 & self ,
572- project_key : ProjectKey ,
573576 path : & Utf8Path ,
574577 content : & str ,
578+ settings : & Settings ,
575579 file_source_index : usize ,
576580 node_cache : & mut NodeCache ,
577581 ) -> Result < ParseResult , WorkspaceError > {
@@ -585,15 +589,11 @@ impl WorkspaceServer {
585589 . parse
586590 . ok_or_else ( self . build_capability_error ( path) ) ?;
587591
588- let settings = self
589- . projects
590- . get_settings_based_on_path ( project_key, path)
591- . ok_or_else ( WorkspaceError :: no_project) ?;
592592 let parsed = parse (
593593 & BiomePath :: new ( path) ,
594594 file_source,
595595 content,
596- & settings,
596+ settings,
597597 node_cache,
598598 ) ;
599599 Ok ( parsed)
@@ -1254,7 +1254,11 @@ impl Workspace for WorkspaceServer {
12541254 let file_size = document. content . len ( ) ;
12551255 let limit = self
12561256 . projects
1257- . get_max_file_size ( params. project_key , params. path . as_path ( ) ) ;
1257+ . get_settings_based_on_path ( params. project_key , & params. path )
1258+ . map_or_else (
1259+ || MaxSize :: default ( ) . into ( ) ,
1260+ |settings| settings. get_max_file_size ( & params. path ) ,
1261+ ) ;
12581262 Ok ( CheckFileSizeResult { file_size, limit } )
12591263 }
12601264
@@ -1276,11 +1280,17 @@ impl Workspace for WorkspaceServer {
12761280
12771281 if existing_version. is_some_and ( |existing_version| existing_version >= version) {
12781282 warn ! ( %version, %path, "outdated_file_change" ) ;
1283+ // Safely ignore older versions.
12791284 return Ok ( ChangeFileResult {
1280- diagnostics : vec ! [ ] ,
1281- } ) ; // Safely ignore older versions.
1285+ diagnostics : Vec :: new ( ) ,
1286+ } ) ;
12821287 }
12831288
1289+ let settings = self
1290+ . projects
1291+ . get_settings_based_on_path ( project_key, & path)
1292+ . ok_or_else ( WorkspaceError :: no_project) ?;
1293+
12841294 // We remove the node cache for the document, if it exists.
12851295 // This is done so that we need to hold the lock as short as possible
12861296 // (it's released directly after the statement). The potential downside
@@ -1293,27 +1303,17 @@ impl Workspace for WorkspaceServer {
12931303 let persist_node_cache = node_cache. is_some ( ) ;
12941304 let mut node_cache = node_cache. unwrap_or_default ( ) ;
12951305
1296- let parsed = self . parse ( project_key , & path, & content, index, & mut node_cache) ?;
1306+ let parsed = self . parse ( & path, & content, & settings , index, & mut node_cache) ?;
12971307 let root = parsed. any_parse . root ( ) ;
12981308
12991309 // Second-pass parsing for HTML files with embedded JavaScript and CSS content
1300- let embedded_snippets = if let Some ( file_source) = self . get_source ( index)
1301- && matches ! ( file_source, DocumentFileSource :: Html ( _) )
1302- && let Some ( html_root) =
1303- biome_html_syntax:: HtmlRoot :: cast ( parsed. any_parse . syntax ( ) . clone ( ) )
1304- {
1305- let mut embedded_node_cache = NodeCache :: default ( ) ;
1306- self . parse_embedded_language_snippets (
1307- project_key,
1308- & path,
1309- & file_source,
1310- & html_root,
1311- & mut embedded_node_cache,
1312- |file_source| self . insert_source ( file_source) ,
1313- ) ?
1314- } else {
1315- Default :: default ( )
1316- } ;
1310+ let embedded_snippets = self . parse_embedded_language_snippets (
1311+ & path,
1312+ & parsed. any_parse ,
1313+ & settings,
1314+ index,
1315+ |file_source| self . insert_source ( file_source) ,
1316+ ) ?;
13171317
13181318 let document = Document {
13191319 content,
0 commit comments