Skip to content

Commit

Permalink
Merge pull request #192 from wechat-miniprogram/fix-template-literal-…
Browse files Browse the repository at this point in the history
…update-path-tree

fix: template literal update path tree calculation (#141)
  • Loading branch information
LastLeaf authored Aug 23, 2024
2 parents 263ade6 + a900d96 commit c937dba
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 43 deletions.
34 changes: 29 additions & 5 deletions glass-easel-template-compiler/src/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ const RUNTIME_ITEMS: [(&'static str, &'static str); 4] = [
("P", "function(a){return typeof a==='function'?a:()=>{}}"),
];

const EXTRA_RUNTIME_ITEMS: [(&'static str, &'static str); 2] = [
("a", "function(a){for(var i=0;i<a.length;i++)if(a[i])return a}"),
("b", "function(b){var a=Object.values(b);for(var i=0;i<a.length;i++)if(a[i])return a}"),
];

const WXS_RUNTIME_ITEMS: [(&'static str, &'static str); 1] = [
("A", "function(a){return a}"),
// "B" "C" are preserved
];

const WXS_RUNTIME: &'static str = r#"
var D = (() => {
var modules = Object.create(null);
Expand Down Expand Up @@ -98,21 +108,35 @@ fn runtime_fns<W: std::fmt::Write>(
Ok(())
})?;
}
w.expr_stmt(|w| {
write!(w, "var Q={{")?;
for (i, (k, v)) in EXTRA_RUNTIME_ITEMS.iter().enumerate() {
if i > 0 {
write!(w, ",")?;
}
write!(w, "{}:{}", k, v)?;
}
if need_wxs_runtime {
for (k, v) in WXS_RUNTIME_ITEMS.iter() {
write!(w, ",{}:{}", k, v)?;
}
}
write!(w, "}}")?;
Ok(())
})?;
if need_wxs_runtime {
w.expr_stmt(|w| {
write!(w, "{}", WXS_RUNTIME)?;
Ok(())
})?;
w.expr_stmt(|w| {
write!(w, "var Q={{A:(x)=>x,B:(x)=>x}}")?;
Ok(())
})?;
}
Ok(())
}

fn runtime_var_list() -> Vec<&'static str> {
RUNTIME_ITEMS.iter().map(|(k, _)| *k).collect()
let mut ret: Vec<_> = RUNTIME_ITEMS.iter().map(|(k, _)| *k).collect();
ret.push("Q");
ret
}

