Merge branch 'master' into gh-371

pull/391/head
Rich Harris 8 years ago committed by GitHub
commit 8558b45337

@ -35,6 +35,12 @@ export default class Generator {
this.cssId = parsed.css ? `svelte-${parsed.hash}` : '';
this.usesRefs = false;
// allow compiler to deconflict user's `import { get } from 'whatever'` and
// Svelte's builtin `import { get, ... } from 'svelte/shared.js'`;
this.importedNames = {};
this.aliases = {};
this._callbacks = {};
}
@ -47,6 +53,20 @@ export default class Generator {
});
}
alias ( name ) {
if ( !( name in this.aliases ) ) {
let alias = name;
let i = 1;
while ( alias in this.importedNames ) {
alias = `${name}$${i++}`;
}
this.aliases[ name ] = alias;
}
return this.aliases[ name ];
}
contextualise ( expression, isEventHandler ) {
this.addSourcemapLocations( expression );
@ -58,6 +78,8 @@ export default class Generator {
let scope = annotateWithScopes( expression );
const self = this;
walk( expression, {
enter ( node, parent, key ) {
if ( node._scope ) {
@ -70,7 +92,7 @@ export default class Generator {
if ( scope.has( name ) ) return;
if ( parent && parent.type === 'CallExpression' && node === parent.callee && helpers[ name ] ) {
code.prependRight( node.start, `template.helpers.` );
code.prependRight( node.start, `${self.alias( 'template' )}.helpers.` );
}
else if ( name === 'event' && isEventHandler ) {
@ -249,6 +271,9 @@ export default class Generator {
imports.push( node );
this.code.remove( a, b );
node.specifiers.forEach( specifier => {
this.importedNames[ specifier.local.name ] = true;
});
}
}
@ -260,21 +285,24 @@ export default class Generator {
// export is last property, we can just return it
this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `return ` );
} else {
// TODO ensure `template` isn't already declared
this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `var template = ` );
const { declarations } = annotateWithScopes( js );
let template = 'template';
for ( let i = 1; template in declarations; template = `template$${i++}` );
this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `var ${template} = ` );
let i = defaultExport.start;
while ( /\s/.test( source[ i - 1 ] ) ) i--;
const indentation = source.slice( i, defaultExport.start );
this.code.appendLeft( finalNode.end, `\n\n${indentation}return template;` );
this.code.appendLeft( finalNode.end, `\n\n${indentation}return ${template};` );
}
defaultExport.declaration.properties.forEach( prop => {
templateProperties[ prop.key.name ] = prop;
});
this.code.prependRight( js.content.start, 'var template = (function () {' );
this.code.prependRight( js.content.start, `var ${this.alias( 'template' )} = (function () {` );
} else {
this.code.prependRight( js.content.start, '(function () {' );
}

@ -28,7 +28,7 @@ export default function annotateWithScopes ( expression ) {
node._scope = scope = new Scope( scope, true );
}
else if ( /Declaration/.test( node.type ) ) {
else if ( /(Function|Class|Variable)Declaration/.test( node.type ) ) {
scope.addDeclaration( node );
}
},
@ -54,7 +54,7 @@ class Scope {
if ( node.kind === 'var' && !this.block && this.parent ) {
this.parent.addDeclaration( node );
} else if ( node.type === 'VariableDeclaration' ) {
node.declarators.forEach( declarator => {
node.declarations.forEach( declarator => {
extractNames( declarator.id ).forEach( name => {
this.declarations[ name ] = true;
});
@ -100,4 +100,3 @@ const extractors = {
extractors[ param.left.type ]( names, param.left );
}
};

@ -148,20 +148,6 @@ class DomGenerator extends Generator {
return this.alias( name );
}
alias ( name ) {
if ( !( name in this.aliases ) ) {
let alias = name;
let i = 1;
while ( alias in this.importedNames ) {
alias = `${name}$${i++}`;
}
this.aliases[ name ] = alias;
}
return this.aliases[ name ];
}
}
export default function dom ( parsed, source, options, names ) {
@ -185,12 +171,6 @@ export default function dom ( parsed, source, options, names ) {
templateProperties.ondestroy = templateProperties.onteardown;
}
generator.imports.forEach( node => {
node.specifiers.forEach( specifier => {
generator.importedNames[ specifier.local.name ] = true;
});
});
let namespace = null;
if ( templateProperties.namespace ) {
const ns = templateProperties.namespace.value.value;
@ -266,7 +246,7 @@ export default function dom ( parsed, source, options, names ) {
computations.forEach( ({ key, deps }) => {
builder.addBlock( deindent`
if ( isInitial || ${deps.map( dep => `( '${dep}' in newState && typeof state.${dep} === 'object' || state.${dep} !== oldState.${dep} )` ).join( ' || ' )} ) {
state.${key} = newState.${key} = template.computed.${key}( ${deps.map( dep => `state.${dep}` ).join( ', ' )} );
state.${key} = newState.${key} = ${generator.alias( 'template' )}.computed.${key}( ${deps.map( dep => `state.${dep}` ).join( ', ' )} );
}
` );
});
@ -343,9 +323,9 @@ export default function dom ( parsed, source, options, names ) {
if ( templateProperties.oncreate ) {
builders.init.addBlock( deindent`
if ( options._root ) {
options._root._renderHooks.push({ fn: template.oncreate, context: this });
options._root._renderHooks.push({ fn: ${generator.alias( 'template' )}.oncreate, context: this });
} else {
template.oncreate.call( this );
${generator.alias( 'template' )}.oncreate.call( this );
}
` );
}
@ -356,7 +336,7 @@ export default function dom ( parsed, source, options, names ) {
if ( generator.usesRefs ) constructorBlock.addLine( `this.refs = {};` );
constructorBlock.addLine(
`this._state = ${templateProperties.data ? `Object.assign( template.data(), options.data )` : `options.data || {}`};`
`this._state = ${templateProperties.data ? `Object.assign( ${generator.alias( 'template' )}.data(), options.data )` : `options.data || {}`};`
);
if ( !generator.builders.metaBindings.isEmpty() ) {
@ -408,11 +388,11 @@ export default function dom ( parsed, source, options, names ) {
const sharedPath = options.shared === true ? 'svelte/shared.js' : options.shared;
if ( sharedPath ) {
const base = templateProperties.methods ? `{}, template.methods` : `{}`;
const base = templateProperties.methods ? `{}, ${generator.alias( 'template' )}.methods` : `{}`;
builders.main.addBlock( `${name}.prototype = Object.assign( ${base}, ${generator.helper( 'proto' )} );` );
} else {
if ( templateProperties.methods ) {
builders.main.addBlock( `${name}.prototype = template.methods;` );
builders.main.addBlock( `${name}.prototype = ${generator.alias( 'template' )}.methods;` );
}
[ 'get', 'fire', 'observe', 'on', 'set', '_flush' ].forEach( methodName => {
@ -427,7 +407,7 @@ export default function dom ( parsed, source, options, names ) {
};
${name}.prototype.teardown = ${name}.prototype.destroy = function destroy ( detach ) {
this.fire( 'destroy' );${templateProperties.ondestroy ? `\ntemplate.ondestroy.call( this );` : ``}
this.fire( 'destroy' );${templateProperties.ondestroy ? `\n${generator.alias( 'template' )}.ondestroy.call( this );` : ``}
this._fragment.teardown( detach !== false );
this._fragment = null;

@ -106,7 +106,7 @@ export default {
componentInitProperties.push(`data: ${name}_initialData`);
}
const expression = node.name === ':Self' ? generator.name : generator.importedComponents[ node.name ] || `template.components.${node.name}`;
const expression = node.name === ':Self' ? generator.name : generator.importedComponents[ node.name ] || `${generator.alias( 'template' )}.components.${node.name}`;
local.init.addBlockAtStart( deindent`
${statements.join( '\n\n' )}

@ -182,7 +182,7 @@ export default function addElementAttributes ( generator, node, local ) {
if ( name in generator.events ) {
local.init.addBlock( deindent`
var ${handlerName} = template.events.${name}.call( component, ${local.name}, function ( event ) {
var ${handlerName} = ${generator.alias( 'template' )}.events.${name}.call( component, ${local.name}, function ( event ) {
${handlerBody}
});
` );

@ -60,12 +60,12 @@ export default function ssr ( parsed, source, options, names ) {
parsed.html.children.forEach( node => generator.visit( node ) );
builders.render.addLine(
templateProperties.data ? `root = Object.assign( template.data(), root || {} );` : `root = root || {};`
templateProperties.data ? `root = Object.assign( ${generator.alias( 'template' )}.data(), root || {} );` : `root = root || {};`
);
computations.forEach( ({ key, deps }) => {
builders.render.addLine(
`root.${key} = template.computed.${key}( ${deps.map( dep => `root.${dep}` ).join( ', ' )} );`
`root.${key} = ${generator.alias( 'template' )}.computed.${key}( ${deps.map( dep => `root.${dep}` ).join( ', ' )} );`
);
});
@ -118,7 +118,7 @@ export default function ssr ( parsed, source, options, names ) {
` );
templateProperties.components.value.properties.forEach( prop => {
builders.renderCss.addLine( `addComponent( template.components.${prop.key.name} );` );
builders.renderCss.addLine( `addComponent( ${generator.alias( 'template' )}.components.${prop.key.name} );` );
});
}
@ -140,7 +140,7 @@ export default function ssr ( parsed, source, options, names ) {
${name}.filename = ${JSON.stringify( options.filename )};
${name}.data = function () {
return ${templateProperties.data ? `template.data()` : `{}`};
return ${templateProperties.data ? `${generator.alias( 'template' )}.data()` : `{}`};
};
${name}.render = function ( root, options ) {

@ -50,7 +50,7 @@ export default {
}))
.join( ', ' );
const expression = node.name === ':Self' ? generator.name : `template.components.${node.name}`;
const expression = node.name === ':Self' ? generator.name : `${generator.alias( 'template' )}.components.${node.name}`;
bindings.forEach( binding => {
generator.addBinding( binding, expression );

@ -0,0 +1,3 @@
export default {
html: `template`
};

@ -0,0 +1,13 @@
{{value}}
<script>
import template from './module.js';
export default {
data() {
return {
value: template
};
}
};
</script>

@ -0,0 +1,3 @@
export default {
html: `template`
};

@ -0,0 +1,15 @@
{{value}}
<script>
export default {
data() {
return {
value: template()
};
}
};
function template() {
return 'template';
}
</script>
Loading…
Cancel
Save