Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | /* |
michael@0 | 6 | * Detect classes that should have overridden members of their parent |
michael@0 | 7 | * classes but didn't. |
michael@0 | 8 | * |
michael@0 | 9 | * Example: |
michael@0 | 10 | * |
michael@0 | 11 | * struct S { |
michael@0 | 12 | * virtual NS_MUST_OVERRIDE void f(); |
michael@0 | 13 | * virtual void g(); |
michael@0 | 14 | * }; |
michael@0 | 15 | * |
michael@0 | 16 | * struct A : S { virtual void f(); }; // ok |
michael@0 | 17 | * struct B : S { virtual NS_MUST_OVERRIDE void f(); }; // also ok |
michael@0 | 18 | * |
michael@0 | 19 | * struct C : S { virtual void g(); }; // ERROR: must override f() |
michael@0 | 20 | * struct D : S { virtual void f(int); }; // ERROR: different overload |
michael@0 | 21 | * struct E : A { }; // ok: A's definition of f() is good for subclasses |
michael@0 | 22 | * struct F : B { }; // ERROR: B's definition of f() is still must-override |
michael@0 | 23 | * |
michael@0 | 24 | * We don't care if you define the method or not. |
michael@0 | 25 | */ |
michael@0 | 26 | |
michael@0 | 27 | function get_must_overrides(cls) |
michael@0 | 28 | { |
michael@0 | 29 | let mos = {}; |
michael@0 | 30 | for each (let base in cls.bases) |
michael@0 | 31 | for each (let m in base.type.members) |
michael@0 | 32 | if (hasAttribute(m, 'NS_must_override')) |
michael@0 | 33 | mos[m.shortName] = m; |
michael@0 | 34 | |
michael@0 | 35 | return mos; |
michael@0 | 36 | } |
michael@0 | 37 | |
michael@0 | 38 | function process_type(t) |
michael@0 | 39 | { |
michael@0 | 40 | if (t.isIncomplete || (t.kind != 'class' && t.kind != 'struct')) |
michael@0 | 41 | return; |
michael@0 | 42 | |
michael@0 | 43 | let mos = get_must_overrides(t); |
michael@0 | 44 | for each (let m in t.members) { |
michael@0 | 45 | let mos_m = mos[m.shortName] |
michael@0 | 46 | if (mos_m && signaturesMatch(mos_m, m)) |
michael@0 | 47 | delete mos[m.shortName]; |
michael@0 | 48 | } |
michael@0 | 49 | |
michael@0 | 50 | for each (let u in mos) |
michael@0 | 51 | error(t.kind + " " + t.name + " must override " + u.name, t.loc); |
michael@0 | 52 | } |