mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Move compile_expr into StaticExpressionCompiler
This commit is contained in:
@@ -17,6 +17,7 @@ mod optimization;
|
||||
mod resolve_path;
|
||||
mod scope;
|
||||
mod scope_analysis;
|
||||
mod static_expression_compiler;
|
||||
mod target_accessor;
|
||||
mod visit_pointers;
|
||||
|
||||
|
||||
@@ -5,19 +5,19 @@ use swc_common::errors::{DiagnosticBuilder, Emitter};
|
||||
use swc_common::{errors::Handler, FileName, SourceMap, Spanned};
|
||||
use swc_ecma_ast::EsVersion;
|
||||
use swc_ecma_parser::{Syntax, TsConfig};
|
||||
use valuescript_vm::operations::to_i32;
|
||||
|
||||
use crate::asm::{
|
||||
Array, Builtin, Class, Definition, DefinitionContent, FnLine, Function, Instruction, Lazy,
|
||||
Module, Number, Object, Pointer, Register, Value,
|
||||
Class, Definition, DefinitionContent, FnLine, Function, Instruction, Lazy, Module, Number,
|
||||
Object, Pointer, Register, Value,
|
||||
};
|
||||
use crate::diagnostic::{Diagnostic, DiagnosticContainer, DiagnosticReporter};
|
||||
use crate::expression_compiler::{value_from_literal, CompiledExpression, ExpressionCompiler};
|
||||
use crate::expression_compiler::{CompiledExpression, ExpressionCompiler};
|
||||
use crate::function_compiler::{FunctionCompiler, Functionish};
|
||||
use crate::ident::Ident;
|
||||
use crate::name_allocator::{ident_from_str, NameAllocator};
|
||||
use crate::scope::OwnerId;
|
||||
use crate::scope_analysis::ScopeAnalysis;
|
||||
use crate::static_expression_compiler::StaticExpressionCompiler;
|
||||
|
||||
struct DiagnosticCollector {
|
||||
diagnostics: Arc<Mutex<Vec<Diagnostic>>>,
|
||||
@@ -108,7 +108,7 @@ impl DiagnosticContainer for ModuleCompiler {
|
||||
}
|
||||
|
||||
impl ModuleCompiler {
|
||||
fn allocate_defn(&mut self, name: &str) -> Pointer {
|
||||
pub fn allocate_defn(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self.definition_allocator.allocate(&name.to_string());
|
||||
|
||||
Pointer {
|
||||
@@ -116,7 +116,7 @@ impl ModuleCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
fn allocate_defn_numbered(&mut self, name: &str) -> Pointer {
|
||||
pub fn allocate_defn_numbered(&mut self, name: &str) -> Pointer {
|
||||
let allocated_name = self.definition_allocator.allocate_numbered(name);
|
||||
|
||||
Pointer {
|
||||
@@ -696,7 +696,7 @@ impl ModuleCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_fn(
|
||||
pub fn compile_fn(
|
||||
&mut self,
|
||||
defn_pointer: Pointer,
|
||||
fn_name: Option<String>,
|
||||
@@ -710,7 +710,7 @@ impl ModuleCompiler {
|
||||
defn
|
||||
}
|
||||
|
||||
fn compile_class(
|
||||
pub fn compile_class(
|
||||
&mut self,
|
||||
export_name: Option<String>,
|
||||
ident: Option<&swc_ecma_ast::Ident>,
|
||||
@@ -945,276 +945,6 @@ impl ModuleCompiler {
|
||||
}
|
||||
|
||||
pub fn compile_expr(&mut self, expr: &swc_ecma_ast::Expr) -> Value {
|
||||
let symbol_iterator_opt = as_symbol_iterator(expr);
|
||||
|
||||
if let Some(symbol_iterator) = symbol_iterator_opt {
|
||||
return symbol_iterator;
|
||||
}
|
||||
|
||||
match expr {
|
||||
swc_ecma_ast::Expr::Lit(lit) => match value_from_literal(lit) {
|
||||
Ok(value) => value,
|
||||
Err(msg) => {
|
||||
self.internal_error(expr.span(), &format!("Failed to compile literal: {}", msg));
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::Expr::Array(array) => {
|
||||
let mut values = Vec::<Value>::new();
|
||||
|
||||
for item in &array.elems {
|
||||
values.push(match item {
|
||||
Some(item) => {
|
||||
if item.spread.is_some() {
|
||||
self.todo(expr.span(), "item.spread in static expression");
|
||||
return Value::String("(error)".to_string());
|
||||
}
|
||||
|
||||
self.compile_expr(&item.expr)
|
||||
}
|
||||
None => Value::Void,
|
||||
});
|
||||
}
|
||||
|
||||
Value::Array(Box::new(Array { values }))
|
||||
}
|
||||
swc_ecma_ast::Expr::Object(object) => {
|
||||
let mut properties = Vec::<(Value, Value)>::new();
|
||||
|
||||
for prop in &object.props {
|
||||
let (key, value) = match prop {
|
||||
swc_ecma_ast::PropOrSpread::Spread(_) => {
|
||||
self.todo(prop.span(), "Static spread");
|
||||
return Value::String("(error)".to_string());
|
||||
}
|
||||
swc_ecma_ast::PropOrSpread::Prop(prop) => match &**prop {
|
||||
swc_ecma_ast::Prop::Shorthand(_) => {
|
||||
self.todo(prop.span(), "Static object shorthand");
|
||||
return Value::String("(error)".to_string());
|
||||
}
|
||||
swc_ecma_ast::Prop::KeyValue(kv) => {
|
||||
let key = match &kv.key {
|
||||
swc_ecma_ast::PropName::Ident(ident) => Value::String(ident.sym.to_string()),
|
||||
swc_ecma_ast::PropName::Str(str) => Value::String(str.value.to_string()),
|
||||
swc_ecma_ast::PropName::Num(num) => Value::Number(Number(num.value)),
|
||||
swc_ecma_ast::PropName::Computed(computed) => self.compile_expr(&computed.expr),
|
||||
swc_ecma_ast::PropName::BigInt(bi) => Value::BigInt(bi.value.clone()),
|
||||
};
|
||||
|
||||
let value = self.compile_expr(&kv.value);
|
||||
|
||||
(key, value)
|
||||
}
|
||||
swc_ecma_ast::Prop::Assign(_)
|
||||
| swc_ecma_ast::Prop::Getter(_)
|
||||
| swc_ecma_ast::Prop::Setter(_) => {
|
||||
self.todo(prop.span(), "This type of static prop");
|
||||
return Value::String("(error)".to_string());
|
||||
}
|
||||
swc_ecma_ast::Prop::Method(method) => {
|
||||
let key = match &method.key {
|
||||
swc_ecma_ast::PropName::Ident(ident) => Value::String(ident.sym.to_string()),
|
||||
_ => {
|
||||
self.todo(method.key.span(), "Static non-ident prop names");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
};
|
||||
|
||||
let fn_ident = match &method.key {
|
||||
swc_ecma_ast::PropName::Ident(ident) => Some(ident.clone()),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let fn_name = fn_ident.clone().map(|ident| ident.sym.to_string());
|
||||
|
||||
let p = match &fn_name {
|
||||
Some(name) => self.allocate_defn(name),
|
||||
None => self.allocate_defn_numbered("_anon"),
|
||||
};
|
||||
|
||||
let mut nested_defns = self.compile_fn(
|
||||
p.clone(),
|
||||
fn_name.clone(),
|
||||
Functionish::Fn(fn_ident, method.function.clone()),
|
||||
);
|
||||
|
||||
self.module.definitions.append(&mut nested_defns);
|
||||
|
||||
(key, Value::Pointer(p))
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
properties.push((key, value));
|
||||
}
|
||||
|
||||
Value::Object(Box::new(Object { properties }))
|
||||
}
|
||||
swc_ecma_ast::Expr::This(_)
|
||||
| swc_ecma_ast::Expr::Update(_)
|
||||
| swc_ecma_ast::Expr::Assign(_)
|
||||
| swc_ecma_ast::Expr::SuperProp(_)
|
||||
| swc_ecma_ast::Expr::Call(_)
|
||||
| swc_ecma_ast::Expr::New(_) => {
|
||||
self.todo(expr.span(), "This type of static expr");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::Expr::Ident(ident) => match self
|
||||
.scope_analysis
|
||||
.lookup(&Ident::from_swc_ident(ident))
|
||||
.map(|name| name.value.clone())
|
||||
{
|
||||
Some(Value::Pointer(p)) => self
|
||||
.constants_map
|
||||
.get(&p)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Value::Pointer(p)),
|
||||
Some(value) => value,
|
||||
None => {
|
||||
self.internal_error(ident.span, "Identifier not found");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::Expr::Fn(fn_) => {
|
||||
let fn_name = fn_.ident.clone().map(|ident| ident.sym.to_string());
|
||||
|
||||
let p = match &fn_name {
|
||||
Some(name) => self.allocate_defn(name),
|
||||
None => self.allocate_defn_numbered("_anon"),
|
||||
};
|
||||
|
||||
let mut fn_defns = self.compile_fn(
|
||||
p.clone(),
|
||||
fn_name,
|
||||
Functionish::Fn(fn_.ident.clone(), fn_.function.clone()),
|
||||
);
|
||||
|
||||
self.module.definitions.append(&mut fn_defns);
|
||||
|
||||
Value::Pointer(p)
|
||||
}
|
||||
swc_ecma_ast::Expr::Arrow(arrow) => {
|
||||
let p = self.allocate_defn_numbered("_anon");
|
||||
let mut fn_defns = self.compile_fn(p.clone(), None, Functionish::Arrow(arrow.clone()));
|
||||
self.module.definitions.append(&mut fn_defns);
|
||||
|
||||
Value::Pointer(p)
|
||||
}
|
||||
swc_ecma_ast::Expr::Class(class) => {
|
||||
Value::Pointer(self.compile_class(None, class.ident.as_ref(), &class.class))
|
||||
}
|
||||
swc_ecma_ast::Expr::TaggedTpl(_)
|
||||
| swc_ecma_ast::Expr::Yield(_)
|
||||
| swc_ecma_ast::Expr::MetaProp(_)
|
||||
| swc_ecma_ast::Expr::Await(_)
|
||||
| swc_ecma_ast::Expr::JSXMember(_)
|
||||
| swc_ecma_ast::Expr::JSXNamespacedName(_)
|
||||
| swc_ecma_ast::Expr::JSXEmpty(_)
|
||||
| swc_ecma_ast::Expr::JSXElement(_)
|
||||
| swc_ecma_ast::Expr::JSXFragment(_)
|
||||
| swc_ecma_ast::Expr::TsInstantiation(_)
|
||||
| swc_ecma_ast::Expr::PrivateName(_)
|
||||
| swc_ecma_ast::Expr::OptChain(_)
|
||||
| swc_ecma_ast::Expr::Invalid(_)
|
||||
| swc_ecma_ast::Expr::Member(_)
|
||||
| swc_ecma_ast::Expr::Cond(_) => {
|
||||
self.todo(expr.span(), "This type of static expr");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::Expr::Unary(unary) => match unary.op {
|
||||
swc_ecma_ast::UnaryOp::Minus => match self.compile_expr(&unary.arg) {
|
||||
Value::Number(Number(x)) => Value::Number(Number(-x)),
|
||||
Value::BigInt(bi) => Value::BigInt(-bi),
|
||||
_ => {
|
||||
self.todo(unary.span, "Static eval for this case");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::UnaryOp::Plus => match self.compile_expr(&unary.arg) {
|
||||
Value::Number(Number(x)) => Value::Number(Number(x)),
|
||||
Value::BigInt(bi) => Value::BigInt(bi),
|
||||
_ => {
|
||||
self.todo(unary.span, "Static eval for this case");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::UnaryOp::Bang => {
|
||||
self.todo(expr.span(), "Static eval of ! operator");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::UnaryOp::Tilde => match self.compile_expr(&unary.arg) {
|
||||
Value::Number(Number(x)) => Value::Number(Number(!to_i32(x) as f64)),
|
||||
Value::BigInt(bi) => Value::BigInt(!bi),
|
||||
_ => {
|
||||
self.todo(unary.span, "Static eval for this case");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::UnaryOp::TypeOf
|
||||
| swc_ecma_ast::UnaryOp::Void
|
||||
| swc_ecma_ast::UnaryOp::Delete => {
|
||||
self.todo(unary.span, "Static eval for this case");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::Expr::Bin(_) => {
|
||||
self.todo(expr.span(), "Static eval of binary operator");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::Expr::Seq(seq) => {
|
||||
let mut last = Value::Void;
|
||||
|
||||
for expr in &seq.exprs {
|
||||
last = self.compile_expr(expr);
|
||||
}
|
||||
|
||||
last
|
||||
}
|
||||
swc_ecma_ast::Expr::Tpl(tpl) => 'b: {
|
||||
let len = tpl.exprs.len();
|
||||
assert_eq!(tpl.quasis.len(), len + 1);
|
||||
|
||||
if len == 0 {
|
||||
break 'b Value::String(tpl.quasis[0].raw.to_string());
|
||||
}
|
||||
|
||||
self.todo(tpl.span, "Static eval of template literal");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::Expr::Paren(paren) => self.compile_expr(&paren.expr),
|
||||
swc_ecma_ast::Expr::TsTypeAssertion(tta) => self.compile_expr(&tta.expr),
|
||||
swc_ecma_ast::Expr::TsConstAssertion(tca) => self.compile_expr(&tca.expr),
|
||||
swc_ecma_ast::Expr::TsNonNull(tnn) => self.compile_expr(&tnn.expr),
|
||||
swc_ecma_ast::Expr::TsAs(ta) => self.compile_expr(&ta.expr),
|
||||
}
|
||||
StaticExpressionCompiler::new(self).expr(expr)
|
||||
}
|
||||
}
|
||||
|
||||
fn as_symbol_iterator(expr: &swc_ecma_ast::Expr) -> Option<Value> {
|
||||
let member_expr = match expr {
|
||||
swc_ecma_ast::Expr::Member(member_expr) => member_expr,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
match &*member_expr.obj {
|
||||
swc_ecma_ast::Expr::Ident(ident) => {
|
||||
if ident.sym.to_string() != "Symbol" {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
match &member_expr.prop {
|
||||
swc_ecma_ast::MemberProp::Ident(ident) => {
|
||||
if ident.sym.to_string() != "iterator" {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
|
||||
Some(Value::Builtin(Builtin {
|
||||
name: "SymbolIterator".to_string(),
|
||||
}))
|
||||
}
|
||||
|
||||
308
valuescript_compiler/src/static_expression_compiler.rs
Normal file
308
valuescript_compiler/src/static_expression_compiler.rs
Normal file
@@ -0,0 +1,308 @@
|
||||
use swc_common::Spanned;
|
||||
use valuescript_vm::operations::to_i32;
|
||||
|
||||
use crate::{
|
||||
asm::{Array, Builtin, Number, Object, Value},
|
||||
diagnostic::{DiagnosticContainer, DiagnosticReporter},
|
||||
expression_compiler::value_from_literal,
|
||||
function_compiler::Functionish,
|
||||
ident::Ident,
|
||||
module_compiler::ModuleCompiler,
|
||||
Diagnostic,
|
||||
};
|
||||
|
||||
pub struct StaticExpressionCompiler<'a> {
|
||||
pub mc: &'a mut ModuleCompiler,
|
||||
}
|
||||
|
||||
impl<'a> DiagnosticContainer for StaticExpressionCompiler<'a> {
|
||||
fn diagnostics_mut(&mut self) -> &mut Vec<Diagnostic> {
|
||||
self.mc.diagnostics_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> StaticExpressionCompiler<'a> {
|
||||
pub fn new(mc: &'a mut ModuleCompiler) -> Self {
|
||||
StaticExpressionCompiler { mc }
|
||||
}
|
||||
|
||||
pub fn expr(&mut self, expr: &swc_ecma_ast::Expr) -> Value {
|
||||
let symbol_iterator_opt = as_symbol_iterator(expr);
|
||||
|
||||
if let Some(symbol_iterator) = symbol_iterator_opt {
|
||||
return symbol_iterator;
|
||||
}
|
||||
|
||||
match expr {
|
||||
swc_ecma_ast::Expr::Lit(lit) => match value_from_literal(lit) {
|
||||
Ok(value) => value,
|
||||
Err(msg) => {
|
||||
self.internal_error(expr.span(), &format!("Failed to compile literal: {}", msg));
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::Expr::Array(array) => {
|
||||
let mut values = Vec::<Value>::new();
|
||||
|
||||
for item in &array.elems {
|
||||
values.push(match item {
|
||||
Some(item) => {
|
||||
if item.spread.is_some() {
|
||||
self.todo(expr.span(), "item.spread in static expression");
|
||||
return Value::String("(error)".to_string());
|
||||
}
|
||||
|
||||
self.expr(&item.expr)
|
||||
}
|
||||
None => Value::Void,
|
||||
});
|
||||
}
|
||||
|
||||
Value::Array(Box::new(Array { values }))
|
||||
}
|
||||
swc_ecma_ast::Expr::Object(object) => {
|
||||
let mut properties = Vec::<(Value, Value)>::new();
|
||||
|
||||
for prop in &object.props {
|
||||
let (key, value) = match prop {
|
||||
swc_ecma_ast::PropOrSpread::Spread(_) => {
|
||||
self.todo(prop.span(), "Static spread");
|
||||
return Value::String("(error)".to_string());
|
||||
}
|
||||
swc_ecma_ast::PropOrSpread::Prop(prop) => match &**prop {
|
||||
swc_ecma_ast::Prop::Shorthand(_) => {
|
||||
self.todo(prop.span(), "Static object shorthand");
|
||||
return Value::String("(error)".to_string());
|
||||
}
|
||||
swc_ecma_ast::Prop::KeyValue(kv) => {
|
||||
let key = match &kv.key {
|
||||
swc_ecma_ast::PropName::Ident(ident) => Value::String(ident.sym.to_string()),
|
||||
swc_ecma_ast::PropName::Str(str) => Value::String(str.value.to_string()),
|
||||
swc_ecma_ast::PropName::Num(num) => Value::Number(Number(num.value)),
|
||||
swc_ecma_ast::PropName::Computed(computed) => self.expr(&computed.expr),
|
||||
swc_ecma_ast::PropName::BigInt(bi) => Value::BigInt(bi.value.clone()),
|
||||
};
|
||||
|
||||
let value = self.expr(&kv.value);
|
||||
|
||||
(key, value)
|
||||
}
|
||||
swc_ecma_ast::Prop::Assign(_)
|
||||
| swc_ecma_ast::Prop::Getter(_)
|
||||
| swc_ecma_ast::Prop::Setter(_) => {
|
||||
self.todo(prop.span(), "This type of static prop");
|
||||
return Value::String("(error)".to_string());
|
||||
}
|
||||
swc_ecma_ast::Prop::Method(method) => {
|
||||
let key = match &method.key {
|
||||
swc_ecma_ast::PropName::Ident(ident) => Value::String(ident.sym.to_string()),
|
||||
_ => {
|
||||
self.todo(method.key.span(), "Static non-ident prop names");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
};
|
||||
|
||||
let fn_ident = match &method.key {
|
||||
swc_ecma_ast::PropName::Ident(ident) => Some(ident.clone()),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let fn_name = fn_ident.clone().map(|ident| ident.sym.to_string());
|
||||
|
||||
let p = match &fn_name {
|
||||
Some(name) => self.mc.allocate_defn(name),
|
||||
None => self.mc.allocate_defn_numbered("_anon"),
|
||||
};
|
||||
|
||||
let mut nested_defns = self.mc.compile_fn(
|
||||
p.clone(),
|
||||
fn_name.clone(),
|
||||
Functionish::Fn(fn_ident, method.function.clone()),
|
||||
);
|
||||
|
||||
self.mc.module.definitions.append(&mut nested_defns);
|
||||
|
||||
(key, Value::Pointer(p))
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
properties.push((key, value));
|
||||
}
|
||||
|
||||
Value::Object(Box::new(Object { properties }))
|
||||
}
|
||||
swc_ecma_ast::Expr::This(_)
|
||||
| swc_ecma_ast::Expr::Update(_)
|
||||
| swc_ecma_ast::Expr::Assign(_)
|
||||
| swc_ecma_ast::Expr::SuperProp(_)
|
||||
| swc_ecma_ast::Expr::Call(_)
|
||||
| swc_ecma_ast::Expr::New(_) => {
|
||||
self.todo(expr.span(), "This type of static expr");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::Expr::Ident(ident) => match self
|
||||
.mc
|
||||
.scope_analysis
|
||||
.lookup(&Ident::from_swc_ident(ident))
|
||||
.map(|name| name.value.clone())
|
||||
{
|
||||
Some(Value::Pointer(p)) => self
|
||||
.mc
|
||||
.constants_map
|
||||
.get(&p)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Value::Pointer(p)),
|
||||
Some(value) => value,
|
||||
None => {
|
||||
self.internal_error(ident.span, "Identifier not found");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::Expr::Fn(fn_) => {
|
||||
let fn_name = fn_.ident.clone().map(|ident| ident.sym.to_string());
|
||||
|
||||
let p = match &fn_name {
|
||||
Some(name) => self.mc.allocate_defn(name),
|
||||
None => self.mc.allocate_defn_numbered("_anon"),
|
||||
};
|
||||
|
||||
let mut fn_defns = self.mc.compile_fn(
|
||||
p.clone(),
|
||||
fn_name,
|
||||
Functionish::Fn(fn_.ident.clone(), fn_.function.clone()),
|
||||
);
|
||||
|
||||
self.mc.module.definitions.append(&mut fn_defns);
|
||||
|
||||
Value::Pointer(p)
|
||||
}
|
||||
swc_ecma_ast::Expr::Arrow(arrow) => {
|
||||
let p = self.mc.allocate_defn_numbered("_anon");
|
||||
let mut fn_defns = self
|
||||
.mc
|
||||
.compile_fn(p.clone(), None, Functionish::Arrow(arrow.clone()));
|
||||
self.mc.module.definitions.append(&mut fn_defns);
|
||||
|
||||
Value::Pointer(p)
|
||||
}
|
||||
swc_ecma_ast::Expr::Class(class) => Value::Pointer(self.mc.compile_class(
|
||||
None,
|
||||
class.ident.as_ref(),
|
||||
&class.class,
|
||||
)),
|
||||
swc_ecma_ast::Expr::TaggedTpl(_)
|
||||
| swc_ecma_ast::Expr::Yield(_)
|
||||
| swc_ecma_ast::Expr::MetaProp(_)
|
||||
| swc_ecma_ast::Expr::Await(_)
|
||||
| swc_ecma_ast::Expr::JSXMember(_)
|
||||
| swc_ecma_ast::Expr::JSXNamespacedName(_)
|
||||
| swc_ecma_ast::Expr::JSXEmpty(_)
|
||||
| swc_ecma_ast::Expr::JSXElement(_)
|
||||
| swc_ecma_ast::Expr::JSXFragment(_)
|
||||
| swc_ecma_ast::Expr::TsInstantiation(_)
|
||||
| swc_ecma_ast::Expr::PrivateName(_)
|
||||
| swc_ecma_ast::Expr::OptChain(_)
|
||||
| swc_ecma_ast::Expr::Invalid(_)
|
||||
| swc_ecma_ast::Expr::Member(_)
|
||||
| swc_ecma_ast::Expr::Cond(_) => {
|
||||
self.todo(expr.span(), "This type of static expr");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::Expr::Unary(unary) => match unary.op {
|
||||
swc_ecma_ast::UnaryOp::Minus => match self.expr(&unary.arg) {
|
||||
Value::Number(Number(x)) => Value::Number(Number(-x)),
|
||||
Value::BigInt(bi) => Value::BigInt(-bi),
|
||||
_ => {
|
||||
self.todo(unary.span, "Static eval for this case");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::UnaryOp::Plus => match self.expr(&unary.arg) {
|
||||
Value::Number(Number(x)) => Value::Number(Number(x)),
|
||||
Value::BigInt(bi) => Value::BigInt(bi),
|
||||
_ => {
|
||||
self.todo(unary.span, "Static eval for this case");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::UnaryOp::Bang => {
|
||||
self.todo(expr.span(), "Static eval of ! operator");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::UnaryOp::Tilde => match self.expr(&unary.arg) {
|
||||
Value::Number(Number(x)) => Value::Number(Number(!to_i32(x) as f64)),
|
||||
Value::BigInt(bi) => Value::BigInt(!bi),
|
||||
_ => {
|
||||
self.todo(unary.span, "Static eval for this case");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::UnaryOp::TypeOf
|
||||
| swc_ecma_ast::UnaryOp::Void
|
||||
| swc_ecma_ast::UnaryOp::Delete => {
|
||||
self.todo(unary.span, "Static eval for this case");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
},
|
||||
swc_ecma_ast::Expr::Bin(_) => {
|
||||
self.todo(expr.span(), "Static eval of binary operator");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::Expr::Seq(seq) => {
|
||||
let mut last = Value::Void;
|
||||
|
||||
for expr in &seq.exprs {
|
||||
last = self.expr(expr);
|
||||
}
|
||||
|
||||
last
|
||||
}
|
||||
swc_ecma_ast::Expr::Tpl(tpl) => 'b: {
|
||||
let len = tpl.exprs.len();
|
||||
assert_eq!(tpl.quasis.len(), len + 1);
|
||||
|
||||
if len == 0 {
|
||||
break 'b Value::String(tpl.quasis[0].raw.to_string());
|
||||
}
|
||||
|
||||
self.todo(tpl.span, "Static eval of template literal");
|
||||
Value::String("(error)".to_string())
|
||||
}
|
||||
swc_ecma_ast::Expr::Paren(paren) => self.expr(&paren.expr),
|
||||
swc_ecma_ast::Expr::TsTypeAssertion(tta) => self.expr(&tta.expr),
|
||||
swc_ecma_ast::Expr::TsConstAssertion(tca) => self.expr(&tca.expr),
|
||||
swc_ecma_ast::Expr::TsNonNull(tnn) => self.expr(&tnn.expr),
|
||||
swc_ecma_ast::Expr::TsAs(ta) => self.expr(&ta.expr),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn as_symbol_iterator(expr: &swc_ecma_ast::Expr) -> Option<Value> {
|
||||
let member_expr = match expr {
|
||||
swc_ecma_ast::Expr::Member(member_expr) => member_expr,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
match &*member_expr.obj {
|
||||
swc_ecma_ast::Expr::Ident(ident) => {
|
||||
if ident.sym.to_string() != "Symbol" {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
match &member_expr.prop {
|
||||
swc_ecma_ast::MemberProp::Ident(ident) => {
|
||||
if ident.sym.to_string() != "iterator" {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
|
||||
Some(Value::Builtin(Builtin {
|
||||
name: "SymbolIterator".to_string(),
|
||||
}))
|
||||
}
|
||||
Reference in New Issue
Block a user