clone whole AST before compiling

also use klona-based clone() in other places instead of JSON.parse(JSON.stringify(...))
pull/6148/head
Conduitry 6 years ago
parent 6ec9c00976
commit 2aaf663c73

@ -32,6 +32,7 @@ import { is_reserved_keyword } from './utils/reserved_keywords';
import { apply_preprocessor_sourcemap } from '../utils/mapped_code'; import { apply_preprocessor_sourcemap } from '../utils/mapped_code';
import Element from './nodes/Element'; import Element from './nodes/Element';
import { DecodedSourceMap, RawSourceMap } from '@ampproject/remapping/dist/types/types'; import { DecodedSourceMap, RawSourceMap } from '@ampproject/remapping/dist/types/types';
import { clone } from '../utils/clone';
interface ComponentOptions { interface ComponentOptions {
namespace?: string; namespace?: string;
@ -116,12 +117,12 @@ export default class Component {
// the instance JS gets mutated, so we park // the instance JS gets mutated, so we park
// a copy here for later. TODO this feels gross // a copy here for later. TODO this feels gross
this.original_ast = { this.original_ast = clone({
html: ast.html, html: ast.html,
css: ast.css, css: ast.css,
instance: ast.instance && JSON.parse(JSON.stringify(ast.instance)), instance: ast.instance,
module: ast.module module: ast.module
}; });
this.file = this.file =
compile_options.filename && compile_options.filename &&

@ -9,6 +9,7 @@ import { TemplateNode } from '../../interfaces';
import Element from './Element'; import Element from './Element';
import InlineComponent from './InlineComponent'; import InlineComponent from './InlineComponent';
import Window from './Window'; import Window from './Window';
import { clone } from '../../utils/clone';
// TODO this should live in a specific binding // TODO this should live in a specific binding
const read_only_media_attributes = new Set([ const read_only_media_attributes = new Set([
@ -42,7 +43,7 @@ export default class Binding extends Node {
this.name = info.name; this.name = info.name;
this.expression = new Expression(component, this, scope, info.expression); this.expression = new Expression(component, this, scope, info.expression);
this.raw_expression = JSON.parse(JSON.stringify(info.expression)); this.raw_expression = clone(info.expression);
const { name } = get_object(this.expression.node); const { name } = get_object(this.expression.node);

@ -2,6 +2,7 @@ import { x } from 'code-red';
import { Node, Identifier, Expression } from 'estree'; import { Node, Identifier, Expression } from 'estree';
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
import is_reference from 'is-reference'; import is_reference from 'is-reference';
import { clone } from '../../../utils/clone';
export interface Context { export interface Context {
key: Identifier; key: Identifier;
@ -81,7 +82,7 @@ function update_reference(contexts: Context[], n: number, expression: Expression
} }
// NOTE: avoid unnecessary deep clone? // NOTE: avoid unnecessary deep clone?
expression = JSON.parse(JSON.stringify(expression)) as Expression; expression = clone(expression) as Expression;
walk(expression, { walk(expression, {
enter(node, parent: Node) { enter(node, parent: Node) {
if (is_reference(node, parent)) { if (is_reference(node, parent)) {

@ -16,6 +16,7 @@ import { is_reserved_keyword } from '../../utils/reserved_keywords';
import replace_object from '../../utils/replace_object'; import replace_object from '../../utils/replace_object';
import is_contextual from './is_contextual'; import is_contextual from './is_contextual';
import EachBlock from '../EachBlock'; import EachBlock from '../EachBlock';
import { clone } from '../../../utils/clone';
type Owner = INode; type Owner = INode;
@ -195,7 +196,7 @@ export default class Expression {
const node = walk(this.node, { const node = walk(this.node, {
enter(node: any, parent: any) { enter(node: any, parent: any) {
if (node.type === 'Property' && node.shorthand) { if (node.type === 'Property' && node.shorthand) {
node.value = JSON.parse(JSON.stringify(node.value)); node.value = clone(node.value);
node.shorthand = false; node.shorthand = false;
} }

Loading…
Cancel
Save