DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (4a108e94d3e2)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* 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/. */

/* object that resolves CSS variables using specified and inherited variable
 * values
 */

#ifndef mozilla_CSSVariableResolver_h
#define mozilla_CSSVariableResolver_h

#include "mozilla/DebugOnly.h"
#include "nsCSSParser.h"
#include "nsCSSScanner.h"
#include "nsDataHashtable.h"
#include "nsTArray.h"

namespace mozilla {

class CSSVariableDeclarations;
class CSSVariableValues;
class EnumerateVariableReferencesData;

class CSSVariableResolver
{
  friend class CSSVariableDeclarations;
  friend class CSSVariableValues;
  friend class EnumerateVariableReferencesData;
public:
  /**
   * Creates a new CSSVariableResolver that will output a set of resolved,
   * computed variables into aOutput.
   */
  explicit CSSVariableResolver(CSSVariableValues* aOutput)
    : mOutput(aOutput)
#ifdef DEBUG
    , mResolved(false)
#endif
  {
    MOZ_ASSERT(aOutput);
  }

  /**
   * Resolves the set of inherited variables from aInherited and the
   * set of specified variables from aSpecified.  The resoled variables
   * are written in to mOutput.
   */
  void Resolve(const CSSVariableValues* aInherited,
               const CSSVariableDeclarations* aSpecified);

private:
  struct Variable
  {
    Variable(const nsAString& aVariableName,
             nsString aValue,
             nsCSSTokenSerializationType aFirstToken,
             nsCSSTokenSerializationType aLastToken,
             bool aWasInherited)
      : mVariableName(aVariableName)
      , mValue(aValue)
      , mFirstToken(aFirstToken)
      , mLastToken(aLastToken)
      , mWasInherited(aWasInherited)
      , mResolved(false)
      , mReferencesNonExistentVariable(false)
      , mInStack(false)
      , mIndex(0)
      , mLowLink(0) { }

    nsString mVariableName;
    nsString mValue;
    nsCSSTokenSerializationType mFirstToken;
    nsCSSTokenSerializationType mLastToken;

    // Whether this variable came from the set of inherited variables.
    bool mWasInherited;

    // Whether this variable has been resolved yet.
    bool mResolved;

    // Whether this variables includes any references to non-existent variables.
    bool mReferencesNonExistentVariable;

    // Bookkeeping for the cycle remover algorithm.
    bool mInStack;
    size_t mIndex;
    size_t mLowLink;
  };

  /**
   * Adds or modifies an existing entry in the set of variables to be resolved.
   * This is intended to be called by the AddVariablesToResolver functions on
   * the CSSVariableDeclarations and CSSVariableValues objects passed in to
   * Resolve.
   *
   * @param aName The variable name (not including any "--" prefix that would
   *   be part of the custom property name) whose value is to be set.
   * @param aValue The variable value.
   * @param aFirstToken The type of token at the start of the variable value.
   * @param aLastToken The type of token at the en of the variable value.
   * @param aWasInherited Whether this variable came from the set of inherited
   *   variables.
   */
  void Put(const nsAString& aVariableName,
           nsString aValue,
           nsCSSTokenSerializationType aFirstToken,
           nsCSSTokenSerializationType aLastToken,
           bool aWasInherited);

  // Helper functions for Resolve.
  void RemoveCycles(size_t aID);
  void ResolveVariable(size_t aID);

  // A mapping of variable names to an ID that indexes into mVariables
  // and mReferences.
  nsDataHashtable<nsStringHashKey, size_t> mVariableIDs;

  // The set of variables.
  nsTArray<Variable> mVariables;

  // The list of variables that each variable references.
  nsTArray<nsTArray<size_t> > mReferences;

  // The next index to assign to a variable found during the cycle removing
  // algorithm's traversal of the variable reference graph.
  size_t mNextIndex;

  // Stack of variable IDs that we push to as we traverse the variable reference
  // graph while looking for cycles.  Variable::mInStack reflects whether a
  // given variable has its ID in mStack.
  nsTArray<size_t> mStack;

  // CSS parser to use for parsing property values with variable references.
  nsCSSParser mParser;

  // The object to output the resolved variables into.
  CSSVariableValues* mOutput;

#ifdef DEBUG
  // Whether Resolve has been called.
  bool mResolved;
#endif
};

}

#endif