Skip to content

Commit 7f9d91f

Browse files
authored
Merge pull request #506 from sveltejs/gh-504
hoist variables where appropriate
2 parents 4012414 + f82d049 commit 7f9d91f

File tree

8 files changed

+48
-24
lines changed

8 files changed

+48
-24
lines changed

src/generators/dom/Block.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export default class Block {
3030
};
3131

3232
this.aliases = new Map();
33+
this.variables = new Map();
3334
this.getUniqueName = this.generator.getUniqueNameMaker( options.params );
3435

3536
// unique names
@@ -62,6 +63,14 @@ export default class Block {
6263
}
6364
}
6465

66+
addVariable ( name, init ) {
67+
if ( this.variables.has( name ) && this.variables.get( name ) !== init ) {
68+
throw new Error( `Variable '${name}' already initialised with a different value` );
69+
}
70+
71+
this.variables.set( name, init );
72+
}
73+
6574
alias ( name ) {
6675
if ( !this.aliases.has( name ) ) {
6776
this.aliases.set( name, this.getUniqueName( name ) );
@@ -96,6 +105,17 @@ export default class Block {
96105
}
97106

98107
render () {
108+
if ( this.variables.size ) {
109+
const variables = Array.from( this.variables.keys() )
110+
.map( key => {
111+
const init = this.variables.get( key );
112+
return init !== undefined ? `${key} = ${init}` : key;
113+
})
114+
.join( ', ' );
115+
116+
this.builders.create.addBlockAtStart( `var ${variables};` );
117+
}
118+
99119
if ( this.autofocus ) {
100120
this.builders.create.addLine( `${this.autofocus}.focus();` );
101121
}
@@ -134,7 +154,6 @@ export default class Block {
134154
if ( this.builders.update.isEmpty() ) {
135155
properties.addBlock( `update: ${this.generator.helper( 'noop' )},` );
136156
} else {
137-
if ( this._tmp ) this.builders.update.addBlockAtStart( `var ${this._tmp};` );
138157
properties.addBlock( deindent`
139158
update: function ( changed, ${this.params.join( ', ' )} ) {
140159
${this.builders.update}

src/generators/dom/visitors/Component/Binding.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ export default function visitBinding ( generator, block, state, node, attribute,
4040
generator.hasComplexBindings = true;
4141

4242
const updating = block.getUniqueName( `${local.name}_updating` );
43+
block.addVariable( updating, 'false' );
4344

4445
local.create.addBlock( deindent`
45-
var ${updating} = false;
46-
4746
${block.component}._bindings.push( function () {
4847
if ( ${local.name}._torndown ) return;
4948
${local.name}.observe( '${attribute.name}', function ( value ) {

src/generators/dom/visitors/Element/Attribute.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default function visitAttribute ( generator, block, state, node, attribut
4444
}
4545

4646
const last = block.getUniqueName( `${state.parentNode}_${name.replace( /[^a-zA-Z_$]/g, '_')}_value` );
47-
block.builders.create.addLine( `var ${last} = ${value};` );
47+
block.addVariable( last );
4848

4949
const isSelectValueAttribute = name === 'value' && state.parentNodeName === 'select';
5050

@@ -66,20 +66,25 @@ export default function visitAttribute ( generator, block, state, node, attribut
6666
}`;
6767

6868
updater = deindent`
69-
var ${last} = ${last};
7069
for ( var ${i} = 0; ${i} < ${state.parentNode}.options.length; ${i} += 1 ) {
7170
var ${option} = ${state.parentNode}.options[${i}];
7271
7372
${ifStatement}
7473
}
7574
`;
75+
76+
block.builders.create.addLine( deindent`
77+
${last} = ${value}
78+
${updater}
79+
` );
7680
} else if ( propertyName ) {
81+
block.builders.create.addLine( `${state.parentNode}.${propertyName} = ${last} = ${value};` );
7782
updater = `${state.parentNode}.${propertyName} = ${last};`;
7883
} else {
84+
block.builders.create.addLine( `${generator.helper( method )}( ${state.parentNode}, '${name}', ${last} = ${value} );` );
7985
updater = `${generator.helper( method )}( ${state.parentNode}, '${name}', ${last} );`;
8086
}
8187

82-
block.builders.create.addLine( updater );
8388
block.builders.update.addBlock( deindent`
8489
if ( ${last} !== ( ${last} = ${value} ) ) {
8590
${updater}

src/generators/dom/visitors/Element/Binding.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@ export default function visitBinding ( generator, block, state, node, attribute
2525
const lock = block.alias( `${state.parentNode}_updating` );
2626
let updateCondition = `!${lock}`;
2727

28+
block.addVariable( lock, 'false' );
29+
2830
// <select> special case
2931
if ( node.name === 'select' ) {
3032
if ( !isMultipleSelect ) {
3133
setter = `var selectedOption = ${state.parentNode}.selectedOptions[0] || ${state.parentNode}.options[0];\n${setter}`;
3234
}
3335

3436
const value = block.getUniqueName( 'value' );
35-
const i = block.getUniqueName( 'i' );
37+
const i = block.alias( 'i' );
3638
const option = block.getUniqueName( 'option' );
3739

3840
const ifStatement = isMultipleSelect ?
@@ -84,7 +86,7 @@ export default function visitBinding ( generator, block, state, node, attribute
8486

8587
if ( attribute.name === 'currentTime' ) {
8688
const frame = block.getUniqueName( `${state.parentNode}_animationframe` );
87-
block.builders.create.addLine( `var ${frame};` );
89+
block.addVariable( frame );
8890
setter = deindent`
8991
cancelAnimationFrame( ${frame} );
9092
if ( !${state.parentNode}.paused ) ${frame} = requestAnimationFrame( ${handler} );
@@ -101,16 +103,14 @@ export default function visitBinding ( generator, block, state, node, attribute
101103
else if ( attribute.name === 'paused' ) {
102104
// this is necessary to prevent the audio restarting by itself
103105
const last = block.getUniqueName( `${state.parentNode}_paused_value` );
104-
block.builders.create.addLine( `var ${last} = true;` );
106+
block.addVariable( last, 'true' );
105107

106108
updateCondition = `${last} !== ( ${last} = ${snippet} )`;
107109
updateElement = `${state.parentNode}[ ${last} ? 'pause' : 'play' ]();`;
108110
}
109111
}
110112

111113
block.builders.create.addBlock( deindent`
112-
var ${lock} = false;
113-
114114
function ${handler} () {
115115
${lock} = true;
116116
${setter}

src/generators/dom/visitors/Element/meta/Window.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export default function visitWindow ( generator, block, node ) {
9898

9999
const handlerBody = new CodeBuilder();
100100
if ( event === 'scroll' ) { // TODO other bidirectional bindings...
101-
block.builders.create.addLine( `var ${lock} = false;` );
101+
block.addVariable( lock, 'false' );
102102
handlerBody.addLine( `${lock} = true;` );
103103
}
104104

src/generators/dom/visitors/MustacheTag.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ export default function visitMustacheTag ( generator, block, state, node ) {
66

77
const { snippet } = block.contextualise( node.expression );
88

9-
block.builders.create.addLine( `var ${value} = ${snippet};` );
10-
block.addElement( name, `${generator.helper( 'createText' )}( ${value} )`, state.parentNode, true );
9+
block.addVariable( value );
10+
block.addElement( name, `${generator.helper( 'createText' )}( ${value} = ${snippet} )`, state.parentNode, true );
1111

1212
block.builders.update.addBlock( deindent`
1313
if ( ${value} !== ( ${value} = ${snippet} ) ) {

test/js/samples/collapses-text-around-comments/expected.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ function add_css () {
1818
}
1919

2020
function create_main_fragment ( root, component ) {
21+
var text_value;
22+
2123
var p = createElement( 'p' );
2224
setAttribute( p, 'svelte-3842350206', '' );
23-
var text_value = root.foo;
24-
var text = createText( text_value );
25+
var text = createText( text_value = root.foo );
2526
appendNode( text, p );
2627

2728
return {

test/js/samples/each-block-changed-check/expected.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { appendNode, assign, createComment, createElement, createText, destroyEach, detachBetween, detachNode, dispatchObservers, insertNode, proto } from "svelte/shared.js";
22

33
function create_main_fragment ( root, component ) {
4+
var text_1_value;
5+
46
var each_block_anchor = createComment();
57
var each_block_value = root.comments;
68
var each_block_iterations = [];
@@ -11,8 +13,7 @@ function create_main_fragment ( root, component ) {
1113

1214
var text = createText( "\n\n" );
1315
var p = createElement( 'p' );
14-
var text_1_value = root.foo;
15-
var text_1 = createText( text_1_value );
16+
var text_1 = createText( text_1_value = root.foo );
1617
appendNode( text_1, p );
1718

1819
return {
@@ -63,23 +64,22 @@ function create_main_fragment ( root, component ) {
6364
}
6465

6566
function create_each_block ( root, each_block_value, comment, i, component ) {
67+
var text_value, text_2_value, text_4_value;
68+
6669
var div = createElement( 'div' );
6770
div.className = "comment";
6871
var strong = createElement( 'strong' );
6972
appendNode( strong, div );
70-
var text_value = i;
71-
var text = createText( text_value );
73+
var text = createText( text_value = i );
7274
appendNode( text, strong );
7375
appendNode( createText( "\n\n\t\t" ), div );
7476
var span = createElement( 'span' );
7577
appendNode( span, div );
7678
span.className = "meta";
77-
var text_2_value = comment.author;
78-
var text_2 = createText( text_2_value );
79+
var text_2 = createText( text_2_value = comment.author );
7980
appendNode( text_2, span );
8081
appendNode( createText( " wrote " ), span );
81-
var text_4_value = root.elapsed(comment.time, root.time);
82-
var text_4 = createText( text_4_value );
82+
var text_4 = createText( text_4_value = root.elapsed(comment.time, root.time) );
8383
appendNode( text_4, span );
8484
appendNode( createText( " ago:" ), span );
8585
appendNode( createText( "\n\n\t\t" ), div );

0 commit comments

Comments
 (0)