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