create()

in src/rule-compat-uses-vars.js [37:142]


  create(context) {
    if (!shouldLint(context)) {
      return {};
    }
    if (!/react-relay\/compat|RelayCompat/.test(context.getSourceCode().text)) {
      // Only run in for compat mode files
      return {};
    }
    function isInScope(name) {
      var scope = context.getScope();
      var variables = scope.variables;

      while (scope.type !== 'global') {
        scope = scope.upper;
        variables = scope.variables.concat(variables);
      }
      if (scope.childScopes.length) {
        variables = scope.childScopes[0].variables.concat(variables);
        // Temporary fix for babel-eslint
        if (scope.childScopes[0].childScopes.length) {
          variables =
            scope.childScopes[0].childScopes[0].variables.concat(variables);
        }
      }

      for (var i = 0, len = variables.length; i < len; i++) {
        if (variables[i].name === name) {
          return true;
        }
      }
      return false;
    }

    return {
      TaggedTemplateExpression(taggedTemplateExpression) {
        const ast = getGraphQLAST(taggedTemplateExpression);
        if (!ast) {
          return;
        }
        visit(ast, {
          FragmentSpread(spreadNode) {
            const m =
              spreadNode.name &&
              spreadNode.name.value.match(/^([a-z0-9]+)_([a-z0-9_]+)/i);
            if (!m) {
              return;
            }
            const componentName = m[1];
            const propName = m[2];
            const loc = getLoc(
              context,
              taggedTemplateExpression,
              spreadNode.name
            );
            if (isInScope(componentName)) {
              // if this variable is defined, mark it as used
              context.markVariableAsUsed(componentName);
            } else if (componentName === getModuleName(context.getFilename())) {
              if (!validateInlineDirective(spreadNode)) {
                context.report({
                  message:
                    'It looks like you are trying to spread the locally defined fragment `{{fragmentName}}`. ' +
                    'In compat mode, Relay only supports that for `@relay(mask: false)` directive. ' +
                    'If you intend to do that, please add the directive to the fragment spread `{{fragmentName}}` ' +
                    'and make sure that it is bound to a local variable named `{{propName}}`.',
                  data: {
                    fragmentName: spreadNode.name.value,
                    propName: propName
                  },
                  loc: loc
                });
                return;
              }

              if (!isInScope(propName)) {
                context.report({
                  message:
                    'When you are unmasking the locally defined fragment spread `{{fragmentName}}`, please make sure ' +
                    'the fragment is bound to a variable named `{{propName}}`.',
                  data: {
                    fragmentName: spreadNode.name.value,
                    propName: propName
                  },
                  loc: loc
                });
              }
              context.markVariableAsUsed(propName);
            } else {
              // otherwise, yell about this needed to be defined
              context.report({
                message:
                  'In compat mode, Relay expects the component that has ' +
                  'the `{{fragmentName}}` fragment to be imported with ' +
                  'the variable name `{{varName}}`.',
                data: {
                  fragmentName: spreadNode.name.value,
                  varName: componentName
                },
                loc: loc
              });
            }
          }
        });
      }
    };
  }