Blame view

天文台pc/tianwentai-ui/node_modules/@jridgewell/remapping/src/build-source-map-tree.ts 3.31 KB
bc518174   王天杨   提交两个项目文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  import { TraceMap } from '@jridgewell/trace-mapping';
  
  import { OriginalSource, MapSource } from './source-map-tree';
  
  import type { Sources, MapSource as MapSourceType } from './source-map-tree';
  import type { SourceMapInput, SourceMapLoader, LoaderContext } from './types';
  
  function asArray<T>(value: T | T[]): T[] {
    if (Array.isArray(value)) return value;
    return [value];
  }
  
  /**
   * Recursively builds a tree structure out of sourcemap files, with each node
   * being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of
   * `OriginalSource`s and `SourceMapTree`s.
   *
   * Every sourcemap is composed of a collection of source files and mappings
   * into locations of those source files. When we generate a `SourceMapTree` for
   * the sourcemap, we attempt to load each source file's own sourcemap. If it
   * does not have an associated sourcemap, it is considered an original,
   * unmodified source file.
   */
  export default function buildSourceMapTree(
    input: SourceMapInput | SourceMapInput[],
    loader: SourceMapLoader,
  ): MapSourceType {
    const maps = asArray(input).map((m) => new TraceMap(m, ''));
    const map = maps.pop()!;
  
    for (let i = 0; i < maps.length; i++) {
      if (maps[i].sources.length > 1) {
        throw new Error(
          `Transformation map ${i} must have exactly one source file.\n` +
            'Did you specify these with the most recent transformation maps first?',
        );
      }
    }
  
    let tree = build(map, loader, '', 0);
    for (let i = maps.length - 1; i >= 0; i--) {
      tree = MapSource(maps[i], [tree]);
    }
    return tree;
  }
  
  function build(
    map: TraceMap,
    loader: SourceMapLoader,
    importer: string,
    importerDepth: number,
  ): MapSourceType {
    const { resolvedSources, sourcesContent, ignoreList } = map;
  
    const depth = importerDepth + 1;
    const children = resolvedSources.map((sourceFile: string | null, i: number): Sources => {
      // The loading context gives the loader more information about why this file is being loaded
      // (eg, from which importer). It also allows the loader to override the location of the loaded
      // sourcemap/original source, or to override the content in the sourcesContent field if it's
      // an unmodified source file.
      const ctx: LoaderContext = {
        importer,
        depth,
        source: sourceFile || '',
        content: undefined,
        ignore: undefined,
      };
  
      // Use the provided loader callback to retrieve the file's sourcemap.
      // TODO: We should eventually support async loading of sourcemap files.
      const sourceMap = loader(ctx.source, ctx);
  
      const { source, content, ignore } = ctx;
  
      // If there is a sourcemap, then we need to recurse into it to load its source files.
      if (sourceMap) return build(new TraceMap(sourceMap, source), loader, source, depth);
  
      // Else, it's an unmodified source file.
      // The contents of this unmodified source file can be overridden via the loader context,
      // allowing it to be explicitly null or a string. If it remains undefined, we fall back to
      // the importing sourcemap's `sourcesContent` field.
      const sourceContent =
        content !== undefined ? content : sourcesContent ? sourcesContent[i] : null;
      const ignored = ignore !== undefined ? ignore : ignoreList ? ignoreList.includes(i) : false;
      return OriginalSource(source, sourceContent, ignored);
    });
  
    return MapSource(map, children);
  }