Skip to content

Commit 19a2edc

Browse files
John Van Schultzmeta-codesync[bot]
authored andcommitted
Implement write_targs
Summary: Implements the write_targs method for OutputWithLocations to handle type arguments in generic types. For non-empty type arguments, writes opening bracket "[", then iterates through each type argument calling write_type (which will recursively capture locations), inserting ", " separators between arguments, and finally writes closing bracket "]". This ensures that each type in a generic like List[int] gets its own location. Empty type arguments produce no output. Includes tests verifying correct bracket structure, comma separation, and integration with write_type calls. Reviewed By: ndmitchell Differential Revision: D87712004 fbshipit-source-id: d082709ff1a57b24eba75fabcf73b57129024672
1 parent 1bd817f commit 19a2edc

File tree

1 file changed

+78
-1
lines changed

1 file changed

+78
-1
lines changed

crates/pyrefly_types/src/type_output.rs

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,20 @@ impl TypeOutput for OutputWithLocations<'_> {
116116
Ok(())
117117
}
118118

119-
fn write_targs(&mut self, _targs: &TArgs) -> fmt::Result {
119+
fn write_targs(&mut self, targs: &TArgs) -> fmt::Result {
120+
// Write each type argument separately with its own location
121+
// This ensures that each type in a union (e.g., int | str) gets its own
122+
// clickable part with a link to its definition
123+
if !targs.is_empty() {
124+
self.write_str("[")?;
125+
for (i, ty) in targs.as_slice().iter().enumerate() {
126+
if i > 0 {
127+
self.write_str(", ")?;
128+
}
129+
self.write_type(ty)?;
130+
}
131+
self.write_str("]")?;
132+
}
120133
Ok(())
121134
}
122135

@@ -145,7 +158,13 @@ mod tests {
145158
use crate::class::ClassDefIndex;
146159
use crate::class::ClassType;
147160
use crate::literal::LitEnum;
161+
use crate::quantified::Quantified;
162+
use crate::quantified::QuantifiedKind;
163+
use crate::type_var::PreInferenceVariance;
164+
use crate::type_var::Restriction;
148165
use crate::types::TArgs;
166+
use crate::types::TParam;
167+
use crate::types::TParams;
149168

150169
fn fake_class(name: &str, module: &str, range: u32) -> Class {
151170
let mi = Module::new(
@@ -259,4 +278,62 @@ mod tests {
259278
assert_eq!(loc.range, TextRange::empty(TextSize::new(10)));
260279
assert_eq!(loc.module.name(), ModuleName::from_str("colors"));
261280
}
281+
282+
#[test]
283+
fn test_output_with_locations_write_targs_multiple() {
284+
let context = TypeDisplayContext::default();
285+
let mut output = OutputWithLocations::new(&context);
286+
287+
// Create TArgs with multiple type arguments
288+
let tparam1 = TParam {
289+
quantified: Quantified::new(
290+
pyrefly_util::uniques::UniqueFactory::new().fresh(),
291+
Name::new("T"),
292+
QuantifiedKind::TypeVar,
293+
None,
294+
Restriction::Unrestricted,
295+
),
296+
variance: PreInferenceVariance::PInvariant,
297+
};
298+
let tparam2 = TParam {
299+
quantified: Quantified::new(
300+
pyrefly_util::uniques::UniqueFactory::new().fresh(),
301+
Name::new("U"),
302+
QuantifiedKind::TypeVar,
303+
None,
304+
Restriction::Unrestricted,
305+
),
306+
variance: PreInferenceVariance::PInvariant,
307+
};
308+
let tparam3 = TParam {
309+
quantified: Quantified::new(
310+
pyrefly_util::uniques::UniqueFactory::new().fresh(),
311+
Name::new("V"),
312+
QuantifiedKind::TypeVar,
313+
None,
314+
Restriction::Unrestricted,
315+
),
316+
variance: PreInferenceVariance::PInvariant,
317+
};
318+
319+
let tparams = Arc::new(TParams::new(vec![tparam1, tparam2, tparam3]));
320+
let targs = TArgs::new(
321+
tparams,
322+
vec![Type::None, Type::LiteralString, Type::any_explicit()],
323+
);
324+
325+
output.write_targs(&targs).unwrap();
326+
327+
// Should have "[", ", ", ", ", and "]"
328+
// write_type is stubbed, so types themselves don't appear
329+
assert_eq!(output.parts().len(), 4);
330+
assert_eq!(output.parts()[0].0, "[");
331+
assert!(output.parts()[0].1.is_none());
332+
assert_eq!(output.parts()[1].0, ", ");
333+
assert!(output.parts()[1].1.is_none());
334+
assert_eq!(output.parts()[2].0, ", ");
335+
assert!(output.parts()[2].1.is_none());
336+
assert_eq!(output.parts()[3].0, "]");
337+
assert!(output.parts()[3].1.is_none());
338+
}
262339
}

0 commit comments

Comments
 (0)