From 48fd851fb78643eb45f63b939b902b47b77bc2a1 Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Fri, 7 Jul 2023 17:07:09 +1000 Subject: [PATCH] Use ScopeAnalysis in static eval --- .../src/compile_enum_value.rs | 4 ++- valuescript_compiler/src/function_compiler.rs | 2 +- valuescript_compiler/src/module_compiler.rs | 26 +++++++++-------- valuescript_compiler/src/static_eval_expr.rs | 29 ++++++++++--------- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/valuescript_compiler/src/compile_enum_value.rs b/valuescript_compiler/src/compile_enum_value.rs index bce2bda..82acc30 100644 --- a/valuescript_compiler/src/compile_enum_value.rs +++ b/valuescript_compiler/src/compile_enum_value.rs @@ -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, ) -> 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); diff --git a/valuescript_compiler/src/function_compiler.rs b/valuescript_compiler/src/function_compiler.rs index 89626a2..cba5870 100644 --- a/valuescript_compiler/src/function_compiler.rs +++ b/valuescript_compiler/src/function_compiler.rs @@ -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, diff --git a/valuescript_compiler/src/module_compiler.rs b/valuescript_compiler/src/module_compiler.rs index 5dc112d..b4d48b5 100644 --- a/valuescript_compiler/src/module_compiler.rs +++ b/valuescript_compiler/src/module_compiler.rs @@ -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; diff --git a/valuescript_compiler/src/static_eval_expr.rs b/valuescript_compiler/src/static_eval_expr.rs index 052943f..45ab4d8 100644 --- a/valuescript_compiler/src/static_eval_expr.rs +++ b/valuescript_compiler/src/static_eval_expr.rs @@ -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 { +pub fn static_eval_expr(sa: &ScopeAnalysis, expr: &swc_ecma_ast::Expr) -> Option { 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 { 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 { 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 { 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 { 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 { 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 { 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), } }