1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import * as ts from "typescript"; 17import { PandaGen } from "../pandagen"; 18import { VReg } from "../irnodes"; 19 20function genRawString(pandaGen: PandaGen, expr: ts.TemplateExpression | ts.NoSubstitutionTemplateLiteral): void { 21 let text = ""; 22 if (ts.isTemplateExpression(expr)) { 23 text = expr.head.rawText!; 24 } else { 25 text = expr.rawText!; 26 } 27 28 text = text.replace(/(\r?\n|\r)/gm, "\n"); 29 pandaGen.loadAccumulatorString(expr, text); 30} 31 32function genCookedString(pandaGen: PandaGen, expr: ts.TemplateExpression | ts.NoSubstitutionTemplateLiteral): void { 33 let text = ""; 34 if (ts.isTemplateExpression(expr)) { 35 text = expr.head.text; 36 } else { 37 text = expr.text; 38 } 39 40 if (text.indexOf("\\u{") != -1) { 41 text = eval("'" + text + "'"); 42 text = unescape(text.replace(/\u/g, "%u")); 43 } 44 45 pandaGen.loadAccumulatorString(expr, text); 46} 47 48function genTemplateArrayArg(pandaGen: PandaGen, expr: ts.TemplateExpression | ts.NoSubstitutionTemplateLiteral, rawArr: VReg, cookedArr: VReg): void { 49 let spans = undefined; 50 if (ts.isTemplateExpression(expr)) { 51 spans = expr.templateSpans; 52 } 53 54 let elemIndex = 0; 55 let indexReg = pandaGen.getTemp(); 56 let rawArrTmp = pandaGen.getTemp(); 57 let cookedArrTmp = pandaGen.getTemp(); 58 59 pandaGen.createEmptyArray(expr); 60 pandaGen.storeAccumulator(expr, rawArrTmp); 61 pandaGen.createEmptyArray(expr); 62 pandaGen.storeAccumulator(expr, cookedArrTmp); 63 pandaGen.loadAccumulatorInt(expr, elemIndex); 64 pandaGen.storeAccumulator(expr, indexReg); 65 66 genRawString(pandaGen, expr); 67 pandaGen.storeObjProperty(expr, rawArrTmp, indexReg); 68 69 genCookedString(pandaGen, expr); 70 pandaGen.storeObjProperty(expr, cookedArrTmp, indexReg); 71 ++elemIndex; 72 73 if (spans && spans.length) { 74 spans.forEach((span: ts.TemplateSpan) => { 75 pandaGen.loadAccumulatorInt(span, elemIndex); 76 pandaGen.storeAccumulator(span, indexReg); 77 pandaGen.loadAccumulatorString(span, span.literal.rawText === undefined ? span.literal.text : span.literal.rawText); 78 pandaGen.storeObjProperty(span, rawArrTmp, indexReg); 79 80 pandaGen.loadAccumulatorString(span, span.literal.text); 81 pandaGen.storeObjProperty(span, cookedArrTmp, indexReg); 82 ++elemIndex; 83 }); 84 } 85 86 pandaGen.moveVreg(expr, rawArr, rawArrTmp); 87 pandaGen.moveVreg(expr, cookedArr, cookedArrTmp); 88 pandaGen.freeTemps(indexReg, rawArrTmp, cookedArrTmp); 89} 90 91export function getTemplateObject(pandaGen: PandaGen, expr: ts.TaggedTemplateExpression): void { 92 let templateArgs = pandaGen.getTemp(); 93 let indexReg = pandaGen.getTemp(); 94 let rawArr = pandaGen.getTemp(); 95 let cookedArr = pandaGen.getTemp(); 96 97 genTemplateArrayArg(pandaGen, expr.template, rawArr, cookedArr); 98 pandaGen.createEmptyArray(expr); 99 pandaGen.storeAccumulator(expr, templateArgs); 100 101 let elemIndex = 0; 102 pandaGen.loadAccumulatorInt(expr, elemIndex); 103 pandaGen.storeAccumulator(expr, indexReg); 104 pandaGen.loadAccumulator(expr, rawArr); 105 pandaGen.storeObjProperty(expr, templateArgs, indexReg); 106 ++elemIndex; 107 pandaGen.loadAccumulatorInt(expr, elemIndex); 108 pandaGen.storeAccumulator(expr, indexReg); 109 pandaGen.loadAccumulator(expr, cookedArr); 110 pandaGen.storeObjProperty(expr, templateArgs, indexReg); 111 112 pandaGen.getTemplateObject(expr, templateArgs); 113 pandaGen.freeTemps(templateArgs, indexReg, rawArr, cookedArr); 114} 115