|
|
@ -2,8 +2,10 @@ |
|
|
|
|
|
|
|
|
|
|
|
use crate::{ |
|
|
|
use crate::{ |
|
|
|
block_to_string, |
|
|
|
block_to_string, |
|
|
|
expression::{operator::assign::AssignTarget, Expression, RESERVED_IDENTIFIERS_STRICT}, |
|
|
|
expression::{ |
|
|
|
function::Function, |
|
|
|
operator::assign::{AssignOp, AssignTarget}, |
|
|
|
|
|
|
|
Expression, RESERVED_IDENTIFIERS_STRICT, |
|
|
|
|
|
|
|
}, |
|
|
|
join_nodes, |
|
|
|
join_nodes, |
|
|
|
pattern::{ObjectPattern, ObjectPatternElement}, |
|
|
|
pattern::{ObjectPattern, ObjectPatternElement}, |
|
|
|
property::{MethodDefinition, PropertyDefinition, PropertyName}, |
|
|
|
property::{MethodDefinition, PropertyDefinition, PropertyName}, |
|
|
@ -52,7 +54,6 @@ impl ObjectLiteral { |
|
|
|
#[must_use] |
|
|
|
#[must_use] |
|
|
|
pub fn to_pattern(&self, strict: bool) -> Option<ObjectPattern> { |
|
|
|
pub fn to_pattern(&self, strict: bool) -> Option<ObjectPattern> { |
|
|
|
let mut bindings = Vec::new(); |
|
|
|
let mut bindings = Vec::new(); |
|
|
|
let mut excluded_keys = Vec::new(); |
|
|
|
|
|
|
|
for (i, property) in self.properties.iter().enumerate() { |
|
|
|
for (i, property) in self.properties.iter().enumerate() { |
|
|
|
match property { |
|
|
|
match property { |
|
|
|
PropertyDefinition::IdentifierReference(ident) if strict && *ident == Sym::EVAL => { |
|
|
|
PropertyDefinition::IdentifierReference(ident) if strict && *ident == Sym::EVAL => { |
|
|
@ -63,7 +64,6 @@ impl ObjectLiteral { |
|
|
|
return None; |
|
|
|
return None; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
excluded_keys.push(*ident); |
|
|
|
|
|
|
|
bindings.push(ObjectPatternElement::SingleName { |
|
|
|
bindings.push(ObjectPatternElement::SingleName { |
|
|
|
ident: *ident, |
|
|
|
ident: *ident, |
|
|
|
name: PropertyName::Literal(ident.sym()), |
|
|
|
name: PropertyName::Literal(ident.sym()), |
|
|
@ -81,7 +81,6 @@ impl ObjectLiteral { |
|
|
|
return None; |
|
|
|
return None; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
excluded_keys.push(*ident); |
|
|
|
|
|
|
|
bindings.push(ObjectPatternElement::SingleName { |
|
|
|
bindings.push(ObjectPatternElement::SingleName { |
|
|
|
ident: *ident, |
|
|
|
ident: *ident, |
|
|
|
name: PropertyName::Literal(*name), |
|
|
|
name: PropertyName::Literal(*name), |
|
|
@ -111,7 +110,11 @@ impl ObjectLiteral { |
|
|
|
default_init: None, |
|
|
|
default_init: None, |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
(_, Expression::Assign(assign)) => match assign.lhs() { |
|
|
|
(_, Expression::Assign(assign)) => { |
|
|
|
|
|
|
|
if assign.op() != AssignOp::Assign { |
|
|
|
|
|
|
|
return None; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
match assign.lhs() { |
|
|
|
AssignTarget::Identifier(ident) => { |
|
|
|
AssignTarget::Identifier(ident) => { |
|
|
|
if let Some(name) = name.literal() { |
|
|
|
if let Some(name) = name.literal() { |
|
|
|
if name == *ident { |
|
|
|
if name == *ident { |
|
|
@ -121,7 +124,6 @@ impl ObjectLiteral { |
|
|
|
if strict && RESERVED_IDENTIFIERS_STRICT.contains(&name) { |
|
|
|
if strict && RESERVED_IDENTIFIERS_STRICT.contains(&name) { |
|
|
|
return None; |
|
|
|
return None; |
|
|
|
} |
|
|
|
} |
|
|
|
excluded_keys.push(*ident); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
bindings.push(ObjectPatternElement::SingleName { |
|
|
|
bindings.push(ObjectPatternElement::SingleName { |
|
|
|
ident: *ident, |
|
|
|
ident: *ident, |
|
|
@ -146,7 +148,8 @@ impl ObjectLiteral { |
|
|
|
default_init: Some(assign.rhs().clone()), |
|
|
|
default_init: Some(assign.rhs().clone()), |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
(_, Expression::PropertyAccess(access)) => { |
|
|
|
(_, Expression::PropertyAccess(access)) => { |
|
|
|
bindings.push(ObjectPatternElement::AssignmentPropertyAccess { |
|
|
|
bindings.push(ObjectPatternElement::AssignmentPropertyAccess { |
|
|
|
name: name.clone(), |
|
|
|
name: name.clone(), |
|
|
@ -166,15 +169,11 @@ impl ObjectLiteral { |
|
|
|
PropertyDefinition::SpreadObject(spread) => { |
|
|
|
PropertyDefinition::SpreadObject(spread) => { |
|
|
|
match spread { |
|
|
|
match spread { |
|
|
|
Expression::Identifier(ident) => { |
|
|
|
Expression::Identifier(ident) => { |
|
|
|
bindings.push(ObjectPatternElement::RestProperty { |
|
|
|
bindings.push(ObjectPatternElement::RestProperty { ident: *ident }); |
|
|
|
ident: *ident, |
|
|
|
|
|
|
|
excluded_keys: excluded_keys.clone(), |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
Expression::PropertyAccess(access) => { |
|
|
|
Expression::PropertyAccess(access) => { |
|
|
|
bindings.push(ObjectPatternElement::AssignmentRestPropertyAccess { |
|
|
|
bindings.push(ObjectPatternElement::AssignmentRestPropertyAccess { |
|
|
|
access: access.clone(), |
|
|
|
access: access.clone(), |
|
|
|
excluded_keys: excluded_keys.clone(), |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
_ => return None, |
|
|
|
_ => return None, |
|
|
@ -212,12 +211,6 @@ impl ToIndentedString for ObjectLiteral { |
|
|
|
format!("{indentation}{},\n", interner.resolve_expect(ident.sym())) |
|
|
|
format!("{indentation}{},\n", interner.resolve_expect(ident.sym())) |
|
|
|
} |
|
|
|
} |
|
|
|
PropertyDefinition::Property(key, value) => { |
|
|
|
PropertyDefinition::Property(key, value) => { |
|
|
|
let value = if let Expression::Function(f) = value { |
|
|
|
|
|
|
|
Function::new(None, f.parameters().clone(), f.body().clone()).into() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
value.clone() |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format!( |
|
|
|
format!( |
|
|
|
"{indentation}{}: {},\n", |
|
|
|
"{indentation}{}: {},\n", |
|
|
|
key.to_interned_string(interner), |
|
|
|
key.to_interned_string(interner), |
|
|
@ -229,13 +222,21 @@ impl ToIndentedString for ObjectLiteral { |
|
|
|
} |
|
|
|
} |
|
|
|
PropertyDefinition::MethodDefinition(key, method) => { |
|
|
|
PropertyDefinition::MethodDefinition(key, method) => { |
|
|
|
format!( |
|
|
|
format!( |
|
|
|
"{indentation}{}{}({}) {},\n", |
|
|
|
"{indentation}{}({}) {},\n", |
|
|
|
match &method { |
|
|
|
match &method { |
|
|
|
MethodDefinition::Get(_) => "get ", |
|
|
|
MethodDefinition::Get(_) => |
|
|
|
MethodDefinition::Set(_) => "set ", |
|
|
|
format!("get {}", key.to_interned_string(interner)), |
|
|
|
_ => "", |
|
|
|
MethodDefinition::Set(_) => |
|
|
|
|
|
|
|
format!("set {}", key.to_interned_string(interner)), |
|
|
|
|
|
|
|
MethodDefinition::Ordinary(_) => |
|
|
|
|
|
|
|
key.to_interned_string(interner).to_string(), |
|
|
|
|
|
|
|
MethodDefinition::Generator(_) => |
|
|
|
|
|
|
|
format!("*{}", key.to_interned_string(interner)), |
|
|
|
|
|
|
|
MethodDefinition::AsyncGenerator(_) => |
|
|
|
|
|
|
|
format!("async *{}", key.to_interned_string(interner)), |
|
|
|
|
|
|
|
MethodDefinition::Async(_) => |
|
|
|
|
|
|
|
format!("async {}", key.to_interned_string(interner)), |
|
|
|
}, |
|
|
|
}, |
|
|
|
key.to_interned_string(interner), |
|
|
|
|
|
|
|
match &method { |
|
|
|
match &method { |
|
|
|
MethodDefinition::Get(expression) |
|
|
|
MethodDefinition::Get(expression) |
|
|
|
| MethodDefinition::Set(expression) |
|
|
|
| MethodDefinition::Set(expression) |
|
|
|