Use ScopeAnalysis in static eval

This commit is contained in:
Andrew Morris
2023-07-07 17:07:09 +10:00
parent 581965e01b
commit 48fd851fb7
4 changed files with 33 additions and 28 deletions

View File

@@ -2,11 +2,13 @@ use swc_common::Spanned;
use crate::{
asm::{Number, Object, Value},
scope_analysis::ScopeAnalysis,
static_eval_expr::static_eval_expr,
Diagnostic, DiagnosticLevel,
};
pub fn compile_enum_value(
sa: &ScopeAnalysis,
ts_enum: &swc_ecma_ast::TsEnumDecl,
diagnostics: &mut Vec<Diagnostic>,
) -> Value {
@@ -20,7 +22,7 @@ pub fn compile_enum_value(
};
let init_value = match &member.init {
Some(init) => match static_eval_expr(init) {
Some(init) => match static_eval_expr(sa, init) {
Some(init_value) => match init_value {
Value::Number(Number(n)) => {
next_default_id = Some(n + 1.0);

View File

@@ -1253,7 +1253,7 @@ impl FunctionCompiler {
}
};
let enum_value = compile_enum_value(ts_enum, &mut self.diagnostics);
let enum_value = compile_enum_value(&self.scope_analysis, ts_enum, &mut self.diagnostics);
self.definitions.push(Definition {
pointer,

View File

@@ -205,7 +205,7 @@ impl ModuleCompiler {
.scope_analysis
.lookup(ident)
.map(|name| name.value.clone()),
expr => static_eval_expr(expr),
expr => static_eval_expr(&self.scope_analysis, expr),
};
match value {
@@ -298,7 +298,7 @@ impl ModuleCompiler {
};
if let (Some(ident), Some(init)) = (ident, init) {
let value = match static_eval_expr(init) {
let value = match static_eval_expr(&self.scope_analysis, init) {
Some(value) => value,
None => {
self.todo(
@@ -407,7 +407,7 @@ impl ModuleCompiler {
));
}
let enum_value = compile_enum_value(ts_enum, &mut self.diagnostics);
let enum_value = compile_enum_value(&self.scope_analysis, ts_enum, &mut self.diagnostics);
self.module.definitions.push(Definition {
pointer,
@@ -918,16 +918,18 @@ impl ModuleCompiler {
Method(method) => {
let name = match &method.key {
swc_ecma_ast::PropName::Ident(ident) => Value::String(ident.sym.to_string()),
swc_ecma_ast::PropName::Computed(computed) => match static_eval_expr(&computed.expr) {
None => {
self.todo(
computed.span,
"Couldn't statically evaluate computed prop name",
);
continue;
swc_ecma_ast::PropName::Computed(computed) => {
match static_eval_expr(&self.scope_analysis, &computed.expr) {
None => {
self.todo(
computed.span,
"Couldn't statically evaluate computed prop name",
);
continue;
}
Some(value) => value,
}
Some(value) => value,
},
}
_ => {
self.todo(method.span, "Non-identifier method name");
continue;

View File

@@ -3,9 +3,10 @@ use valuescript_vm::operations::to_i32;
use crate::{
asm::{Array, Builtin, Number, Object, Value},
expression_compiler::value_from_literal,
scope_analysis::ScopeAnalysis,
};
pub fn static_eval_expr(expr: &swc_ecma_ast::Expr) -> Option<Value> {
pub fn static_eval_expr(sa: &ScopeAnalysis, expr: &swc_ecma_ast::Expr) -> Option<Value> {
let symbol_iterator_opt = as_symbol_iterator(expr);
if symbol_iterator_opt.is_some() {
@@ -27,7 +28,7 @@ pub fn static_eval_expr(expr: &swc_ecma_ast::Expr) -> Option<Value> {
return None;
}
static_eval_expr(&item.expr)?
static_eval_expr(sa, &item.expr)?
}
None => Value::Void,
});
@@ -48,11 +49,11 @@ pub fn static_eval_expr(expr: &swc_ecma_ast::Expr) -> Option<Value> {
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) => static_eval_expr(&computed.expr)?,
swc_ecma_ast::PropName::Computed(computed) => static_eval_expr(sa, &computed.expr)?,
swc_ecma_ast::PropName::BigInt(bi) => Value::BigInt(bi.value.clone()),
};
let value = static_eval_expr(&kv.value)?;
let value = static_eval_expr(sa, &kv.value)?;
(key, value)
}
@@ -75,7 +76,7 @@ pub fn static_eval_expr(expr: &swc_ecma_ast::Expr) -> Option<Value> {
swc_ecma_ast::Expr::SuperProp(_) => None,
swc_ecma_ast::Expr::Call(_) => None,
swc_ecma_ast::Expr::New(_) => None,
swc_ecma_ast::Expr::Ident(_) => None,
swc_ecma_ast::Expr::Ident(ident) => sa.lookup(ident).map(|name| name.value.clone()),
swc_ecma_ast::Expr::TaggedTpl(_) => None,
swc_ecma_ast::Expr::Arrow(_) => None,
swc_ecma_ast::Expr::Class(_) => None,
@@ -94,18 +95,18 @@ pub fn static_eval_expr(expr: &swc_ecma_ast::Expr) -> Option<Value> {
swc_ecma_ast::Expr::Member(_) => None,
swc_ecma_ast::Expr::Cond(_) => None,
swc_ecma_ast::Expr::Unary(unary) => match unary.op {
swc_ecma_ast::UnaryOp::Minus => match static_eval_expr(&unary.arg)? {
swc_ecma_ast::UnaryOp::Minus => match static_eval_expr(sa, &unary.arg)? {
Value::Number(Number(x)) => Some(Value::Number(Number(-x))),
Value::BigInt(bi) => Some(Value::BigInt(-bi)),
_ => None,
},
swc_ecma_ast::UnaryOp::Plus => match static_eval_expr(&unary.arg)? {
swc_ecma_ast::UnaryOp::Plus => match static_eval_expr(sa, &unary.arg)? {
Value::Number(Number(x)) => Some(Value::Number(Number(x))),
Value::BigInt(bi) => Some(Value::BigInt(bi)),
_ => None,
},
swc_ecma_ast::UnaryOp::Bang => None,
swc_ecma_ast::UnaryOp::Tilde => match static_eval_expr(&unary.arg)? {
swc_ecma_ast::UnaryOp::Tilde => match static_eval_expr(sa, &unary.arg)? {
Value::Number(Number(x)) => Some(Value::Number(Number(!to_i32(x) as f64))),
Value::BigInt(bi) => Some(Value::BigInt(!bi)),
_ => None,
@@ -119,7 +120,7 @@ pub fn static_eval_expr(expr: &swc_ecma_ast::Expr) -> Option<Value> {
let mut last = Value::Void;
for expr in &seq.exprs {
last = static_eval_expr(expr)?;
last = static_eval_expr(sa, expr)?;
}
Some(last)
@@ -134,11 +135,11 @@ pub fn static_eval_expr(expr: &swc_ecma_ast::Expr) -> Option<Value> {
None // TODO
}
swc_ecma_ast::Expr::Paren(paren) => static_eval_expr(&paren.expr),
swc_ecma_ast::Expr::TsTypeAssertion(tta) => static_eval_expr(&tta.expr),
swc_ecma_ast::Expr::TsConstAssertion(tca) => static_eval_expr(&tca.expr),
swc_ecma_ast::Expr::TsNonNull(tnn) => static_eval_expr(&tnn.expr),
swc_ecma_ast::Expr::TsAs(ta) => static_eval_expr(&ta.expr),
swc_ecma_ast::Expr::Paren(paren) => static_eval_expr(sa, &paren.expr),
swc_ecma_ast::Expr::TsTypeAssertion(tta) => static_eval_expr(sa, &tta.expr),
swc_ecma_ast::Expr::TsConstAssertion(tca) => static_eval_expr(sa, &tca.expr),
swc_ecma_ast::Expr::TsNonNull(tnn) => static_eval_expr(sa, &tnn.expr),
swc_ecma_ast::Expr::TsAs(ta) => static_eval_expr(sa, &ta.expr),
}
}