Bug 1527519 Part 1 - Make do_QueryFrame more const-friendly, and mark nsIFrame::IsBlockFrameOrSubclass() as a const method. r=mats

This patch makes do_QueryFrame() accept const frame pointer e.g.
"const nsIFrame*", and also helps eliminate a few const_cast in Part 3.

Note that the fast path of do_QueryFrame is const-correct, but the slow
path is not (due to nsIFrame::QueryFrame() returns void*).

For example:

```
const nsIFrame* f;
nsBlockFrame* a = do_QueryFrame(f); // fast path, compile error.
nsIAnonymousContentCreator* b = do_QueryFrame(f); // slow path, still compiles.
```

Differential Revision: https://phabricator.services.mozilla.com/D19860

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ting-Yu Lin 2019-02-15 01:38:04 +00:00
Родитель fc7e92ad83
Коммит 646fb37989
5 изменённых файлов: 15 добавлений и 24 удалений

Просмотреть файл

@ -7241,8 +7241,8 @@ bool nsIFrame::IsBlockWrapper() const {
pseudoType == nsCSSAnonBoxes::cellContent()); pseudoType == nsCSSAnonBoxes::cellContent());
} }
bool nsIFrame::IsBlockFrameOrSubclass() { bool nsIFrame::IsBlockFrameOrSubclass() const {
nsBlockFrame* thisAsBlock = do_QueryFrame(this); const nsBlockFrame* thisAsBlock = do_QueryFrame(this);
return !!thisAsBlock; return !!thisAsBlock;
} }

Просмотреть файл

@ -100,7 +100,7 @@ enum class TableSelection : uint32_t;
NS_DECL_QUERYFRAME_TARGET(class) \ NS_DECL_QUERYFRAME_TARGET(class) \
static constexpr nsIFrame::ClassID kClassID = nsIFrame::ClassID::class##_id; \ static constexpr nsIFrame::ClassID kClassID = nsIFrame::ClassID::class##_id; \
void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE; \ void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE; \
nsQueryFrame::FrameIID GetFrameId() override MOZ_MUST_OVERRIDE { \ nsQueryFrame::FrameIID GetFrameId() const override MOZ_MUST_OVERRIDE { \
return nsQueryFrame::class##_id; \ return nsQueryFrame::class##_id; \
} }
@ -111,7 +111,7 @@ enum class TableSelection : uint32_t;
#define NS_DECL_ABSTRACT_FRAME(class) \ #define NS_DECL_ABSTRACT_FRAME(class) \
void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE = delete; \ void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE = delete; \
virtual nsQueryFrame::FrameIID GetFrameId() override MOZ_MUST_OVERRIDE = 0; nsQueryFrame::FrameIID GetFrameId() const override MOZ_MUST_OVERRIDE = 0;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -155,7 +155,7 @@ class nsFrame : public nsBox {
// nsQueryFrame // nsQueryFrame
NS_DECL_QUERYFRAME NS_DECL_QUERYFRAME
NS_DECL_QUERYFRAME_TARGET(nsFrame) NS_DECL_QUERYFRAME_TARGET(nsFrame)
virtual nsQueryFrame::FrameIID GetFrameId() MOZ_MUST_OVERRIDE { virtual nsQueryFrame::FrameIID GetFrameId() const MOZ_MUST_OVERRIDE {
return kFrameIID; return kFrameIID;
} }
void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE; void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE;

Просмотреть файл

@ -2883,14 +2883,8 @@ class nsIFrame : public nsQueryFrame {
/** /**
* Returns true if the frame is an instance of nsBlockFrame or one of its * Returns true if the frame is an instance of nsBlockFrame or one of its
* subclasses. * subclasses.
*
* XXXdholbert this is non-const because it uses nsIFrame::QueryFrame which
* is non-const. If we need this accessor to be 'const' down the road, the
* right way to do it would be to make the QueryFrame machinery
* const-friendly. But it may not be worth the trouble, because we rarely
* handle const frame pointers anyway.
*/ */
bool IsBlockFrameOrSubclass(); bool IsBlockFrameOrSubclass() const;
/** /**
* Get this frame's CSS containing block. * Get this frame's CSS containing block.

Просмотреть файл

@ -19,17 +19,17 @@
nsQueryFrame::classname##_id; \ nsQueryFrame::classname##_id; \
typedef classname Has_NS_DECL_QUERYFRAME_TARGET; typedef classname Has_NS_DECL_QUERYFRAME_TARGET;
#define NS_DECL_QUERYFRAME void* QueryFrame(FrameIID id) override; #define NS_DECL_QUERYFRAME void* QueryFrame(FrameIID id) const override;
#define NS_QUERYFRAME_HEAD(class) \ #define NS_QUERYFRAME_HEAD(class) \
void* class ::QueryFrame(FrameIID id) { \ void* class ::QueryFrame(FrameIID id) const { \
switch (id) { switch (id) {
#define NS_QUERYFRAME_ENTRY(class) \ #define NS_QUERYFRAME_ENTRY(class) \
case class ::kFrameIID: { \ case class ::kFrameIID: { \
static_assert( \ static_assert( \
mozilla::IsSame<class, class ::Has_NS_DECL_QUERYFRAME_TARGET>::value, \ mozilla::IsSame<class, class ::Has_NS_DECL_QUERYFRAME_TARGET>::value, \
#class " must declare itself as a queryframe target"); \ #class " must declare itself as a queryframe target"); \
return static_cast<class*>(this); \ return const_cast<class*>(static_cast<const class*>(this)); \
} }
#define NS_QUERYFRAME_ENTRY_CONDITIONAL(class, condition) \ #define NS_QUERYFRAME_ENTRY_CONDITIONAL(class, condition) \
@ -39,7 +39,7 @@
mozilla::IsSame<class, \ mozilla::IsSame<class, \
class ::Has_NS_DECL_QUERYFRAME_TARGET>::value, \ class ::Has_NS_DECL_QUERYFRAME_TARGET>::value, \
#class " must declare itself as a queryframe target"); \ #class " must declare itself as a queryframe target"); \
return static_cast<class*>(this); \ return const_cast<class*>(static_cast<const class*>(this)); \
} \ } \
break; break;
@ -85,7 +85,7 @@ class nsQueryFrame {
#undef ABSTRACT_FRAME_ID #undef ABSTRACT_FRAME_ID
}; };
virtual void* QueryFrame(FrameIID id) = 0; virtual void* QueryFrame(FrameIID id) const = 0;
}; };
class nsIFrame; class nsIFrame;
@ -104,7 +104,7 @@ class do_QueryFrameHelper {
template <class Dest> template <class Dest>
operator Dest*() { operator Dest*() {
static_assert( static_assert(
mozilla::IsSame<Dest, mozilla::IsSame<typename mozilla::RemoveConst<Dest>::Type,
typename Dest::Has_NS_DECL_QUERYFRAME_TARGET>::value, typename Dest::Has_NS_DECL_QUERYFRAME_TARGET>::value,
"Dest must declare itself as a queryframe target"); "Dest must declare itself as a queryframe target");
if (!mRawPtr) { if (!mRawPtr) {

Просмотреть файл

@ -11,6 +11,8 @@
class nsMathMLSelectedFrame : public nsMathMLContainerFrame { class nsMathMLSelectedFrame : public nsMathMLContainerFrame {
public: public:
NS_DECL_ABSTRACT_FRAME(nsMathMLSelectedFrame)
NS_IMETHOD NS_IMETHOD
TransmitAutomaticData() override; TransmitAutomaticData() override;
@ -35,8 +37,6 @@ class nsMathMLSelectedFrame : public nsMathMLContainerFrame {
const ReflowInput& aReflowInput, const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) override; nsReflowStatus& aStatus) override;
virtual nsQueryFrame::FrameIID GetFrameId() override = 0;
protected: protected:
nsMathMLSelectedFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, nsMathMLSelectedFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
ClassID aID) ClassID aID)
@ -49,9 +49,6 @@ class nsMathMLSelectedFrame : public nsMathMLContainerFrame {
nsIFrame* mSelectedFrame; nsIFrame* mSelectedFrame;
bool mInvalidMarkup; bool mInvalidMarkup;
private:
void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE = delete;
}; };
#endif /* nsMathMLSelectedFrame_h___ */ #endif /* nsMathMLSelectedFrame_h___ */