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());
}
bool nsIFrame::IsBlockFrameOrSubclass() {
nsBlockFrame* thisAsBlock = do_QueryFrame(this);
bool nsIFrame::IsBlockFrameOrSubclass() const {
const nsBlockFrame* thisAsBlock = do_QueryFrame(this);
return !!thisAsBlock;
}

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

@ -100,7 +100,7 @@ enum class TableSelection : uint32_t;
NS_DECL_QUERYFRAME_TARGET(class) \
static constexpr nsIFrame::ClassID kClassID = nsIFrame::ClassID::class##_id; \
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; \
}
@ -111,7 +111,7 @@ enum class TableSelection : uint32_t;
#define NS_DECL_ABSTRACT_FRAME(class) \
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
NS_DECL_QUERYFRAME
NS_DECL_QUERYFRAME_TARGET(nsFrame)
virtual nsQueryFrame::FrameIID GetFrameId() MOZ_MUST_OVERRIDE {
virtual nsQueryFrame::FrameIID GetFrameId() const MOZ_MUST_OVERRIDE {
return kFrameIID;
}
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
* 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.

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

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

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

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