@@ -24,11 +24,13 @@ export const FUNCTION_BLOCK_DISPLAY_CODE_KEY = '_runtimeDisplayCode'
2424const logger = createLogger ( 'VariableResolver' )
2525
2626type ShellQuoteContext = 'single' | 'double' | null
27- type CodeStringQuoteContext = ShellQuoteContext | 'template'
27+ type CodeStringQuoteContext = ShellQuoteContext | 'triple-single' | 'triple-double' | ' template'
2828type CodeScanMode =
2929 | { type : 'normal' }
3030 | { type : 'single' }
3131 | { type : 'double' }
32+ | { type : 'triple-single' }
33+ | { type : 'triple-double' }
3234 | { type : 'template' }
3335 | { type : 'template-expression' ; depth : number }
3436 | { type : 'line-comment' }
@@ -362,8 +364,8 @@ export class VariableResolver {
362364 if ( language === 'python' ) {
363365 const expression = `globals()[${ JSON . stringify ( varName ) } ]`
364366 const quoteContext = this . getCodeStringQuoteContext ( template , matchIndex , language )
365- if ( quoteContext === 'single' || quoteContext === 'double' ) {
366- const quote = quoteContext === 'single' ? "'" : '"'
367+ if ( this . isPythonStringQuoteContext ( quoteContext ) ) {
368+ const quote = this . getCodeStringQuoteToken ( quoteContext )
367369 return `${ quote } + json.dumps(${ expression } ) + ${ quote } `
368370 }
369371 return expression
@@ -379,12 +381,32 @@ export class VariableResolver {
379381 return `\${JSON.stringify(${ expression } )}`
380382 }
381383 if ( quoteContext === 'single' || quoteContext === 'double' ) {
382- const quote = quoteContext === 'single' ? "'" : '"'
384+ const quote = this . getCodeStringQuoteToken ( quoteContext )
383385 return `${ quote } + JSON.stringify(${ expression } ) + ${ quote } `
384386 }
385387 return expression
386388 }
387389
390+ private isPythonStringQuoteContext (
391+ quoteContext : CodeStringQuoteContext
392+ ) : quoteContext is 'single' | 'double' | 'triple-single' | 'triple-double' {
393+ return (
394+ quoteContext === 'single' ||
395+ quoteContext === 'double' ||
396+ quoteContext === 'triple-single' ||
397+ quoteContext === 'triple-double'
398+ )
399+ }
400+
401+ private getCodeStringQuoteToken (
402+ quoteContext : 'single' | 'double' | 'triple-single' | 'triple-double'
403+ ) : string {
404+ if ( quoteContext === 'single' ) return "'"
405+ if ( quoteContext === 'double' ) return '"'
406+ if ( quoteContext === 'triple-single' ) return "'''"
407+ return '"""'
408+ }
409+
388410 private formatDisplayValueForCodeContext (
389411 value : unknown ,
390412 language : string | undefined ,
@@ -461,6 +483,15 @@ export class VariableResolver {
461483 continue
462484 }
463485
486+ if ( mode . type === 'triple-single' || mode . type === 'triple-double' ) {
487+ const quote = mode . type === 'triple-single' ? "'" : '"'
488+ if ( char === quote && next === quote && template [ i + 2 ] === quote ) {
489+ modes . pop ( )
490+ i += 2
491+ }
492+ continue
493+ }
494+
464495 if ( mode . type === 'template' ) {
465496 if ( char === '\\' ) {
466497 i ++
@@ -488,6 +519,16 @@ export class VariableResolver {
488519 i ++
489520 continue
490521 }
522+ if ( isPython && char === "'" && next === "'" && template [ i + 2 ] === "'" ) {
523+ modes . push ( { type : 'triple-single' } )
524+ i += 2
525+ continue
526+ }
527+ if ( isPython && char === '"' && next === '"' && template [ i + 2 ] === '"' ) {
528+ modes . push ( { type : 'triple-double' } )
529+ i += 2
530+ continue
531+ }
491532 if ( char === "'" ) {
492533 modes . push ( { type : 'single' } )
493534 continue
@@ -527,7 +568,13 @@ export class VariableResolver {
527568 i ++
528569 continue
529570 }
530- if ( char === "'" ) {
571+ if ( isPython && char === "'" && next === "'" && template [ i + 2 ] === "'" ) {
572+ modes . push ( { type : 'triple-single' } )
573+ i += 2
574+ } else if ( isPython && char === '"' && next === '"' && template [ i + 2 ] === '"' ) {
575+ modes . push ( { type : 'triple-double' } )
576+ i += 2
577+ } else if ( char === "'" ) {
531578 modes . push ( { type : 'single' } )
532579 } else if ( char === '"' ) {
533580 modes . push ( { type : 'double' } )
@@ -537,7 +584,13 @@ export class VariableResolver {
537584 }
538585
539586 const mode = modes [ modes . length - 1 ]
540- if ( mode . type === 'single' || mode . type === 'double' || mode . type === 'template' ) {
587+ if (
588+ mode . type === 'single' ||
589+ mode . type === 'double' ||
590+ mode . type === 'triple-single' ||
591+ mode . type === 'triple-double' ||
592+ mode . type === 'template'
593+ ) {
541594 return mode . type
542595 }
543596 return null
0 commit comments