mirror of
https://github.com/biomejs/biome.git
synced 2025-12-23 08:21:13 +00:00
feat: unknown nodes to track incorrect code (#1752)
This commit is contained in:
parent
c0104e59b2
commit
aab688d98f
15 changed files with 321 additions and 26 deletions
|
|
@ -60,6 +60,7 @@ impl ToFormatElement for ClassElement {
|
|||
ClassElement::TsIndexSignature(_) => todo!(),
|
||||
ClassElement::Getter(getter) => getter.to_format_element(formatter),
|
||||
ClassElement::Setter(setter) => setter.to_format_element(formatter),
|
||||
ClassElement::JsUnknownMember(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ impl ToFormatElement for Expr {
|
|||
Expr::TsNonNull(_) => todo!(),
|
||||
Expr::TsAssertion(_) => todo!(),
|
||||
Expr::TsConstAssertion(_) => todo!(),
|
||||
Expr::JsUnknownExpression(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ impl ToFormatElement for Pattern {
|
|||
Pattern::ArrayPattern(array_pattern) => array_pattern.to_format_element(formatter),
|
||||
Pattern::ExprPattern(_) => todo!(),
|
||||
Pattern::SinglePattern(single) => single.to_format_element(formatter),
|
||||
Pattern::JsUnknownPattern(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ impl ToFormatElement for ObjectProp {
|
|||
ObjectProp::InitializedProp(_) => todo!(),
|
||||
ObjectProp::IdentProp(ident) => ident.to_format_element(formatter),
|
||||
ObjectProp::Method(_) => todo!(),
|
||||
ObjectProp::JsUnknownMember(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ impl ToFormatElement for PropName {
|
|||
PropName::Literal(literal) => literal.to_format_element(formatter),
|
||||
PropName::Ident(ident) => ident.to_format_element(formatter),
|
||||
PropName::Name(name) => name.to_format_element(formatter),
|
||||
PropName::JsUnknownBinding(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ impl ToFormatElement for Stmt {
|
|||
|
||||
Stmt::ForOfStmt(_) => todo!(),
|
||||
Stmt::Decl(decl) => decl.to_format_element(formatter),
|
||||
Stmt::JsUnknownStatement(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ impl<N: AstNode> IntoIterator for AstNodeList<N> {
|
|||
}
|
||||
|
||||
mod support {
|
||||
use super::{AstNode, AstNodeList, SyntaxKind, SyntaxNode, SyntaxToken};
|
||||
use super::{AstNode, AstNodeList, SyntaxElementChildren, SyntaxKind, SyntaxNode, SyntaxToken};
|
||||
use crate::ast::AstChildren;
|
||||
use crate::SyntaxList;
|
||||
use crate::{SyntaxError, SyntaxResult};
|
||||
|
|
@ -201,6 +201,10 @@ mod support {
|
|||
parent.children().find_map(N::cast)
|
||||
}
|
||||
|
||||
pub(super) fn elements(parent: &SyntaxNode) -> SyntaxElementChildren {
|
||||
parent.children_with_tokens()
|
||||
}
|
||||
|
||||
pub(super) fn children<N: AstNode>(parent: &SyntaxNode) -> AstChildren<N> {
|
||||
AstChildren::new(parent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,9 +35,8 @@ impl LiteralProp {
|
|||
pub fn value(&self) -> SyntaxResult<Expr> {
|
||||
let child = self.syntax().children().nth(1);
|
||||
match child {
|
||||
Some(child) => {
|
||||
Expr::cast(child).ok_or_else(|| SyntaxError::MissingRequiredChild(self.syntax().clone()))
|
||||
}
|
||||
Some(child) => Expr::cast(child)
|
||||
.ok_or_else(|| SyntaxError::MissingRequiredChild(self.syntax().clone())),
|
||||
None => Err(SyntaxError::MissingRequiredChild(self.syntax().clone())),
|
||||
}
|
||||
}
|
||||
|
|
@ -569,6 +568,7 @@ impl ObjectProp {
|
|||
.key()
|
||||
.map_or_else(|_| None, |key| Some(key.syntax().clone()))?,
|
||||
ObjectProp::SpreadProp(_) => return None,
|
||||
ObjectProp::JsUnknownMember(_) => todo!(),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
|
|
@ -581,6 +581,7 @@ fn prop_name_syntax(name: PropName) -> Option<SyntaxNode> {
|
|||
PropName::Literal(lit) => lit.syntax().clone(),
|
||||
PropName::Name(name) => name.syntax().clone(),
|
||||
PropName::ComputedPropertyName(_) => return None,
|
||||
PropName::JsUnknownBinding(_) => todo!(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,48 @@ use crate::{
|
|||
SyntaxNode, SyntaxResult, SyntaxToken, T,
|
||||
};
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct JsUnknownStatement {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl JsUnknownStatement {
|
||||
pub fn syntax_element(&self) -> SyntaxElementChildren { support::elements(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct JsUnknownExpression {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl JsUnknownExpression {
|
||||
pub fn syntax_element(&self) -> SyntaxElementChildren { support::elements(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct JsUnknownPattern {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl JsUnknownPattern {
|
||||
pub fn syntax_element(&self) -> SyntaxElementChildren { support::elements(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct JsUnknownMember {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl JsUnknownMember {
|
||||
pub fn syntax_element(&self) -> SyntaxElementChildren { support::elements(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct JsUnknownBinding {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl JsUnknownBinding {
|
||||
pub fn syntax_element(&self) -> SyntaxElementChildren { support::elements(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct JsUnknownAssignmentTarget {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl JsUnknownAssignmentTarget {
|
||||
pub fn syntax_element(&self) -> SyntaxElementChildren { support::elements(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Ident {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
|
|
@ -2214,6 +2256,7 @@ pub enum Stmt {
|
|||
TryStmt(TryStmt),
|
||||
DebuggerStmt(DebuggerStmt),
|
||||
Decl(Decl),
|
||||
JsUnknownStatement(JsUnknownStatement),
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum ModuleItem {
|
||||
|
|
@ -2270,6 +2313,7 @@ pub enum Expr {
|
|||
TsNonNull(TsNonNull),
|
||||
TsAssertion(TsAssertion),
|
||||
TsConstAssertion(TsConstAssertion),
|
||||
JsUnknownExpression(JsUnknownExpression),
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum ForHead {
|
||||
|
|
@ -2289,6 +2333,7 @@ pub enum Pattern {
|
|||
ObjectPattern(ObjectPattern),
|
||||
ArrayPattern(ArrayPattern),
|
||||
ExprPattern(ExprPattern),
|
||||
JsUnknownPattern(JsUnknownPattern),
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum TsType {
|
||||
|
|
@ -2343,6 +2388,7 @@ pub enum ObjectProp {
|
|||
InitializedProp(InitializedProp),
|
||||
IdentProp(IdentProp),
|
||||
Method(Method),
|
||||
JsUnknownMember(JsUnknownMember),
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum ClassElement {
|
||||
|
|
@ -2354,6 +2400,7 @@ pub enum ClassElement {
|
|||
TsIndexSignature(TsIndexSignature),
|
||||
Getter(Getter),
|
||||
Setter(Setter),
|
||||
JsUnknownMember(JsUnknownMember),
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum PropName {
|
||||
|
|
@ -2361,6 +2408,7 @@ pub enum PropName {
|
|||
Literal(Literal),
|
||||
Ident(Ident),
|
||||
Name(Name),
|
||||
JsUnknownBinding(JsUnknownBinding),
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum ConstructorParamOrPat {
|
||||
|
|
@ -2384,6 +2432,7 @@ pub enum ObjectPatternProp {
|
|||
KeyValuePattern(KeyValuePattern),
|
||||
RestPattern(RestPattern),
|
||||
SinglePattern(SinglePattern),
|
||||
JsUnknownPattern(JsUnknownPattern),
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum ImportClause {
|
||||
|
|
@ -2425,6 +2474,72 @@ pub enum TsNamespaceBody {
|
|||
TsModuleBlock(TsModuleBlock),
|
||||
TsNamespaceDecl(TsNamespaceDecl),
|
||||
}
|
||||
impl AstNode for JsUnknownStatement {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == JS_UNKNOWN_STATEMENT }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for JsUnknownExpression {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == JS_UNKNOWN_EXPRESSION }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for JsUnknownPattern {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == JS_UNKNOWN_PATTERN }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for JsUnknownMember {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == JS_UNKNOWN_MEMBER }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for JsUnknownBinding {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == JS_UNKNOWN_BINDING }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for JsUnknownAssignmentTarget {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == JS_UNKNOWN_ASSIGNMENT_TARGET }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for Ident {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == IDENT }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
|
|
@ -4250,12 +4365,16 @@ impl From<TryStmt> for Stmt {
|
|||
impl From<DebuggerStmt> for Stmt {
|
||||
fn from(node: DebuggerStmt) -> Stmt { Stmt::DebuggerStmt(node) }
|
||||
}
|
||||
impl From<JsUnknownStatement> for Stmt {
|
||||
fn from(node: JsUnknownStatement) -> Stmt { Stmt::JsUnknownStatement(node) }
|
||||
}
|
||||
impl AstNode for Stmt {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
BLOCK_STMT | EMPTY_STMT | EXPR_STMT | IF_STMT | DO_WHILE_STMT | WHILE_STMT
|
||||
| FOR_STMT | FOR_IN_STMT | FOR_OF_STMT | CONTINUE_STMT | BREAK_STMT | RETURN_STMT
|
||||
| WITH_STMT | LABELLED_STMT | SWITCH_STMT | THROW_STMT | TRY_STMT | DEBUGGER_STMT => true,
|
||||
| WITH_STMT | LABELLED_STMT | SWITCH_STMT | THROW_STMT | TRY_STMT | DEBUGGER_STMT
|
||||
| JS_UNKNOWN_STATEMENT => true,
|
||||
k if Decl::can_cast(k) => true,
|
||||
_ => false,
|
||||
}
|
||||
|
|
@ -4280,6 +4399,7 @@ impl AstNode for Stmt {
|
|||
THROW_STMT => Stmt::ThrowStmt(ThrowStmt { syntax }),
|
||||
TRY_STMT => Stmt::TryStmt(TryStmt { syntax }),
|
||||
DEBUGGER_STMT => Stmt::DebuggerStmt(DebuggerStmt { syntax }),
|
||||
JS_UNKNOWN_STATEMENT => Stmt::JsUnknownStatement(JsUnknownStatement { syntax }),
|
||||
_ => {
|
||||
if let Some(decl) = Decl::cast(syntax.clone()) {
|
||||
return Some(Stmt::Decl(decl));
|
||||
|
|
@ -4309,6 +4429,7 @@ impl AstNode for Stmt {
|
|||
Stmt::ThrowStmt(it) => &it.syntax,
|
||||
Stmt::TryStmt(it) => &it.syntax,
|
||||
Stmt::DebuggerStmt(it) => &it.syntax,
|
||||
Stmt::JsUnknownStatement(it) => &it.syntax,
|
||||
Stmt::Decl(it) => it.syntax(),
|
||||
}
|
||||
}
|
||||
|
|
@ -4539,14 +4660,42 @@ impl From<TsAssertion> for Expr {
|
|||
impl From<TsConstAssertion> for Expr {
|
||||
fn from(node: TsConstAssertion) -> Expr { Expr::TsConstAssertion(node) }
|
||||
}
|
||||
impl From<JsUnknownExpression> for Expr {
|
||||
fn from(node: JsUnknownExpression) -> Expr { Expr::JsUnknownExpression(node) }
|
||||
}
|
||||
impl AstNode for Expr {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
ARROW_EXPR | LITERAL | TEMPLATE | NAME_REF | THIS_EXPR | ARRAY_EXPR | OBJECT_EXPR
|
||||
| GROUPING_EXPR | BRACKET_EXPR | DOT_EXPR | NEW_EXPR | CALL_EXPR | UNARY_EXPR
|
||||
| BIN_EXPR | COND_EXPR | ASSIGN_EXPR | SEQUENCE_EXPR | FN_EXPR | CLASS_EXPR
|
||||
| NEW_TARGET | IMPORT_META | SUPER_CALL | IMPORT_CALL | YIELD_EXPR | AWAIT_EXPR
|
||||
| PRIVATE_PROP_ACCESS | TS_NON_NULL | TS_ASSERTION | TS_CONST_ASSERTION => true,
|
||||
ARROW_EXPR
|
||||
| LITERAL
|
||||
| TEMPLATE
|
||||
| NAME_REF
|
||||
| THIS_EXPR
|
||||
| ARRAY_EXPR
|
||||
| OBJECT_EXPR
|
||||
| GROUPING_EXPR
|
||||
| BRACKET_EXPR
|
||||
| DOT_EXPR
|
||||
| NEW_EXPR
|
||||
| CALL_EXPR
|
||||
| UNARY_EXPR
|
||||
| BIN_EXPR
|
||||
| COND_EXPR
|
||||
| ASSIGN_EXPR
|
||||
| SEQUENCE_EXPR
|
||||
| FN_EXPR
|
||||
| CLASS_EXPR
|
||||
| NEW_TARGET
|
||||
| IMPORT_META
|
||||
| SUPER_CALL
|
||||
| IMPORT_CALL
|
||||
| YIELD_EXPR
|
||||
| AWAIT_EXPR
|
||||
| PRIVATE_PROP_ACCESS
|
||||
| TS_NON_NULL
|
||||
| TS_ASSERTION
|
||||
| TS_CONST_ASSERTION
|
||||
| JS_UNKNOWN_EXPRESSION => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -4581,6 +4730,7 @@ impl AstNode for Expr {
|
|||
TS_NON_NULL => Expr::TsNonNull(TsNonNull { syntax }),
|
||||
TS_ASSERTION => Expr::TsAssertion(TsAssertion { syntax }),
|
||||
TS_CONST_ASSERTION => Expr::TsConstAssertion(TsConstAssertion { syntax }),
|
||||
JS_UNKNOWN_EXPRESSION => Expr::JsUnknownExpression(JsUnknownExpression { syntax }),
|
||||
_ => return None,
|
||||
};
|
||||
Some(res)
|
||||
|
|
@ -4616,6 +4766,7 @@ impl AstNode for Expr {
|
|||
Expr::TsNonNull(it) => &it.syntax,
|
||||
Expr::TsAssertion(it) => &it.syntax,
|
||||
Expr::TsConstAssertion(it) => &it.syntax,
|
||||
Expr::JsUnknownExpression(it) => &it.syntax,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4695,11 +4846,14 @@ impl From<ArrayPattern> for Pattern {
|
|||
impl From<ExprPattern> for Pattern {
|
||||
fn from(node: ExprPattern) -> Pattern { Pattern::ExprPattern(node) }
|
||||
}
|
||||
impl From<JsUnknownPattern> for Pattern {
|
||||
fn from(node: JsUnknownPattern) -> Pattern { Pattern::JsUnknownPattern(node) }
|
||||
}
|
||||
impl AstNode for Pattern {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
SINGLE_PATTERN | REST_PATTERN | ASSIGN_PATTERN | OBJECT_PATTERN | ARRAY_PATTERN
|
||||
| EXPR_PATTERN => true,
|
||||
| EXPR_PATTERN | JS_UNKNOWN_PATTERN => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -4711,6 +4865,7 @@ impl AstNode for Pattern {
|
|||
OBJECT_PATTERN => Pattern::ObjectPattern(ObjectPattern { syntax }),
|
||||
ARRAY_PATTERN => Pattern::ArrayPattern(ArrayPattern { syntax }),
|
||||
EXPR_PATTERN => Pattern::ExprPattern(ExprPattern { syntax }),
|
||||
JS_UNKNOWN_PATTERN => Pattern::JsUnknownPattern(JsUnknownPattern { syntax }),
|
||||
_ => return None,
|
||||
};
|
||||
Some(res)
|
||||
|
|
@ -4723,6 +4878,7 @@ impl AstNode for Pattern {
|
|||
Pattern::ObjectPattern(it) => &it.syntax,
|
||||
Pattern::ArrayPattern(it) => &it.syntax,
|
||||
Pattern::ExprPattern(it) => &it.syntax,
|
||||
Pattern::JsUnknownPattern(it) => &it.syntax,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4983,11 +5139,14 @@ impl From<IdentProp> for ObjectProp {
|
|||
impl From<Method> for ObjectProp {
|
||||
fn from(node: Method) -> ObjectProp { ObjectProp::Method(node) }
|
||||
}
|
||||
impl From<JsUnknownMember> for ObjectProp {
|
||||
fn from(node: JsUnknownMember) -> ObjectProp { ObjectProp::JsUnknownMember(node) }
|
||||
}
|
||||
impl AstNode for ObjectProp {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
LITERAL_PROP | GETTER | SETTER | SPREAD_PROP | INITIALIZED_PROP | IDENT_PROP
|
||||
| METHOD => true,
|
||||
| METHOD | JS_UNKNOWN_MEMBER => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -5000,6 +5159,7 @@ impl AstNode for ObjectProp {
|
|||
INITIALIZED_PROP => ObjectProp::InitializedProp(InitializedProp { syntax }),
|
||||
IDENT_PROP => ObjectProp::IdentProp(IdentProp { syntax }),
|
||||
METHOD => ObjectProp::Method(Method { syntax }),
|
||||
JS_UNKNOWN_MEMBER => ObjectProp::JsUnknownMember(JsUnknownMember { syntax }),
|
||||
_ => return None,
|
||||
};
|
||||
Some(res)
|
||||
|
|
@ -5013,6 +5173,7 @@ impl AstNode for ObjectProp {
|
|||
ObjectProp::InitializedProp(it) => &it.syntax,
|
||||
ObjectProp::IdentProp(it) => &it.syntax,
|
||||
ObjectProp::Method(it) => &it.syntax,
|
||||
ObjectProp::JsUnknownMember(it) => &it.syntax,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5040,11 +5201,14 @@ impl From<Getter> for ClassElement {
|
|||
impl From<Setter> for ClassElement {
|
||||
fn from(node: Setter) -> ClassElement { ClassElement::Setter(node) }
|
||||
}
|
||||
impl From<JsUnknownMember> for ClassElement {
|
||||
fn from(node: JsUnknownMember) -> ClassElement { ClassElement::JsUnknownMember(node) }
|
||||
}
|
||||
impl AstNode for ClassElement {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
EMPTY_STMT | METHOD | PRIVATE_PROP | CLASS_PROP | CONSTRUCTOR | TS_INDEX_SIGNATURE
|
||||
| GETTER | SETTER => true,
|
||||
| GETTER | SETTER | JS_UNKNOWN_MEMBER => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -5058,6 +5222,7 @@ impl AstNode for ClassElement {
|
|||
TS_INDEX_SIGNATURE => ClassElement::TsIndexSignature(TsIndexSignature { syntax }),
|
||||
GETTER => ClassElement::Getter(Getter { syntax }),
|
||||
SETTER => ClassElement::Setter(Setter { syntax }),
|
||||
JS_UNKNOWN_MEMBER => ClassElement::JsUnknownMember(JsUnknownMember { syntax }),
|
||||
_ => return None,
|
||||
};
|
||||
Some(res)
|
||||
|
|
@ -5072,6 +5237,7 @@ impl AstNode for ClassElement {
|
|||
ClassElement::TsIndexSignature(it) => &it.syntax,
|
||||
ClassElement::Getter(it) => &it.syntax,
|
||||
ClassElement::Setter(it) => &it.syntax,
|
||||
ClassElement::JsUnknownMember(it) => &it.syntax,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5087,10 +5253,13 @@ impl From<Ident> for PropName {
|
|||
impl From<Name> for PropName {
|
||||
fn from(node: Name) -> PropName { PropName::Name(node) }
|
||||
}
|
||||
impl From<JsUnknownBinding> for PropName {
|
||||
fn from(node: JsUnknownBinding) -> PropName { PropName::JsUnknownBinding(node) }
|
||||
}
|
||||
impl AstNode for PropName {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
COMPUTED_PROPERTY_NAME | LITERAL | IDENT | NAME => true,
|
||||
COMPUTED_PROPERTY_NAME | LITERAL | IDENT | NAME | JS_UNKNOWN_BINDING => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -5102,6 +5271,7 @@ impl AstNode for PropName {
|
|||
LITERAL => PropName::Literal(Literal { syntax }),
|
||||
IDENT => PropName::Ident(Ident { syntax }),
|
||||
NAME => PropName::Name(Name { syntax }),
|
||||
JS_UNKNOWN_BINDING => PropName::JsUnknownBinding(JsUnknownBinding { syntax }),
|
||||
_ => return None,
|
||||
};
|
||||
Some(res)
|
||||
|
|
@ -5112,6 +5282,7 @@ impl AstNode for PropName {
|
|||
PropName::Literal(it) => &it.syntax,
|
||||
PropName::Ident(it) => &it.syntax,
|
||||
PropName::Name(it) => &it.syntax,
|
||||
PropName::JsUnknownBinding(it) => &it.syntax,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5220,10 +5391,16 @@ impl From<RestPattern> for ObjectPatternProp {
|
|||
impl From<SinglePattern> for ObjectPatternProp {
|
||||
fn from(node: SinglePattern) -> ObjectPatternProp { ObjectPatternProp::SinglePattern(node) }
|
||||
}
|
||||
impl From<JsUnknownPattern> for ObjectPatternProp {
|
||||
fn from(node: JsUnknownPattern) -> ObjectPatternProp {
|
||||
ObjectPatternProp::JsUnknownPattern(node)
|
||||
}
|
||||
}
|
||||
impl AstNode for ObjectPatternProp {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
ASSIGN_PATTERN | KEY_VALUE_PATTERN | REST_PATTERN | SINGLE_PATTERN => true,
|
||||
ASSIGN_PATTERN | KEY_VALUE_PATTERN | REST_PATTERN | SINGLE_PATTERN
|
||||
| JS_UNKNOWN_PATTERN => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -5233,6 +5410,7 @@ impl AstNode for ObjectPatternProp {
|
|||
KEY_VALUE_PATTERN => ObjectPatternProp::KeyValuePattern(KeyValuePattern { syntax }),
|
||||
REST_PATTERN => ObjectPatternProp::RestPattern(RestPattern { syntax }),
|
||||
SINGLE_PATTERN => ObjectPatternProp::SinglePattern(SinglePattern { syntax }),
|
||||
JS_UNKNOWN_PATTERN => ObjectPatternProp::JsUnknownPattern(JsUnknownPattern { syntax }),
|
||||
_ => return None,
|
||||
};
|
||||
Some(res)
|
||||
|
|
@ -5243,6 +5421,7 @@ impl AstNode for ObjectPatternProp {
|
|||
ObjectPatternProp::KeyValuePattern(it) => &it.syntax,
|
||||
ObjectPatternProp::RestPattern(it) => &it.syntax,
|
||||
ObjectPatternProp::SinglePattern(it) => &it.syntax,
|
||||
ObjectPatternProp::JsUnknownPattern(it) => &it.syntax,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5607,6 +5786,36 @@ impl std::fmt::Display for TsNamespaceBody {
|
|||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for JsUnknownStatement {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for JsUnknownExpression {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for JsUnknownPattern {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for JsUnknownMember {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for JsUnknownBinding {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for JsUnknownAssignmentTarget {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for Ident {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ fn check_pat(
|
|||
}
|
||||
ast::ObjectPatternProp::RestPattern(pat) => pat.into(),
|
||||
ast::ObjectPatternProp::SinglePattern(pat) => pat.into(),
|
||||
ast::ObjectPatternProp::JsUnknownPattern(_) => todo!(),
|
||||
};
|
||||
check_pat(p, pat, map, marker);
|
||||
}
|
||||
|
|
@ -193,6 +194,7 @@ fn check_pat(
|
|||
}
|
||||
}
|
||||
ast::Pattern::ExprPattern(_) => unreachable!(),
|
||||
ast::Pattern::JsUnknownPattern(_) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -332,6 +332,12 @@ pub enum SyntaxKind {
|
|||
TS_ENTITY_NAME,
|
||||
BOOLEAN,
|
||||
BIG_INT_VALUE,
|
||||
JS_UNKNOWN_EXPRESSION,
|
||||
JS_UNKNOWN_STATEMENT,
|
||||
JS_UNKNOWN_PATTERN,
|
||||
JS_UNKNOWN_MEMBER,
|
||||
JS_UNKNOWN_BINDING,
|
||||
JS_UNKNOWN_ASSIGNMENT_TARGET,
|
||||
#[doc(hidden)]
|
||||
__LAST,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Here's a list of internal conventions that we follow to write grammar:
|
|||
}
|
||||
```
|
||||
|
||||
2. unions of tokens have to have a label. In this way, the code generation can handle it properly and generate a better AST.
|
||||
1. unions of tokens have to have a label. In this way, the code generation can handle it properly and generate a better AST.
|
||||
|
||||
```text
|
||||
BinExpr = left: Expr op: ('+' | '-' | '*') right: Expr
|
||||
|
|
@ -51,3 +51,6 @@ Here's a list of internal conventions that we follow to write grammar:
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Nodes used to track broken code should contain the **Unknown** word in its name (it's case sensitive).
|
||||
This is needed because it will generate a different type of code, useful in case of errors inside the source code Rome will parse.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,29 @@
|
|||
//
|
||||
// - "manual__" prefix is used to _exclude_ those method from being autogenerated
|
||||
// and they will be manually implemented
|
||||
// - SyntaxNode, SyntaxToken and SyntaxElement will be stripped from the codegen
|
||||
// - Unknown nodes are special nodes used to keep track of broken code; they are
|
||||
// not part of the grammar but they will appear inside the green tree
|
||||
//
|
||||
|
||||
|
||||
///////////////
|
||||
// UNKNOWN NODES
|
||||
///////////////
|
||||
// SyntaxElement is a generic data structure that is meant to track nodes and tokens
|
||||
// in cases where we care about both types
|
||||
//
|
||||
// As Unknown* node will need to yield both tokens and nodes without discrimition,
|
||||
// and their children will need to yield nodes and tokens as well.
|
||||
// For this reason, SyntaxElement = SyntaxElement
|
||||
SyntaxElement = SyntaxElement
|
||||
|
||||
JsUnknownStatement = SyntaxElement*
|
||||
JsUnknownExpression = SyntaxElement*
|
||||
JsUnknownPattern = SyntaxElement*
|
||||
JsUnknownMember = SyntaxElement*
|
||||
JsUnknownBinding = SyntaxElement*
|
||||
JsUnknownAssignmentTarget = SyntaxElement*
|
||||
|
||||
Ident = 'ident'
|
||||
Script = 'shebang'? items:Stmt*
|
||||
|
|
@ -49,6 +72,7 @@ Stmt =
|
|||
| TryStmt
|
||||
| DebuggerStmt
|
||||
| Decl
|
||||
| JsUnknownStatement
|
||||
|
||||
|
||||
// Block statement
|
||||
|
|
@ -181,6 +205,7 @@ Expr =
|
|||
| TsNonNull
|
||||
| TsAssertion
|
||||
| TsConstAssertion
|
||||
| JsUnknownExpression
|
||||
|
||||
|
||||
// the backtick is just a placeholder, there's
|
||||
|
|
@ -273,6 +298,7 @@ ClassElement =
|
|||
| TsIndexSignature
|
||||
| Getter
|
||||
| Setter
|
||||
| JsUnknownMember
|
||||
|
||||
Constructor =
|
||||
accessibility:TsAccessibility?
|
||||
|
|
@ -399,6 +425,7 @@ Pattern =
|
|||
| ObjectPattern
|
||||
| ArrayPattern
|
||||
| ExprPattern
|
||||
| JsUnknownPattern
|
||||
|
||||
// single pattern
|
||||
SinglePattern
|
||||
|
|
@ -419,6 +446,7 @@ ObjectPatternProp =
|
|||
| KeyValuePattern
|
||||
| RestPattern
|
||||
| SinglePattern
|
||||
| JsUnknownPattern
|
||||
|
||||
// assign pattern
|
||||
AssignPattern = key:Pattern ':'? ty:TsType '=' value:Expr
|
||||
|
|
@ -444,6 +472,7 @@ ObjectProp =
|
|||
| InitializedProp
|
||||
| IdentProp
|
||||
| Method
|
||||
| JsUnknownMember
|
||||
|
||||
|
||||
// literal prop
|
||||
|
|
@ -454,6 +483,7 @@ PropName =
|
|||
| Literal
|
||||
| Ident
|
||||
| Name
|
||||
| JsUnknownBinding
|
||||
|
||||
|
||||
// computed property
|
||||
|
|
|
|||
|
|
@ -7,11 +7,29 @@ use crate::{
|
|||
};
|
||||
use quote::{format_ident, quote};
|
||||
|
||||
// these node won't generate any code
|
||||
const BUILT_IN_TYPE: &str = "SyntaxElement";
|
||||
|
||||
pub fn generate_nodes(ast: &AstSrc) -> Result<String> {
|
||||
let (node_defs, node_boilerplate_impls): (Vec<_>, Vec<_>) = ast
|
||||
let filtered_enums: Vec<_> = ast
|
||||
.enums
|
||||
.iter()
|
||||
.filter(|e| e.name.as_str() != BUILT_IN_TYPE)
|
||||
.collect();
|
||||
|
||||
let filtered_nodes: Vec<_> = ast
|
||||
.nodes
|
||||
.iter()
|
||||
.map(|node| {
|
||||
.filter(|e| e.name.as_str() != BUILT_IN_TYPE)
|
||||
.collect();
|
||||
|
||||
let (node_defs, node_boilerplate_impls): (Vec<_>, Vec<_>) = filtered_nodes
|
||||
.iter()
|
||||
.filter_map(|node| {
|
||||
if node.name.as_str() == BUILT_IN_TYPE {
|
||||
return None;
|
||||
}
|
||||
|
||||
let name = format_ident!("{}", node.name);
|
||||
let kind = format_ident!("{}", to_upper_snake_case(node.name.as_str()));
|
||||
let mut slot = 0usize;
|
||||
|
|
@ -55,10 +73,20 @@ pub fn generate_nodes(ast: &AstSrc) -> Result<String> {
|
|||
optional,
|
||||
has_many,
|
||||
} => {
|
||||
let is_built_in_tpe = &ty.eq(BUILT_IN_TYPE);
|
||||
let ty = format_ident!("{}", &ty);
|
||||
|
||||
let method_name = field.method_name();
|
||||
if *optional {
|
||||
// this is when we encounter a node that has "Unknown" in its name
|
||||
// it will return tokens a and nodes regardless because there's an error
|
||||
// inside the code
|
||||
if *is_built_in_tpe {
|
||||
quote! {
|
||||
pub fn #method_name(&self) -> SyntaxElementChildren {
|
||||
support::elements(&self.syntax)
|
||||
}
|
||||
}
|
||||
} else if *optional {
|
||||
quote! {
|
||||
pub fn #method_name(&self) -> Option<#ty> {
|
||||
support::as_optional_node(&self.syntax)
|
||||
|
|
@ -81,7 +109,7 @@ pub fn generate_nodes(ast: &AstSrc) -> Result<String> {
|
|||
}
|
||||
}
|
||||
});
|
||||
(
|
||||
Some((
|
||||
quote! {
|
||||
// TODO: review documentation
|
||||
// #[doc = #documentation]
|
||||
|
|
@ -105,7 +133,7 @@ pub fn generate_nodes(ast: &AstSrc) -> Result<String> {
|
|||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
},
|
||||
)
|
||||
))
|
||||
})
|
||||
.unzip();
|
||||
|
||||
|
|
@ -116,8 +144,7 @@ pub fn generate_nodes(ast: &AstSrc) -> Result<String> {
|
|||
.map(|current_enum| (current_enum.name.clone(), current_enum.variants.clone()))
|
||||
.collect();
|
||||
|
||||
let (enum_defs, enum_boilerplate_impls): (Vec<_>, Vec<_>) = ast
|
||||
.enums
|
||||
let (enum_defs, enum_boilerplate_impls): (Vec<_>, Vec<_>) = filtered_enums
|
||||
.iter()
|
||||
.map(|en| {
|
||||
// here we collect all the variants because this will generate the enums
|
||||
|
|
@ -161,7 +188,7 @@ pub fn generate_nodes(ast: &AstSrc) -> Result<String> {
|
|||
let variant_cast: Vec<_> = simple_variants
|
||||
.iter()
|
||||
.map(|current_enum| {
|
||||
let variant_is_enum = ast.enums.iter().find(|e| &e.name == *current_enum);
|
||||
let variant_is_enum = filtered_enums.iter().find(|e| &e.name == *current_enum);
|
||||
let variant_name = format_ident!("{}", current_enum);
|
||||
|
||||
if variant_is_enum.is_some() {
|
||||
|
|
@ -292,8 +319,8 @@ pub fn generate_nodes(ast: &AstSrc) -> Result<String> {
|
|||
})
|
||||
.unzip();
|
||||
|
||||
let enum_names = ast.enums.iter().map(|it| &it.name);
|
||||
let node_names = ast.nodes.iter().map(|it| &it.name);
|
||||
let enum_names = filtered_enums.iter().map(|it| &it.name);
|
||||
let node_names = filtered_nodes.iter().map(|it| &it.name);
|
||||
|
||||
let display_impls = enum_names
|
||||
.chain(node_names.clone())
|
||||
|
|
|
|||
|
|
@ -342,6 +342,13 @@ pub const KINDS_SRC: KindsSrc = KindsSrc {
|
|||
"TS_ENTITY_NAME",
|
||||
"BOOLEAN",
|
||||
"BIG_INT_VALUE",
|
||||
// unknown tokens
|
||||
"JS_UNKNOWN_EXPRESSION",
|
||||
"JS_UNKNOWN_STATEMENT",
|
||||
"JS_UNKNOWN_PATTERN",
|
||||
"JS_UNKNOWN_MEMBER",
|
||||
"JS_UNKNOWN_BINDING",
|
||||
"JS_UNKNOWN_ASSIGNMENT_TARGET",
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue