!2407 Added support extension functions for arrays

Merge pull request !2407 from Maxim Logaev/impl-extension-functions-for-array
This commit is contained in:
openharmony_ci 2024-11-22 06:15:38 +00:00 committed by Gitee
commit da6e0b36c5
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 354 additions and 0 deletions

View File

@ -0,0 +1,97 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
cases:
# 0. Regular extension functions
- decl: |-
class A {}
function A[].test() { return 1 }
function A[][].test() { return 2 }
function A[][][].test() { return 3 }
use: |-
let a: A[] = []
let b: A[][] = [[]]
let c: A[][][] = [[[]]]
assert a.test() == 1
assert b.test() == 2
assert c.test() == 3
# 1. Extension functions with different signatures
- decl: |-
class A {}
function A[].test(n: double) { return 1 }
function A[].test(n: string) { return 2 }
function A[].test(n: int) { return 3 }
use: |-
let a: A[] = [new A(), new A(), new A()]
assert a.test(1) == 3
assert a.test(14.1) == 1
assert a.test("test") == 2
# 2. Extension Function working with an array element
- decl: |-
class A {
value: int
constructor(n: int) { this.value = n }
}
function A[].test(i: int) { return this[i].value }
use: |-
let a: A[] = [new A(42), new A(81), new A(1), new A(890)]
assert a.test(0) == 42
assert a.test(1) == 81
assert a.test(2) == 1
assert a.test(3) == 890
# 3. Extension function working with built-in array member
- decl: |-
class A {}
function A[].test_len() { return this.length }
use: |-
let a: A[] = [new A(), new A(), new A(), new A()]
let b: A[] = []
assert a.test_len() == 4
assert b.test_len() == 0
# 4. Extension function with the same signatures for the class and the array.
- decl: |-
class A {}
function A.test() { return 1 }
function A[].test() { return 2 }
use: |-
let a = new A()
let b = [new A()]
assert a.test() == 1
assert b.test() == 2
# 5. Extension function for primitive array
- decl: |-
function int[].sum() {
let sum: int = 0;
for (let i of this) {
sum += i
}
return sum;
}
use: |-
let a: int[] = [800000, 80000, 8000, 800, 80, 8]
assert a.sum() == 888888
# 6. Extension function is shadowed by built-in function
- decl: |-
function double[].toString() {
return "ext-func"
}
use: |-
let a = [4.211, 0.00001, 1.2, 1.999]
assert a.toString() == "4.211,0.00001,1.2,1.999"

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{%- for c in cases %}
/*---
desc: >-
The extension function mechanism allows using a special form of top-level functions
as extensions of class, interface or array.
These cases test array support.
---*/
{{c.decl}}
function main() {
{{c.use|indent}}
}
{%- endfor %}

View File

@ -0,0 +1,96 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
cases:
# 0. Regular extension functions
- decl: |-
class A {}
function A.test(n: int) { return n }
use: |-
let a = new A()
assert a.test(99) == 99
# 1. Extension functions with different signatures
- decl: |-
class A {}
function A.test(n: double) { return 1 }
function A.test(n: string) { return 2 }
function A.test(n: int) { return 3 }
use: |-
let a = new A()
assert a.test(1) == 3
assert a.test(14.1) == 1
assert a.test("test") == 2
# 2. Extension function working with class member
- decl: |-
class A { n1: int = 10 }
function A.test() { return this.n1 }
use: |-
let a = new A()
assert a.test() == 10
# 3. Extension function working with class member function
- decl: |-
class A {
sum(n1: int, n2: int) {
return n1 + n2
}
}
function A.test(n1: int, n2: int) {
return this.sum(n1, n2)
}
use: |-
let a = new A()
assert a.test(99, 100) == 199
# 4. Extension function is shadowed by a class member function
- decl: |-
class A {
test(): int { return 1 }
}
function A.test(): int { return 2 }
use: |-
let a = new A()
assert a.test() == 1
# 5. Extension function and member function with different signatures
- decl: |-
class A {
test(n: long): int { return 1 }
}
function A.test(n: double): int { return 2 }
use: |-
let a = new A()
assert a.test(4140100.0) == 2
assert a.test(4140100) == 1
# 6. Extension function for built-in class
- decl: |-
function Long.test_add(n: long): long {
return this as long + n
}
use: |-
let a: Long = 1002000
assert a.test_add(444) == 1002444
# 7. Extension function is shadowed by built-in function
- decl: |-
function Object.toString() {
return "ext-func"
}
use: |-
let a = new Object()
assert a.toString() == "[object Object]"

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{%- for c in cases %}
/*---
desc: >-
The extension function mechanism allows using a special form of top-level functions
as extensions of class, interface or array.
These cases test class support.
---*/
{{c.decl}}
function main() {
{{c.use|indent}}
}
{%- endfor %}

View File

@ -0,0 +1,74 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
cases:
# 0. Regular extension functions
- decl: |-
interface I {}
class A implements I {}
function I.test(n: int) { return n }
use: |-
let a = new A()
assert a.test(99) == 99
# 1. Extension functions with different signatures
- decl: |-
interface I {}
class A implements I {}
function I.test(n: double) { return 1 }
function I.test(n: string) { return 2 }
function I.test(n: int) { return 3 }
use: |-
let a = new A()
assert a.test(1) == 3
assert a.test(14.1) == 1
assert a.test("test") == 2
# 2. Extension function working with interface member function
- decl: |-
interface I {
sum(n1: int, n2: int) {
return n1 + n2
}
}
class A implements I {}
function I.test(n1: int, n2: int) {
return this.sum(n1, n2)
}
use: |-
let a = new A()
assert a.test(99, 100) == 199
# 3. Extension function is shadowed by a interface member function
- decl: |-
interface I {
test(): int { return 1 }
}
class A implements I {}
function I.test(): int { return 2 }
use: |-
let a = new A()
assert a.test() == 1
# 4. Extension function and member function with different signatures
- decl: |-
interface I {
test(n: long): int { return 1 }
}
class A implements I {}
function I.test(n: double): int { return 2 }
use: |-
let a = new A()
assert a.test(4140100.0) == 2
assert a.test(4140100) == 1

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{%- for c in cases %}
/*---
desc: >-
The extension function mechanism allows using a special form of top-level functions
as extensions of class, interface or array.
These cases test interface support.
---*/
{{c.decl}}
function main() {
{{c.use|indent}}
}
{%- endfor %}