function transformClassDeclaration()

in src/decorator_downlevel_transformer.ts [468:536]


    function transformClassDeclaration(classDecl: ts.ClassDeclaration): ts.ClassDeclaration {
      const newMembers: ts.ClassElement[] = [];
      const decoratedProperties = new Map<string, ts.Decorator[]>();
      let classParameters: ParameterDecorationInfo[]|null = null;

      for (const member of classDecl.members) {
        switch (member.kind) {
          case ts.SyntaxKind.PropertyDeclaration:
          case ts.SyntaxKind.GetAccessor:
          case ts.SyntaxKind.SetAccessor:
          case ts.SyntaxKind.MethodDeclaration: {
            const [name, newMember, decorators] = transformClassElement(
                member as ts.PropertyDeclaration | ts.GetAccessorDeclaration |
                ts.SetAccessorDeclaration | ts.MethodDeclaration);
            newMembers.push(newMember);
            if (name) decoratedProperties.set(name, decorators);
            continue;
          }
          case ts.SyntaxKind.Constructor: {
            const ctor = member as ts.ConstructorDeclaration;
            if (!ctor.body) break;
            const [newMember, parametersInfo] =
                transformConstructor(member as ts.ConstructorDeclaration);
            classParameters = parametersInfo;
            newMembers.push(newMember);
            continue;
          }
          default:
            break;
        }
        newMembers.push(ts.visitEachChild(member, visitor, context));
      }
      const decorators = classDecl.decorators || [];

      const decoratorsToLower = [];
      const decoratorsToKeep: ts.Decorator[] = [];
      for (const decorator of decorators) {
        if (shouldLower(decorator, typeChecker)) {
          decoratorsToLower.push(extractMetadataFromSingleDecorator(decorator, diagnostics));
        } else {
          decoratorsToKeep.push(decorator);
        }
      }

      if (decoratorsToLower.length) {
        newMembers.push(createDecoratorClassProperty(decoratorsToLower));
      }
      if (classParameters) {
        if ((decoratorsToLower.length) || classParameters.some(p => !!p.decorators.length)) {
          // emit ctorParameters if the class was decoratored at all, or if any of its ctors
          // were classParameters
          newMembers.push(createCtorParametersClassProperty(
              diagnostics, entityNameToExpression, classParameters));
        }
      }
      if (decoratedProperties.size) {
        newMembers.push(createPropDecoratorsClassProperty(diagnostics, decoratedProperties));
      }
      const newDecorators = decoratorsToKeep.length ?
          ts.factory.createNodeArray(decoratorsToKeep) :
          undefined;
      return ts.factory.updateClassDeclaration(
          classDecl, newDecorators, classDecl.modifiers, classDecl.name,
          classDecl.typeParameters, classDecl.heritageClauses,
          ts.setTextRange(
              ts.factory.createNodeArray(
                  newMembers, classDecl.members.hasTrailingComma),
              classDecl.members));
    }