33use crate :: metadata:: options:: OptionDiagnostic ;
44pub use db:: { Db , ProjectDatabase } ;
55use files:: { Index , Indexed , IndexedFiles } ;
6+ use metadata:: settings:: Settings ;
67pub use metadata:: { ProjectDiscoveryError , ProjectMetadata } ;
7- use red_knot_python_semantic:: lint:: { LintRegistry , LintRegistryBuilder , RuleSelection } ;
8+ use red_knot_python_semantic:: lint:: { LintRegistry , LintRegistryBuilder } ;
89use red_knot_python_semantic:: register_lints;
910use red_knot_python_semantic:: types:: check_types;
1011use ruff_db:: diagnostic:: { Diagnostic , DiagnosticId , ParseDiagnostic , Severity } ;
@@ -66,12 +67,22 @@ pub struct Project {
6667 /// The metadata describing the project, including the unresolved options.
6768 #[ return_ref]
6869 pub metadata : ProjectMetadata ,
70+
71+ /// The resolved project settings.
72+ #[ return_ref]
73+ pub settings : Settings ,
74+
75+ /// Diagnostics that were generated when resolving the project settings.
76+ #[ return_ref]
77+ settings_diagnostics : Vec < OptionDiagnostic > ,
6978}
7079
7180#[ salsa:: tracked]
7281impl Project {
7382 pub fn from_metadata ( db : & dyn Db , metadata : ProjectMetadata ) -> Self {
74- Project :: builder ( metadata)
83+ let ( settings, settings_diagnostics) = metadata. options ( ) . to_settings ( db) ;
84+
85+ Project :: builder ( metadata, settings, settings_diagnostics)
7586 . durability ( Durability :: MEDIUM )
7687 . open_fileset_durability ( Durability :: LOW )
7788 . file_set_durability ( Durability :: LOW )
@@ -91,25 +102,22 @@ impl Project {
91102 assert_eq ! ( self . root( db) , metadata. root( ) ) ;
92103
93104 if & metadata != self . metadata ( db) {
105+ let ( settings, settings_diagnostics) = metadata. options ( ) . to_settings ( db) ;
106+
107+ if self . settings ( db) != & settings {
108+ self . set_settings ( db) . to ( settings) ;
109+ }
110+
111+ if self . settings_diagnostics ( db) != & settings_diagnostics {
112+ self . set_settings_diagnostics ( db) . to ( settings_diagnostics) ;
113+ }
114+
94115 self . set_metadata ( db) . to ( metadata) ;
95116 }
96117
97118 self . reload_files ( db) ;
98119 }
99120
100- pub fn rule_selection ( self , db : & dyn Db ) -> & RuleSelection {
101- let ( selection, _) = self . rule_selection_with_diagnostics ( db) ;
102- selection
103- }
104-
105- #[ salsa:: tracked( return_ref) ]
106- fn rule_selection_with_diagnostics (
107- self ,
108- db : & dyn Db ,
109- ) -> ( RuleSelection , Vec < OptionDiagnostic > ) {
110- self . metadata ( db) . options ( ) . to_rule_selection ( db)
111- }
112-
113121 /// Checks all open files in the project and its dependencies.
114122 pub ( crate ) fn check ( self , db : & ProjectDatabase ) -> Vec < Box < dyn Diagnostic > > {
115123 let project_span = tracing:: debug_span!( "Project::check" ) ;
@@ -118,8 +126,7 @@ impl Project {
118126 tracing:: debug!( "Checking project '{name}'" , name = self . name( db) ) ;
119127
120128 let mut diagnostics: Vec < Box < dyn Diagnostic > > = Vec :: new ( ) ;
121- let ( _, options_diagnostics) = self . rule_selection_with_diagnostics ( db) ;
122- diagnostics. extend ( options_diagnostics. iter ( ) . map ( |diagnostic| {
129+ diagnostics. extend ( self . settings_diagnostics ( db) . iter ( ) . map ( |diagnostic| {
123130 let diagnostic: Box < dyn Diagnostic > = Box :: new ( diagnostic. clone ( ) ) ;
124131 diagnostic
125132 } ) ) ;
@@ -151,9 +158,8 @@ impl Project {
151158 }
152159
153160 pub ( crate ) fn check_file ( self , db : & dyn Db , file : File ) -> Vec < Box < dyn Diagnostic > > {
154- let ( _, options_diagnostics) = self . rule_selection_with_diagnostics ( db) ;
155-
156- let mut file_diagnostics: Vec < _ > = options_diagnostics
161+ let mut file_diagnostics: Vec < _ > = self
162+ . settings_diagnostics ( db)
157163 . iter ( )
158164 . map ( |diagnostic| {
159165 let diagnostic: Box < dyn Diagnostic > = Box :: new ( diagnostic. clone ( ) ) ;
0 commit comments