Skip to content

Commit

Permalink
new aliaser mechanism replacing exisintg mechanism and counters; a bu…
Browse files Browse the repository at this point in the history
…nch more deconflicting
  • Loading branch information
Conduitry committed Mar 26, 2017
1 parent e67c6b7 commit 679c56a
Show file tree
Hide file tree
Showing 18 changed files with 149 additions and 223 deletions.
41 changes: 10 additions & 31 deletions src/generators/Generator.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import MagicString, { Bundle } from 'magic-string';
import { walk } from 'estree-walker';
import isReference from '../utils/isReference.js';
import counter from './shared/utils/counter.js';
import flattenReference from '../utils/flattenReference.js';
import globalWhitelist from '../utils/globalWhitelist.js';
import getIntro from './shared/utils/getIntro.js';
import getOutro from './shared/utils/getOutro.js';
import annotateWithScopes from './annotateWithScopes.js';
import { initAliaser, getGlobalAlias, getUniqueGlobalAlias } from './shared/utils/aliaser.js';

export default class Generator {
constructor ( parsed, source, name, names, visitors, options ) {
constructor ( parsed, source, name, visitors, options ) {
this.parsed = parsed;
this.source = source;
this.name = name;
this.names = names;
this.visitors = visitors;
this.options = options;

Expand All @@ -31,16 +30,14 @@ export default class Generator {
this.elementDepth = 0;

this.code = new MagicString( source );
this.getUniqueName = counter( names );
this.getUniqueName = getUniqueGlobalAlias;
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 = new Set();

this.aliases = new Map();

this._callbacks = new Map();
}

Expand All @@ -53,20 +50,6 @@ export default class Generator {
});
}

alias ( name ) {
if ( !( this.aliases.has( name ) ) ) {
let alias = name;
let i = 1;
while ( alias in this.importedNames ) {
alias = `${name}$${i++}`;
}

this.aliases.set( name, alias );
}

return this.aliases.get( name );
}

contextualise ( expression, isEventHandler ) {
this.addSourcemapLocations( expression );

Expand All @@ -78,8 +61,6 @@ export default class Generator {

let scope = annotateWithScopes( expression );

const self = this;

walk( expression, {
enter ( node, parent, key ) {
if ( node._scope ) {
Expand All @@ -92,7 +73,7 @@ export default class Generator {
if ( scope.has( name ) ) return;

if ( parent && parent.type === 'CallExpression' && node === parent.callee && helpers.has( name ) ) {
code.prependRight( node.start, `${self.alias( 'template' )}.helpers.` );
code.prependRight( node.start, `${getGlobalAlias( 'template' )}.helpers.` );
}

else if ( name === 'event' && isEventHandler ) {
Expand Down Expand Up @@ -124,7 +105,7 @@ export default class Generator {
}
}

if ( globalWhitelist[ name ] ) {
if ( globalWhitelist.has( name ) ) {
code.prependRight( node.start, `( '${name}' in root ? root.` );
code.appendLeft( node.object ? node.object.end : node.end, ` : ${name} )` );
} else {
Expand Down Expand Up @@ -244,10 +225,6 @@ export default class Generator {
};
}

getUniqueNameMaker () {
return counter( this.names );
}

parseJs () {
const { source } = this;
const { js } = this.parsed;
Expand All @@ -272,11 +249,13 @@ export default class Generator {
imports.push( node );
this.code.remove( a, b );
node.specifiers.forEach( specifier => {
this.importedNames[ specifier.local.name ] = true;
this.importedNames.add( specifier.local.name );
});
}
}

initAliaser( this );

defaultExport = js.content.body.find( node => node.type === 'ExportDefaultDeclaration' );

if ( defaultExport ) {
Expand All @@ -287,7 +266,7 @@ export default class Generator {
} else {
const { declarations } = annotateWithScopes( js );
let template = 'template';
for ( let i = 1; declarations.has( template ); template = `template$${i++}` );
for ( let c = 1; declarations.has( template ); template = `template$${c++}` );

this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `var ${template} = ` );

Expand All @@ -302,7 +281,7 @@ export default class Generator {
templateProperties[ prop.key.name ] = prop;
});

this.code.prependRight( js.content.start, `var ${this.alias( 'template' )} = (function () {` );
this.code.prependRight( js.content.start, `var ${getGlobalAlias( 'template' )} = (function () {` );
} else {
this.code.prependRight( js.content.start, '(function () {' );
}
Expand Down
55 changes: 28 additions & 27 deletions src/generators/dom/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import removeObjectKey from '../../utils/removeObjectKey.js';
import visitors from './visitors/index.js';
import Generator from '../Generator.js';
import * as shared from '../../shared/index.js';
import { getGlobalAlias, getUniqueLocalAliasMaker } from '../shared/utils/aliaser.js';

class DomGenerator extends Generator {
constructor ( parsed, source, name, names, visitors, options ) {
super( parsed, source, name, names, visitors, options );
constructor ( parsed, source, name, visitors, options ) {
super( parsed, source, name, visitors, options );
this.renderers = [];
this.uses = new Set();

Expand Down Expand Up @@ -117,7 +118,7 @@ class DomGenerator extends Generator {
target: 'target',
localElementDepth: 0,
builders: getBuilders(),
getUniqueName: this.getUniqueNameMaker()
getUniqueName: getUniqueLocalAliasMaker( this.params )
});

// walk the children here
Expand All @@ -136,15 +137,15 @@ class DomGenerator extends Generator {

this.uses.add( name );

return this.alias( name );
return getGlobalAlias( name );
}
}

export default function dom ( parsed, source, options, names ) {
export default function dom ( parsed, source, options ) {
const format = options.format || 'es';
const name = options.name || 'SvelteComponent';

const generator = new DomGenerator( parsed, source, name, names, visitors, options );
const generator = new DomGenerator( parsed, source, name, visitors, options );

const { computations, defaultExport, templateProperties } = generator.parseJs();

Expand Down Expand Up @@ -192,7 +193,7 @@ export default function dom ( parsed, source, options, names ) {
}

generator.push({
name: generator.alias( 'renderMainFragment' ),
name: getGlobalAlias( 'renderMainFragment' ),
namespace,
target: 'target',
localElementDepth: 0,
Expand All @@ -206,7 +207,7 @@ export default function dom ( parsed, source, options, names ) {
listNames: new Map(),

builders: getBuilders(),
getUniqueName: generator.getUniqueNameMaker()
getUniqueName: getUniqueLocalAliasMaker( [ 'root' ] )
});

parsed.html.children.forEach( node => generator.visit( node ) );
Expand Down Expand Up @@ -236,18 +237,18 @@ 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} = ${generator.alias( 'template' )}.computed.${key}( ${deps.map( dep => `state.${dep}` ).join( ', ' )} );
state.${key} = newState.${key} = ${getGlobalAlias( 'template' )}.computed.${key}( ${deps.map( dep => `state.${dep}` ).join( ', ' )} );
}
` );
});

builders.main.addBlock( deindent`
function ${generator.alias( 'applyComputations' )} ( state, newState, oldState, isInitial ) {
function ${getGlobalAlias( 'applyComputations' )} ( state, newState, oldState, isInitial ) {
${builder}
}
` );

builders._set.addLine( `${generator.alias( 'applyComputations' )}( this._state, newState, oldState, false )` );
builders._set.addLine( `${getGlobalAlias( 'applyComputations' )}( this._state, newState, oldState, false )` );
}

// TODO is the `if` necessary?
Expand All @@ -263,13 +264,13 @@ export default function dom ( parsed, source, options, names ) {

if ( parsed.css && options.css !== false ) {
builders.main.addBlock( deindent`
var ${generator.alias( 'addedCss' )} = false;
function ${generator.alias( 'addCss' )} () {
var ${getGlobalAlias( 'addedCss' )} = false;
function ${getGlobalAlias( 'addCss' )} () {
var style = ${generator.helper( 'createElement' )}( 'style' );
style.textContent = ${JSON.stringify( processCss( parsed, generator.code ) )};
${generator.helper( 'appendNode' )}( style, document.head );
${generator.alias( 'addedCss' )} = true;
${getGlobalAlias( 'addedCss' )} = true;
}
` );
}
Expand All @@ -280,7 +281,7 @@ export default function dom ( parsed, source, options, names ) {
builders.init.addLine( `this._torndown = false;` );

if ( parsed.css && options.css !== false ) {
builders.init.addLine( `if ( !${generator.alias( 'addedCss' )} ) ${generator.alias( 'addCss' )}();` );
builders.init.addLine( `if ( !${getGlobalAlias( 'addedCss' )} ) ${getGlobalAlias( 'addCss' )}();` );
}

if ( generator.hasComponents ) {
Expand All @@ -290,15 +291,15 @@ export default function dom ( parsed, source, options, names ) {
if ( generator.hasComplexBindings ) {
builders.init.addBlock( deindent`
this._bindings = [];
this._fragment = ${generator.alias( 'renderMainFragment' )}( this._state, this );
this._fragment = ${getGlobalAlias( 'renderMainFragment' )}( this._state, this );
if ( options.target ) this._fragment.mount( options.target, null );
while ( this._bindings.length ) this._bindings.pop()();
` );

builders._set.addLine( `while ( this._bindings.length ) this._bindings.pop()();` );
} else {
builders.init.addBlock( deindent`
this._fragment = ${generator.alias( 'renderMainFragment' )}( this._state, this );
this._fragment = ${getGlobalAlias( 'renderMainFragment' )}( this._state, this );
if ( options.target ) this._fragment.mount( options.target, null );
` );
}
Expand All @@ -313,9 +314,9 @@ export default function dom ( parsed, source, options, names ) {
if ( templateProperties.oncreate ) {
builders.init.addBlock( deindent`
if ( options._root ) {
options._root._renderHooks.push({ fn: ${generator.alias( 'template' )}.oncreate, context: this });
options._root._renderHooks.push({ fn: ${getGlobalAlias( 'template' )}.oncreate, context: this });
} else {
${generator.alias( 'template' )}.oncreate.call( this );
${getGlobalAlias( 'template' )}.oncreate.call( this );
}
` );
}
Expand All @@ -326,12 +327,12 @@ export default function dom ( parsed, source, options, names ) {
if ( generator.usesRefs ) constructorBlock.addLine( `this.refs = {};` );

constructorBlock.addLine(
`this._state = ${templateProperties.data ? `Object.assign( ${generator.alias( 'template' )}.data(), options.data )` : `options.data || {}`};`
`this._state = ${templateProperties.data ? `Object.assign( ${getGlobalAlias( 'template' )}.data(), options.data )` : `options.data || {}`};`
);

if ( templateProperties.computed ) {
constructorBlock.addLine(
`${generator.alias( 'applyComputations' )}( this._state, this._state, {}, true );`
`${getGlobalAlias( 'applyComputations' )}( this._state, this._state, {}, true );`
);
}

Expand Down Expand Up @@ -374,11 +375,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 ? `{}, ${generator.alias( 'template' )}.methods` : `{}`;
const base = templateProperties.methods ? `{}, ${getGlobalAlias( 'template' )}.methods` : `{}`;
builders.main.addBlock( `${name}.prototype = Object.assign( ${base}, ${generator.helper( 'proto' )} );` );
} else {
if ( templateProperties.methods ) {
builders.main.addBlock( `${name}.prototype = ${generator.alias( 'template' )}.methods;` );
builders.main.addBlock( `${name}.prototype = ${getGlobalAlias( 'template' )}.methods;` );
}

[ 'get', 'fire', 'observe', 'on', 'set', '_flush' ].forEach( methodName => {
Expand All @@ -393,7 +394,7 @@ export default function dom ( parsed, source, options, names ) {
};
${name}.prototype.teardown = ${name}.prototype.destroy = function destroy ( detach ) {
this.fire( 'destroy' );${templateProperties.ondestroy ? `\n${generator.alias( 'template' )}.ondestroy.call( this );` : ``}
this.fire( 'destroy' );${templateProperties.ondestroy ? `\n${getGlobalAlias( 'template' )}.ondestroy.call( this );` : ``}
this._fragment.teardown( detach !== false );
this._fragment = null;
Expand All @@ -409,16 +410,16 @@ export default function dom ( parsed, source, options, names ) {
}

const names = Array.from( generator.uses ).map( name => {
return name !== generator.aliases.get( name ) ? `${name} as ${generator.aliases.get( name )}` : name;
return name !== getGlobalAlias( name ) ? `${name} as ${getGlobalAlias( name )}` : name;
});

builders.main.addLineAtStart(
`import { ${names.join( ', ' )} } from ${JSON.stringify( sharedPath )}`
`import { ${names.join( ', ' )} } from ${JSON.stringify( sharedPath )};`
);
} else {
generator.uses.forEach( key => {
const fn = shared[ key ]; // eslint-disable-line import/namespace
builders.main.addBlock( fn.toString().replace( /^function [^(]*/, 'function ' + generator.aliases.get( key ) ) );
builders.main.addBlock( fn.toString().replace( /^function [^(]*/, 'function ' + getGlobalAlias( key ) ) );
});
}

Expand Down
3 changes: 2 additions & 1 deletion src/generators/dom/visitors/Component.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import deindent from '../../../utils/deindent.js';
import CodeBuilder from '../../../utils/CodeBuilder.js';
import addComponentAttributes from './attributes/addComponentAttributes.js';
import { getGlobalAlias } from '../../shared/utils/aliaser.js';

function capDown ( name ) {
return `${name[0].toLowerCase()}${name.slice( 1 )}`;
Expand Down Expand Up @@ -106,7 +107,7 @@ export default {
componentInitProperties.push(`data: ${name}_initialData`);
}

const expression = node.name === ':Self' ? generator.name : generator.importedComponents.get( node.name ) || `${generator.alias( 'template' )}.components.${node.name}`;
const expression = node.name === ':Self' ? generator.name : generator.importedComponents.get( node.name ) || `${getGlobalAlias( 'template' )}.components.${node.name}`;

local.init.addBlockAtStart( deindent`
${statements.join( '\n\n' )}
Expand Down
Loading

0 comments on commit 679c56a

Please sign in to comment.