• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
21    Copyrestargs,
22    Definefunc,
23    Returnundefined,
24    Stglobalvar,
25    Sttoglobalrecord,
26    Stricteq,
27    Imm,
28    Jeqz,
29    Label,
30    Lda,
31    Ldai,
32    Sta,
33    VReg,
34    IRNode
35} from "../../src/irnodes";
36import {
37    GlobalVariable,
38    LocalVariable
39} from "../../src/variable";
40import { checkInstructions, compileAllSnippet, SnippetCompiler } from "../utils/base";
41import { creatAstFromSnippet } from "../utils/asthelper"
42import { PandaGen } from '../../src/pandagen';
43
44describe("FunctionDeclarationTest", function () {
45    it('function definition in the global scope', function () {
46        let snippetCompiler = new SnippetCompiler();
47        snippetCompiler.compile("function foo() {}");
48        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
49        let funcInternalName = "UnitTest.foo";
50        let funcName = "foo";
51        let expected = [
52            new Definefunc(new Imm(0), funcInternalName, new Imm(0)),
53            new Stglobalvar(new Imm(1), funcName),
54            new Returnundefined()
55        ];
56        let insns = snippetCompiler.getGlobalInsns();
57        let globalScope = snippetCompiler.getGlobalScope();
58        expect(checkInstructions(insns, expected)).to.be.true;
59        let foo = globalScope!.findLocal(funcName);
60        expect(foo != undefined).to.be.true;
61        expect(foo instanceof GlobalVariable).to.be.true;
62    });
63
64    it('function redefinition in the global scope', function () {
65        let snippetCompiler = new SnippetCompiler();
66        snippetCompiler.compile(`
67      function foo() {}
68      function foo() {}
69      `);
70        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
71        let expected = [
72            new Definefunc(new Imm(0), "UnitTest.#2#foo", new Imm(0)),
73            new Stglobalvar(new Imm(1), "foo"),
74            new Returnundefined()
75        ];
76        let insns = snippetCompiler.getGlobalInsns();
77        let globalScope = snippetCompiler.getGlobalScope();
78        expect(checkInstructions(insns, expected)).to.be.true;
79        let foo = globalScope!.findLocal("foo");
80        expect(foo != undefined).to.be.true;
81        expect(foo instanceof GlobalVariable).to.be.true;
82    });
83
84    it('function definition inside a function', function () {
85        let snippetCompiler = new SnippetCompiler();
86        snippetCompiler.compile(`function out() {function foo() {}}`);
87        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
88        let funcReg = new VReg();
89        let expected = [
90            new Definefunc(new Imm(0), "UnitTest.foo", new Imm(0)),
91            new Sta(funcReg),
92
93            new Returnundefined()
94        ];
95        let functionPg = snippetCompiler.getPandaGenByName("UnitTest.out");
96        let insns = functionPg!.getInsns();
97        let functionScope = functionPg!.getScope();
98
99        expect(checkInstructions(insns!, expected)).to.be.true;
100        let foo = functionScope!.findLocal("foo");
101        expect(foo != undefined).to.be.true;
102        expect(foo instanceof LocalVariable).to.be.true;
103        let parameterLength = functionPg!.getParameterLength();
104        expect(parameterLength === 0).to.be.true;
105    });
106
107    it("function expression", function () {
108        let snippetCompiler = new SnippetCompiler();
109        snippetCompiler.compile("let foo = function() {}");
110        let insns = snippetCompiler.getGlobalInsns();
111        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
112        let expected = [
113            new Definefunc(new Imm(0), "UnitTest.foo", new Imm(0)),
114            new Sttoglobalrecord(new Imm(1), "foo"),
115            new Returnundefined()
116        ];
117        expect(checkInstructions(insns, expected)).to.be.true;
118    });
119
120    it("Parameters with initializer", function () {
121        let compilerunit = compileAllSnippet("function test(a, b = 1) {}");
122        let undefinedVReg = new VReg();
123        let value = new VReg();
124        let endLabel = new Label();
125
126        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
127        let expectedMain = [
128            new Definefunc(new Imm(0), "UnitTest.test", new Imm(1)),
129            new Stglobalvar(new Imm(1), "test"),
130            new Returnundefined()
131        ];
132
133        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
134        let expectedFunc = [
135            // func_test_0
136            new Lda(new VReg()),
137            new Stricteq(new Imm(0), undefinedVReg),
138            new Jeqz(endLabel),
139            new Ldai(new Imm(1)),
140            new Sta(value),
141            endLabel,
142            new Returnundefined(),
143        ];
144
145        compilerunit.forEach(element => {
146            if (element.internalName === "UnitTest.func_main_0") {
147                let insns = element.getInsns();
148                expect(checkInstructions(insns, expectedMain)).to.be.true;
149            } else if (element.internalName === "UnitTest.test") {
150                let insns = element.getInsns();
151                expect(checkInstructions(insns, expectedFunc)).to.be.true;
152                let parameterLength = element.getParameterLength();
153                expect(parameterLength === 1).to.be.true;
154            }
155        });
156    });
157
158    it("Rest Parameters", function () {
159        let snippetCompiler = new SnippetCompiler();
160        snippetCompiler.compile(`function test(a, ...b) {}`);
161
162        IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined);
163        let idx = new Imm(1);
164        let lastParam = new VReg();
165        let expectedFunc = [
166            // func_test_0
167            new Copyrestargs(idx),
168            new Sta(lastParam),
169            new Returnundefined(),
170        ];
171
172        let functionPg = snippetCompiler.getPandaGenByName("UnitTest.test");
173        let insns = functionPg!.getInsns();
174
175        expect(checkInstructions(insns, expectedFunc)).to.be.true;
176    });
177});
178