* Returns result expression. * @param {(string | { expr: string })[]} args args * @returns {string} result expression
(...args)
| 293 | * @returns {string} result expression |
| 294 | */ |
| 295 | concatenation(...args) { |
| 296 | const len = args.length; |
| 297 | |
| 298 | if (len === 2) return this._es5Concatenation(args); |
| 299 | if (len === 0) return '""'; |
| 300 | if (len === 1) { |
| 301 | return typeof args[0] === "string" |
| 302 | ? JSON.stringify(args[0]) |
| 303 | : `"" + ${args[0].expr}`; |
| 304 | } |
| 305 | if (!this.supportTemplateLiteral()) return this._es5Concatenation(args); |
| 306 | |
| 307 | // cost comparison between template literal and concatenation: |
| 308 | // both need equal surroundings: `xxx` vs "xxx" |
| 309 | // template literal has constant cost of 3 chars for each expression |
| 310 | // es5 concatenation has cost of 3 + n chars for n expressions in row |
| 311 | // when a es5 concatenation ends with an expression it reduces cost by 3 |
| 312 | // when a es5 concatenation starts with an single expression it reduces cost by 3 |
| 313 | // e. g. `${a}${b}${c}` (3*3 = 9) is longer than ""+a+b+c ((3+3)-3 = 3) |
| 314 | // e. g. `x${a}x${b}x${c}x` (3*3 = 9) is shorter than "x"+a+"x"+b+"x"+c+"x" (4+4+4 = 12) |
| 315 | |
| 316 | let templateCost = 0; |
| 317 | let concatenationCost = 0; |
| 318 | |
| 319 | let lastWasExpr = false; |
| 320 | for (const arg of args) { |
| 321 | const isExpr = typeof arg !== "string"; |
| 322 | if (isExpr) { |
| 323 | templateCost += 3; |
| 324 | concatenationCost += lastWasExpr ? 1 : 4; |
| 325 | } |
| 326 | lastWasExpr = isExpr; |
| 327 | } |
| 328 | if (lastWasExpr) concatenationCost -= 3; |
| 329 | if (typeof args[0] !== "string" && typeof args[1] === "string") { |
| 330 | concatenationCost -= 3; |
| 331 | } |
| 332 | |
| 333 | if (concatenationCost <= templateCost) return this._es5Concatenation(args); |
| 334 | |
| 335 | return `\`${args |
| 336 | .map((arg) => (typeof arg === "string" ? arg : `\${${arg.expr}}`)) |
| 337 | .join("")}\``; |
| 338 | } |
| 339 | |
| 340 | /** |
| 341 | * Returns result expression. |
no test coverage detected