🏡 index : quine-global-boneyard/electron-builder.git

import { Application, Renderer } from "typedoc"

import { Context, Converter, DeclarationReflection, Reflection, ReflectionKind } from "typedoc"

export const load = (app: Application) => {
  new NoInheritPlugin(app).initialize()
}

class FilterInheritPlugin {
  constructor(private readonly app: Application) {}

  initialize() {
    this.app.renderer.on(Renderer.EVENT_END_PAGE, async context => {
      // Filter out properties that are Inherited. It causes too much visual noise and there's already the Extends code block
      const content = context
        .contents!.split("\n")
        .reduce((prev, curr, _index, _arr) => {
          const isInheritedProperty = /\|.*\[.*\]\(.*\).*\|/.test(curr)
          if (!isInheritedProperty) {
            return [...prev, curr]
          }
          return prev
        }, [] as string[])
        .join("\n")

      // await mkdir(path.dirname(context.filename), { recursive: true })
      // await writeFile(context.filename, content)
    })
  }
}

/**
 * A handler that deals with inherited reflections.
 */
export class NoInheritPlugin {
  /**
   * A list of reflections that are inherited from a super.
   */
  private inheritedReflections: DeclarationReflection[] = []

  constructor(private readonly app: Application) {}
  initialize() {
    this.app.converter.on(Converter.EVENT_BEGIN, this.onBegin.bind(this))
    this.app.converter.on(Converter.EVENT_CREATE_DECLARATION, this.onDeclaration.bind(this), -1100) // after ImplementsPlugin
    this.app.converter.on(Converter.EVENT_RESOLVE_BEGIN, this.onBeginResolve.bind(this))
  }

  /**
   * Triggered when the converter begins converting a project.
   */
  private onBegin(context: Context) {
    this.inheritedReflections = []
  }

  /**
   * Triggered when the converter has created a declaration or signature reflection.
   * Builds the list of classes/interfaces for the list of reflections that are inherited that could end up being removed.
   */
  private onDeclaration(context: Context, reflection: Reflection) {
    if (reflection instanceof DeclarationReflection) {
      if (
        reflection.inheritedFrom &&
        reflection.parent &&
        reflection.parent.kindOf(ReflectionKind.ClassOrInterface) &&
        (!reflection.overwrites || (reflection.overwrites && reflection.overwrites !== reflection.inheritedFrom))
      ) {
        this.inheritedReflections.push(reflection)
      }
    }
  }

  /**
   * Triggered when the converter begins resolving a project.
   * Goes over the list of inherited reflections and removes any that are down the hierarchy
   * from a class that doesn't inherit docs.
   */
  private onBeginResolve(context: Context) {
    const project = context.project
    const removals: DeclarationReflection[] = []

    this.inheritedReflections.forEach(reflection => {
      if (this.isInherited(context, reflection)) {
        removals.push(reflection)
      }
    })

    removals.forEach(removal => {
      project.removeReflection(removal)
    })
  }

  private isInherited(context: Context, current: Reflection): boolean {
    const parent = current.parent as DeclarationReflection
    if (!parent) {
      return false
    }
    return true
  }
}