@@ -8156,16 +8156,71 @@ export class Compiler extends DiagnosticEmitter {
8156
8156
var expressions = expression . expressions ;
8157
8157
assert ( numParts - 1 == expressions . length ) ;
8158
8158
8159
- // Shortcut if just a (multi-line) string
8160
- if ( tag === null && numParts == 1 ) {
8161
- return this . ensureStaticString ( parts [ 0 ] ) ;
8162
- }
8163
-
8164
8159
var module = this . module ;
8165
- var stringType = this . program . stringInstance . type ;
8160
+ var stringInstance = this . program . stringInstance ;
8161
+ var stringType = stringInstance . type ;
8166
8162
8167
- // Compile to a `StaticArray<string>#join("")` if untagged
8168
8163
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
8169
8224
let length = 2 * numParts - 1 ;
8170
8225
let values = new Array < usize > ( length ) ;
8171
8226
values [ 0 ] = this . ensureStaticString ( parts [ 0 ] ) ;
@@ -8178,26 +8233,22 @@ export class Compiler extends DiagnosticEmitter {
8178
8233
let offset = i64_add ( segment . offset , i64_new ( this . program . totalOverhead ) ) ;
8179
8234
let joinInstance = assert ( arrayInstance . getMethod ( "join" ) ) ;
8180
8235
let indexedSetInstance = assert ( arrayInstance . lookupOverload ( OperatorKind . INDEXED_SET , true ) ) ;
8181
- let stmts = new Array < ExpressionRef > ( ) ;
8236
+ let stmts = new Array < ExpressionRef > ( numParts ) ;
8182
8237
for ( let i = 0 , k = numParts - 1 ; i < k ; ++ i ) {
8183
8238
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 , [
8197
8240
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 ) ;
8201
8252
return module . flatten ( stmts , stringType . toRef ( ) ) ;
8202
8253
}
8203
8254
@@ -8210,7 +8261,12 @@ export class Compiler extends DiagnosticEmitter {
8210
8261
if ( target ) {
8211
8262
switch ( target . kind ) {
8212
8263
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
+ ) ;
8214
8270
if ( ! instance ) break ;
8215
8271
target = instance ;
8216
8272
// fall-through
0 commit comments