mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 21:25:25 +00:00 
			
		
		
		
	Track diagnostic generations per package
This commit is contained in:
		
							parent
							
								
									4d7b9044c3
								
							
						
					
					
						commit
						e87a2fcff2
					
				
					 1 changed files with 32 additions and 24 deletions
				
			
		| 
						 | 
					@ -26,17 +26,15 @@ pub struct DiagnosticsMapConfig {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) type DiagnosticsGeneration = usize;
 | 
					pub(crate) type DiagnosticsGeneration = usize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone, Default)]
 | 
				
			||||||
pub(crate) struct WorkspaceFlycheckDiagnostic {
 | 
					pub(crate) struct WorkspaceFlycheckDiagnostic {
 | 
				
			||||||
    pub(crate) generation: DiagnosticsGeneration,
 | 
					    pub(crate) per_package: FxHashMap<Option<Arc<PackageId>>, PackageFlycheckDiagnostic>,
 | 
				
			||||||
    pub(crate) per_package:
 | 
					 | 
				
			||||||
        FxHashMap<Option<Arc<PackageId>>, FxHashMap<FileId, Vec<lsp_types::Diagnostic>>>,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl WorkspaceFlycheckDiagnostic {
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
    fn new(generation: DiagnosticsGeneration) -> Self {
 | 
					pub(crate) struct PackageFlycheckDiagnostic {
 | 
				
			||||||
        WorkspaceFlycheckDiagnostic { generation, per_package: Default::default() }
 | 
					    generation: DiagnosticsGeneration,
 | 
				
			||||||
    }
 | 
					    per_file: FxHashMap<FileId, Vec<lsp_types::Diagnostic>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Default, Clone)]
 | 
					#[derive(Debug, Default, Clone)]
 | 
				
			||||||
| 
						 | 
					@ -68,7 +66,7 @@ impl DiagnosticCollection {
 | 
				
			||||||
        let Some(check) = self.check.get_mut(flycheck_id) else {
 | 
					        let Some(check) = self.check.get_mut(flycheck_id) else {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        self.changes.extend(check.per_package.drain().flat_map(|(_, v)| v.into_keys()));
 | 
					        self.changes.extend(check.per_package.drain().flat_map(|(_, v)| v.per_file.into_keys()));
 | 
				
			||||||
        if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) {
 | 
					        if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) {
 | 
				
			||||||
            fixes.clear();
 | 
					            fixes.clear();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -79,7 +77,7 @@ impl DiagnosticCollection {
 | 
				
			||||||
        self.changes.extend(
 | 
					        self.changes.extend(
 | 
				
			||||||
            self.check
 | 
					            self.check
 | 
				
			||||||
                .iter_mut()
 | 
					                .iter_mut()
 | 
				
			||||||
                .flat_map(|it| it.per_package.drain().flat_map(|(_, v)| v.into_keys())),
 | 
					                .flat_map(|it| it.per_package.drain().flat_map(|(_, v)| v.per_file.into_keys())),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,7 +91,7 @@ impl DiagnosticCollection {
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let package_id = Some(package_id);
 | 
					        let package_id = Some(package_id);
 | 
				
			||||||
        if let Some(checks) = check.per_package.remove(&package_id) {
 | 
					        if let Some(checks) = check.per_package.remove(&package_id) {
 | 
				
			||||||
            self.changes.extend(checks.into_keys());
 | 
					            self.changes.extend(checks.per_file.into_keys());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) {
 | 
					        if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) {
 | 
				
			||||||
            fixes.remove(&package_id);
 | 
					            fixes.remove(&package_id);
 | 
				
			||||||
| 
						 | 
					@ -105,8 +103,20 @@ impl DiagnosticCollection {
 | 
				
			||||||
        flycheck_id: usize,
 | 
					        flycheck_id: usize,
 | 
				
			||||||
        generation: DiagnosticsGeneration,
 | 
					        generation: DiagnosticsGeneration,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        if self.check.get(flycheck_id).is_some_and(|it| it.generation < generation) {
 | 
					        if let Some(flycheck) = self.check.get_mut(flycheck_id) {
 | 
				
			||||||
            self.clear_check(flycheck_id);
 | 
					            let mut packages = vec![];
 | 
				
			||||||
 | 
					            self.changes.extend(
 | 
				
			||||||
 | 
					                flycheck
 | 
				
			||||||
 | 
					                    .per_package
 | 
				
			||||||
 | 
					                    .extract_if(|_, v| v.generation < generation)
 | 
				
			||||||
 | 
					                    .inspect(|(package_id, _)| packages.push(package_id.clone()))
 | 
				
			||||||
 | 
					                    .flat_map(|(_, v)| v.per_file.into_keys()),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) {
 | 
				
			||||||
 | 
					                for package in packages {
 | 
				
			||||||
 | 
					                    fixes.remove(&package);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,21 +136,19 @@ impl DiagnosticCollection {
 | 
				
			||||||
        fix: Option<Box<Fix>>,
 | 
					        fix: Option<Box<Fix>>,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        if self.check.len() <= flycheck_id {
 | 
					        if self.check.len() <= flycheck_id {
 | 
				
			||||||
            self.check
 | 
					            self.check.resize_with(flycheck_id + 1, WorkspaceFlycheckDiagnostic::default);
 | 
				
			||||||
                .resize_with(flycheck_id + 1, || WorkspaceFlycheckDiagnostic::new(generation));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let check = &mut self.check[flycheck_id];
 | 
				
			||||||
 | 
					        let package = check.per_package.entry(package_id.clone()).or_insert_with(|| {
 | 
				
			||||||
 | 
					            PackageFlycheckDiagnostic { generation, per_file: FxHashMap::default() }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
        // Getting message from old generation. Might happen in restarting checks.
 | 
					        // Getting message from old generation. Might happen in restarting checks.
 | 
				
			||||||
        if self.check[flycheck_id].generation > generation {
 | 
					        if package.generation > generation {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.check[flycheck_id].generation = generation;
 | 
					        package.generation = generation;
 | 
				
			||||||
        let diagnostics = self.check[flycheck_id]
 | 
					        let diagnostics = package.per_file.entry(file_id).or_default();
 | 
				
			||||||
            .per_package
 | 
					 | 
				
			||||||
            .entry(package_id.clone())
 | 
					 | 
				
			||||||
            .or_default()
 | 
					 | 
				
			||||||
            .entry(file_id)
 | 
					 | 
				
			||||||
            .or_default();
 | 
					 | 
				
			||||||
        for existing_diagnostic in diagnostics.iter() {
 | 
					        for existing_diagnostic in diagnostics.iter() {
 | 
				
			||||||
            if are_diagnostics_equal(existing_diagnostic, &diagnostic) {
 | 
					            if are_diagnostics_equal(existing_diagnostic, &diagnostic) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
| 
						 | 
					@ -210,7 +218,7 @@ impl DiagnosticCollection {
 | 
				
			||||||
            .check
 | 
					            .check
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .flat_map(|it| it.per_package.values())
 | 
					            .flat_map(|it| it.per_package.values())
 | 
				
			||||||
            .filter_map(move |it| it.get(&file_id))
 | 
					            .filter_map(move |it| it.per_file.get(&file_id))
 | 
				
			||||||
            .flatten();
 | 
					            .flatten();
 | 
				
			||||||
        native_syntax.chain(native_semantic).chain(check)
 | 
					        native_syntax.chain(native_semantic).chain(check)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue