export function lookupJsiiSymbol()

in src/jsii/jsii-utils.ts [191:257]


export function lookupJsiiSymbol(typeChecker: ts.TypeChecker, sym: ts.Symbol): JsiiSymbol | undefined {
  // Resolve alias, if it is one. This comes into play if the symbol refers to a module,
  // we need to resolve the alias to find the ACTUAL module.
  if (hasAnyFlag(sym.flags, ts.SymbolFlags.Alias)) {
    sym = typeChecker.getAliasedSymbol(sym);
  }

  const decl: ts.Node | undefined = sym.declarations?.[0];
  if (!decl) {
    return undefined;
  }

  if (ts.isSourceFile(decl)) {
    // This is a module.
    const sourceAssembly = findTypeLookupAssembly(decl.fileName);
    return fmap(
      sourceAssembly,
      (asm) =>
        ({
          fqn:
            fmap(
              symbolIdentifier(
                typeChecker,
                sym,
                fmap(sourceAssembly, (sa) => ({ assembly: sa.assembly })),
              ),
              (symbolId) => sourceAssembly?.symbolIdMap[symbolId],
            ) ?? sourceAssembly?.assembly.name,
          sourceAssembly: asm,
          symbolType: 'module',
        } as JsiiSymbol),
    );
  }

  if (!isDeclaration(decl)) {
    return undefined;
  }

  const declaringFile = decl.getSourceFile();
  if (/^\/\/\/ fake-from-jsii/m.test(declaringFile.getFullText())) {
    return { fqn: `fake_jsii.${sym.name}`, symbolType: 'type' };
  }

  const declSym = getSymbolFromDeclaration(decl, typeChecker);
  if (!declSym) {
    return undefined;
  }

  const fileName = decl.getSourceFile().fileName;
  const sourceAssembly = findTypeLookupAssembly(fileName);
  const symbolId = symbolIdentifier(typeChecker, declSym, { assembly: sourceAssembly?.assembly });
  if (!symbolId) {
    return undefined;
  }

  return fmap(/([^#]*)(#.*)?/.exec(symbolId), ([, typeSymbolId, memberFragment]) => {
    if (memberFragment) {
      return fmap(sourceAssembly?.symbolIdMap[typeSymbolId], (fqn) => ({
        fqn: `${fqn}${memberFragment}`,
        sourceAssembly,
        symbolType: 'member',
      }));
    }

    return fmap(sourceAssembly?.symbolIdMap[typeSymbolId], (fqn) => ({ fqn, sourceAssembly, symbolType: 'type' }));
  });
}