mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
1457 lines
51 KiB
Rust
1457 lines
51 KiB
Rust
use std::rc::Rc;
|
|
|
|
use enum_as_inner::EnumAsInner;
|
|
use oxc_ast::ast::ArrayExpressionElement;
|
|
#[allow(clippy::wildcard_imports)]
|
|
use oxc_ast::{ast::*, AstKind};
|
|
use oxc_semantic::{AstNode, AstNodeId};
|
|
use oxc_span::{GetSpan, Span};
|
|
use trustfall::provider::{Typename, VertexIterator};
|
|
use url::Url;
|
|
|
|
use crate::{
|
|
util::{
|
|
calculate_hash, jsx_attribute_to_constant_string,
|
|
try_get_constant_string_field_value_from_template_lit,
|
|
},
|
|
Adapter,
|
|
};
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone, EnumAsInner)]
|
|
pub enum Vertex<'a> {
|
|
ASTNode(AstNode<'a>),
|
|
AssignmentType(&'a BindingPatternKind<'a>),
|
|
Class(Rc<ClassVertex<'a>>),
|
|
ClassMethod(Rc<ClassMethodVertex<'a>>),
|
|
ClassProperty(Rc<ClassPropertyVertex<'a>>),
|
|
DefaultImport(&'a ImportDefaultSpecifier),
|
|
Expression(&'a Expression<'a>),
|
|
File,
|
|
Import(Rc<ImportVertex<'a>>),
|
|
Interface(Rc<InterfaceVertex<'a>>),
|
|
InterfaceExtend(Rc<InterfaceExtendVertex<'a>>),
|
|
JSXAttribute(&'a JSXAttribute<'a>),
|
|
JSXElement(Rc<JSXElementVertex<'a>>),
|
|
JSXExpressionContainer(&'a JSXExpressionContainer<'a>),
|
|
JSXFragment(&'a JSXFragment<'a>),
|
|
JSXOpeningElement(Rc<JSXOpeningElementVertex<'a>>),
|
|
JSXSpreadAttribute(&'a JSXSpreadAttribute<'a>),
|
|
JSXSpreadChild(&'a JSXSpreadChild<'a>),
|
|
JSXText(&'a JSXText),
|
|
ObjectLiteral(Rc<ObjectLiteralVertex<'a>>),
|
|
NumberLiteral(Rc<NumberLiteralVertex<'a>>),
|
|
Name(Rc<NameVertex<'a>>),
|
|
PathPart(usize),
|
|
SearchParameter(Rc<SearchParameterVertex>),
|
|
Span(Span),
|
|
SpecificImport(&'a ImportSpecifier),
|
|
TypeAnnotation(Rc<TypeAnnotationVertex<'a>>),
|
|
Type(&'a TSType<'a>),
|
|
Url(Rc<Url>),
|
|
VariableDeclaration(Rc<VariableDeclarationVertex<'a>>),
|
|
Return(Rc<ReturnVertex<'a>>),
|
|
IfStatementAST(Rc<IfStatementVertex<'a>>),
|
|
Spread(Rc<SpreadVertex<'a>>),
|
|
ObjectEntry(Rc<ObjectEntryVertex<'a>>),
|
|
DotProperty(Rc<DotPropertyVertex<'a>>),
|
|
Reassignment(Rc<ReassignmentVertex<'a>>),
|
|
FnCall(Rc<FnCallVertex<'a>>),
|
|
FnDeclaration(Rc<FnDeclarationVertex<'a>>),
|
|
ArrowFunction(Rc<ArrowFunctionVertex<'a>>),
|
|
Argument(Rc<ArgumentVertex<'a>>),
|
|
FunctionBody(Rc<FunctionBodyVertex<'a>>),
|
|
Statement(&'a Statement<'a>),
|
|
Parameter(Rc<ParameterVertex<'a>>),
|
|
LogicalExpression(Rc<LogicalExpressionVertex<'a>>),
|
|
UnaryExpression(Rc<UnaryExpressionVertex<'a>>),
|
|
ExpressionStatement(Rc<ExpressionStatementVertex<'a>>),
|
|
WhileStatement(Rc<WhileStatementVertex<'a>>),
|
|
BlockStatement(Rc<BlockStatementVertex<'a>>),
|
|
VarRef(Rc<VarRefVertex<'a>>),
|
|
DoWhileStatement(Rc<DoWhileStatementVertex<'a>>),
|
|
ForStatement(Rc<ForStatementVertex<'a>>),
|
|
TernaryExpression(Rc<TernaryExpressionVertex<'a>>),
|
|
New(Rc<NewVertex<'a>>),
|
|
Throw(Rc<ThrowVertex<'a>>),
|
|
Array(Rc<ArrayVertex<'a>>),
|
|
StringLiteral(Rc<StringLiteralVertex<'a>>),
|
|
TemplateLiteral(Rc<TemplateLiteralVertex<'a>>),
|
|
RegExpLiteral(Rc<RegExpLiteralVertex<'a>>),
|
|
ParenthesizedExpression(Rc<ParenthesizedExpressionVertex<'a>>),
|
|
ElidedArrayElement(Rc<ElidedArrayElementVertex<'a>>),
|
|
ExpressionArrayElement(Rc<ExpressionArrayElementVertex<'a>>),
|
|
}
|
|
|
|
impl<'a> Vertex<'a> {
|
|
pub fn span(&self) -> Span {
|
|
match &self {
|
|
Self::AssignmentType(data) => data.span(),
|
|
Self::ASTNode(data) => data.kind().span(),
|
|
Self::Class(data) => data.class.span,
|
|
Self::ClassMethod(data) => data.method.span,
|
|
Self::ClassProperty(data) => data.property.span,
|
|
Self::DefaultImport(data) => data.span,
|
|
Self::Expression(data) => data.span(),
|
|
Self::Import(data) => data.import.span,
|
|
Self::Interface(data) => data.interface.span,
|
|
Self::InterfaceExtend(data) => match **data {
|
|
InterfaceExtendVertex::Identifier(ident) => ident.span,
|
|
InterfaceExtendVertex::MemberExpression(membexpr) => (*membexpr).span(),
|
|
},
|
|
Self::JSXAttribute(data) => data.span,
|
|
Self::JSXElement(data) => data.element.span,
|
|
Self::JSXExpressionContainer(data) => data.span,
|
|
Self::JSXFragment(data) => data.span,
|
|
Self::JSXOpeningElement(data) => data.opening_element.span,
|
|
Self::DotProperty(data) => data.static_member_expr.span,
|
|
Self::JSXSpreadAttribute(data) => data.span,
|
|
Self::JSXSpreadChild(data) => data.span,
|
|
Self::JSXText(data) => data.span,
|
|
Self::ObjectLiteral(data) => data.object_expression.span,
|
|
Self::Spread(data) => data.spread.span,
|
|
Self::ObjectEntry(data) => data.property.span,
|
|
Self::SpecificImport(data) => data.span,
|
|
Self::TypeAnnotation(data) => data.type_annotation.span,
|
|
Self::Type(data) => data.span(),
|
|
Self::VariableDeclaration(data) => data.variable_declaration.span,
|
|
Self::Return(data) => data.return_statement.span,
|
|
Self::IfStatementAST(data) => data.return_statement.span,
|
|
Self::NumberLiteral(data) => data.number_literal.span,
|
|
Self::Reassignment(data) => data.assignment_expression.span,
|
|
Self::Name(data) => data.name.span,
|
|
Self::FnCall(data) => data.call_expression.span,
|
|
Self::Argument(data) => data.argument.span(),
|
|
Self::FnDeclaration(data) => data.function.span,
|
|
Self::ArrowFunction(data) => data.arrow_expression.span,
|
|
Self::FunctionBody(data) => data.function_body.span,
|
|
Self::Statement(data) => data.span(),
|
|
Self::Parameter(data) => data.parameter.span,
|
|
Self::LogicalExpression(data) => data.logical_expression.span,
|
|
Self::UnaryExpression(data) => data.unary_expression.span,
|
|
Self::ExpressionStatement(data) => data.expression_statement.span,
|
|
Self::WhileStatement(data) => data.while_statement.span,
|
|
Self::DoWhileStatement(data) => data.do_while_statement.span,
|
|
Self::BlockStatement(data) => data.block_statement.span,
|
|
Self::VarRef(data) => data.identifier_reference.span,
|
|
Self::ForStatement(data) => data.for_statement.span,
|
|
Self::TernaryExpression(data) => data.conditional_expression.span,
|
|
Self::New(data) => data.new_expression.span,
|
|
Self::Throw(data) => data.throw_statement.span,
|
|
Self::Array(data) => data.array_expression.span,
|
|
Self::StringLiteral(data) => data.string.span,
|
|
Self::TemplateLiteral(data) => data.template.span,
|
|
Self::RegExpLiteral(data) => data.regexp.span,
|
|
Self::ParenthesizedExpression(data) => data.parenthesized_expression.span,
|
|
Self::ElidedArrayElement(data) => data.span,
|
|
Self::ExpressionArrayElement(data) => data.expression.span(),
|
|
Self::File
|
|
| Self::Url(_)
|
|
| Self::PathPart(_)
|
|
| Self::SearchParameter(_)
|
|
| Self::Span(_) => {
|
|
unreachable!("Tried to get the span from a {self:#?}")
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn ast_node_id(&self) -> Option<AstNodeId> {
|
|
match &self {
|
|
Vertex::ASTNode(data) => Some(data.id()),
|
|
Vertex::Argument(data) => match data.data {
|
|
ArgumentData::Index(_) => None,
|
|
ArgumentData::AstNode(ast_node) => Some(ast_node.id()),
|
|
},
|
|
Vertex::Class(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::Import(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::Interface(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::JSXElement(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::TypeAnnotation(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::VariableDeclaration(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::ObjectLiteral(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::Return(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::IfStatementAST(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::JSXOpeningElement(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::NumberLiteral(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::Name(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::Spread(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::ObjectEntry(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::DotProperty(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::Reassignment(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::FnCall(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::FnDeclaration(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::ArrowFunction(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::FunctionBody(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::Parameter(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::LogicalExpression(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::UnaryExpression(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::ExpressionStatement(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::WhileStatement(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::BlockStatement(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::VarRef(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::DoWhileStatement(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::ForStatement(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::TernaryExpression(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::New(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::Throw(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::Array(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::StringLiteral(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::TemplateLiteral(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::RegExpLiteral(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::ParenthesizedExpression(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::ElidedArrayElement(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::ExpressionArrayElement(data) => data.ast_node.map(|x| x.id()),
|
|
Vertex::DefaultImport(_)
|
|
| Vertex::Statement(_)
|
|
| Vertex::AssignmentType(_)
|
|
| Vertex::ClassMethod(_)
|
|
| Vertex::Expression(_)
|
|
| Vertex::File
|
|
| Vertex::InterfaceExtend(_)
|
|
| Vertex::JSXAttribute(_)
|
|
| Vertex::JSXExpressionContainer(_)
|
|
| Vertex::JSXFragment(_)
|
|
| Vertex::JSXText(_)
|
|
| Vertex::JSXSpreadChild(_)
|
|
| Vertex::JSXSpreadAttribute(_)
|
|
| Vertex::PathPart(_)
|
|
| Vertex::Url(_)
|
|
| Vertex::Type(_)
|
|
| Vertex::SpecificImport(_)
|
|
| Vertex::Span(_)
|
|
| Vertex::SearchParameter(_)
|
|
| Vertex::ClassProperty(_) => None,
|
|
}
|
|
}
|
|
|
|
pub fn make_url(attr: &'a JSXAttribute<'a>) -> Option<Self> {
|
|
jsx_attribute_to_constant_string(attr)
|
|
.as_deref()
|
|
.and_then(|v| Url::parse(v).ok())
|
|
.map(Rc::new)
|
|
.map(Vertex::Url)
|
|
}
|
|
|
|
pub fn as_constant_string(&self) -> Option<String> {
|
|
match &self {
|
|
Vertex::StringLiteral(slit) => Some(slit.string.value.to_string()),
|
|
Vertex::TemplateLiteral(tlit) => {
|
|
try_get_constant_string_field_value_from_template_lit(tlit.template)
|
|
}
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
// todo: remove `Option` when the match covers all the cases
|
|
pub fn try_from_member_expression(member_expression: &'a MemberExpression<'a>) -> Option<Self> {
|
|
match &member_expression {
|
|
MemberExpression::StaticMemberExpression(static_member_expr) => {
|
|
Some(Vertex::DotProperty(
|
|
DotPropertyVertex { ast_node: None, static_member_expr }.into(),
|
|
))
|
|
}
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn try_from_identifier_reference(identifier_reference: &'a IdentifierReference) -> Self {
|
|
Vertex::VarRef(VarRefVertex { ast_node: None, identifier_reference }.into())
|
|
}
|
|
|
|
pub fn function_is_async(&self) -> bool {
|
|
match &self {
|
|
Vertex::ArrowFunction(data) => data.arrow_expression.r#async,
|
|
Vertex::FnDeclaration(data) => data.function.r#async,
|
|
_ => unreachable!(
|
|
"'function_is_async' function should only ever be called with an ArrowFunction or FnDeclaration"
|
|
),
|
|
}
|
|
}
|
|
|
|
pub fn function_is_generator(&self) -> bool {
|
|
match &self {
|
|
Vertex::ArrowFunction(data) => data.arrow_expression.generator,
|
|
Vertex::FnDeclaration(data) => data.function.generator,
|
|
_ => unreachable!(
|
|
"'function_is_generator' function should only ever be called with an ArrowFunction or FnDeclaration"
|
|
),
|
|
}
|
|
}
|
|
|
|
pub fn function_parameter(&self) -> VertexIterator<'a, Vertex<'a>> {
|
|
let parameter = match &self {
|
|
Vertex::ArrowFunction(data) => &data.arrow_expression.params.items,
|
|
Vertex::FnDeclaration(data) => &data.function.params.items,
|
|
_ => unreachable!(
|
|
"'function_parameter' function should only ever be called with an ArrowFunction or FnDeclaration"
|
|
),
|
|
};
|
|
Box::new(parameter.iter().map(|parameter| {
|
|
Vertex::Parameter(ParameterVertex { ast_node: None, parameter }.into())
|
|
}))
|
|
}
|
|
|
|
pub fn function_body(&self) -> VertexIterator<'a, Vertex<'a>> {
|
|
let body = match &self {
|
|
Vertex::ArrowFunction(data) => Some(&*data.arrow_expression.body),
|
|
Vertex::FnDeclaration(data) => data.function.body.as_deref(),
|
|
_ => unreachable!(
|
|
"'function_body' function should only ever be called with an ArrowFunction or FnDeclaration"
|
|
),
|
|
};
|
|
Box::new(body.into_iter().map(|function_body| {
|
|
Vertex::FunctionBody(FunctionBodyVertex { ast_node: None, function_body }.into())
|
|
}))
|
|
}
|
|
|
|
pub fn is_expr(&self) -> bool {
|
|
match &self {
|
|
Vertex::ObjectLiteral(..)
|
|
| Vertex::JSXElement(..)
|
|
| Vertex::NumberLiteral(..)
|
|
| Vertex::Expression(..)
|
|
| Vertex::Reassignment(..)
|
|
| Vertex::FnCall(..)
|
|
| Vertex::FnDeclaration(..)
|
|
| Vertex::ArrowFunction(..)
|
|
| Vertex::LogicalExpression(..)
|
|
| Vertex::UnaryExpression(..)
|
|
| Vertex::VarRef(..)
|
|
| Vertex::TernaryExpression(..)
|
|
| Vertex::New(..)
|
|
| Vertex::StringLiteral(..)
|
|
| Vertex::TemplateLiteral(..)
|
|
| Vertex::RegExpLiteral(..)
|
|
| Vertex::ParenthesizedExpression(..)
|
|
| Vertex::Array(..) => true,
|
|
Vertex::ASTNode(..)
|
|
| Vertex::AssignmentType(..)
|
|
| Vertex::ElidedArrayElement(..)
|
|
| Vertex::Class(..)
|
|
| Vertex::ClassMethod(..)
|
|
| Vertex::ClassProperty(..)
|
|
| Vertex::DefaultImport(..)
|
|
| Vertex::File
|
|
| Vertex::Import(..)
|
|
| Vertex::Interface(..)
|
|
| Vertex::InterfaceExtend(..)
|
|
| Vertex::JSXAttribute(..)
|
|
| Vertex::JSXExpressionContainer(..)
|
|
| Vertex::JSXFragment(..)
|
|
| Vertex::JSXOpeningElement(..)
|
|
| Vertex::JSXSpreadAttribute(..)
|
|
| Vertex::JSXSpreadChild(..)
|
|
| Vertex::JSXText(..)
|
|
| Vertex::Name(..)
|
|
| Vertex::PathPart(..)
|
|
| Vertex::SearchParameter(..)
|
|
| Vertex::Span(..)
|
|
| Vertex::SpecificImport(..)
|
|
| Vertex::TypeAnnotation(..)
|
|
| Vertex::Type(..)
|
|
| Vertex::Url(..)
|
|
| Vertex::VariableDeclaration(..)
|
|
| Vertex::Return(..)
|
|
| Vertex::IfStatementAST(..)
|
|
| Vertex::Spread(..)
|
|
| Vertex::ObjectEntry(..)
|
|
| Vertex::DotProperty(..)
|
|
| Vertex::Argument(..)
|
|
| Vertex::FunctionBody(..)
|
|
| Vertex::Statement(..)
|
|
| Vertex::Parameter(..)
|
|
| Vertex::ExpressionStatement(..)
|
|
| Vertex::WhileStatement(..)
|
|
| Vertex::BlockStatement(..)
|
|
| Vertex::DoWhileStatement(..)
|
|
| Vertex::ForStatement(..)
|
|
| Vertex::Throw(..)
|
|
| Vertex::ExpressionArrayElement(..) => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Typename for Vertex<'_> {
|
|
fn typename(&self) -> &'static str {
|
|
match self {
|
|
Vertex::ASTNode(_) => "ASTNode",
|
|
Vertex::AssignmentType(_) => "AssignmentType",
|
|
Vertex::Class(data) => data.typename(),
|
|
Vertex::ClassMethod(_) => "ClassMethod",
|
|
Vertex::ClassProperty(_) => "ClassProperty",
|
|
Vertex::DefaultImport(_) => "DefaultImport",
|
|
Vertex::Expression(_) => "Expression",
|
|
Vertex::File => "File",
|
|
Vertex::Import(data) => data.typename(),
|
|
Vertex::Interface(data) => data.typename(),
|
|
Vertex::NumberLiteral(data) => data.typename(),
|
|
Vertex::DotProperty(data) => data.typename(),
|
|
Vertex::InterfaceExtend(data) => match **data {
|
|
InterfaceExtendVertex::Identifier(_) => "SimpleExtend",
|
|
InterfaceExtendVertex::MemberExpression(_) => "MemberExtend",
|
|
},
|
|
Vertex::JSXAttribute(_) => "JSXAttribute",
|
|
Vertex::JSXElement(data) => data.typename(),
|
|
Vertex::JSXExpressionContainer(_) => "JSXExpressionContainer",
|
|
Vertex::JSXFragment(_) => "JSXFragment",
|
|
Vertex::JSXOpeningElement(data) => data.typename(),
|
|
Vertex::JSXSpreadAttribute(_) => "JSXSpreadAttribute",
|
|
Vertex::JSXSpreadChild(_) => "JSXSpreadChild",
|
|
Vertex::JSXText(_) => "JSXText",
|
|
Vertex::ObjectLiteral(data) => data.typename(),
|
|
Vertex::PathPart(_) => "PathPart",
|
|
Vertex::SearchParameter(_) => "SearchParameter",
|
|
Vertex::Span(_) => "Span",
|
|
Vertex::SpecificImport(_) => "SpecificImport",
|
|
Vertex::TypeAnnotation(data) => data.typename(),
|
|
Vertex::Type(_) => "Type",
|
|
Vertex::Url(_) => "URL",
|
|
Vertex::VariableDeclaration(datat) => datat.typename(),
|
|
Vertex::Name(data) => data.typename(),
|
|
Vertex::Return(data) => data.typename(),
|
|
Vertex::IfStatementAST(_) => "IfStatementAST",
|
|
Vertex::Spread(data) => data.typename(),
|
|
Vertex::ObjectEntry(data) => data.typename(),
|
|
Vertex::FnCall(data) => data.typename(),
|
|
Vertex::Reassignment(data) => data.typename(),
|
|
Vertex::Argument(data) => data.typename(),
|
|
Vertex::FnDeclaration(data) => data.typename(),
|
|
Vertex::ArrowFunction(data) => data.typename(),
|
|
Vertex::FunctionBody(data) => data.typename(),
|
|
Vertex::Parameter(data) => data.typename(),
|
|
Vertex::LogicalExpression(data) => data.typename(),
|
|
Vertex::UnaryExpression(datat) => datat.typename(),
|
|
Vertex::Statement(_) => "Statement",
|
|
Vertex::ExpressionStatement(data) => data.typename(),
|
|
Vertex::WhileStatement(data) => data.typename(),
|
|
Vertex::DoWhileStatement(data) => data.typename(),
|
|
Vertex::BlockStatement(data) => data.typename(),
|
|
Vertex::VarRef(data) => data.typename(),
|
|
Vertex::ForStatement(data) => data.typename(),
|
|
Vertex::TernaryExpression(data) => data.typename(),
|
|
Vertex::New(data) => data.typename(),
|
|
Vertex::Throw(data) => data.typename(),
|
|
Vertex::Array(data) => data.typename(),
|
|
Vertex::StringLiteral(data) => data.typename(),
|
|
Vertex::TemplateLiteral(data) => data.typename(),
|
|
Vertex::RegExpLiteral(data) => data.typename(),
|
|
Vertex::ParenthesizedExpression(data) => data.typename(),
|
|
Vertex::ElidedArrayElement(data) => data.typename(),
|
|
Vertex::ExpressionArrayElement(data) => data.typename(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::too_many_lines)]
|
|
impl<'a> From<AstNode<'a>> for Vertex<'a> {
|
|
fn from(ast_node: AstNode<'a>) -> Self {
|
|
match ast_node.kind() {
|
|
AstKind::ReturnStatement(return_statement) => {
|
|
Self::Return(ReturnVertex { ast_node: Some(ast_node), return_statement }.into())
|
|
}
|
|
AstKind::IfStatement(if_statement) => Self::IfStatementAST(
|
|
IfStatementVertex { ast_node: Some(ast_node), return_statement: if_statement }
|
|
.into(),
|
|
),
|
|
AstKind::JSXElement(element) => {
|
|
Self::JSXElement(JSXElementVertex { ast_node: Some(ast_node), element }.into())
|
|
}
|
|
AstKind::TSInterfaceDeclaration(interface) => {
|
|
Self::Interface(InterfaceVertex { ast_node: Some(ast_node), interface }.into())
|
|
}
|
|
AstKind::TSTypeAnnotation(type_annotation) => Self::TypeAnnotation(
|
|
TypeAnnotationVertex { ast_node: Some(ast_node), type_annotation }.into(),
|
|
),
|
|
AstKind::VariableDeclarator(variable_declaration) => Self::VariableDeclaration(
|
|
VariableDeclarationVertex { ast_node: Some(ast_node), variable_declaration }.into(),
|
|
),
|
|
AstKind::ModuleDeclaration(ModuleDeclaration::ImportDeclaration(import)) => {
|
|
Self::Import(ImportVertex { ast_node: Some(ast_node), import }.into())
|
|
}
|
|
AstKind::Class(class) => {
|
|
Self::Class(ClassVertex { ast_node: Some(ast_node), class }.into())
|
|
}
|
|
AstKind::ObjectExpression(objexpr) => Self::ObjectLiteral(
|
|
ObjectLiteralVertex { ast_node: Some(ast_node), object_expression: objexpr }.into(),
|
|
),
|
|
AstKind::JSXOpeningElement(opening_element) => Self::JSXOpeningElement(
|
|
JSXOpeningElementVertex { ast_node: Some(ast_node), opening_element }.into(),
|
|
),
|
|
AstKind::NumberLiteral(number_literal) => Self::NumberLiteral(
|
|
NumberLiteralVertex { ast_node: Some(ast_node), number_literal }.into(),
|
|
),
|
|
AstKind::IdentifierName(identifier_name) => {
|
|
Self::Name(NameVertex { ast_node: Some(ast_node), name: identifier_name }.into())
|
|
}
|
|
AstKind::ObjectProperty(property) => {
|
|
Self::ObjectEntry(ObjectEntryVertex { ast_node: Some(ast_node), property }.into())
|
|
}
|
|
AstKind::SpreadElement(property) => {
|
|
Self::Spread(SpreadVertex { ast_node: Some(ast_node), spread: property }.into())
|
|
}
|
|
AstKind::MemberExpression(member_expr)
|
|
if matches!(member_expr, MemberExpression::StaticMemberExpression(_)) =>
|
|
{
|
|
match member_expr {
|
|
MemberExpression::StaticMemberExpression(member_expr) => Self::DotProperty(
|
|
DotPropertyVertex {
|
|
ast_node: Some(ast_node),
|
|
static_member_expr: member_expr,
|
|
}
|
|
.into(),
|
|
),
|
|
_ => unreachable!("we should only ever have StaticMemberExpression"),
|
|
}
|
|
}
|
|
AstKind::AssignmentExpression(assignment_expression) => Vertex::Reassignment(
|
|
ReassignmentVertex { ast_node: Some(ast_node), assignment_expression }.into(),
|
|
),
|
|
AstKind::CallExpression(call_expression) => {
|
|
Vertex::FnCall(FnCallVertex { ast_node: Some(ast_node), call_expression }.into())
|
|
}
|
|
AstKind::Function(function) => Vertex::FnDeclaration(
|
|
FnDeclarationVertex { ast_node: Some(ast_node), function }.into(),
|
|
),
|
|
AstKind::ArrowExpression(arrow_expression) => Vertex::ArrowFunction(
|
|
ArrowFunctionVertex { ast_node: Some(ast_node), arrow_expression }.into(),
|
|
),
|
|
AstKind::FunctionBody(function_body) => Vertex::FunctionBody(
|
|
FunctionBodyVertex { ast_node: Some(ast_node), function_body }.into(),
|
|
),
|
|
AstKind::FormalParameter(parameter) => {
|
|
Vertex::Parameter(ParameterVertex { ast_node: Some(ast_node), parameter }.into())
|
|
}
|
|
AstKind::Argument(argument) => Vertex::Argument(
|
|
ArgumentVertex { argument, data: ArgumentData::AstNode(ast_node) }.into(),
|
|
),
|
|
AstKind::LogicalExpression(logical_expression) => Vertex::LogicalExpression(
|
|
LogicalExpressionVertex { ast_node: Some(ast_node), logical_expression }.into(),
|
|
),
|
|
AstKind::UnaryExpression(unary_expression) => Vertex::UnaryExpression(
|
|
UnaryExpressionVertex { ast_node: Some(ast_node), unary_expression }.into(),
|
|
),
|
|
AstKind::ExpressionStatement(expression_statement) => Vertex::ExpressionStatement(
|
|
ExpressionStatementVertex { ast_node: Some(ast_node), expression_statement }.into(),
|
|
),
|
|
AstKind::WhileStatement(expression_statement) => Vertex::WhileStatement(
|
|
WhileStatementVertex {
|
|
ast_node: Some(ast_node),
|
|
while_statement: expression_statement,
|
|
}
|
|
.into(),
|
|
),
|
|
AstKind::BlockStatement(block_statement) => Vertex::BlockStatement(
|
|
BlockStatementVertex { ast_node: Some(ast_node), block_statement }.into(),
|
|
),
|
|
AstKind::IdentifierReference(identifier_reference) => Vertex::VarRef(
|
|
VarRefVertex { ast_node: Some(ast_node), identifier_reference }.into(),
|
|
),
|
|
AstKind::DoWhileStatement(do_while_statement) => Vertex::DoWhileStatement(
|
|
DoWhileStatementVertex { ast_node: Some(ast_node), do_while_statement }.into(),
|
|
),
|
|
AstKind::ForStatement(for_statement) => Vertex::ForStatement(
|
|
ForStatementVertex { ast_node: Some(ast_node), for_statement }.into(),
|
|
),
|
|
AstKind::ConditionalExpression(conditional_expression) => Vertex::TernaryExpression(
|
|
TernaryExpressionVertex { ast_node: Some(ast_node), conditional_expression }.into(),
|
|
),
|
|
AstKind::NewExpression(new_expression) => {
|
|
Vertex::New(NewVertex { ast_node: Some(ast_node), new_expression }.into())
|
|
}
|
|
AstKind::ThrowStatement(throw_statement) => {
|
|
Vertex::Throw(ThrowVertex { ast_node: Some(ast_node), throw_statement }.into())
|
|
}
|
|
AstKind::StringLiteral(string_literal) => Vertex::StringLiteral(
|
|
StringLiteralVertex { ast_node: Some(ast_node), string: string_literal }.into(),
|
|
),
|
|
AstKind::TemplateLiteral(template_literal) => Vertex::TemplateLiteral(
|
|
TemplateLiteralVertex { ast_node: Some(ast_node), template: template_literal }
|
|
.into(),
|
|
),
|
|
AstKind::RegExpLiteral(regexp_literal) => Vertex::RegExpLiteral(
|
|
RegExpLiteralVertex { ast_node: Some(ast_node), regexp: regexp_literal }.into(),
|
|
),
|
|
AstKind::ArrayExpression(array_expression) => {
|
|
Vertex::Array(ArrayVertex { ast_node: Some(ast_node), array_expression }.into())
|
|
}
|
|
AstKind::ParenthesizedExpression(parenthesized_expression) => {
|
|
Vertex::ParenthesizedExpression(
|
|
ParenthesizedExpressionVertex {
|
|
ast_node: Some(ast_node),
|
|
parenthesized_expression,
|
|
}
|
|
.into(),
|
|
)
|
|
}
|
|
AstKind::Elision(span) => Vertex::ElidedArrayElement(
|
|
ElidedArrayElementVertex { span, ast_node: Some(ast_node) }.into(),
|
|
),
|
|
AstKind::ExpressionArrayElement(expression) => Vertex::ExpressionArrayElement(
|
|
ExpressionArrayElementVertex { expression, ast_node: Some(ast_node) }.into(),
|
|
),
|
|
_ => Vertex::ASTNode(ast_node),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> From<&'a Statement<'a>> for Vertex<'a> {
|
|
fn from(stmt: &'a Statement<'a>) -> Self {
|
|
match &stmt {
|
|
Statement::ReturnStatement(return_statement) => {
|
|
Vertex::Return(ReturnVertex { ast_node: None, return_statement }.into())
|
|
}
|
|
Statement::ExpressionStatement(expression_statement) => Vertex::ExpressionStatement(
|
|
ExpressionStatementVertex { ast_node: None, expression_statement }.into(),
|
|
),
|
|
Statement::WhileStatement(while_statement) => Vertex::WhileStatement(
|
|
WhileStatementVertex { ast_node: None, while_statement }.into(),
|
|
),
|
|
Statement::DoWhileStatement(do_while_statement) => Vertex::DoWhileStatement(
|
|
DoWhileStatementVertex { ast_node: None, do_while_statement }.into(),
|
|
),
|
|
Statement::BlockStatement(block_statement) => Vertex::BlockStatement(
|
|
BlockStatementVertex { ast_node: None, block_statement }.into(),
|
|
),
|
|
Statement::ForStatement(for_statement) => {
|
|
Vertex::ForStatement(ForStatementVertex { ast_node: None, for_statement }.into())
|
|
}
|
|
Statement::ThrowStatement(throw_statement) => {
|
|
Vertex::Throw(ThrowVertex { ast_node: None, throw_statement }.into())
|
|
}
|
|
_ => Vertex::Statement(stmt),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> From<&'a Expression<'a>> for Vertex<'a> {
|
|
fn from(expr: &'a Expression<'a>) -> Self {
|
|
match &expr {
|
|
Expression::ObjectExpression(object_expression) => Vertex::ObjectLiteral(
|
|
ObjectLiteralVertex { ast_node: None, object_expression }.into(),
|
|
),
|
|
Expression::JSXElement(element) => {
|
|
Vertex::JSXElement(JSXElementVertex { ast_node: None, element }.into())
|
|
}
|
|
Expression::NumberLiteral(number_literal) => {
|
|
Vertex::NumberLiteral(NumberLiteralVertex { ast_node: None, number_literal }.into())
|
|
}
|
|
Expression::MemberExpression(me) => {
|
|
let vertex = Vertex::try_from_member_expression(me);
|
|
|
|
vertex.unwrap_or(Vertex::Expression(expr))
|
|
}
|
|
Expression::AssignmentExpression(assignment_expression) => Vertex::Reassignment(
|
|
ReassignmentVertex { ast_node: None, assignment_expression }.into(),
|
|
),
|
|
Expression::CallExpression(call_expression) => {
|
|
Vertex::FnCall(FnCallVertex { ast_node: None, call_expression }.into())
|
|
}
|
|
Expression::FunctionExpression(fn_expression) => Vertex::FnDeclaration(
|
|
FnDeclarationVertex { ast_node: None, function: fn_expression }.into(),
|
|
),
|
|
Expression::ArrowExpression(arrow_expression) => Vertex::ArrowFunction(
|
|
ArrowFunctionVertex { ast_node: None, arrow_expression }.into(),
|
|
),
|
|
Expression::LogicalExpression(logical_expression) => Vertex::LogicalExpression(
|
|
LogicalExpressionVertex { ast_node: None, logical_expression }.into(),
|
|
),
|
|
Expression::UnaryExpression(unary_expression) => Vertex::UnaryExpression(
|
|
UnaryExpressionVertex { ast_node: None, unary_expression }.into(),
|
|
),
|
|
Expression::Identifier(identifier_reference) => {
|
|
Vertex::VarRef(VarRefVertex { ast_node: None, identifier_reference }.into())
|
|
}
|
|
Expression::ConditionalExpression(conditional_expression) => Vertex::TernaryExpression(
|
|
TernaryExpressionVertex { ast_node: None, conditional_expression }.into(),
|
|
),
|
|
Expression::NewExpression(new_expression) => {
|
|
Vertex::New(NewVertex { ast_node: None, new_expression }.into())
|
|
}
|
|
Expression::ArrayExpression(array_expression) => {
|
|
Vertex::Array(ArrayVertex { ast_node: None, array_expression }.into())
|
|
}
|
|
Expression::StringLiteral(string_literal) => Vertex::StringLiteral(
|
|
StringLiteralVertex { ast_node: None, string: string_literal }.into(),
|
|
),
|
|
Expression::TemplateLiteral(template_literal) => Vertex::TemplateLiteral(
|
|
TemplateLiteralVertex { ast_node: None, template: template_literal }.into(),
|
|
),
|
|
Expression::RegExpLiteral(regexp_literal) => Vertex::RegExpLiteral(
|
|
RegExpLiteralVertex { ast_node: None, regexp: regexp_literal }.into(),
|
|
),
|
|
Expression::ParenthesizedExpression(parenthesized_expression) => {
|
|
Vertex::ParenthesizedExpression(
|
|
ParenthesizedExpressionVertex { ast_node: None, parenthesized_expression }
|
|
.into(),
|
|
)
|
|
}
|
|
_ => Vertex::Expression(expr),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> From<&'a ArrayExpressionElement<'a>> for Vertex<'a> {
|
|
fn from(array_element: &'a ArrayExpressionElement<'a>) -> Self {
|
|
match &array_element {
|
|
ArrayExpressionElement::SpreadElement(spread) => {
|
|
Vertex::Spread(SpreadVertex { ast_node: None, spread }.into())
|
|
}
|
|
ArrayExpressionElement::Elision(span) => Vertex::ElidedArrayElement(
|
|
ElidedArrayElementVertex { ast_node: None, span: *span }.into(),
|
|
),
|
|
ArrayExpressionElement::Expression(expression) => Vertex::ExpressionArrayElement(
|
|
ExpressionArrayElementVertex { expression, ast_node: None }.into(),
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ClassVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub class: &'a Class<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ClassVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ClassAST"
|
|
} else {
|
|
"Class"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ClassMethodVertex<'a> {
|
|
pub method: &'a MethodDefinition<'a>,
|
|
pub is_abstract: bool,
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ClassPropertyVertex<'a> {
|
|
pub property: &'a PropertyDefinition<'a>,
|
|
pub is_abstract: bool,
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ImportVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub import: &'a ImportDeclaration<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ImportVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ImportAST"
|
|
} else {
|
|
"Import"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct InterfaceVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub interface: &'a TSInterfaceDeclaration<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for InterfaceVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"InterfaceAST"
|
|
} else {
|
|
"Interface"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub enum InterfaceExtendVertex<'a> {
|
|
Identifier(&'a IdentifierReference),
|
|
MemberExpression(&'a MemberExpression<'a>),
|
|
}
|
|
|
|
impl<'a> From<&'a Expression<'a>> for InterfaceExtendVertex<'a> {
|
|
fn from(expr: &'a Expression<'a>) -> Self {
|
|
match &expr {
|
|
Expression::Identifier(ident) => InterfaceExtendVertex::Identifier(ident),
|
|
Expression::MemberExpression(membexpr) => {
|
|
InterfaceExtendVertex::MemberExpression(membexpr)
|
|
}
|
|
_ => unreachable!(
|
|
"Only ever possible to have an interface extend an identifier or memberexpr. see TS:2499"
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct JSXElementVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub element: &'a JSXElement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for JSXElementVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"JSXElementAST"
|
|
} else {
|
|
"JSXElement"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct IfStatementVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub return_statement: &'a IfStatement<'a>,
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ReturnVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub return_statement: &'a ReturnStatement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ReturnVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ReturnAST"
|
|
} else {
|
|
"ReturnStatement"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct TypeAnnotationVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub type_annotation: &'a TSTypeAnnotation<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for TypeAnnotationVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"TypeAnnotationAST"
|
|
} else {
|
|
"TypeAnnotation"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct SearchParameterVertex {
|
|
pub key: String,
|
|
pub value: String,
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct VariableDeclarationVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub variable_declaration: &'a VariableDeclarator<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for VariableDeclarationVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"VariableDeclarationAST"
|
|
} else {
|
|
"VariableDeclaration"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ObjectLiteralVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub object_expression: &'a ObjectExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ObjectLiteralVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ObjectLiteralAST"
|
|
} else {
|
|
"ObjectLiteral"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct JSXOpeningElementVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub opening_element: &'a JSXOpeningElement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for JSXOpeningElementVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"JSXOpeningElementAST"
|
|
} else {
|
|
"JSXOpeningElement"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct NumberLiteralVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub number_literal: &'a NumberLiteral<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for NumberLiteralVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"NumberLiteralAST"
|
|
} else {
|
|
"NumberLiteral"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct NameVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub name: &'a IdentifierName,
|
|
}
|
|
|
|
impl<'a> Typename for NameVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"NameAST"
|
|
} else {
|
|
"Name"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ObjectEntryVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub property: &'a ObjectProperty<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ObjectEntryVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ObjectEntryAST"
|
|
} else {
|
|
"ObjectEntry"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct SpreadVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub spread: &'a SpreadElement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for SpreadVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"SpreadAST"
|
|
} else {
|
|
"Spread"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct DotPropertyVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub static_member_expr: &'a StaticMemberExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for DotPropertyVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"DotPropertyAST"
|
|
} else {
|
|
"DotProperty"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ReassignmentVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub assignment_expression: &'a AssignmentExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ReassignmentVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ReassignmentAST"
|
|
} else {
|
|
"Reassignment"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct FnCallVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub call_expression: &'a CallExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for FnCallVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"FnCallAST"
|
|
} else {
|
|
"FnCall"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct FnDeclarationVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub function: &'a Function<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for FnDeclarationVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"FnDeclarationAST"
|
|
} else {
|
|
"FnDeclaration"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ArrowFunctionVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub arrow_expression: &'a ArrowExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ArrowFunctionVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ArrowFunctionAST"
|
|
} else {
|
|
"ArrowFunction"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct FunctionBodyVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub function_body: &'a FunctionBody<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for FunctionBodyVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"FunctionBodyAST"
|
|
} else {
|
|
"FunctionBody"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ParameterVertex<'a> {
|
|
ast_node: Option<AstNode<'a>>,
|
|
pub parameter: &'a FormalParameter<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ParameterVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ParameterAST"
|
|
} else {
|
|
"Parameter"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ArgumentVertex<'a> {
|
|
/// Represents data from when the vertex is created
|
|
/// If the vertex is created from an AST node, this will be the AST node
|
|
/// Otherwise, it will be the index of the argument in the arguments vec
|
|
pub data: ArgumentData<'a>,
|
|
pub argument: &'a Argument<'a>,
|
|
}
|
|
|
|
/// Data used to find the index of the argument in the arguments vec and sometimes holds the [`AstNode`]
|
|
#[derive(Debug, Clone)]
|
|
pub enum ArgumentData<'a> {
|
|
/// If the vertex is created from a [`CallExpression`], this will be the index of the argument in the arguments vec
|
|
Index(usize),
|
|
/// If the vertex is created from an [`AstNode`], this will be the AST node, which can be used to find the index of the argument
|
|
/// in the arguments vec by finding the astnode's parent node which will be a [`CallExpression`], then finding the index of the
|
|
/// argument in the arguments vec
|
|
AstNode(AstNode<'a>),
|
|
}
|
|
|
|
impl<'a> ArgumentVertex<'a> {
|
|
pub fn index<'c, 'b: 'c>(&self, adapter: &'c Adapter<'b>) -> usize {
|
|
match &self.data {
|
|
ArgumentData::Index(index) => *index,
|
|
ArgumentData::AstNode(ast_node) => {
|
|
let AstKind::CallExpression(call_expr) = adapter
|
|
.semantic
|
|
.nodes()
|
|
.parent_node(ast_node.id())
|
|
.expect("argument should have parent")
|
|
.kind()
|
|
else {
|
|
unreachable!("Argument's parent should always be a CallExpression")
|
|
};
|
|
call_expr
|
|
.arguments
|
|
.iter()
|
|
.position(|x| calculate_hash(x) == calculate_hash(self.argument))
|
|
.expect("to find index of this argument in it's parent's arguments vec")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> Typename for ArgumentVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if let ArgumentData::AstNode(_) = self.data {
|
|
"ArgumentAST"
|
|
} else {
|
|
"Argument"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct LogicalExpressionVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub logical_expression: &'a LogicalExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for LogicalExpressionVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"LogicalExpressionAST"
|
|
} else {
|
|
"LogicalExpression"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct UnaryExpressionVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub unary_expression: &'a UnaryExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for UnaryExpressionVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"UnaryExpressionAST"
|
|
} else {
|
|
"UnaryExpression"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ExpressionStatementVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub expression_statement: &'a ExpressionStatement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ExpressionStatementVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ExpressionStatementAST"
|
|
} else {
|
|
"ExpressionStatement"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct WhileStatementVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub while_statement: &'a WhileStatement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for WhileStatementVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"WhileStatementAST"
|
|
} else {
|
|
"WhileStatement"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct BlockStatementVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub block_statement: &'a BlockStatement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for BlockStatementVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"BlockStatementAST"
|
|
} else {
|
|
"BlockStatement"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct VarRefVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub identifier_reference: &'a IdentifierReference,
|
|
}
|
|
|
|
impl<'a> Typename for VarRefVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"VarRefAST"
|
|
} else {
|
|
"VarRef"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct DoWhileStatementVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub do_while_statement: &'a DoWhileStatement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for DoWhileStatementVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"DoWhileStatementAST"
|
|
} else {
|
|
"DoWhileStatement"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ForStatementVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub for_statement: &'a ForStatement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ForStatementVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ForStatementAST"
|
|
} else {
|
|
"ForStatement"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct TernaryExpressionVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub conditional_expression: &'a ConditionalExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for TernaryExpressionVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"TernaryExpressionAST"
|
|
} else {
|
|
"TernaryExpression"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct NewVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub new_expression: &'a NewExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for NewVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"NewAST"
|
|
} else {
|
|
"New"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ThrowVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub throw_statement: &'a ThrowStatement<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ThrowVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ThrowAST"
|
|
} else {
|
|
"Throw"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ArrayVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub array_expression: &'a ArrayExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ArrayVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ArrayAST"
|
|
} else {
|
|
"Array"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct StringLiteralVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub string: &'a StringLiteral,
|
|
}
|
|
|
|
impl<'a> Typename for StringLiteralVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"StringLiteralAST"
|
|
} else {
|
|
"StringLiteral"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct TemplateLiteralVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub template: &'a TemplateLiteral<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for TemplateLiteralVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"TemplateLiteralAST"
|
|
} else {
|
|
"TemplateLiteral"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct RegExpLiteralVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub regexp: &'a RegExpLiteral,
|
|
}
|
|
|
|
impl<'a> Typename for RegExpLiteralVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"RegExpLiteralAST"
|
|
} else {
|
|
"RegExpLiteral"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ParenthesizedExpressionVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub parenthesized_expression: &'a ParenthesizedExpression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ParenthesizedExpressionVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ParenthesizedExpressionAST"
|
|
} else {
|
|
"ParenthesizedExpression"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ElidedArrayElementVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub span: Span,
|
|
}
|
|
|
|
impl<'a> Typename for ElidedArrayElementVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ElidedArrayElementAST"
|
|
} else {
|
|
"ElidedArrayElement"
|
|
}
|
|
}
|
|
}
|
|
|
|
#[non_exhaustive]
|
|
#[derive(Debug, Clone)]
|
|
pub struct ExpressionArrayElementVertex<'a> {
|
|
pub ast_node: Option<AstNode<'a>>,
|
|
pub expression: &'a Expression<'a>,
|
|
}
|
|
|
|
impl<'a> Typename for ExpressionArrayElementVertex<'a> {
|
|
fn typename(&self) -> &'static str {
|
|
if self.ast_node.is_some() {
|
|
"ExpressionArrayElementAST"
|
|
} else {
|
|
"ExpressionArrayElement"
|
|
}
|
|
}
|
|
}
|