diff --git a/src/html/symbols/function.rs b/src/html/symbols/function.rs
index 334da4c8..689e60c0 100644
--- a/src/html/symbols/function.rs
+++ b/src/html/symbols/function.rs
@@ -62,7 +62,6 @@ pub(crate) fn render_function(
ctx: &RenderContext,
doc_nodes: Vec<&DocNodeWithContext>,
) -> FunctionCtx {
- // TODO: this needs to be handled more gracefully on the frontend
let mut overloads_ctx = Vec::with_capacity(doc_nodes.len());
let mut functions_content = Vec::with_capacity(doc_nodes.len());
diff --git a/src/html/symbols/mod.rs b/src/html/symbols/mod.rs
index c15aef99..35d91b7a 100644
--- a/src/html/symbols/mod.rs
+++ b/src/html/symbols/mod.rs
@@ -58,8 +58,6 @@ impl SymbolGroupCtx {
split_nodes.sort_keys();
- // TODO: property drilldown
-
let symbols = split_nodes
.values()
.map(|doc_nodes| {
diff --git a/src/html/types.rs b/src/html/types.rs
index bd82d47b..6a3f97a8 100644
--- a/src/html/types.rs
+++ b/src/html/types.rs
@@ -56,8 +56,25 @@ pub(crate) fn render_type_def(
format!("{:?}", html_escape::encode_safe(&def.repr))
}
LiteralDefKind::Template => {
- // TODO(@kitsonk) do this properly and escape properly
- format!("`{}`", html_escape::encode_safe(&def.repr))
+ if let Some(types) = &lit.ts_types {
+ let mut out = String::new();
+
+ for ts_type in types {
+ out.push_str(&if ts_type
+ .literal
+ .as_ref()
+ .is_some_and(|literal| literal.string.is_some())
+ {
+ html_escape::encode_safe(&ts_type.repr).into_owned()
+ } else {
+ format!("${{{}}}", render_type_def(ctx, ts_type))
+ });
+ }
+
+ format!("`{out}`")
+ } else {
+ format!("`{}`", html_escape::encode_safe(&def.repr))
+ }
}
}
}
diff --git a/src/parser.rs b/src/parser.rs
index 0a2ef152..55ed8b30 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -393,14 +393,14 @@ impl<'a> DocParser<'a> {
var_declarator,
)
.into_iter()
- .find(|(name, _, _)| name.as_str() == &*ident.sym)
- .map(|(name, var_def, _)| {
+ .find(|(name, _)| name.as_str() == &*ident.sym)
+ .map(|(name, var_def)| {
let location = get_location(module_info.source(), ident.start());
DocNode::variable(
name,
location,
DeclarationKind::Declare,
- js_doc.clone(),
+ js_doc,
var_def,
)
})
diff --git a/src/printer.rs b/src/printer.rs
index 598e4da1..ed91626d 100644
--- a/src/printer.rs
+++ b/src/printer.rs
@@ -1,15 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-// TODO(ry) This module builds up output by appending to a string. Instead it
-// should either use a formatting trait
-// https://doc.rust-lang.org/std/fmt/index.html#formatting-traits
-// Or perhaps implement a Serializer for serde
-// https://docs.serde.rs/serde/ser/trait.Serializer.html
-
-// TODO(ry) The methods in this module take ownership of the DocNodes, this is
-// unnecessary and can result in unnecessary copying. Instead they should take
-// references.
-
use crate::colors;
use crate::display::display_abstract;
use crate::display::display_async;
diff --git a/src/ts_type.rs b/src/ts_type.rs
index c6192a43..35e9c5c1 100644
--- a/src/ts_type.rs
+++ b/src/ts_type.rs
@@ -17,8 +17,6 @@ use crate::ParamDef;
use deno_ast::swc::ast::*;
use deno_ast::ParsedSource;
-use deno_ast::SourceRange;
-use deno_ast::SourceRangedForSpanned;
use serde::Deserialize;
use serde::Serialize;
use std::fmt::Display;
@@ -30,9 +28,15 @@ impl TsTypeDef {
match &other.lit {
TsLit::Number(num) => TsTypeDef::number_literal(num),
TsLit::Str(str_) => TsTypeDef::string_literal(str_),
- TsLit::Tpl(tpl) => {
- TsTypeDef::tpl_literal(parsed_source, &tpl.types, &tpl.quasis)
- }
+ TsLit::Tpl(tpl) => TsTypeDef::tpl_literal(
+ parsed_source,
+ tpl
+ .types
+ .iter()
+ .map(|types| TsTypeDef::new(parsed_source, types))
+ .collect::>(),
+ &tpl.quasis,
+ ),
TsLit::Bool(bool_) => TsTypeDef::bool_literal(bool_),
TsLit::BigInt(bigint_) => TsTypeDef::bigint_literal(bigint_),
}
@@ -1128,49 +1132,6 @@ impl Display for TsTypePredicateDef {
}
}
-fn get_range_from_type(ts_type: &TsType) -> SourceRange {
- use deno_ast::swc::ast::TsType::*;
-
- match ts_type {
- TsArrayType(ref t) => get_range_from_type(t.elem_type.as_ref()),
- TsConditionalType(ref t) => get_range_from_type(t.check_type.as_ref()),
- TsFnOrConstructorType(ref t) => {
- if let Some(t) = t.clone().ts_constructor_type() {
- t.range()
- } else if let Some(t) = t.clone().ts_fn_type() {
- t.range()
- } else {
- unreachable!("no type found")
- }
- }
- TsImportType(ref t) => t.range(),
- TsIndexedAccessType(ref t) => get_range_from_type(&t.index_type),
- TsInferType(t) => t.range(),
- TsKeywordType(t) => t.range(),
- TsLitType(t) => t.range(),
- TsMappedType(t) => t.range(),
- TsOptionalType(t) => t.range(),
- TsParenthesizedType(t) => t.range(),
- TsRestType(t) => t.range(),
- TsThisType(t) => t.range(),
- TsTupleType(t) => t.range(),
- TsTypeLit(t) => t.range(),
- TsTypeOperator(t) => t.range(),
- TsTypePredicate(t) => t.range(),
- TsTypeQuery(t) => t.range(),
- TsTypeRef(t) => t.range(),
- TsUnionOrIntersectionType(t) => {
- if let Some(t) = t.clone().ts_intersection_type() {
- t.range()
- } else if let Some(t) = t.clone().ts_union_type() {
- t.range()
- } else {
- unreachable!("no type found")
- }
- }
- }
-}
-
impl TsTypeDef {
pub fn number_literal(num: &Number) -> Self {
Self::number_value(num.value)
@@ -1205,16 +1166,16 @@ impl TsTypeDef {
}
pub fn tpl_literal(
- parsed_source: &ParsedSource,
- types: &[Box],
+ _parsed_source: &ParsedSource,
+ types: Vec,
quasis: &[TplElement],
) -> Self {
- let mut ts_types: Vec<(SourceRange, Self, String)> = Vec::new();
+ let mut types_out: Vec<(Self, String)> = Vec::new();
for ts_type in types {
- let t = TsTypeDef::new(parsed_source, ts_type);
- let repr = format!("${{{}}}", t);
- ts_types.push((get_range_from_type(ts_type), t, repr))
+ let repr = format!("${{{}}}", ts_type);
+ types_out.push((ts_type, repr))
}
+ let mut qasis_out: Vec<(Self, String)> = Vec::new();
for quasi in quasis {
let repr = quasi.raw.to_string();
let lit = LiteralDef {
@@ -1224,15 +1185,22 @@ impl TsTypeDef {
ts_types: None,
boolean: None,
};
- ts_types.push((quasi.range(), Self::literal(repr.clone(), lit), repr));
+ qasis_out.push((Self::literal(repr.clone(), lit), repr));
}
- ts_types.sort_by(|(a, _, _), (b, _, _)| a.cmp(b));
- let repr = ts_types
- .iter()
- .map(|(_, _, s)| s.as_str())
- .collect::>()
- .join("");
- let ts_types = Some(ts_types.into_iter().map(|(_, t, _)| t).collect());
+
+ let mut out = vec![];
+
+ let mut types_iter = types_out.into_iter();
+
+ for quasi in qasis_out {
+ out.push(quasi);
+ if let Some(ts_type) = types_iter.next() {
+ out.push(ts_type);
+ }
+ }
+
+ let repr = out.iter().map(|(_, s)| s.as_str()).collect::();
+ let ts_types = Some(out.into_iter().map(|(t, _)| t).collect());
let lit = LiteralDef {
kind: LiteralDefKind::Template,
number: None,
@@ -1815,11 +1783,14 @@ fn infer_ts_type_from_tpl(
tpl: &Tpl,
is_const: bool,
) -> TsTypeDef {
- // TODO(@kitsonk) we should iterate over the expr and if each expr has a
- // ts_type or can be trivially inferred, it should be passed to the
- // tp_literal
- if tpl.quasis.len() == 1 && is_const {
- TsTypeDef::tpl_literal(parsed_source, &[], &tpl.quasis)
+ let exprs = tpl
+ .exprs
+ .iter()
+ .map(|expr| infer_ts_type_from_expr(parsed_source, expr, is_const))
+ .collect::