Repository: facebook/react
File: compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts (TypeScript)

Code before:
  // known generated or referenced identifiers in the program
  knownReferencedNames: Set<string> = new Set();
  // generated imports
  imports: Map<string, Map<string, NonLocalImportSpecifier>> = new Map();

  /**
   * Metadata from compilation
   */
  retryErrors: Array<{fn: BabelFn; error: CompilerError}> = [];
  inferredEffectLocations: Set<t.SourceLocation> = new Set();

  constructor({
    program,
    suppressions,
    opts,
    filename,
    code,
  }: ProgramContextOptions) {
    this.scope = program.scope;
    this.opts = opts;
    this.filename = filename;
    this.code = code;
    this.reactRuntimeModule = getReactCompilerRuntimeModule(opts.target);
    this.suppressions = suppressions;
    this.hasModuleScopeOptOut =
      findDirectiveDisablingMemoization(program.node.directives) != null;
  }

  isHookName(name: string): boolean {
    if (this.opts.environment.hookPattern == null) {
      return isHookName(name);
    } else {
      const match = new RegExp(this.opts.environment.hookPattern).exec(name);
      return (
        match != null && typeof match[1] === 'string' && isHookName(match[1])
      );
    }
  }

  hasReference(name: string): boolean {
    return (
      this.knownReferencedNames.has(name) ||
      this.scope.hasBinding(name) ||
      this.scope.hasGlobal(name) ||
      this.scope.hasReference(name)
    );
  }

  newUid(name: string): string {
    /**
     * Don't call babel's generateUid for known hook imports, as

Review comment (refactor):
It's much easier to reason about constructors when they are dumb data initialization, but this is moderately interesting program analysis. Maybe move this to be passed to the constructor as an argument?

Code after:
  imports: Map<string, Map<string, NonLocalImportSpecifier>> = new Map();

  /**
   * Metadata from compilation
   */
  retryErrors: Array<{fn: BabelFn; error: CompilerError}> = [];
  inferredEffectLocations: Set<t.SourceLocation> = new Set();

  constructor({
    program,
    suppressions,
    opts,
    filename,
    code,
    hasModuleScopeOptOut,
  }: ProgramContextOptions) {
    this.scope = program.scope;
    this.opts = opts;
    this.filename = filename;
    this.code = code;
    this.reactRuntimeModule = getReactCompilerRuntimeModule(opts.target);
    this.suppressions = suppressions;
    this.hasModuleScopeOptOut = hasModuleScopeOptOut;
  }

  isHookName(name: string): boolean {
    if (this.opts.environment.hookPattern == null) {
      return isHookName(name);
    } else {
      const match = new RegExp(this.opts.environment.hookPattern).exec(name);
      return (
        match != null && typeof match[1] === 'string' && isHookName(match[1])
      );
    }
  }

  hasReference(name: string): boolean {
    return (
      this.knownReferencedNames.has(name) ||
      this.scope.hasBinding(name) ||
      this.scope.hasGlobal(name) ||
      this.scope.hasReference(name)
    );
  }

  newUid(name: string): string {
    /**
     * Don't call babel's generateUid for known hook imports, as
     * InferTypes might eventually type `HookKind` based on callee naming
     * convention and `_useFoo` is not named as a hook.
     *