private _validatedDecorator()

in tools/tslint-rules/validateDecoratorsRule.ts [73:115]


  private _validatedDecorator(decorator: any) {
    // Get the rules that are relevant for the current decorator.
    const rules = this._rules[decorator.expression.getText()];

    // Don't do anything if there are no rules.
    if (!rules) {
      return;
    }

    // Extract the property names and values.
    const props = decorator.arguments[0].properties.map((node: ts.PropertyAssignment) => ({
      name: node.name.getText(),
      value: node.initializer.getText(),
      node
    }));

    // Find all of the required rule properties that are missing from the decorator.
    const missing = Object.keys(rules.required)
      .filter(key => !props.find((prop: any) => prop.name === key));

    if (missing.length) {
      // Exit early if any of the properties are missing.
      this.addFailureAtNode(decorator.parent, 'Missing required properties: ' + missing.join(', '));
    } else {
      // If all the necessary properties are defined, ensure that
      // they match the pattern and aren't in the forbidden list.
      props
        .filter((prop: any) => rules.required[prop.name] || rules.forbidden[prop.name])
        .forEach((prop: any) => {
          const {name, value, node} = prop;
          const requiredPattern = rules.required[name];
          const forbiddenPattern = rules.forbidden[name];

          if (requiredPattern && !requiredPattern.test(value)) {
            this.addFailureAtNode(node, `Invalid value for property. ` +
              `Expected value to match "${requiredPattern}".`);
          } else if (forbiddenPattern && forbiddenPattern.test(value)) {
            this.addFailureAtNode(node, `Property value not allowed. ` +
              `Value should not match "${forbiddenPattern}".`);
          }
        });
    }
  }