mirror of
https://github.com/dlang/dmd.git
synced 2025-04-28 06:00:13 +03:00
Deprecate traits(isVirtualFunction) and traits(getVirtualFunctions) (#14802)
This commit is contained in:
parent
35abfc4a9f
commit
636e61ea4d
10 changed files with 70 additions and 72 deletions
11
changelog/dmd.get-is-virtual-function.dd
Normal file
11
changelog/dmd.get-is-virtual-function.dd
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Deprecate `traits(isVirtualFunction)` and `traits(getVirtualFunctions)`
|
||||||
|
|
||||||
|
Up until this release, D had both `traits(isVirtualFunction)` and `traits(isVirtualMethod)`
|
||||||
|
(and their coressponding `traits(get...)` counterpart). The differenrcte between the two is
|
||||||
|
that `isVirtualFunction` returns true for `final` methods that do not override anything. This
|
||||||
|
is in contradiction with the D spec which states that `final` functions that do not override
|
||||||
|
other functions cannot be virtual. `isVirtualMethod` correctly returns `false` in that case.
|
||||||
|
|
||||||
|
Starting with this release, both `traits(isVirtualFunction)` and `traits(getVirtualFunctions)`
|
||||||
|
are deprecated. If the behavior of `traits(isVirtualFunction)` is desired, it can be achieved by
|
||||||
|
`traits(isVirtualMethod, f) || (traits(isFinalFunction, f) && !traits(isOverrideFunction, f))`.
|
|
@ -634,6 +634,10 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
|
||||||
}
|
}
|
||||||
if (e.ident == Id.isVirtualFunction)
|
if (e.ident == Id.isVirtualFunction)
|
||||||
{
|
{
|
||||||
|
// @@@DEPRECATED2.121@@@
|
||||||
|
// Deprecated in 2.101 - Can be removed from 2.121
|
||||||
|
e.deprecation("`traits(isVirtualFunction)` is deprecated. Use `traits(isVirtualMethod)` instead");
|
||||||
|
|
||||||
if (dim != 1)
|
if (dim != 1)
|
||||||
return dimError(1);
|
return dimError(1);
|
||||||
|
|
||||||
|
@ -995,6 +999,13 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
|
||||||
if (errors < global.errors)
|
if (errors < global.errors)
|
||||||
e.error("`%s` cannot be resolved", eorig.toChars());
|
e.error("`%s` cannot be resolved", eorig.toChars());
|
||||||
|
|
||||||
|
if (e.ident == Id.getVirtualFunctions)
|
||||||
|
{
|
||||||
|
// @@@DEPRECATED2.121@@@
|
||||||
|
// Deprecated in 2.101 - Can be removed from 2.121
|
||||||
|
e.deprecation("`traits(getVirtualFunctions)` is deprecated. Use `traits(getVirtualMethods)` instead");
|
||||||
|
}
|
||||||
|
|
||||||
/* Create tuple of functions of ex
|
/* Create tuple of functions of ex
|
||||||
*/
|
*/
|
||||||
auto exps = new Expressions();
|
auto exps = new Expressions();
|
||||||
|
|
|
@ -14,11 +14,6 @@ class Foo
|
||||||
{
|
{
|
||||||
auto dg = &f;
|
auto dg = &f;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (f; __traits(getVirtualFunctions, typeof(this), "bar"))
|
|
||||||
{
|
|
||||||
auto dg = &f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint bar() { return 0; }
|
uint bar() { return 0; }
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// REQUIRED_ARGS: -de
|
||||||
|
|
||||||
|
/*
|
||||||
|
TEST_OUTPUT:
|
||||||
|
---
|
||||||
|
fail_compilation/deprecate_getVirtualFunctions.d(18): Deprecation: `traits(isVirtualFunction)` is deprecated. Use `traits(isVirtualMethod)` instead
|
||||||
|
fail_compilation/deprecate_getVirtualFunctions.d(19): Deprecation: `traits(getVirtualFunctions)` is deprecated. Use `traits(getVirtualMethods)` instead
|
||||||
|
---
|
||||||
|
*/
|
||||||
|
|
||||||
|
class A
|
||||||
|
{
|
||||||
|
void fun() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
auto a = __traits(isVirtualFunction, A.fun);
|
||||||
|
foreach(f; __traits(getVirtualFunctions, A, "fun")) {}
|
||||||
|
}
|
|
@ -8,4 +8,4 @@ fail_compilation/fail19076.d(11): Error: `(I).V` cannot be resolved
|
||||||
|
|
||||||
interface P { }
|
interface P { }
|
||||||
interface I : P { }
|
interface I : P { }
|
||||||
auto F = __traits(getVirtualFunctions, I, "V");
|
auto F = __traits(getVirtualMethods, I, "V");
|
||||||
|
|
|
@ -1,28 +1,29 @@
|
||||||
/* TEST_OUTPUT:
|
/* TEST_OUTPUT:
|
||||||
---
|
---
|
||||||
fail_compilation/test17096.d(28): Error: expected 1 arguments for `isPOD` but had 2
|
fail_compilation/test17096.d(29): Error: expected 1 arguments for `isPOD` but had 2
|
||||||
fail_compilation/test17096.d(29): Error: expected 1 arguments for `isNested` but had 2
|
fail_compilation/test17096.d(30): Error: expected 1 arguments for `isNested` but had 2
|
||||||
fail_compilation/test17096.d(30): Error: expected 1 arguments for `isVirtualFunction` but had 2
|
fail_compilation/test17096.d(31): Deprecation: `traits(isVirtualFunction)` is deprecated. Use `traits(isVirtualMethod)` instead
|
||||||
fail_compilation/test17096.d(31): Error: expected 1 arguments for `isVirtualMethod` but had 2
|
fail_compilation/test17096.d(31): Error: expected 1 arguments for `isVirtualFunction` but had 2
|
||||||
fail_compilation/test17096.d(32): Error: expected 1 arguments for `isAbstractFunction` but had 2
|
fail_compilation/test17096.d(32): Error: expected 1 arguments for `isVirtualMethod` but had 2
|
||||||
fail_compilation/test17096.d(33): Error: expected 1 arguments for `isFinalFunction` but had 2
|
fail_compilation/test17096.d(33): Error: expected 1 arguments for `isAbstractFunction` but had 2
|
||||||
fail_compilation/test17096.d(34): Error: expected 1 arguments for `isOverrideFunction` but had 2
|
fail_compilation/test17096.d(34): Error: expected 1 arguments for `isFinalFunction` but had 2
|
||||||
fail_compilation/test17096.d(35): Error: expected 1 arguments for `isStaticFunction` but had 2
|
fail_compilation/test17096.d(35): Error: expected 1 arguments for `isOverrideFunction` but had 2
|
||||||
fail_compilation/test17096.d(36): Error: expected 1 arguments for `isRef` but had 2
|
fail_compilation/test17096.d(36): Error: expected 1 arguments for `isStaticFunction` but had 2
|
||||||
fail_compilation/test17096.d(37): Error: expected 1 arguments for `isOut` but had 2
|
fail_compilation/test17096.d(37): Error: expected 1 arguments for `isRef` but had 2
|
||||||
fail_compilation/test17096.d(38): Error: expected 1 arguments for `isLazy` but had 2
|
fail_compilation/test17096.d(38): Error: expected 1 arguments for `isOut` but had 2
|
||||||
fail_compilation/test17096.d(39): Error: expected 1 arguments for `identifier` but had 2
|
fail_compilation/test17096.d(39): Error: expected 1 arguments for `isLazy` but had 2
|
||||||
fail_compilation/test17096.d(40): Error: expected 1 arguments for `getProtection` but had 2
|
fail_compilation/test17096.d(40): Error: expected 1 arguments for `identifier` but had 2
|
||||||
fail_compilation/test17096.d(41): Error: expected 1 arguments for `parent` but had 2
|
fail_compilation/test17096.d(41): Error: expected 1 arguments for `getProtection` but had 2
|
||||||
fail_compilation/test17096.d(42): Error: expected 1 arguments for `classInstanceSize` but had 2
|
fail_compilation/test17096.d(42): Error: expected 1 arguments for `parent` but had 2
|
||||||
fail_compilation/test17096.d(43): Error: expected 1 arguments for `allMembers` but had 2
|
fail_compilation/test17096.d(43): Error: expected 1 arguments for `classInstanceSize` but had 2
|
||||||
fail_compilation/test17096.d(44): Error: expected 1 arguments for `derivedMembers` but had 2
|
fail_compilation/test17096.d(44): Error: expected 1 arguments for `allMembers` but had 2
|
||||||
fail_compilation/test17096.d(45): Error: expected 1 arguments for `getAliasThis` but had 2
|
fail_compilation/test17096.d(45): Error: expected 1 arguments for `derivedMembers` but had 2
|
||||||
fail_compilation/test17096.d(46): Error: expected 1 arguments for `getAttributes` but had 2
|
fail_compilation/test17096.d(46): Error: expected 1 arguments for `getAliasThis` but had 2
|
||||||
fail_compilation/test17096.d(47): Error: expected 1 arguments for `getFunctionAttributes` but had 2
|
fail_compilation/test17096.d(47): Error: expected 1 arguments for `getAttributes` but had 2
|
||||||
fail_compilation/test17096.d(48): Error: expected 1 arguments for `getUnitTests` but had 2
|
fail_compilation/test17096.d(48): Error: expected 1 arguments for `getFunctionAttributes` but had 2
|
||||||
fail_compilation/test17096.d(49): Error: expected 1 arguments for `getVirtualIndex` but had 2
|
fail_compilation/test17096.d(49): Error: expected 1 arguments for `getUnitTests` but had 2
|
||||||
fail_compilation/test17096.d(50): Error: a single type expected for trait pointerBitmap
|
fail_compilation/test17096.d(50): Error: expected 1 arguments for `getVirtualIndex` but had 2
|
||||||
|
fail_compilation/test17096.d(51): Error: a single type expected for trait pointerBitmap
|
||||||
---
|
---
|
||||||
*/
|
*/
|
||||||
enum b03 = __traits(isPOD, 1, 2);
|
enum b03 = __traits(isPOD, 1, 2);
|
||||||
|
|
|
@ -63,8 +63,6 @@ TmpPrm!(__traits(getMember, Foo, "MyInt")) tpt = TmpPrm!(__traits(getMember, Foo
|
||||||
int virtual(int p){return p;}
|
int virtual(int p){return p;}
|
||||||
void test(this T)()
|
void test(this T)()
|
||||||
{
|
{
|
||||||
alias vf = __traits(getVirtualFunctions, Class, "virtual");
|
|
||||||
assert(vf.length == 2);
|
|
||||||
alias vm = __traits(getVirtualMethods, Class, "virtual");
|
alias vm = __traits(getVirtualMethods, Class, "virtual");
|
||||||
assert(vm.length == 1);
|
assert(vm.length == 1);
|
||||||
assert(vm[0](42) == 42);
|
assert(vm[0](42) == 42);
|
||||||
|
|
|
@ -312,14 +312,6 @@ void test9()
|
||||||
|
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
|
|
||||||
void test10()
|
|
||||||
{
|
|
||||||
assert(__traits(isVirtualFunction, C.bar) == true);
|
|
||||||
assert(__traits(isVirtualFunction, S.bar) == false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************/
|
|
||||||
|
|
||||||
void test11()
|
void test11()
|
||||||
{
|
{
|
||||||
assert(__traits(isAbstractFunction, C.bar) == false);
|
assert(__traits(isAbstractFunction, C.bar) == false);
|
||||||
|
@ -403,24 +395,6 @@ class D15
|
||||||
int foo(int) { return 2; }
|
int foo(int) { return 2; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void test15()
|
|
||||||
{
|
|
||||||
D15 d = new D15();
|
|
||||||
|
|
||||||
assert(__traits(getVirtualFunctions, D15, "foo").length == 2);
|
|
||||||
assert(typeid(typeof(__traits(getVirtualFunctions, D15, "foo")[0])).toString()
|
|
||||||
== "void function()");
|
|
||||||
assert(typeid(typeof(__traits(getVirtualFunctions, D15, "foo")[1])).toString()
|
|
||||||
== "int function(int)");
|
|
||||||
|
|
||||||
alias typeof(__traits(getVirtualFunctions, D15, "foo")) b;
|
|
||||||
assert(typeid(b[0]).toString() == "void function()");
|
|
||||||
assert(typeid(b[1]).toString() == "int function(int)");
|
|
||||||
|
|
||||||
auto i = __traits(getVirtualFunctions, d, "foo")[1](1);
|
|
||||||
assert(i == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
|
|
||||||
struct S16 { }
|
struct S16 { }
|
||||||
|
@ -714,14 +688,6 @@ interface AA
|
||||||
int YYY();
|
int YYY();
|
||||||
}
|
}
|
||||||
|
|
||||||
class CC : AA
|
|
||||||
{
|
|
||||||
final int YYY() { return 4; }
|
|
||||||
}
|
|
||||||
|
|
||||||
static assert(__traits(isVirtualMethod, CC.YYY));
|
|
||||||
static assert(__traits(getVirtualMethods, CC, "YYY").length == 1);
|
|
||||||
|
|
||||||
class DD
|
class DD
|
||||||
{
|
{
|
||||||
final int YYY() { return 4; }
|
final int YYY() { return 4; }
|
||||||
|
@ -790,8 +756,6 @@ void test7858()
|
||||||
|
|
||||||
static assert(__traits(isFinalFunction, C.ffunc) ==
|
static assert(__traits(isFinalFunction, C.ffunc) ==
|
||||||
__traits(isFinalFunction, __traits(getOverloads, C, "ffunc")[0])); // NG
|
__traits(isFinalFunction, __traits(getOverloads, C, "ffunc")[0])); // NG
|
||||||
static assert(__traits(isVirtualFunction, C.vfunc) ==
|
|
||||||
__traits(isVirtualFunction, __traits(getOverloads, C, "vfunc")[0])); // NG
|
|
||||||
static assert(__traits(isVirtualMethod, C.vfunc) ==
|
static assert(__traits(isVirtualMethod, C.vfunc) ==
|
||||||
__traits(isVirtualMethod, __traits(getOverloads, C, "vfunc")[0])); // NG
|
__traits(isVirtualMethod, __traits(getOverloads, C, "vfunc")[0])); // NG
|
||||||
static assert(__traits(isAbstractFunction, C.afunc) ==
|
static assert(__traits(isAbstractFunction, C.afunc) ==
|
||||||
|
@ -1456,13 +1420,11 @@ int main()
|
||||||
test7();
|
test7();
|
||||||
test8();
|
test8();
|
||||||
test9();
|
test9();
|
||||||
test10();
|
|
||||||
test11();
|
test11();
|
||||||
test12();
|
test12();
|
||||||
test13();
|
test13();
|
||||||
test7123();
|
test7123();
|
||||||
test14();
|
test14();
|
||||||
test15();
|
|
||||||
test16();
|
test16();
|
||||||
test17();
|
test17();
|
||||||
test18();
|
test18();
|
||||||
|
|
|
@ -654,7 +654,7 @@ if (func.length == 1 /*&& isCallable!func*/)
|
||||||
int test(int);
|
int test(int);
|
||||||
int test() @property;
|
int test() @property;
|
||||||
}
|
}
|
||||||
alias ov = __traits(getVirtualFunctions, Overloads, "test");
|
alias ov = __traits(getVirtualMethods, Overloads, "test");
|
||||||
alias F_ov0 = FunctionTypeOf!(ov[0]);
|
alias F_ov0 = FunctionTypeOf!(ov[0]);
|
||||||
alias F_ov1 = FunctionTypeOf!(ov[1]);
|
alias F_ov1 = FunctionTypeOf!(ov[1]);
|
||||||
alias F_ov2 = FunctionTypeOf!(ov[2]);
|
alias F_ov2 = FunctionTypeOf!(ov[2]);
|
||||||
|
|
|
@ -1417,7 +1417,7 @@ class TypeInfo_Function : TypeInfo
|
||||||
int func(int a, int b);
|
int func(int a, int b);
|
||||||
}
|
}
|
||||||
|
|
||||||
alias functionTypes = typeof(__traits(getVirtualFunctions, C, "func"));
|
alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
|
||||||
assert(typeid(functionTypes[0]).toString() == "void function()");
|
assert(typeid(functionTypes[0]).toString() == "void function()");
|
||||||
assert(typeid(functionTypes[1]).toString() == "void function(int)");
|
assert(typeid(functionTypes[1]).toString() == "void function(int)");
|
||||||
assert(typeid(functionTypes[2]).toString() == "int function(int, int)");
|
assert(typeid(functionTypes[2]).toString() == "int function(int, int)");
|
||||||
|
@ -1431,7 +1431,7 @@ class TypeInfo_Function : TypeInfo
|
||||||
void func(int a);
|
void func(int a);
|
||||||
}
|
}
|
||||||
|
|
||||||
alias functionTypes = typeof(__traits(getVirtualFunctions, C, "func"));
|
alias functionTypes = typeof(__traits(getVirtualMethods, C, "func"));
|
||||||
|
|
||||||
Object obj = typeid(functionTypes[0]);
|
Object obj = typeid(functionTypes[0]);
|
||||||
assert(obj.opEquals(typeid(functionTypes[0])));
|
assert(obj.opEquals(typeid(functionTypes[0])));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue