function transformClassElement()

in src/decorator_downlevel_transformer.ts [353:416]


    function transformClassElement(
        element: ts.PropertyDeclaration|ts.GetAccessorDeclaration|
        ts.SetAccessorDeclaration|ts.MethodDeclaration):
        [string|undefined, ts.ClassElement, ts.Decorator[]] {
      element = ts.visitEachChild(element, visitor, context);
      const decoratorsToKeep: ts.Decorator[] = [];
      const toLower: ts.Decorator[] = [];
      for (const decorator of element.decorators || []) {
        if (!shouldLower(decorator, typeChecker)) {
          decoratorsToKeep.push(decorator);
          continue;
        }
        toLower.push(decorator);
      }
      if (!toLower.length) return [undefined, element, []];

      if (!element.name || element.name.kind !== ts.SyntaxKind.Identifier) {
        // Method has a weird name, e.g.
        //   [Symbol.foo]() {...}
        diagnostics.push({
          file: element.getSourceFile(),
          start: element.getStart(),
          length: element.getEnd() - element.getStart(),
          messageText: `cannot process decorators on strangely named method`,
          category: ts.DiagnosticCategory.Error,
          code: 0,
        });
        return [undefined, element, []];
      }

      const name = (element.name as ts.Identifier).text;
      let newNode: ts.ClassElement;
      const decorators = decoratorsToKeep.length ?
          ts.setTextRange(
              ts.factory.createNodeArray(decoratorsToKeep), element.decorators) :
          undefined;
      switch (element.kind) {
        case ts.SyntaxKind.PropertyDeclaration:
          newNode = ts.factory.updatePropertyDeclaration(
              element, decorators, element.modifiers, element.name,
              element.questionToken ?? element.exclamationToken, element.type,
              element.initializer);
          break;
        case ts.SyntaxKind.GetAccessor:
          newNode = ts.factory.updateGetAccessorDeclaration(
              element, decorators, element.modifiers, element.name,
              element.parameters, element.type, element.body);
          break;
        case ts.SyntaxKind.SetAccessor:
          newNode = ts.factory.updateSetAccessorDeclaration(
              element, decorators, element.modifiers, element.name,
              element.parameters, element.body);
          break;
        case ts.SyntaxKind.MethodDeclaration:
          newNode = ts.factory.updateMethodDeclaration(
              element, decorators, element.modifiers, element.asteriskToken,
              element.name, element.questionToken, element.typeParameters,
              element.parameters, element.type, element.body);
          break;
        default:
          throw new Error(`unexpected element: ${element}`);
      }
      return [name, newNode, toLower];
    }