@@ -1330,30 +1330,100 @@ namespace ts {
13301330 : node ;
13311331 }
13321332
1333- export function createTemplateHead ( text : string ) {
1334- const node = < TemplateHead > createSynthesizedNode ( SyntaxKind . TemplateHead ) ;
1333+ let rawTextScanner : Scanner | undefined ;
1334+ const invalidValueSentinel : object = { } ;
1335+
1336+ function getCookedText ( kind : TemplateLiteralToken [ "kind" ] , rawText : string ) {
1337+ if ( ! rawTextScanner ) {
1338+ rawTextScanner = createScanner ( ScriptTarget . Latest , /*skipTrivia*/ false , LanguageVariant . Standard ) ;
1339+ }
1340+ switch ( kind ) {
1341+ case SyntaxKind . NoSubstitutionTemplateLiteral :
1342+ rawTextScanner . setText ( "`" + rawText + "`" ) ;
1343+ break ;
1344+ case SyntaxKind . TemplateHead :
1345+ // tslint:disable-next-line no-invalid-template-strings
1346+ rawTextScanner . setText ( "`" + rawText + "${" ) ;
1347+ break ;
1348+ case SyntaxKind . TemplateMiddle :
1349+ // tslint:disable-next-line no-invalid-template-strings
1350+ rawTextScanner . setText ( "}" + rawText + "${" ) ;
1351+ break ;
1352+ case SyntaxKind . TemplateTail :
1353+ rawTextScanner . setText ( "}" + rawText + "`" ) ;
1354+ break ;
1355+ }
1356+
1357+ let token = rawTextScanner . scan ( ) ;
1358+ if ( token === SyntaxKind . CloseBracketToken ) {
1359+ token = rawTextScanner . reScanTemplateToken ( ) ;
1360+ }
1361+
1362+ if ( rawTextScanner . isUnterminated ( ) ) {
1363+ rawTextScanner . setText ( undefined ) ;
1364+ return invalidValueSentinel ;
1365+ }
1366+
1367+ let tokenValue : string | undefined ;
1368+ switch ( token ) {
1369+ case SyntaxKind . NoSubstitutionTemplateLiteral :
1370+ case SyntaxKind . TemplateHead :
1371+ case SyntaxKind . TemplateMiddle :
1372+ case SyntaxKind . TemplateTail :
1373+ tokenValue = rawTextScanner . getTokenValue ( ) ;
1374+ break ;
1375+ }
1376+
1377+ if ( rawTextScanner . scan ( ) !== SyntaxKind . EndOfFileToken ) {
1378+ rawTextScanner . setText ( undefined ) ;
1379+ return invalidValueSentinel ;
1380+ }
1381+
1382+ rawTextScanner . setText ( undefined ) ;
1383+ return tokenValue ;
1384+ }
1385+
1386+ function createTemplateLiteralLikeNode ( kind : TemplateLiteralToken [ "kind" ] , text : string , rawText : string | undefined ) {
1387+ const node = < TemplateLiteralLikeNode > createSynthesizedNode ( kind ) ;
13351388 node . text = text ;
1389+ if ( rawText === undefined || text === rawText ) {
1390+ node . rawText = rawText ;
1391+ }
1392+ else {
1393+ const cooked = getCookedText ( kind , rawText ) ;
1394+ if ( typeof cooked === "object" ) {
1395+ return Debug . fail ( "Invalid raw text" ) ;
1396+ }
1397+
1398+ Debug . assert ( text === cooked , "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'." ) ;
1399+ node . rawText = rawText ;
1400+ }
13361401 return node ;
13371402 }
13381403
1339- export function createTemplateMiddle ( text : string ) {
1340- const node = < TemplateMiddle > createSynthesizedNode ( SyntaxKind . TemplateMiddle ) ;
1404+ export function createTemplateHead ( text : string , rawText ? : string ) {
1405+ const node = < TemplateHead > createTemplateLiteralLikeNode ( SyntaxKind . TemplateHead , text , rawText ) ;
13411406 node . text = text ;
13421407 return node ;
13431408 }
13441409
1345- export function createTemplateTail ( text : string ) {
1346- const node = < TemplateTail > createSynthesizedNode ( SyntaxKind . TemplateTail ) ;
1410+ export function createTemplateMiddle ( text : string , rawText ? : string ) {
1411+ const node = < TemplateMiddle > createTemplateLiteralLikeNode ( SyntaxKind . TemplateMiddle , text , rawText ) ;
13471412 node . text = text ;
13481413 return node ;
13491414 }
13501415
1351- export function createNoSubstitutionTemplateLiteral ( text : string ) {
1352- const node = < NoSubstitutionTemplateLiteral > createSynthesizedNode ( SyntaxKind . NoSubstitutionTemplateLiteral ) ;
1416+ export function createTemplateTail ( text : string , rawText ? : string ) {
1417+ const node = < TemplateTail > createTemplateLiteralLikeNode ( SyntaxKind . TemplateTail , text , rawText ) ;
13531418 node . text = text ;
13541419 return node ;
13551420 }
13561421
1422+ export function createNoSubstitutionTemplateLiteral ( text : string , rawText ?: string ) {
1423+ const node = < NoSubstitutionTemplateLiteral > createTemplateLiteralLikeNode ( SyntaxKind . NoSubstitutionTemplateLiteral , text , rawText ) ;
1424+ return node ;
1425+ }
1426+
13571427 export function createYield ( expression ?: Expression ) : YieldExpression ;
13581428 export function createYield ( asteriskToken : AsteriskToken | undefined , expression : Expression ) : YieldExpression ;
13591429 export function createYield ( asteriskTokenOrExpression ?: AsteriskToken | undefined | Expression , expression ?: Expression ) {
0 commit comments