Skip to content

Commit a788c47

Browse files
committed
[ty] Add None, True and False to scoped completions
This doesn't implement fully context aware keyword completions, but it does let us include the 3 keywords that are also values in completions. This helps improve the completion experience when trying to write one of these values in the ty playground. Ranking could still be improved here. We haven't yet devised a mechanism for ranking "builtin" symbols above others. It's even plausible that these _particular_ symbols should get special treatment over and above others.
1 parent 6821b7a commit a788c47

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-3
lines changed

crates/ty_completion_eval/completion-evaluation-tasks.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ higher-level-symbols-preferred,main.py,1,1
55
import-deprioritizes-dunder,main.py,0,1
66
import-deprioritizes-sunder,main.py,0,1
77
internal-typeshed-hidden,main.py,0,4
8-
none-completion,main.py,0,
8+
none-completion,main.py,0,11
99
numpy-array,main.py,0,
1010
numpy-array,main.py,1,1
1111
object-attr-instance-methods,main.py,0,1

crates/ty_ide/src/completion.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use ruff_python_ast::name::Name;
99
use ruff_python_codegen::Stylist;
1010
use ruff_python_parser::{Token, TokenAt, TokenKind, Tokens};
1111
use ruff_text_size::{Ranged, TextRange, TextSize};
12+
use ty_python_semantic::types::KnownClass;
1213
use ty_python_semantic::{
1314
Completion as SemanticCompletion, ModuleName, NameKind, SemanticModel,
1415
types::{CycleDetector, Type},
@@ -252,6 +253,9 @@ pub fn completion<'db>(
252253
.map(|c| Completion::from_semantic_completion(db, c))
253254
.collect();
254255

256+
if scoped.is_some() {
257+
add_keyword_value_completions(db, &typed_query, &mut completions);
258+
}
255259
if settings.auto_import {
256260
if let Some(scoped) = scoped {
257261
add_unimported_completions(
@@ -269,6 +273,37 @@ pub fn completion<'db>(
269273
completions
270274
}
271275

276+
/// Adds a subset of completions derived from keywords.
277+
///
278+
/// Note that at present, these should only be added to "scoped"
279+
/// completions. i.e., This will include `None`, `True`, `False`, etc.
280+
fn add_keyword_value_completions<'db>(
281+
db: &'db dyn Db,
282+
query: &QueryPattern,
283+
completions: &mut Vec<Completion<'db>>,
284+
) {
285+
let keywords = [
286+
("None", KnownClass::NoneType),
287+
("True", KnownClass::Bool),
288+
("False", KnownClass::Bool),
289+
];
290+
for (name, known) in keywords {
291+
if !query.is_match_symbol_name(name) {
292+
continue;
293+
}
294+
completions.push(Completion {
295+
name: ast::name::Name::new(name),
296+
insert: None,
297+
ty: Some(known.to_class_literal(db)),
298+
kind: None,
299+
module_name: None,
300+
import: None,
301+
builtin: true,
302+
documentation: None,
303+
});
304+
}
305+
}
306+
272307
/// Adds completions not in scope.
273308
///
274309
/// `scoped` should be information about the identified scope

crates/ty_python_semantic/src/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use crate::types::visitor::any_over_type;
6666
use crate::unpack::EvaluationMode;
6767
pub use crate::util::diagnostics::add_inferred_python_version_hint_to_diagnostic;
6868
use crate::{Db, FxOrderSet, Module, Program};
69-
pub(crate) use class::{ClassLiteral, ClassType, GenericAlias, KnownClass};
69+
pub use class::{ClassLiteral, ClassType, GenericAlias, KnownClass};
7070
use instance::Protocol;
7171
pub use instance::{NominalInstanceType, ProtocolInstanceType};
7272
pub use special_form::SpecialFormType;

crates/ty_python_semantic/src/types/class.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4576,7 +4576,7 @@ impl KnownClass {
45764576
/// Lookup a [`KnownClass`] in typeshed and return a [`Type`] representing that class-literal.
45774577
///
45784578
/// If the class cannot be found in typeshed, a debug-level log message will be emitted stating this.
4579-
pub(crate) fn to_class_literal(self, db: &dyn Db) -> Type<'_> {
4579+
pub fn to_class_literal(self, db: &dyn Db) -> Type<'_> {
45804580
self.try_to_class_literal(db)
45814581
.map(Type::ClassLiteral)
45824582
.unwrap_or_else(Type::unknown)

0 commit comments

Comments
 (0)