@@ -8156,16 +8156,71 @@ export class Compiler extends DiagnosticEmitter {
81568156 var expressions = expression . expressions ;
81578157 assert ( numParts - 1 == expressions . length ) ;
81588158
8159- // Shortcut if just a (multi-line) string
8160- if ( tag === null && numParts == 1 ) {
8161- return this . ensureStaticString ( parts [ 0 ] ) ;
8162- }
8163-
81648159 var module = this . module ;
8165- var stringType = this . program . stringInstance . type ;
8160+ var stringInstance = this . program . stringInstance ;
8161+ var stringType = stringInstance . type ;
81668162
8167- // Compile to a `StaticArray<string>#join("")` if untagged
81688163 if ( tag === null ) {
8164+ // Shortcut if just a (multi-line) string
8165+ if ( numParts == 1 ) {
8166+ return this . ensureStaticString ( parts [ 0 ] ) ;
8167+ }
8168+
8169+ // Shortcut for `${expr}`, `<prefix>${expr}`, `${expr}<suffix>`
8170+ if ( numParts == 2 ) {
8171+ let expression = expressions [ 0 ] ;
8172+ let lhsLen = parts [ 0 ] . length ;
8173+ let rhsLen = parts [ 1 ] . length ;
8174+ // Shortcut for `${expr}` -> expr.toString()
8175+ if ( ! lhsLen && ! rhsLen ) {
8176+ return this . makeToString (
8177+ this . compileExpression ( expression , stringType ) ,
8178+ this . currentType , expression
8179+ ) ;
8180+ }
8181+ // Shortcuts for
8182+ // `<prefix>${expr}` -> "<prefix>" + expr.toString()
8183+ // `${expr}<suffix>` -> expr.toString() + "<suffix>"
8184+ let hasPrefix = lhsLen != 0 ;
8185+ // @ts -ignore: cast
8186+ if ( hasPrefix ^ ( rhsLen != 0 ) ) {
8187+ let lhs : ExpressionRef ;
8188+ let rhs : ExpressionRef ;
8189+ let expr = this . makeToString (
8190+ this . compileExpression ( expression , stringType ) ,
8191+ this . currentType , expression
8192+ ) ;
8193+ if ( hasPrefix ) {
8194+ lhs = this . ensureStaticString ( parts [ 0 ] ) ;
8195+ rhs = expr ;
8196+ } else {
8197+ // suffix
8198+ lhs = expr ;
8199+ rhs = this . ensureStaticString ( parts [ 1 ] ) ;
8200+ }
8201+ let concatMethod = assert ( stringInstance . getMethod ( "concat" ) ) ;
8202+ return this . makeCallDirect ( concatMethod , [ lhs , rhs ] , expression ) ;
8203+ }
8204+ }
8205+
8206+ // Shortcut for `${exprA}${exprB}` -> exprA.toString() + exprB.toString()
8207+ if ( numParts == 3 && ! parts [ 0 ] . length && ! parts [ 1 ] . length && ! parts [ 2 ] . length ) {
8208+ let exprA = expressions [ 0 ] ;
8209+ let exprB = expressions [ 1 ] ;
8210+
8211+ let lhs = this . makeToString (
8212+ this . compileExpression ( exprA , stringType ) ,
8213+ this . currentType , exprA
8214+ ) ;
8215+ let rhs = this . makeToString (
8216+ this . compileExpression ( exprB , stringType ) ,
8217+ this . currentType , exprB
8218+ ) ;
8219+ let concatMethod = assert ( stringInstance . getMethod ( "concat" ) ) ;
8220+ return this . makeCallDirect ( concatMethod , [ lhs , rhs ] , expression ) ;
8221+ }
8222+
8223+ // Compile to a `StaticArray<string>#join("") for general case
81698224 let length = 2 * numParts - 1 ;
81708225 let values = new Array < usize > ( length ) ;
81718226 values [ 0 ] = this . ensureStaticString ( parts [ 0 ] ) ;
@@ -8178,26 +8233,22 @@ export class Compiler extends DiagnosticEmitter {
81788233 let offset = i64_add ( segment . offset , i64_new ( this . program . totalOverhead ) ) ;
81798234 let joinInstance = assert ( arrayInstance . getMethod ( "join" ) ) ;
81808235 let indexedSetInstance = assert ( arrayInstance . lookupOverload ( OperatorKind . INDEXED_SET , true ) ) ;
8181- let stmts = new Array < ExpressionRef > ( ) ;
8236+ let stmts = new Array < ExpressionRef > ( numParts ) ;
81828237 for ( let i = 0 , k = numParts - 1 ; i < k ; ++ i ) {
81838238 let expression = expressions [ i ] ;
8184- stmts . push (
8185- this . makeCallDirect ( indexedSetInstance , [
8186- module . usize ( offset ) ,
8187- module . i32 ( 2 * i + 1 ) ,
8188- this . makeToString (
8189- this . compileExpression ( expression , stringType ) ,
8190- this . currentType , expression
8191- )
8192- ] , expression )
8193- ) ;
8194- }
8195- stmts . push (
8196- this . makeCallDirect ( joinInstance , [
8239+ stmts [ i ] = this . makeCallDirect ( indexedSetInstance , [
81978240 module . usize ( offset ) ,
8198- this . ensureStaticString ( "" )
8199- ] , expression )
8200- ) ;
8241+ module . i32 ( 2 * i + 1 ) ,
8242+ this . makeToString (
8243+ this . compileExpression ( expression , stringType ) ,
8244+ this . currentType , expression
8245+ )
8246+ ] , expression ) ;
8247+ }
8248+ stmts [ numParts - 1 ] = this . makeCallDirect ( joinInstance , [
8249+ module . usize ( offset ) ,
8250+ this . ensureStaticString ( "" )
8251+ ] , expression ) ;
82018252 return module . flatten ( stmts , stringType . toRef ( ) ) ;
82028253 }
82038254
@@ -8210,7 +8261,12 @@ export class Compiler extends DiagnosticEmitter {
82108261 if ( target ) {
82118262 switch ( target . kind ) {
82128263 case ElementKind . FUNCTION_PROTOTYPE : {
8213- let instance = this . resolver . resolveFunction ( < FunctionPrototype > target , null , uniqueMap < string , Type > ( ) , ReportMode . SWALLOW ) ;
8264+ let instance = this . resolver . resolveFunction (
8265+ < FunctionPrototype > target ,
8266+ null ,
8267+ uniqueMap < string , Type > ( ) ,
8268+ ReportMode . SWALLOW
8269+ ) ;
82148270 if ( ! instance ) break ;
82158271 target = instance ;
82168272 // fall-through
0 commit comments