/// A general template error.
Expand Down
45 changes: 28 additions & 17 deletions glass-easel-template-compiler/src/proc_gen/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl PathSliceList {
list: &Vec<Self>,
w: &mut W,
scopes: &Vec<ScopeVar>,
is_template_data: bool,
) -> Result<(), TmplError> {
if list.len() > 0 {
let need_paren = list.len() > 1;
Expand All @@ -48,7 +49,7 @@ impl PathSliceList {
if i > 0 {
write!(w, "||")?;
}
write!(w, "{}", this.to_path_analysis_str(scopes)?)?;
write!(w, "{}", this.to_path_analysis_str(scopes, is_template_data)?)?;
}
if need_paren {
write!(w, ")")?;
Expand Down Expand Up @@ -209,7 +210,7 @@ impl PathSliceList {
Ok(())
}

fn to_path_analysis_str(&self, scopes: &Vec<ScopeVar>) -> Result<String, TmplError> {
fn to_path_analysis_str(&self, scopes: &Vec<ScopeVar>, is_template_data: bool) -> Result<String, TmplError> {
let mut ret = String::new();
for path_slice in self.0.iter() {
match path_slice {
Expand All @@ -235,7 +236,7 @@ impl PathSliceList {
for (key, sub_pas_str, sub_p) in v.iter() {
let mut sub_s = String::new();
let sub_pas_str =
sub_pas_str.to_path_analysis_str(sub_p, &mut sub_s, scopes)?;
sub_pas_str.to_path_analysis_str(sub_p, &mut sub_s, scopes, is_template_data)?;
if let Some(_) = sub_pas_str {
match key {
Some(key) => {
Expand All @@ -254,47 +255,55 @@ impl PathSliceList {
}
}
}
if need_object_assign {
write!(ret, "{}Object.assign({{{}}})", prepend, s)?;
if is_template_data {
if need_object_assign {
write!(ret, "{}Object.assign({{{}}})", prepend, s)?;
} else {
write!(ret, "{}{{{}}}", prepend, s)?;
}
} else {
write!(ret, "{}{{{}}}", prepend, s)?;
if need_object_assign {
write!(ret, "{}Q.b(Object.assign({{{}}}))", prepend, s)?;
} else {
write!(ret, "{}Q.b({{{}}})", prepend, s)?;
}
}
}
PathSlice::CombineArr(v, spread) => {
for (sub_pas, sub_p) in spread.iter() {
let mut sub_s = String::new();
let sub_pas_str =
sub_pas.to_path_analysis_str(sub_p, &mut sub_s, scopes)?;
sub_pas.to_path_analysis_str(sub_p, &mut sub_s, scopes, is_template_data)?;
if let Some(_) = sub_pas_str {
write!(ret, "({})===true||", sub_s)?;
write!(ret, "({})!==undefined||", sub_s)?;
}
}
write!(ret, "[")?;
write!(ret, "Q.a([")?;
let mut next_need_comma_sep = false;
for (sub_pas, sub_p) in v.iter() {
if next_need_comma_sep {
write!(ret, ",")?;
}
let mut s = String::new();
let sub_pas_str = sub_pas.to_path_analysis_str(sub_p, &mut s, scopes)?;
let sub_pas_str = sub_pas.to_path_analysis_str(sub_p, &mut s, scopes, is_template_data)?;
if let Some(_) = sub_pas_str {
write!(ret, "{}", s)?;
next_need_comma_sep = true;
}
}
write!(ret, "]")?;
write!(ret, "])")?;
}
PathSlice::Condition(cond, (true_pas, true_p), (false_pas, false_p)) => {
write!(ret, "({}?", cond)?;
write!(ret, "({}?", cond)?; // FIXME `cond` itself should calc its path slices?
if true_pas
.to_path_analysis_str(true_p, &mut ret, scopes)?
.to_path_analysis_str(true_p, &mut ret, scopes, is_template_data)?
.is_none()
{
write!(ret, "undefined")?;
}
write!(ret, ":")?;
if false_pas
.to_path_analysis_str(false_p, &mut ret, scopes)?
.to_path_analysis_str(false_p, &mut ret, scopes, is_template_data)?
.is_none()
{
write!(ret, "undefined")?;
Expand All @@ -319,11 +328,12 @@ impl PathAnalysisState {
sub_p: &Vec<PathSliceList>,
w: &mut W,
scopes: &Vec<ScopeVar>,
is_template_data: bool,
) -> Result<Option<()>, TmplError> {
PathSliceList::to_path_analysis_str_group_prefix(&sub_p, w, scopes)?;
PathSliceList::to_path_analysis_str_group_prefix(&sub_p, w, scopes, is_template_data)?;
let ret = match self {
PathAnalysisState::InPath(path_slices) => {
let s = path_slices.to_path_analysis_str(scopes)?;
let s = path_slices.to_path_analysis_str(scopes, is_template_data)?;
write!(w, "{}", s)?;
Some(())
}
Expand Down Expand Up @@ -1228,8 +1238,9 @@ impl ExpressionProcGen {
&self,
w: &mut JsExprWriter<W>,
scopes: &Vec<ScopeVar>,
is_template_data: bool,
) -> Result<(), TmplError> {
let pas_str = self.pas.to_path_analysis_str(&self.sub_p, w, scopes)?;
let pas_str = self.pas.to_path_analysis_str(&self.sub_p, w, scopes, is_template_data)?;
if let Some(_) = pas_str {
// empty
} else {
Expand Down
20 changes: 10 additions & 10 deletions glass-easel-template-compiler/src/proc_gen/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ impl Node {
let p = expression.to_proc_gen_prepare(w, scopes)?;
w.expr_stmt(|w| {
write!(w, r#"C||K||"#)?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, false)?;
write!(w, r#"?T(Y("#)?;
p.value_expr(w)?;
write!(w, r#")"#)?;
Expand Down Expand Up @@ -952,7 +952,7 @@ impl Element {
key => gen_lit_str(key),
}
)?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, false)?;
write!(w, ":undefined,")?;
if lvalue_path_from_data_scope.is_some() {
p.lvalue_path(w, scopes, None)?;
Expand Down Expand Up @@ -1013,7 +1013,7 @@ impl Element {
)?;
p.value_expr(w)?;
write!(w, ",K||(U?")?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, true)?;
write!(w, ":undefined)).C(C,T,E,B,F,S,J)")?;
Ok(())
})
Expand Down Expand Up @@ -1070,7 +1070,7 @@ impl Element {
}
StaticStrOrProcGen::Dynamic(p) => {
write!(w, r#"C||K||"#)?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, false)?;
write!(w, r#"?Y("#)?;
p.value_expr(w)?;
write!(w, "):undefined")?;
Expand Down Expand Up @@ -1108,7 +1108,7 @@ impl Element {
let p = expression.to_proc_gen_prepare(w, scopes)?;
w.expr_stmt(|w| {
write!(w, "if(C||K||")?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, false)?;
write!(w, ")R.l(N,{},", gen_lit_str(name))?;
p.value_expr(w)?;
if attr_name_maybe_event_binding(name) {
Expand Down Expand Up @@ -1161,7 +1161,7 @@ fn write_attribute_value<W: Write>(
let p = expression.to_proc_gen_prepare(w, scopes)?;
w.expr_stmt(|w| {
write!(w, "if(C||K||")?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, false)?;
write!(w, "){}(N,", method_name)?;
p.value_expr(w)?;
write!(w, ")")?;
Expand Down Expand Up @@ -1247,7 +1247,7 @@ impl Attribute {
let p = expression.to_proc_gen_prepare(w, scopes)?;
w.expr_stmt(|w| {
write!(w, "if(C||K||")?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, false)?;
write!(w, "){}(N,{},", method_name, gen_lit_str(&self.name.name))?;
p.value_expr(w)?;
write!(w, ")")?;
Expand Down Expand Up @@ -1303,7 +1303,7 @@ impl Attribute {
let p = expression.to_proc_gen_prepare(w, scopes)?;
w.expr_stmt(|w| {
write!(w, "if(C||K||")?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, false)?;
write!(w, ")O(N,{},", attr_name)?;
p.value_expr(w)?;
if self.is_model {
Expand Down Expand Up @@ -1370,7 +1370,7 @@ impl Attribute {
let p = expression.to_proc_gen_prepare(w, scopes)?;
w.expr_stmt(|w| {
write!(w, "if(C||K||")?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, false)?;
write!(w, ")R.p(N,{},", attr_name)?;
p.value_expr(w)?;
if p.has_script_lvalue_path(scopes) {
Expand Down Expand Up @@ -1433,7 +1433,7 @@ impl EventBinding {
let p = expression.to_proc_gen_prepare(w, scopes)?;
w.expr_stmt(|w| {
write!(w, "if(C||K||")?;
p.lvalue_state_expr(w, scopes)?;
p.lvalue_state_expr(w, scopes, false)?;
write!(w, ")R.v(N,{},", gen_lit_str(&self.name.name),)?;
p.value_expr(w)?;
write!(
Expand Down
6 changes: 1 addition & 5 deletions glass-easel/tests/base/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,8 @@ export const tmpl = (src: string, options?: TemplateOptions, filterFuncs?: Filte
let genObjectSrc = `return ${group.getTmplGenObjectGroups()}`
group.free()
if (filterFuncs !== undefined) {
const A = filterFuncs.A || ((x) => x)
const C = filterFuncs.C || 'undefined'
genObjectSrc = genObjectSrc.replace(
'var Q={A:(x)=>x,B:(x)=>x}',
`var Q={A:${A.toString()},C:${C.toString()}}`,
)
genObjectSrc = genObjectSrc.replace('var Q={', `var Q={C:${C.toString()},`)
}
// console.info(genObjectSrc)
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
Expand Down
Loading

0 comments on commit c937dba

Please sign in to comment.