import { PLACEHOLDER , normalizeAngleTagName } from './utils' ; import { builders as b } from '@glimmer/syntax' ; export function isParamPath ( astPath ) { const parentType = astPath . parent && astPath . parent . type ; const itemsWithBlock = [ "BlockStatement" , "SubExpression" , "MustacheStatement" , "ElementModifierStatement" ] ; if ( itemsWithBlock . includes ( parentType ) ) { return astPath . parent . params . includes ( astPath . node ) ; } return false ; } export function relplaceFocusPathForExternalComponentArgument ( focusPath ) { let truePath = focusPath ; if ( focusPath . node . type === 'TextNode' ) { truePath = focusPath . parentPath ; } return truePath ; } export function isExternalComponentArgument ( focusPath ) { let truePath = focusPath ; if ( focusPath . node . type === 'TextNode' ) { truePath = focusPath . parentPath ; } if ( truePath . parent . type === 'ElementNode' && ! isSimpleBlockComponentElement ( truePath . parent ) ) { return false ; } if ( truePath . node . type === 'AttrNode' && truePath . node . name . startsWith ( '@' ) ) { return true ; } return false ; } export function realPathName ( focusPath ) { return focusPath . sourceForNode ( ) . replace ( PLACEHOLDER , "" ) ; } export function isArgumentName ( textPath ) { return textPath . startsWith ( '@' ) ; } export function normalizeArgumentName ( textPath ) { return textPath . replace ( '@' , 'this.args.' ) ; } export function serializeArgumentName ( textPath ) { return textPath . replace ( 'this.args.' , '@' ) . replace ( 'ELSCompletionDummy' , '' ) ; } export function canHandle ( type , focusPath ) { if ( type !== "template" ) { return false ; } if ( focusPath . node . type !== "PathExpression" ) { if ( [ 'AttrNode' ] . includes ( focusPath . node . type ) ) { if ( focusPath . node . type === 'AttrNode' && focusPath . node . name . startsWith ( '@' ) ) { return true ; } if ( focusPath . node . type === 'TextNode' && focusPath . parentPath && focusPath . parentPath . node . type == 'AttrNode' && focusPath . parentPath . node . name . startsWith ( '@' ) ) { return true ; } return false ; } return false ; } const meta = focusPath . metaForType ( "handlebars" ) ; const realName = realPathName ( focusPath ) . split ( '.' ) [ 0 ] ; const scope = meta . localScope ; for ( let i = 0 ; i < scope . length ; i ++ ) { if ( scope [ i ] . name === realName ) { return true ; } } if ( focusPath . node . this === false && focusPath . node . data === false ) { return false ; } return true ; } export function isEachArgument ( focusPath ) { if ( focusPath . parent . type === "BlockStatement" ) { if ( focusPath . parent . path . original === "each" && focusPath . parent . params [ 0 ] === focusPath . node ) { return true ; } } } export function isSimpleBlockComponentElement ( node ) { return ! node . tag . startsWith ( '.' ) && node . tag . charAt ( 0 ) !== '@' && node . tag . charAt ( 0 ) === node . tag . charAt ( 0 ) . toUpperCase ( ) && node . tag . indexOf ( '.' ) === - 1 ; } export function positionForItem ( item ) { if ( ! item . loc ) { throw new Error ( `Unknown position fro ${ item . type }` ) ; } const { start , end } = item . loc ; return `${ start . line },${ start . column }:${ end . line },${ end . column }` ; } export function keyForItem ( item ) { return `${ positionForItem ( item ) } - ${ item . type }` ; } export function tagComponentToBlock ( node ) { const componentName = normalizeAngleTagName ( node . tag ) ; return { type : 'BlockStatement' , isComponent : true , path : b . path ( componentName , node . loc ) , params : [ ] , inverse : null , hash : { type : 'Hash' , pairs : node . attributes . filter ( ( attr ) => attr . name . startsWith ( '@' ) ) . map ( ( attr ) => { let value = attr . value ; if ( value . type === 'MustacheStatement' ) { value . type = 'SubExpression' ; value . isIgnored = true ; } return b . pair ( attr . name . replace ( '@' , '' ) , value , attr . loc ) ; } ) } , program : { type : "Block" , body : node . children , blockParams : node . blockParams , chained : false , loc : node . loc } , loc : node . loc } ; }