diff --git a/src/generators/Generator.js b/src/generators/Generator.js index f28b2a0f438e..20618ee60ea3 100644 --- a/src/generators/Generator.js +++ b/src/generators/Generator.js @@ -58,7 +58,13 @@ export default class Generator { // noop } - else if ( contexts[ name ] ) { + else if ( name in contexts ) { + const context = contexts[ name ]; + if ( context !== name ) { + // this is true for 'reserved' names like `root` and `component` + code.overwrite( node.start, node.start + name.length, context, true ); + } + dependencies.push( ...contextDependencies[ name ] ); if ( !~usedContexts.indexOf( name ) ) usedContexts.push( name ); } diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index 147883b7ae78..4cc71cbc1434 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -71,7 +71,7 @@ class DomGenerator extends Generator { properties.addBlock( `update: ${this.helper( 'noop' )},` ); } else { properties.addBlock( deindent` - update: function ( changed, ${fragment.params} ) { + update: function ( changed, ${fragment.params.join( ', ' )} ) { var __tmp; ${fragment.builders.update} @@ -90,7 +90,7 @@ class DomGenerator extends Generator { } this.renderers.push( deindent` - function ${fragment.name} ( ${fragment.params}, component${fragment.key ? `, key` : ''} ) { + function ${fragment.name} ( ${fragment.params.join( ', ' )}, component${fragment.key ? `, key` : ''} ) { ${fragment.builders.init} return { @@ -180,7 +180,7 @@ export default function dom ( parsed, source, options, names ) { contexts: {}, indexes: {}, - params: 'root', + params: [ 'root' ], indexNames: {}, listNames: {}, @@ -364,7 +364,7 @@ export default function dom ( parsed, source, options, names ) { } const names = [ 'get', 'fire', 'observe', 'on', 'set', '_flush', 'dispatchObservers' ].concat( Object.keys( generator.uses ) ) - .map( name => name in generator.aliases ? `${name} as ${generator.aliases[ name ]}` : name ); + .map( name => name in generator.aliases && name !== generator.aliases[ name ] ? `${name} as ${generator.aliases[ name ]}` : name ); builders.main.addLineAtStart( `import { ${names.join( ', ' )} } from ${JSON.stringify( sharedPath )}` diff --git a/src/generators/dom/visitors/Component.js b/src/generators/dom/visitors/Component.js index a6d63cfc9497..a7d114cbe6b8 100644 --- a/src/generators/dom/visitors/Component.js +++ b/src/generators/dom/visitors/Component.js @@ -62,7 +62,7 @@ export default { // Component has children, put them in a separate {{yield}} block if ( hasChildren ) { const yieldName = generator.getUniqueName( `render${name}YieldFragment` ); - const { params } = generator.current; + const params = generator.current.params.join( ', ' ); generator.generateBlock( node, yieldName ); diff --git a/src/generators/dom/visitors/EachBlock.js b/src/generators/dom/visitors/EachBlock.js index e9e0eb4fd350..8113e9380360 100644 --- a/src/generators/dom/visitors/EachBlock.js +++ b/src/generators/dom/visitors/EachBlock.js @@ -2,6 +2,11 @@ import CodeBuilder from '../../../utils/CodeBuilder.js'; import deindent from '../../../utils/deindent.js'; import getBuilders from '../utils/getBuilders.js'; +const reserved = { + component: true, + root: true +}; + export default { enter ( generator, node ) { const name = generator.getUniqueName( `eachBlock` ); @@ -172,8 +177,16 @@ export default { const listNames = Object.assign( {}, generator.current.listNames ); listNames[ node.context ] = listName; + // ensure that contexts like `root` or `component` don't blow up the whole show + let context = node.context; + let c = 1; + + while ( context in reserved || ~generator.current.params.indexOf( context ) ) { + context = `${node.context}$${c++}`; + } + const contexts = Object.assign( {}, generator.current.contexts ); - contexts[ node.context ] = true; + contexts[ node.context ] = context; const indexes = Object.assign( {}, generator.current.indexes ); if ( node.index ) indexes[ indexName ] = node.context; @@ -181,7 +194,7 @@ export default { const contextDependencies = Object.assign( {}, generator.current.contextDependencies ); contextDependencies[ node.context ] = dependencies; - const blockParams = generator.current.params + `, ${listName}, ${node.context}, ${indexName}`; + const blockParams = generator.current.params.concat( listName, context, indexName ); generator.push({ name: renderer, diff --git a/src/generators/dom/visitors/IfBlock.js b/src/generators/dom/visitors/IfBlock.js index 5ceb42d48b13..6f89b55f97f2 100644 --- a/src/generators/dom/visitors/IfBlock.js +++ b/src/generators/dom/visitors/IfBlock.js @@ -32,7 +32,7 @@ function getConditionsAndBlocks ( generator, node, _name, i = 0 ) { export default { enter ( generator, node ) { - const { params } = generator.current; + const params = generator.current.params.join( ', ' ); const name = generator.getUniqueName( `ifBlock` ); const getBlock = generator.getUniqueName( `getBlock` ); const currentBlock = generator.getUniqueName( `currentBlock` ); diff --git a/src/generators/server-side-rendering/visitors/EachBlock.js b/src/generators/server-side-rendering/visitors/EachBlock.js index de4bfffe6de0..70a9527a1a7f 100644 --- a/src/generators/server-side-rendering/visitors/EachBlock.js +++ b/src/generators/server-side-rendering/visitors/EachBlock.js @@ -8,7 +8,7 @@ export default { // TODO should this be the generator's job? It's duplicated between // here and the equivalent DOM compiler visitor const contexts = Object.assign( {}, generator.current.contexts ); - contexts[ node.context ] = true; + contexts[ node.context ] = node.context; const indexes = Object.assign( {}, generator.current.indexes ); if ( node.index ) indexes[ node.index ] = node.context; diff --git a/test/generator/deconflict-contexts/_config.js b/test/generator/deconflict-contexts/_config.js new file mode 100644 index 000000000000..1a08133218b2 --- /dev/null +++ b/test/generator/deconflict-contexts/_config.js @@ -0,0 +1,9 @@ +export default { + html: ` +