Skip to content

Commit 1f38ca5

Browse files
committed
Create default project lazily, centralize apply_changes
1 parent faa2615 commit 1f38ca5

File tree

15 files changed

+201
-141
lines changed

15 files changed

+201
-141
lines changed

crates/ty/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,17 @@ fn run_check(args: CheckCommand) -> anyhow::Result<ExitStatus> {
115115
None => ProjectMetadata::discover(&project_path, &system)?,
116116
};
117117

118-
let options = args.into_options();
119-
project_metadata.apply_options(options.clone());
120118
project_metadata.apply_configuration_files(&system)?;
121119

120+
let project_options_overrides = ProjectOptionsOverrides::new(config_file, args.into_options());
121+
project_metadata.apply_overrides(&project_options_overrides);
122+
122123
let mut db = ProjectDatabase::new(project_metadata, system)?;
123124

124125
if !check_paths.is_empty() {
125126
db.project().set_included_paths(&mut db, check_paths);
126127
}
127128

128-
let project_options_overrides = ProjectOptionsOverrides::new(config_file, options);
129129
let (main_loop, main_loop_cancellation_token) = MainLoop::new(project_options_overrides);
130130

131131
// Listen to Ctrl+C and abort the watch mode.

crates/ty_project/src/db.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::panic::{AssertUnwindSafe, RefUnwindSafe};
33
use std::sync::Arc;
44
use std::{cmp, fmt};
55

6+
pub use self::changes::ChangeResult;
67
use crate::metadata::settings::file_settings;
78
use crate::{DEFAULT_LINT_REGISTRY, DummyReporter};
89
use crate::{Project, ProjectMetadata, Reporter};

