layout/style/nsCSSAnonBoxes.h
author Nika Layzell <nika@thelayzells.com>
Tue, 25 Sep 2018 17:34:53 +0200
changeset 507828 5e6dae0c1e5a4939ccd406f14607f7fafffd45a7
parent 498945 3924e39ce03a0004287b06dc478b90d257e1dd45
child 508163 6f3709b3878117466168c40affa7bca0b60cf75b
permissions -rw-r--r--
Bug 1448426 - Wrap windows.h to avoid problematic define statements, r=froydnj,glandium By default, windows.h exposes a large number of problematic define statements which are UpperCamelCase, such as a define from `CreateWindow` to `CreateWindow{A,W}`. As many of these names are generic (e.g. CreateFile, CreateWindow), they can mess up Gecko code that may legitimately have its own methods with the same names. The header also defines some traditional SCREAMING_SNAKE_CASE defines which can mess up our code by conflicting with local values. This patch adds a simple code generator which generates wrappers for these defines, and uses them to wrap the windows.h wrapper using the `stl_wrappers` mechanism, allowing us to use windows.h in more places. Differential Revision: https://phabricator.services.mozilla.com/D10932

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* atom list for CSS anonymous boxes */

#ifndef nsCSSAnonBoxes_h___
#define nsCSSAnonBoxes_h___

#include "nsAtom.h"
#include "nsGkAtoms.h"

class nsCSSAnonBoxes {
public:
  static bool IsAnonBox(nsAtom *aAtom);
#ifdef MOZ_XUL
  static bool IsTreePseudoElement(nsAtom* aPseudo);
#endif
  static bool IsNonElement(nsAtom* aPseudo)
  {
    return aPseudo == nsCSSAnonBoxes::mozText() ||
           aPseudo == nsCSSAnonBoxes::oofPlaceholder() ||
           aPseudo == nsCSSAnonBoxes::firstLetterContinuation();
  }

  typedef uint8_t NonInheritingBase;
  enum class NonInheriting : NonInheritingBase {
#define CSS_ANON_BOX(_name, _value) /* nothing */
#define CSS_NON_INHERITING_ANON_BOX(_name, _value) _name,
#include "nsCSSAnonBoxList.h"
#undef CSS_NON_INHERITING_ANON_BOX
#undef CSS_ANON_BOX
    _Count
  };

  // Be careful using this: if we have a lot of non-inheriting anon box types it
  // might not be very fast.  We may want to think of ways to handle that
  // (e.g. by moving to an enum instead of an atom, like we did for
  // pseudo-elements, or by adding a new value of the pseudo-element enum for
  // non-inheriting anon boxes or something).
  static bool IsNonInheritingAnonBox(nsAtom* aPseudo)
  {
    return
#define CSS_ANON_BOX(_name, _value) /* nothing */
#define CSS_NON_INHERITING_ANON_BOX(_name, _value) \
      nsGkAtoms::AnonBox_##_name == aPseudo ||
#include "nsCSSAnonBoxList.h"
#undef CSS_NON_INHERITING_ANON_BOX
#undef CSS_ANON_BOX
      false;
  }

#ifdef DEBUG
  // NOTE(emilio): DEBUG only because this does a pretty slow linear search. Try
  // to use IsNonInheritingAnonBox if you know the atom is an anon box already
  // or, even better, nothing like this.  Note that this function returns true
  // for wrapper anon boxes as well, since they're all inheriting.
  static bool IsInheritingAnonBox(nsAtom* aPseudo)
  {
    return
#define CSS_ANON_BOX(_name, _value) nsGkAtoms::AnonBox_##_name == aPseudo ||
#define CSS_NON_INHERITING_ANON_BOX(_name, _value) /* nothing */
#include "nsCSSAnonBoxList.h"
#undef CSS_NON_INHERITING_ANON_BOX
#undef CSS_ANON_BOX
      false;
  }
#endif // DEBUG

  // This function is rather slow; you probably don't want to use it outside
  // asserts unless you have to.
  static bool IsWrapperAnonBox(nsAtom* aPseudo) {
    // We commonly get null passed here, and want to quickly return false for
    // it.
    return aPseudo &&
      (
#define CSS_ANON_BOX(_name, _value) /* nothing */
#define CSS_WRAPPER_ANON_BOX(_name, _value) nsGkAtoms::AnonBox_##_name == aPseudo ||
#define CSS_NON_INHERITING_ANON_BOX(_name, _value) /* nothing */
#include "nsCSSAnonBoxList.h"
#undef CSS_NON_INHERITING_ANON_BOX
#undef CSS_WRAPPER_ANON_BOX
#undef CSS_ANON_BOX
       false);
  }

  // Get the NonInheriting type for a given pseudo tag.  The pseudo tag must
  // test true for IsNonInheritingAnonBox.
  static NonInheriting NonInheritingTypeForPseudoTag(nsAtom* aPseudo);

#ifdef DEBUG
  static void AssertAtoms();
#endif

  // Alias nsCSSAnonBoxes::foo() to nsGkAtoms::AnonBox_foo.
  #define CSS_ANON_BOX(name_, value_)                     \
    static nsCSSAnonBoxPseudoStaticAtom* name_()          \
    {                                                     \
      return const_cast<nsCSSAnonBoxPseudoStaticAtom*>(   \
        static_cast<const nsCSSAnonBoxPseudoStaticAtom*>( \
          nsGkAtoms::AnonBox_##name_));                   \
    }
  #include "nsCSSAnonBoxList.h"
  #undef CSS_ANON_BOX
};

#endif /* nsCSSAnonBoxes_h___ */