declaration method

Declaration declaration ()

Declaration is

property: value;
@variable: value;

Example:

color: red;

Implementation

Declaration declaration() {
  final c = parserInput.currentChar();
  var hasDR = false; // has DetachedRuleset
  String important;
  final index = parserInput.i;
  bool isVariable;
  var merge = '';
  dynamic name; //String or List<Node>
  Node value;

  if (c == '.' || c == '#' || c == '&' || c == ':') return null;

  parserInput.save();

  name = variable() ?? ruleProperty();

  if (name != null) {
    isVariable = name is String;

    if (isVariable) {
      value = detachedRuleset();
      if (value != null) hasDR = true;
    }

    parserInput.commentStore.length = 0;
    if (value == null) {
      // a name returned by this.ruleProperty() is always an array of the form:
      // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"]
      // where each item is a tree.Keyword or tree.Variable
      merge = (!isVariable && name.length > 1)
          ? (name as List<Node>).removeLast().value
          : '';

      // Custom property values get permissive parsing
      if ((name is List) &&
          (name.first.value is String) &&
          (name.first.value as String).startsWith('--')) {
        value = permissiveValue();
      } else {
        // Try to store values as anonymous
        // If we need the value later we'll re-parse it in ruleset.parseValue
        value = anonymousValue();
      }

      if (value != null) {
        parserInput.forget();
        // anonymous values absorb the end ';' which is required for them to work
        return Declaration(name, value,
            important: '',
            merge: merge,
            index: index,
            currentFileInfo: fileInfo);
      }

      value ??= this.value();

      if (value != null) {
        important = this.important();
      } else if (isVariable) {
        // As a last resort, try permissive value
        value = permissiveValue();
      }
    }

    if (value != null && (end() || hasDR)) {
      parserInput.forget();
      return Declaration(name, value,
          important: important,
          merge: merge,
          index: index,
          currentFileInfo: fileInfo);
    } else {
      parserInput.restore();
    }
  } else {
    parserInput.restore();
  }

  return null;

// 3.5.1 20180706
//  declaration: function () {
//      var name, value, index = parserInput.i, hasDR,
//          c = parserInput.currentChar(), important, merge, isVariable;
//
//      if (c === '.' || c === '#' || c === '&' || c === ':') { return; }
//
//      parserInput.save();
//
//      name = this.variable() || this.ruleProperty();
//      if (name) {
//          isVariable = typeof name === 'string';
//
//          if (isVariable) {
//              value = this.detachedRuleset();
//              if (value) {
//                  hasDR = true;
//              }
//          }
//
//          parserInput.commentStore.length = 0;
//          if (!value) {
//              // a name returned by this.ruleProperty() is always an array of the form:
//              // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"]
//              // where each item is a tree.Keyword or tree.Variable
//              merge = !isVariable && name.length > 1 && name.pop().value;
//
//              // Custom property values get permissive parsing
//              if (name[0].value && name[0].value.slice(0, 2) === '--') {
//                  value = this.permissiveValue();
//              }
//              // Try to store values as anonymous
//              // If we need the value later we'll re-parse it in ruleset.parseValue
//              else {
//                  value = this.anonymousValue();
//              }
//              if (value) {
//                  parserInput.forget();
//                  // anonymous values absorb the end ';' which is required for them to work
//                  return new (tree.Declaration)(name, value, false, merge, index, fileInfo);
//              }
//
//              if (!value) {
//                  value = this.value();
//              }
//
//              if (value) {
//                  important = this.important();
//              } else if (isVariable) {
//                  // As a last resort, try permissiveValue
//                  value = this.permissiveValue();
//              }
//          }
//
//          if (value && (this.end() || hasDR)) {
//              parserInput.forget();
//              return new (tree.Declaration)(name, value, important, merge, index, fileInfo);
//          }
//          else {
//              parserInput.restore();
//          }
//      } else {
//          parserInput.restore();
//      }
//  },
}