crates/ty_project/src/db/changes.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ impl ProjectDatabase {
4141
let project_root = project.root(self).to_path_buf();
4242
let config_file_override =
4343
project_options_overrides.and_then(|options| options.config_file_override.clone());
44-
let options =
45-
project_options_overrides.map(|project_options| project_options.options.clone());
4644
let program = Program::get(self);
4745
let custom_stdlib_versions_path = program
4846
.custom_stdlib_search_path(self)
@@ -218,16 +216,16 @@ impl ProjectDatabase {
218216
};
219217
match new_project_metadata {
220218
Ok(mut metadata) => {
221-
if let Some(cli_options) = options {
222-
metadata.apply_options(cli_options);
223-
}
224-
225219
if let Err(error) = metadata.apply_configuration_files(self.system()) {
226220
tracing::error!(
227221
"Failed to apply configuration files, continuing without applying them: {error}"
228222
);
229223
}
230224

225+
if let Some(overrides) = project_options_overrides {
226+
metadata.apply_overrides(overrides);
227+
}
228+
231229
match metadata.to_program_settings(self.system(), self.vendored()) {
232230
Ok(program_settings) => {
233231
let program = Program::get(self);

crates/ty_project/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::glob::{GlobFilterCheckMode, IncludeResult};
22
use crate::metadata::options::{OptionDiagnostic, ToSettingsError};
33
use crate::walk::{ProjectFilesFilter, ProjectFilesWalker};
4-
pub use db::{CheckMode, Db, ProjectDatabase, SalsaMemoryDump};
4+
pub use db::{ChangeResult, CheckMode, Db, ProjectDatabase, SalsaMemoryDump};
55
use files::{Index, Indexed, IndexedFiles};
66
use metadata::settings::Settings;
77
pub use metadata::{ProjectMetadata, ProjectMetadataError};

crates/ty_project/src/metadata.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use thiserror::Error;
77
use ty_python_semantic::ProgramSettings;
88

99
use crate::combine::Combine;
10+
use crate::metadata::options::ProjectOptionsOverrides;
1011
use crate::metadata::pyproject::{Project, PyProject, PyProjectError, ResolveRequiresPythonError};
1112
use crate::metadata::value::ValueSource;
1213
pub use options::Options;
@@ -276,6 +277,10 @@ impl ProjectMetadata {
276277
.to_program_settings(self.root(), self.name(), system, vendored)
277278
}
278279

280+
pub fn apply_overrides(&mut self, overrides: &ProjectOptionsOverrides) {
281+
self.options = overrides.apply_to(std::mem::take(&mut self.options));
282+
}
283+
279284
/// Combine the project options with the CLI options where the CLI options take precedence.
280285
pub fn apply_options(&mut self, options: Options) {
281286
self.options = options.combine(std::mem::take(&mut self.options));

crates/ty_project/src/metadata/options.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,8 +1476,11 @@ impl OptionDiagnostic {
14761476
/// This is a wrapper for options that actually get loaded from configuration files
14771477
/// and the CLI, which also includes a `config_file_override` option that overrides
14781478
/// default configuration discovery with an explicitly-provided path to a configuration file
1479+
#[derive(Debug, Default)]
14791480
pub struct ProjectOptionsOverrides {
14801481
pub config_file_override: Option<SystemPathBuf>,
1482+
pub fallback_python_version: Option<RangedValue<PythonVersion>>,
1483+
pub fallback_python: Option<RelativePathBuf>,
14811484
pub options: Options,
14821485
}
14831486

@@ -1486,8 +1489,51 @@ impl ProjectOptionsOverrides {
14861489
Self {
14871490
config_file_override,
14881491
options,
1492+
..Self::default()
14891493
}
14901494
}
1495+
1496+
pub fn apply_to(&self, options: Options) -> Options {
1497+
let mut combined = self.options.clone().combine(options);
1498+
1499+
if let Some(python_version) = &self.fallback_python_version {
1500+
let configured_python_version = combined
1501+
.environment
1502+
.as_ref()
1503+
.and_then(|environment| environment.python_version.as_ref());
1504+
1505+
if configured_python_version.is_none() {
1506+
tracing::debug!(
1507+
"Using the Python version of the selected Python interpreter in the VS Code Python extension: {python_version}"
1508+
);
1509+
1510+
combined.environment = Some(EnvironmentOptions {
1511+
python_version: Some(python_version.clone()),
1512+
..combined.environment.unwrap_or_default()
1513+
});
1514+
}
1515+
}
1516+
1517+
if let Some(python) = &self.fallback_python {
1518+
let configured_python = combined
1519+
.environment
1520+
.as_ref()
1521+
.and_then(|environment| environment.python.as_ref());
1522+
1523+
if configured_python.is_none() {
1524+
tracing::debug!(
1525+
"Using the environment selected in the VS Code Python extension as python path: {python}"
1526+
);
1527+
1528+
combined.environment = Some(EnvironmentOptions {
1529+
python: Some(python.clone()),
1530+
..combined.environment.unwrap_or_default()
1531+
});
1532+
}
1533+
}
1534+
1535+
combined
1536+
}
14911537
}
14921538

14931539
trait OrDefault {

crates/ty_server/src/server/api/notifications/did_change.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,16 @@ impl SyncNotificationHandler for DidChangeTextDocumentHandler {
3737
.update_text_document(&key, content_changes, version)
3838
.with_failure_code(ErrorCode::InternalError)?;
3939

40-
match key.path() {
40+
let changes = match key.path() {
4141
AnySystemPath::System(path) => {
42-
let db = match session.project_db_for_path_mut(path) {
43-
Some(db) => db,
44-
None => session.default_project_db_mut(),
45-
};
46-
db.apply_changes(vec![ChangeEvent::file_content_changed(path.clone())], None);
42+
vec![ChangeEvent::file_content_changed(path.clone())]
4743
}
4844
AnySystemPath::SystemVirtual(virtual_path) => {
49-
let db = session.default_project_db_mut();
50-
db.apply_changes(
51-
vec![ChangeEvent::ChangedVirtual(virtual_path.clone())],
52-
None,
53-
);
45+
vec![ChangeEvent::ChangedVirtual(virtual_path.clone())]
5446
}
55-
}
47+
};
48+
49+
session.apply_changes(key.path(), changes);
5650

5751
publish_diagnostics(session, &key, client)
5852
}

crates/ty_server/src/server/api/notifications/did_change_watched_files.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,7 @@ impl SyncNotificationHandler for DidChangeWatchedFiles {
8888
for (root, changes) in events_by_db {
8989
tracing::debug!("Applying changes to `{root}`");
9090

91-
// SAFETY: Only paths that are part of the workspace are registered for file watching.
92-
// So, virtual paths and paths that are outside of a workspace does not trigger this
93-
// notification.
94-
let db = session.project_db_for_path_mut(&*root).unwrap();
95-
96-
let result = db.apply_changes(changes, None);
91+
let result = session.apply_changes(&AnySystemPath::System(root), changes);
9792

9893
project_changed |= result.project_changed();
9994
}

crates/ty_server/src/server/api/notifications/did_close.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@ impl SyncNotificationHandler for DidCloseTextDocumentHandler {
3434
.with_failure_code(ErrorCode::InternalError)?;
3535

3636
if let AnySystemPath::SystemVirtual(virtual_path) = key.path() {
37-
let db = session.default_project_db_mut();
38-
db.apply_changes(
37+
session.apply_changes(
38+
key.path(),
3939
vec![ChangeEvent::DeletedVirtual(virtual_path.clone())],
40-
None,
4140
);
4241
}
4342

crates/ty_server/src/server/api/notifications/did_close_notebook.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@ impl SyncNotificationHandler for DidCloseNotebookHandler {
3333
.with_failure_code(lsp_server::ErrorCode::InternalError)?;
3434

3535
if let AnySystemPath::SystemVirtual(virtual_path) = key.path() {
36-
let db = session.default_project_db_mut();
37-
db.apply_changes(
36+
session.apply_changes(
37+
key.path(),
3838
vec![ChangeEvent::DeletedVirtual(virtual_path.clone())],
39-
None,
4039
);
4140
}
4241

0 commit comments

Comments
 (0)