Skip to content
File

Blob: types/src/transforms/ambient.ts

typescript59 lines
1// Copyright (c) 2022-2023 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5import ts from "typescript";
6import { ensureStatementModifiers } from "./helpers";
7 
8// This ensures that all top-level nodes have the `declare` keyword, but no
9// nodes inside `declare modules` blocks do. It also ensures no top-level
10// nodes are `export`ed.
11//
12// ```ts
13// export class A { ... }
14// declare module "thing" {
15// declare class B { ... }
16// }
17// ```
18//
19// --- transforms to --->
20//
21// ```ts
22// declare class A { ... }
23// declare module "thing" {
24// class B { ... }
25// }
26// ```
27export function createAmbientTransformer(): ts.TransformerFactory<ts.SourceFile> {
28 return (ctx) => {
29 return (node) => {
30 const visitor = createVisitor(ctx);
31 return ts.visitEachChild(node, visitor, ctx);
32 };
33 };
34}
35 
36function createVisitor(ctx: ts.TransformationContext): ts.Visitor {
37 const moduleBlockChildVisitor: ts.Visitor = (node) => {
38 return ensureStatementModifiers(ctx, node, { declare: false });
39 };
40 const moduleDeclarationVisitor: ts.Visitor = (node) => {
41 if (ts.isModuleBlock(node)) {
42 return ts.visitEachChild(node, moduleBlockChildVisitor, ctx);
43 }
44 return node;
45 };
46 return (node) => {
47 if (
48 ts.isModuleDeclaration(node) &&
49 (node.flags & ts.NodeFlags.Namespace) === 0
50 ) {
51 return ts.visitEachChild(node, moduleDeclarationVisitor, ctx);
52 }
53 return ensureStatementModifiers(ctx, node, {
54 export: false,
55 declare: true,
56 });
57 };
58}