1/*
2 * Copyright (c) 2024 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
16// 1. sendable can only inherit from sendable
17try {
18  class SendableParent {
19    constructor() {
20      'use sendable';
21    }
22  }
23  class SendableChild extends SendableParent {
24    constructor() {
25      'use sendable';
26      super();
27    }
28  }
29  print('sendable inherit from sendable succeed.');
30} catch (err) {
31  print('sendable inherit from sendable failed. err: ' + err + ', code: ' + err.code);
32}
33try {
34  class Parent {
35    constructor() {}
36  }
37  class SendableChild extends Parent {
38    constructor() {
39      'use sendable';
40      super();
41    }
42  }
43  print('sendable inherit from sendable succeed.');
44} catch (err) {
45  print('sendable inherit from non-sendable failed. err: ' + err + ', code: ' + err.code);
46}
47try {
48  class A {
49    constructor() {
50      'use sendable';
51    }
52  }
53  class B extends A {
54    constructor() {
55      'use sendable';
56      super();
57    }
58  }
59  let b = new B();
60  b.__proto__ = new A();
61  print('sendable change proto succeed.');
62} catch (err) {
63  print('sendable change proto failed. err: ' + err + ', code: ' + err.code);
64}
65
66// 2. non-sendable can not inherit from sendable
67try {
68  class Parent {
69    constructor() {}
70  }
71  class Child extends Parent {
72    constructor() {
73      super();
74    }
75  }
76  print('non-sendable inherit from non-sendable succeed.');
77} catch (err) {
78  print('non-sendable inherit from non-sendable failed. err: ' + err + ', code: ' + err.code);
79}
80try {
81  class SendableParent {
82    constructor() {
83      'use sendable';
84    }
85  }
86  class Child extends SendableParent {
87    constructor() {
88      super();
89    }
90  }
91  print('non-sendable inherit from sendable succeed.');
92} catch (err) {
93  print('non-sendable inherit from sendable failed. err: ' + err + ', code: ' + err.code);
94}
95
96// 3. non-sendable can not implement sendable
97
98// 4. sendable can only contain sendable
99try {
100  class A {
101    constructor() {
102      'use sendable';
103    }
104  }
105  class B {
106    a: A | null = null;
107    constructor(a: A) {
108      'use sendable';
109      this.a = a;
110    }
111  }
112  let b = new B(new A());
113  print('sendable contain sendable succeed.');
114} catch (err) {
115  print('sendable contain sendable failed. err: ' + err + ', code: ' + err.code);
116}
117try {
118  class A {
119    constructor() {}
120  }
121  class B {
122    a: A | null = null;
123    constructor(a: A) {
124      'use sendable';
125      this.a = a;
126    }
127  }
128  let b = new B(new A());
129  print('sendable contain non-sendable succeed.');
130} catch (err) {
131  print('sendable contain non-sendable failed. err: ' + err + ', code: ' + err.code);
132}
133try {
134  class A {
135    constructor() {}
136  }
137  class B {
138    static a: A | null = new A();
139    constructor() {
140      'use sendable';
141    }
142  }
143  print('sendable contain static non-sendable succeed.');
144} catch (err) {
145  print('sendable contain static non-sendable failed. err: ' + err + ', code: ' + err.code);
146}
147try {
148  class B {
149    static b: B;
150    constructor() {
151      'use sendable';
152    }
153  }
154  print('sendable contain undefined succeed.');
155} catch (err) {
156  print('sendable contain undefined failed. err: ' + err + ', code: ' + err.code);
157}
158
159// 5. template type of collections must be sendable
160
161// 6. sendable can not use ! assertion
162
163// 7. sendable can not use computeed property names
164
165// 8. sendable can not use variables in current context
166try {
167  class B {
168    constructor() {
169      'use sendable';
170    }
171  }
172  function bar(): B {
173    return new B();
174  }
175  class C {
176    constructor() {
177      'use sendable';
178    }
179    v: B = new B();
180    u: B = bar();
181    foo() {
182      return new B();
183    }
184  }
185  print('sendable contain lexenv succeed.');
186} catch (err) {
187  print('sendable contain lexenv failed. err: ' + err + ', code: ' + err.code);
188}
189
190// 9. sendable can not use decorator except @sendable
191try {
192  class A {
193    constructor() {
194      'use sendable';
195      'use concurrent';
196    }
197  }
198  class B {
199    constructor() {
200      'use sendable';
201    }
202    foo() {
203      'use concurrent';
204    }
205  }
206  print('sendable with concurrent decorator succeed.');
207} catch (err) {
208  print('sendable with concurrent decorator failed. err: ' + err + ', code: ' + err.code);
209}
210
211// 10. sendable can not be initial with object or array
212
213// 11. non-sendable can not be `as` sendable
214
215// 12. the rest
216try {
217  class A {
218    constructor() {
219      'use sendable';
220    }
221  }
222  let a = new A();
223  a.age = 0;
224  print('sendable add property succeed.');
225} catch (err) {
226  print('sendable add property failed. err: ' + err + ', code: ' + err.code);
227}
228try {
229  class A {
230    age: number;
231    constructor() {
232      'use sendable';
233    }
234  }
235  let a = new A();
236  a.age = '0';
237  print('sendable change property succeed.');
238} catch (err) {
239  print('sendable change property failed. err: ' + err + ', code: ' + err.code);
240}
241try {
242  class A {
243    age: number;
244    constructor() {
245      'use sendable';
246      this.age = 0;
247    }
248  }
249  let a = new A();
250  delete a.age;
251  print('sendable delete property succeed.');
252} catch (err) {
253  print('sendable delete property failed. err: ' + err + ', code: ' + err.code);
254}
255//sendable can not change attr.
256class Test {
257  v: number = 123
258  constructor() {
259    'use sendable'
260  }
261}
262
263let test = new Test()
264try {
265  Object.defineProperty(test, 'v', {
266    value: 42,
267    writable: false,
268  });
269} catch (e) {
270  print("sendable can not change attr. err: " + e);
271}
272