mirror of https://github.com/sveltejs/svelte
Merge pull request #329 from sveltejs/gh-269
allow [arrow] function expressions inside tagspull/330/head
commit
61ae2fd6d3
@ -0,0 +1,103 @@
|
|||||||
|
import { walk } from 'estree-walker';
|
||||||
|
|
||||||
|
export default function annotateWithScopes ( expression ) {
|
||||||
|
let scope = new Scope( null, false );
|
||||||
|
|
||||||
|
walk( expression, {
|
||||||
|
enter ( node ) {
|
||||||
|
if ( /Function/.test( node.type ) ) {
|
||||||
|
if ( node.type === 'FunctionDeclaration' ) {
|
||||||
|
scope.declarations[ node.id.name ] = true;
|
||||||
|
} else {
|
||||||
|
node._scope = scope = new Scope( scope, false );
|
||||||
|
if ( node.id ) scope.declarations[ node.id.name ] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
node.params.forEach( param => {
|
||||||
|
extractNames( param ).forEach( name => {
|
||||||
|
scope.declarations[ name ] = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( /For(?:In|Of)Statement/.test( node.type ) ) {
|
||||||
|
node._scope = scope = new Scope( scope, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( node.type === 'BlockStatement' ) {
|
||||||
|
node._scope = scope = new Scope( scope, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( /Declaration/.test( node.type ) ) {
|
||||||
|
scope.addDeclaration( node );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
leave ( node ) {
|
||||||
|
if ( node._scope ) {
|
||||||
|
scope = scope.parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Scope {
|
||||||
|
constructor ( parent, block ) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.block = block;
|
||||||
|
this.declarations = Object.create( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
addDeclaration ( node ) {
|
||||||
|
if ( node.kind === 'var' && !this.block && this.parent ) {
|
||||||
|
this.parent.addDeclaration( node );
|
||||||
|
} else if ( node.type === 'VariableDeclaration' ) {
|
||||||
|
node.declarators.forEach( declarator => {
|
||||||
|
extractNames( declarator.id ).forEach( name => {
|
||||||
|
this.declarations[ name ] = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.declarations[ node.id.name ] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
has ( name ) {
|
||||||
|
return name in this.declarations || this.parent && this.parent.has( name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractNames ( param ) {
|
||||||
|
const names = [];
|
||||||
|
extractors[ param.type ]( names, param );
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
const extractors = {
|
||||||
|
Identifier ( names, param ) {
|
||||||
|
names.push( param.name );
|
||||||
|
},
|
||||||
|
|
||||||
|
ObjectPattern ( names, param ) {
|
||||||
|
param.properties.forEach( prop => {
|
||||||
|
extractors[ prop.value.type ]( names, prop.value );
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
ArrayPattern ( names, param ) {
|
||||||
|
param.elements.forEach( element => {
|
||||||
|
if ( element ) extractors[ element.type ]( names, element );
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
RestElement ( names, param ) {
|
||||||
|
extractors[ param.argument.type ]( names, param.argument );
|
||||||
|
},
|
||||||
|
|
||||||
|
AssignmentPattern ( names, param ) {
|
||||||
|
extractors[ param.left.type ]( names, param.left );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
export default {
|
||||||
|
allowES2015: true,
|
||||||
|
|
||||||
|
data: {
|
||||||
|
numbers: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
|
||||||
|
},
|
||||||
|
|
||||||
|
html: '1, 3, 5, 7, 9',
|
||||||
|
|
||||||
|
test ( assert, component, target ) {
|
||||||
|
component.set({
|
||||||
|
numbers: [ 10, 11, 12, 13, 14, 15, 16 ]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.htmlEqual( target.innerHTML, `11, 13, 15` );
|
||||||
|
|
||||||
|
component.destroy();
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1 @@
|
|||||||
|
{{ numbers.filter( x => x % 2 ).join( ', ' ) }}
|
Loading…
Reference in new issue