summaryrefslogtreecommitdiff
path: root/cli/doc/params.rs
diff options
context:
space:
mode:
authorValentin Anger <syrupthinker@gryphno.de>2020-07-12 14:16:33 +0200
committerGitHub <noreply@github.com>2020-07-12 14:16:33 +0200
commit3374c73fba3a96df22d0c04e6c17078ca8cce45b (patch)
tree91d996554a2e276724a86ecb3bff19ea5411238b /cli/doc/params.rs
parent871f9255e37b4d2e63439c84da8e9bed6b388034 (diff)
feat(doc): Improve terminal printer (#6594)
- Add more support for generics - Add the --private flag - displays documentation for not exported and private nodes - Display more attributes like abstract, static and readonly - Display type aliases - Refactor module to use the Display trait - Use a bit more color
Diffstat (limited to 'cli/doc/params.rs')
-rw-r--r--cli/doc/params.rs275
1 files changed, 239 insertions, 36 deletions
diff --git a/cli/doc/params.rs b/cli/doc/params.rs
index 0869c1969..3e7967c81 100644
--- a/cli/doc/params.rs
+++ b/cli/doc/params.rs
@@ -1,58 +1,228 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+use super::display::{display_optional, SliceDisplayer};
+use super::ts_type::{ts_type_ann_to_def, TsTypeDef};
+use crate::swc_common::SourceMap;
use crate::swc_ecma_ast;
+use crate::swc_ecma_ast::{ObjectPatProp, Pat, TsFnParam};
+use serde::Serialize;
+use std::fmt::{Display, Formatter, Result as FmtResult};
-use super::ts_type::ts_type_ann_to_def;
-use super::ParamDef;
-use super::ParamKind;
-use crate::swc_ecma_ast::Pat;
-use crate::swc_ecma_ast::TsFnParam;
+#[derive(Debug, Serialize, Clone)]
+#[serde(rename_all = "camelCase")]
+#[serde(tag = "kind")]
+pub enum ParamDef {
+ #[serde(rename_all = "camelCase")]
+ Array {
+ elements: Vec<Option<ParamDef>>,
+ optional: bool,
+ ts_type: Option<TsTypeDef>,
+ },
+ #[serde(rename_all = "camelCase")]
+ Assign {
+ left: Box<ParamDef>,
+ right: String,
+ ts_type: Option<TsTypeDef>,
+ },
+ #[serde(rename_all = "camelCase")]
+ Identifier {
+ name: String,
+ optional: bool,
+ ts_type: Option<TsTypeDef>,
+ },
+ #[serde(rename_all = "camelCase")]
+ Object {
+ props: Vec<ObjectPatPropDef>,
+ optional: bool,
+ ts_type: Option<TsTypeDef>,
+ },
+ #[serde(rename_all = "camelCase")]
+ Rest {
+ arg: Box<ParamDef>,
+ ts_type: Option<TsTypeDef>,
+ },
+}
+
+impl Display for ParamDef {
+ fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
+ match self {
+ Self::Array {
+ elements,
+ optional,
+ ts_type,
+ } => {
+ write!(f, "[")?;
+ if !elements.is_empty() {
+ if let Some(v) = &elements[0] {
+ write!(f, "{}", v)?;
+ }
+ for maybe_v in &elements[1..] {
+ write!(f, ", ")?;
+ if let Some(v) = maybe_v {
+ write!(f, "{}", v)?;
+ }
+ }
+ }
+ write!(f, "]")?;
+ write!(f, "{}", display_optional(*optional))?;
+ if let Some(ts_type) = ts_type {
+ write!(f, ": {}", ts_type)?;
+ }
+ Ok(())
+ }
+ Self::Assign { left, ts_type, .. } => {
+ write!(f, "{}", left)?;
+ if let Some(ts_type) = ts_type {
+ write!(f, ": {}", ts_type)?;
+ }
+ // TODO(SyrupThinker) As we cannot display expressions the value is just omitted
+ // write!(f, " = {}", right)?;
+ Ok(())
+ }
+ Self::Identifier {
+ name,
+ optional,
+ ts_type,
+ } => {
+ write!(f, "{}{}", name, display_optional(*optional))?;
+ if let Some(ts_type) = ts_type {
+ write!(f, ": {}", ts_type)?;
+ }
+ Ok(())
+ }
+ Self::Object {
+ props,
+ optional,
+ ts_type,
+ } => {
+ write!(
+ f,
+ "{{{}}}{}",
+ SliceDisplayer::new(&props, ", ", false),
+ display_optional(*optional)
+ )?;
+ if let Some(ts_type) = ts_type {
+ write!(f, ": {}", ts_type)?;
+ }
+ Ok(())
+ }
+ Self::Rest { arg, ts_type } => {
+ write!(f, "...{}", arg)?;
+ if let Some(ts_type) = ts_type {
+ write!(f, ": {}", ts_type)?;
+ }
+ Ok(())
+ }
+ }
+ }
+}
-pub fn ident_to_param_def(ident: &swc_ecma_ast::Ident) -> ParamDef {
+#[derive(Debug, Serialize, Clone)]
+#[serde(rename_all = "camelCase")]
+#[serde(tag = "kind")]
+pub enum ObjectPatPropDef {
+ Assign { key: String, value: Option<String> },
+ KeyValue { key: String, value: Box<ParamDef> },
+ Rest { arg: Box<ParamDef> },
+}
+
+impl Display for ObjectPatPropDef {
+ fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
+ match self {
+ Self::KeyValue { key, .. } => {
+ // The internal identifier does not need to be exposed
+ write!(f, "{}", key)
+ }
+ Self::Assign { key, value } => {
+ if let Some(_value) = value {
+ // TODO(SyrupThinker) As we cannot display expressions the value is just omitted
+ write!(f, "{}", key)
+ } else {
+ write!(f, "{}", key)
+ }
+ }
+ Self::Rest { arg } => write!(f, "...{}", arg),
+ }
+ }
+}
+
+pub fn ident_to_param_def(
+ ident: &swc_ecma_ast::Ident,
+ _source_map: Option<&SourceMap>,
+) -> ParamDef {
let ts_type = ident.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt));
- ParamDef {
+ ParamDef::Identifier {
name: ident.sym.to_string(),
- kind: ParamKind::Identifier,
optional: ident.optional,
ts_type,
}
}
-fn rest_pat_to_param_def(rest_pat: &swc_ecma_ast::RestPat) -> ParamDef {
- let name = match &*rest_pat.arg {
- Pat::Ident(ident) => ident.sym.to_string(),
- _ => "<TODO>".to_string(),
- };
+fn rest_pat_to_param_def(
+ rest_pat: &swc_ecma_ast::RestPat,
+ source_map: Option<&SourceMap>,
+) -> ParamDef {
let ts_type = rest_pat.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt));
- ParamDef {
- name,
- kind: ParamKind::Rest,
- optional: false,
+ ParamDef::Rest {
+ arg: Box::new(pat_to_param_def(&*rest_pat.arg, source_map)),
ts_type,
}
}
-fn object_pat_to_param_def(object_pat: &swc_ecma_ast::ObjectPat) -> ParamDef {
+fn object_pat_prop_to_def(
+ object_pat_prop: &ObjectPatProp,
+ source_map: Option<&SourceMap>,
+) -> ObjectPatPropDef {
+ match object_pat_prop {
+ ObjectPatProp::Assign(assign) => ObjectPatPropDef::Assign {
+ key: assign.key.sym.to_string(),
+ value: assign.value.as_ref().map(|_| "<UNIMPLEMENTED>".to_string()),
+ },
+ ObjectPatProp::KeyValue(keyvalue) => ObjectPatPropDef::KeyValue {
+ key: prop_name_to_string(&keyvalue.key, source_map),
+ value: Box::new(pat_to_param_def(&*keyvalue.value, source_map)),
+ },
+ ObjectPatProp::Rest(rest) => ObjectPatPropDef::Rest {
+ arg: Box::new(pat_to_param_def(&*rest.arg, source_map)),
+ },
+ }
+}
+
+fn object_pat_to_param_def(
+ object_pat: &swc_ecma_ast::ObjectPat,
+ source_map: Option<&SourceMap>,
+) -> ParamDef {
+ let props = object_pat
+ .props
+ .iter()
+ .map(|prop| object_pat_prop_to_def(prop, source_map))
+ .collect::<Vec<_>>();
let ts_type = object_pat
.type_ann
.as_ref()
.map(|rt| ts_type_ann_to_def(rt));
- ParamDef {
- name: "".to_string(),
- kind: ParamKind::Object,
+ ParamDef::Object {
+ props,
optional: object_pat.optional,
ts_type,
}
}
-fn array_pat_to_param_def(array_pat: &swc_ecma_ast::ArrayPat) -> ParamDef {
+fn array_pat_to_param_def(
+ array_pat: &swc_ecma_ast::ArrayPat,
+ source_map: Option<&SourceMap>,
+) -> ParamDef {
+ let elements = array_pat
+ .elems
+ .iter()
+ .map(|elem| elem.as_ref().map(|e| pat_to_param_def(e, source_map)))
+ .collect::<Vec<Option<_>>>();
let ts_type = array_pat.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt));
- ParamDef {
- name: "".to_string(),
- kind: ParamKind::Array,
+ ParamDef::Array {
+ elements,
optional: array_pat.optional,
ts_type,
}
@@ -60,28 +230,61 @@ fn array_pat_to_param_def(array_pat: &swc_ecma_ast::ArrayPat) -> ParamDef {
pub fn assign_pat_to_param_def(
assign_pat: &swc_ecma_ast::AssignPat,
+ source_map: Option<&SourceMap>,
) -> ParamDef {
- pat_to_param_def(&*assign_pat.left)
+ let ts_type = assign_pat
+ .type_ann
+ .as_ref()
+ .map(|rt| ts_type_ann_to_def(rt));
+
+ ParamDef::Assign {
+ left: Box::new(pat_to_param_def(&*assign_pat.left, source_map)),
+ right: "<UNIMPLEMENTED>".to_string(),
+ ts_type,
+ }
}
-pub fn pat_to_param_def(pat: &swc_ecma_ast::Pat) -> ParamDef {
+pub fn pat_to_param_def(
+ pat: &swc_ecma_ast::Pat,
+ source_map: Option<&SourceMap>,
+) -> ParamDef {
match pat {
- Pat::Ident(ident) => ident_to_param_def(ident),
- Pat::Array(array_pat) => array_pat_to_param_def(array_pat),
- Pat::Rest(rest_pat) => rest_pat_to_param_def(rest_pat),
- Pat::Object(object_pat) => object_pat_to_param_def(object_pat),
- Pat::Assign(assign_pat) => assign_pat_to_param_def(assign_pat),
+ Pat::Ident(ident) => ident_to_param_def(ident, source_map),
+ Pat::Array(array_pat) => array_pat_to_param_def(array_pat, source_map),
+ Pat::Rest(rest_pat) => rest_pat_to_param_def(rest_pat, source_map),
+ Pat::Object(object_pat) => object_pat_to_param_def(object_pat, source_map),
+ Pat::Assign(assign_pat) => assign_pat_to_param_def(assign_pat, source_map),
_ => unreachable!(),
}
}
pub fn ts_fn_param_to_param_def(
ts_fn_param: &swc_ecma_ast::TsFnParam,
+ source_map: Option<&SourceMap>,
) -> ParamDef {
match ts_fn_param {
- TsFnParam::Ident(ident) => ident_to_param_def(ident),
- TsFnParam::Array(array_pat) => array_pat_to_param_def(array_pat),
- TsFnParam::Rest(rest_pat) => rest_pat_to_param_def(rest_pat),
- TsFnParam::Object(object_pat) => object_pat_to_param_def(object_pat),
+ TsFnParam::Ident(ident) => ident_to_param_def(ident, source_map),
+ TsFnParam::Array(array_pat) => {
+ array_pat_to_param_def(array_pat, source_map)
+ }
+ TsFnParam::Rest(rest_pat) => rest_pat_to_param_def(rest_pat, source_map),
+ TsFnParam::Object(object_pat) => {
+ object_pat_to_param_def(object_pat, source_map)
+ }
+ }
+}
+
+pub fn prop_name_to_string(
+ prop_name: &swc_ecma_ast::PropName,
+ source_map: Option<&SourceMap>,
+) -> String {
+ use crate::swc_ecma_ast::PropName;
+ match prop_name {
+ PropName::Ident(ident) => ident.sym.to_string(),
+ PropName::Str(str_) => str_.value.to_string(),
+ PropName::Num(num) => num.value.to_string(),
+ PropName::Computed(comp_prop_name) => source_map
+ .map(|sm| sm.span_to_snippet(comp_prop_name.span).unwrap())
+ .unwrap_or_else(|| "<UNAVAILABLE>".to_string()),
}
}