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 { 17 expect 18} from 'chai'; 19import 'mocha'; 20import { DiagnosticCode, DiagnosticError } from '../../src/diagnostic'; 21import { 22 Returnundefined, 23 Stconsttoglobalrecord, 24 Stglobalvar, 25 Sttoglobalrecord, 26 Imm, 27 Lda, 28 Ldai, 29 Sta, 30 VReg, 31 IRNode 32} from "../../src/irnodes"; 33import { 34 FunctionScope, 35 GlobalScope 36} from "../../src/scope"; 37import { 38 GlobalVariable, 39 LocalVariable 40} from "../../src/variable"; 41import { checkInstructions, SnippetCompiler } from "../utils/base"; 42import { creatAstFromSnippet } from "../utils/asthelper" 43import { PandaGen } from '../../src/pandagen'; 44 45describe("VariableDeclarationTest", function () { 46 47 it('var i in the global scope', function () { 48 let snippetCompiler = new SnippetCompiler(); 49 50 snippetCompiler.compile("var i;"); 51 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 52 let globalScope = <GlobalScope>snippetCompiler.getGlobalScope(); 53 let insns = snippetCompiler.getGlobalInsns(); 54 55 let expected = [ 56 new Lda(new VReg()), 57 new Stglobalvar(new Imm(0), "i"), 58 new Returnundefined() 59 ]; 60 expect(checkInstructions(insns, expected)).to.be.true; 61 let v = globalScope.findLocal("i"); 62 expect(v instanceof GlobalVariable).to.be.true; 63 }); 64 65 it('let i in the global scope', function () { 66 let snippetCompiler = new SnippetCompiler(); 67 snippetCompiler.compile("let i;"); 68 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 69 let globalScope = <GlobalScope>snippetCompiler.getGlobalScope(); 70 let insns = snippetCompiler.getGlobalInsns(); 71 let expected = [ 72 new Lda(new VReg()), 73 new Sttoglobalrecord(new Imm(0), 'i'), 74 new Returnundefined() 75 ]; 76 expect(checkInstructions(insns, expected)).to.be.true; 77 let v = globalScope.findLocal("i"); 78 expect(v instanceof LocalVariable).to.be.true; 79 }); 80 81 it('const i in the global scope', function () { 82 let snippetCompiler = new SnippetCompiler(); 83 snippetCompiler.compile("const i = 5;"); 84 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 85 let globalScope = <GlobalScope>snippetCompiler.getGlobalScope(); 86 let insns = snippetCompiler.getGlobalInsns(); 87 let expected = [ 88 new Ldai(new Imm(5)), 89 new Stconsttoglobalrecord(new Imm(0), 'i'), 90 new Returnundefined() 91 ]; 92 expect(checkInstructions(insns, expected)).to.be.true; 93 let v = globalScope.findLocal("i"); 94 expect(v instanceof LocalVariable).to.be.true; 95 }); 96 97 it('var i = 5 in the global scope', function () { 98 let snippetCompiler = new SnippetCompiler(); 99 snippetCompiler.compile("var i = 5;"); 100 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 101 let globalScope = <GlobalScope>snippetCompiler.getGlobalScope(); 102 let insns = snippetCompiler.getGlobalInsns(); 103 let expected = [ 104 new Lda(new VReg()), 105 new Stglobalvar(new Imm(0), "i"), 106 new Ldai(new Imm(5)), 107 new Stglobalvar(new Imm(1), "i"), 108 new Returnundefined() 109 ]; 110 expect(checkInstructions(insns, expected)).to.be.true; 111 let v = globalScope.findLocal("i"); 112 expect(v instanceof GlobalVariable).to.be.true; 113 }); 114 115 it('let i = 5 in the global scope', function () { 116 let snippetCompiler = new SnippetCompiler(); 117 snippetCompiler.compile("let i = 5;"); 118 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 119 let globalScope = <GlobalScope>snippetCompiler.getGlobalScope(); 120 let insns = snippetCompiler.getGlobalInsns(); 121 let expected = [ 122 new Ldai(new Imm(5)), 123 new Sttoglobalrecord(new Imm(0), 'i'), 124 new Returnundefined() 125 ]; 126 expect(checkInstructions(insns, expected)).to.be.true; 127 let v = globalScope.findLocal("i"); 128 expect(v instanceof LocalVariable).to.be.true; 129 }); 130 131 it('var i, j in the global scope', function () { 132 let snippetCompiler = new SnippetCompiler(); 133 snippetCompiler.compile("var i, j;"); 134 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 135 let globalScope = <GlobalScope>snippetCompiler.getGlobalScope(); 136 let i = globalScope.findLocal("i"); 137 expect(i instanceof GlobalVariable).to.be.true; 138 let j = globalScope.findLocal("j"); 139 expect(j instanceof GlobalVariable).to.be.true; 140 }); 141 142 it('let i, j in the global scope', function () { 143 let snippetCompiler = new SnippetCompiler(); 144 snippetCompiler.compile("let i, j;"); 145 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 146 let globalScope = <GlobalScope>snippetCompiler.getGlobalScope(); 147 let i = globalScope.findLocal("i"); 148 expect(i instanceof LocalVariable).to.be.true; 149 let j = globalScope.findLocal("j"); 150 expect(j instanceof LocalVariable).to.be.true; 151 }); 152 153 it('const i, j in the global scope', function () { 154 let snippetCompiler = new SnippetCompiler(); 155 snippetCompiler.compile("const i=5, j=5;"); 156 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 157 let globalScope = <GlobalScope>snippetCompiler.getGlobalScope(); 158 let i = globalScope.findLocal("i"); 159 expect(i instanceof LocalVariable).to.be.true; 160 let j = globalScope.findLocal("j"); 161 expect(j instanceof LocalVariable).to.be.true; 162 }); 163 164 it('var i in a function scope', function () { 165 let snippetCompiler = new SnippetCompiler(); 166 snippetCompiler.compile("function a() {var i;}"); 167 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 168 let funcPg = snippetCompiler.getPandaGenByName("UnitTest.a"); 169 let functionScope = <FunctionScope>funcPg!.getScope(); 170 let insns = funcPg!.getInsns(); 171 let expected = [ 172 new Lda(new VReg()), 173 new Sta(new VReg()), 174 new Returnundefined() 175 ]; 176 177 expect(checkInstructions(insns, expected)).to.be.true; 178 let i = functionScope.findLocal("i"); 179 expect(i).to.not.be.equal(undefined); 180 expect(i instanceof LocalVariable).to.be.true; 181 }); 182 183 it('let i in a function scope', function () { 184 let snippetCompiler = new SnippetCompiler(); 185 snippetCompiler.compile("function a() {let i;}"); 186 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 187 let funcPg = snippetCompiler.getPandaGenByName("UnitTest.a"); 188 let functionScope = <FunctionScope>funcPg!.getScope(); 189 let insns = funcPg!.getInsns(); 190 let expected = [ 191 new Lda(new VReg()), 192 new Sta(new VReg()), 193 new Returnundefined() 194 ]; 195 expect(checkInstructions(insns, expected)).to.be.true; 196 let i = functionScope.findLocal("i"); 197 expect(i).to.be.equal(undefined); 198 }); 199 200 it('const i in a function scope', function () { 201 let snippetCompiler = new SnippetCompiler(); 202 snippetCompiler.compile("function a() {const i = 5;}"); 203 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 204 let funcPg = snippetCompiler.getPandaGenByName("UnitTest.a"); 205 let functionScope = <FunctionScope>funcPg!.getScope(); 206 let insns = funcPg!.getInsns(); 207 let expected = [ 208 new Ldai(new Imm(5)), 209 new Sta(new VReg()), 210 new Returnundefined() 211 ]; 212 expect(checkInstructions(insns, expected)).to.be.true; 213 let i = functionScope.findLocal("i"); 214 expect(i).to.be.equal(undefined); 215 }); 216 217 it('let i in a local scope', function () { 218 let snippetCompiler = new SnippetCompiler(); 219 snippetCompiler.compile("{let i;}"); 220 let funcPg = snippetCompiler.getPandaGenByName("UnitTest.func_main_0"); 221 let localScope = funcPg!.getScope(); 222 let insns = funcPg!.getInsns(); 223 224 let expected = [ 225 new Lda(new VReg()), 226 new Sta(new VReg()), 227 new Returnundefined() 228 ]; 229 expect(checkInstructions(insns, expected)).to.be.true; 230 let i = localScope!.findLocal("i"); 231 expect(i).to.be.equal(undefined); 232 }); 233 234 it('let declaration syntax error', function () { 235 let errorThrown = false; 236 let snippetCompiler = new SnippetCompiler(); 237 try { 238 snippetCompiler.compile("label: let i = 5;"); 239 } catch (err) { 240 expect(err instanceof DiagnosticError).to.be.true; 241 expect((<DiagnosticError>err).code).to.equal(DiagnosticCode.Lexical_declaration_let_not_allowed_in_statement_position); 242 errorThrown = true; 243 } 244 expect(errorThrown).to.be.true; 245 }); 246 247 it('const i in a local scope', function () { 248 let snippetCompiler = new SnippetCompiler(); 249 snippetCompiler.compile("{const i = 5;}"); 250 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 251 let insns = snippetCompiler.getGlobalInsns(); 252 let scope = snippetCompiler.getGlobalScope(); 253 let expected = [ 254 new Ldai(new Imm(5)), 255 new Sta(new VReg()), 256 new Returnundefined() 257 ]; 258 expect(checkInstructions(insns, expected)).to.be.true; 259 let i = scope!.findLocal("i"); 260 expect(i == undefined).to.be.true; // not in global 261 }); 262}); 263