@@ -20,8 +20,13 @@ import {
2020 TmplAstNode ,
2121 TmplAstReference ,
2222 TmplAstTemplate ,
23+ AST ,
24+ LiteralArray ,
25+ LiteralMap ,
26+ TmplAstIfBlock ,
27+ TmplAstLetDeclaration ,
28+ ParseTemplateOptions ,
2329} from '@angular/compiler' ;
24- import { AST , LiteralArray , LiteralMap , TmplAstIfBlock } from '@angular/compiler/src/compiler' ;
2530import ts from 'typescript' ;
2631
2732import { absoluteFrom , AbsoluteFsPath , getSourceFileOrError } from '../../file_system' ;
@@ -33,6 +38,7 @@ import {
3338 ElementSymbol ,
3439 ExpressionSymbol ,
3540 InputBindingSymbol ,
41+ LetDeclarationSymbol ,
3642 OutputBindingSymbol ,
3743 PipeSymbol ,
3844 ReferenceSymbol ,
@@ -1947,6 +1953,86 @@ runInEachFileSystem(() => {
19471953 } ) ;
19481954 } ) ;
19491955
1956+ describe ( 'let declarations' , ( ) => {
1957+ let templateTypeChecker : TemplateTypeChecker ;
1958+ let cmp : ClassDeclaration < ts . ClassDeclaration > ;
1959+ let ast : TmplAstNode [ ] ;
1960+ let program : ts . Program ;
1961+
1962+ beforeEach ( ( ) => {
1963+ const fileName = absoluteFrom ( '/main.ts' ) ;
1964+ const dirFile = absoluteFrom ( '/dir.ts' ) ;
1965+ const templateString = `
1966+ @let message = 'The value is ' + value;
1967+ <div [dir]="message"></div>
1968+ ` ;
1969+ const testValues = setup (
1970+ [
1971+ {
1972+ fileName,
1973+ templates : { 'Cmp' : templateString } ,
1974+ source : `
1975+ export class Cmp {
1976+ value = 1;
1977+ }
1978+ ` ,
1979+ declarations : [
1980+ {
1981+ name : 'TestDir' ,
1982+ selector : '[dir]' ,
1983+ file : dirFile ,
1984+ type : 'directive' ,
1985+ exportAs : [ 'dir' ] ,
1986+ inputs : { dir : 'dir' } ,
1987+ } ,
1988+ ] ,
1989+ } ,
1990+ {
1991+ fileName : dirFile ,
1992+ source : `export class TestDir {dir: any;}` ,
1993+ templates : { } ,
1994+ } ,
1995+ ] ,
1996+ undefined ,
1997+ {
1998+ enableLetSyntax : true ,
1999+ } ,
2000+ ) ;
2001+ templateTypeChecker = testValues . templateTypeChecker ;
2002+ program = testValues . program ;
2003+ const sf = getSourceFileOrError ( testValues . program , fileName ) ;
2004+ cmp = getClass ( sf , 'Cmp' ) ;
2005+ ast = templateTypeChecker . getTemplate ( cmp ) ! ;
2006+ } ) ;
2007+
2008+ it ( 'should get symbol of a let declaration at the declaration location' , ( ) => {
2009+ const symbol = templateTypeChecker . getSymbolOfNode ( ast [ 0 ] as TmplAstLetDeclaration , cmp ) ! ;
2010+ assertLetDeclarationSymbol ( symbol ) ;
2011+ expect ( program . getTypeChecker ( ) . typeToString ( symbol . tsType ! ) ) . toBe ( 'string' ) ;
2012+ expect ( symbol . declaration . name ) . toBe ( 'message' ) ;
2013+ } ) ;
2014+
2015+ it ( 'should get symbol of a let declaration at a usage site' , ( ) => {
2016+ const symbol = templateTypeChecker . getSymbolOfNode (
2017+ ( ast [ 1 ] as TmplAstElement ) . inputs [ 0 ] . value ,
2018+ cmp ,
2019+ ) ! ;
2020+ assertLetDeclarationSymbol ( symbol ) ;
2021+ expect ( program . getTypeChecker ( ) . typeToString ( symbol . tsType ! ) ) . toEqual ( 'string' ) ;
2022+ expect ( symbol . declaration . name ) . toEqual ( 'message' ) ;
2023+
2024+ // Ensure we can map the shim locations back to the template
2025+ const initializerMapping = templateTypeChecker . getTemplateMappingAtTcbLocation (
2026+ symbol . initializerLocation ,
2027+ ) ! ;
2028+ expect ( initializerMapping . span . toString ( ) ) . toEqual ( `'The value is ' + value` ) ;
2029+ const localVarMapping = templateTypeChecker . getTemplateMappingAtTcbLocation (
2030+ symbol . localVarLocation ,
2031+ ) ! ;
2032+ expect ( localVarMapping . span . toString ( ) ) . toEqual ( 'message' ) ;
2033+ } ) ;
2034+ } ) ;
2035+
19502036 it ( 'elements with generic directives' , ( ) => {
19512037 const fileName = absoluteFrom ( '/main.ts' ) ;
19522038 const dirFile = absoluteFrom ( '/dir.ts' ) ;
@@ -2093,9 +2179,18 @@ function assertDomBindingSymbol(tSymbol: Symbol): asserts tSymbol is DomBindingS
20932179 expect ( tSymbol . kind ) . toEqual ( SymbolKind . DomBinding ) ;
20942180}
20952181
2096- export function setup ( targets : TypeCheckingTarget [ ] , config ?: Partial < TypeCheckingConfig > ) {
2182+ function assertLetDeclarationSymbol ( tSymbol : Symbol ) : asserts tSymbol is LetDeclarationSymbol {
2183+ expect ( tSymbol . kind ) . toEqual ( SymbolKind . LetDeclaration ) ;
2184+ }
2185+
2186+ export function setup (
2187+ targets : TypeCheckingTarget [ ] ,
2188+ config ?: Partial < TypeCheckingConfig > ,
2189+ parseOptions ?: ParseTemplateOptions ,
2190+ ) {
20972191 return baseTestSetup ( targets , {
20982192 inlining : false ,
20992193 config : { ...config , enableTemplateTypeChecker : true , useInlineTypeConstructors : false } ,
2194+ parseOptions,
21002195 } ) ;
21012196}
0 commit comments