mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 500870 - NS_OVERRIDE indicates that a method must override a base-class method, r=taras
--HG-- extra : rebase_source : 3dc3327030dc2cdf45bdd9170c5e9d02908c0d0c
This commit is contained in:
parent
90f86309a0
commit
b4cc34446e
@ -5,6 +5,7 @@ DEHYDRA_SCRIPT = $(topsrcdir)/config/static-checking.js
|
||||
|
||||
DEHYDRA_MODULES = \
|
||||
$(topsrcdir)/xpcom/analysis/final.js \
|
||||
$(topsrcdir)/xpcom/analysis/override.js \
|
||||
$(topsrcdir)/xpcom/analysis/must-override.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -62,6 +62,12 @@ function signaturesMatch(m1, m2)
|
||||
{
|
||||
if (m1.shortName != m2.shortName)
|
||||
return false;
|
||||
|
||||
if (m1.isVirtual != m2.isVirtual)
|
||||
return false;
|
||||
|
||||
if (m1.isStatic != m2.isStatic)
|
||||
return false;
|
||||
|
||||
let p1 = m1.type.parameters;
|
||||
let p2 = m2.type.parameters;
|
||||
|
42
xpcom/analysis/override.js
Normal file
42
xpcom/analysis/override.js
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* NS_OVERRIDE may be marked on class methods which are intended to override
|
||||
* a method in a base class. If the method is removed or altered in the base
|
||||
* class, the compiler will force all subclass overrides to be modified.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate all the base classes recursively of class `c`.
|
||||
*/
|
||||
function all_bases(c)
|
||||
{
|
||||
for each (let b in c.bases) {
|
||||
yield b.type;
|
||||
for (let bb in all_bases(b.type))
|
||||
yield bb;
|
||||
}
|
||||
}
|
||||
|
||||
function process_decl(d)
|
||||
{
|
||||
if (!hasAttribute(d, 'NS_override'))
|
||||
return;
|
||||
|
||||
if (!d.memberOf || !d.isFunction) {
|
||||
error("%s is marked NS_OVERRIDE but is not a class function.".format(d.name), d.loc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (d.isStatic) {
|
||||
error("Marking NS_OVERRIDE on static function %s is meaningless.".format(d.name), d.loc);
|
||||
return;
|
||||
}
|
||||
|
||||
for (let base in all_bases(d.memberOf)) {
|
||||
for each (let m in base.members) {
|
||||
if (m.shortName == d.shortName && signaturesMatch(m, d))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
error("NS_OVERRIDE function %s does not override a base class method with the same name and signature".format(d.name), d.loc);
|
||||
}
|
@ -505,11 +505,13 @@ typedef PRUint32 nsrefcnt;
|
||||
# define NS_INPARAM __attribute__((user("NS_inparam")))
|
||||
# define NS_OUTPARAM __attribute__((user("NS_outparam")))
|
||||
# define NS_INOUTPARAM __attribute__((user("NS_inoutparam")))
|
||||
# define NS_OVERRIDE __attribute__((user("NS_override")))
|
||||
#else
|
||||
# define NS_SCRIPTABLE
|
||||
# define NS_INPARAM
|
||||
# define NS_OUTPARAM
|
||||
# define NS_INOUTPARAM
|
||||
# define NS_OVERRIDE
|
||||
#endif
|
||||
|
||||
#endif /* nscore_h___ */
|
||||
|
@ -124,10 +124,22 @@ MUST_OVERRIDE_FAILURE_TESTCASES = \
|
||||
OverrideFail4.cpp \
|
||||
$(NULL)
|
||||
|
||||
OVERRIDE_PASS_TESTCASES = \
|
||||
override-pass.cpp \
|
||||
$(NULL)
|
||||
|
||||
OVERRIDE_FAILURE_TESTCASES = \
|
||||
override-global.cpp \
|
||||
override-signature.cpp \
|
||||
override-static.cpp \
|
||||
override-virtual.cpp \
|
||||
$(NULL)
|
||||
|
||||
STATIC_FAILURE_TESTCASES = \
|
||||
$(FINAL_FAILURE_TESTCASES) \
|
||||
$(FLOW_FAILURE_TESTCASES) \
|
||||
$(MUST_OVERRIDE_FAILURE_TESTCASES) \
|
||||
$(OVERRIDE_FAILURE_TESTCASES) \
|
||||
$(NULL)
|
||||
|
||||
STATIC_WARNING_TESTCASES = \
|
||||
@ -141,6 +153,7 @@ STATIC_PASS_TESTCASES = \
|
||||
$(STACK_PASS_TESTCASES) \
|
||||
$(FLOW_PASS_TESTCASES) \
|
||||
$(MUST_OVERRIDE_PASS_TESTCASES) \
|
||||
$(OVERRIDE_PASS_TESTCASES) \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
1
xpcom/tests/static-checker/override-global.cpp
Normal file
1
xpcom/tests/static-checker/override-global.cpp
Normal file
@ -0,0 +1 @@
|
||||
__attribute__((user("NS_override"))) int m();
|
15
xpcom/tests/static-checker/override-pass.cpp
Normal file
15
xpcom/tests/static-checker/override-pass.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
class A
|
||||
{
|
||||
int a(int, char*);
|
||||
void c(char);
|
||||
};
|
||||
|
||||
class B : A
|
||||
{
|
||||
__attribute__((user("NS_override"))) int a(int, char*);
|
||||
};
|
||||
|
||||
class C : B
|
||||
{
|
||||
__attribute__((user("NS_override"))) void c(char);
|
||||
};
|
9
xpcom/tests/static-checker/override-signature.cpp
Normal file
9
xpcom/tests/static-checker/override-signature.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
class A
|
||||
{
|
||||
int m(int);
|
||||
};
|
||||
|
||||
class B : A
|
||||
{
|
||||
__attribute__((user("NS_override"))) int m(void*);
|
||||
};
|
9
xpcom/tests/static-checker/override-static.cpp
Normal file
9
xpcom/tests/static-checker/override-static.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
class A
|
||||
{
|
||||
static int m();
|
||||
};
|
||||
|
||||
class B : A
|
||||
{
|
||||
__attribute__((user("NS_override"))) static int m();
|
||||
};
|
9
xpcom/tests/static-checker/override-virtual.cpp
Normal file
9
xpcom/tests/static-checker/override-virtual.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
class A
|
||||
{
|
||||
int m();
|
||||
};
|
||||
|
||||
class B : A
|
||||
{
|
||||
__attribute__((user("NS_override"))) virtual int m();
|
||||
};
|
Loading…
Reference in New Issue
Block a user