• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

source-academy / js-slang / 23995741899

05 Apr 2026 06:14AM UTC coverage: 77.093% (+0.002%) from 77.091%
23995741899

push

github

web-flow
Upgrade to TypeScript 6 and Prettier improvements (#1936)

* Upgrade TypeScript to v6

* Fix import source

* Fix tsconfig

* Fix preexisting type errors

* Remove scm-slang

* Bump node types

* Fix tsconfig

* Fix node types specifier

* Enable trailing commas

* Enable semicolons

* Check and commit files with changed line numbers

* Update Yarn to 4.13.0

* Remove unneeded sicp package deps

3112 of 4282 branches covered (72.68%)

Branch coverage included in aggregate %.

3761 of 5218 new or added lines in 152 files covered. (72.08%)

26 existing lines in 9 files now uncovered.

7136 of 9011 relevant lines covered (79.19%)

175254.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.67
/src/modules/preprocessor/index.ts
1
import type es from 'estree';
2
// import * as TypedES from '../../typeChecker/tsESTree'
3

4
import type { Context, IOptions } from '../..';
5
import { Variant } from '../../langs';
6
import { RecursivePartial } from '../../types';
7
import loadSourceModules, { loadSourceModuleTypes } from '../loader';
8
import type { FileGetter } from '../moduleTypes';
9
import analyzeImportsAndExports from './analyzer';
10
import defaultBundler, { type Bundler } from './bundler';
11
import parseProgramsAndConstructImportGraph from './linker';
12

13
export type PreprocessResult =
14
  | {
15
      ok: true;
16
      program: es.Program;
17
      files: Record<string, string>;
18
      verboseErrors: boolean;
19
    }
20
  | {
21
      ok: false;
22
      verboseErrors: boolean;
23
    };
24

25
/**
26
 * Preprocesses file imports and returns a transformed Abstract Syntax Tree (AST).
27
 * If an error is encountered at any point, returns `undefined` to signify that an
28
 * error occurred. Details of the error can be found inside `context.errors`.
29
 *
30
 * The preprocessing works by transforming each imported file into a function whose
31
 * parameters are other files (results of transformed functions) and return value
32
 * is a pair where the head is the default export or null, and the tail is a list
33
 * of pairs that map from exported names to identifiers.
34
 *
35
 * See https://github.com/source-academy/js-slang/wiki/Local-Module-Import-&-Export
36
 * for more information.
37
 *
38
 * @param files              An object mapping absolute file paths to file content.
39
 * @param entrypointFilePath The absolute path of the entrypoint file.
40
 * @param context            The information associated with the program evaluation.
41
 */
42
const preprocessFileImports = async (
53✔
43
  files: FileGetter,
44
  entrypointFilePath: string,
45
  context: Context,
46
  options: RecursivePartial<IOptions> = {},
1,186✔
47
  bundler: Bundler = defaultBundler,
1,186✔
48
): Promise<PreprocessResult> => {
49
  if (context.variant === Variant.TYPED) {
1,186✔
50
    // Load typed source modules into context first to ensure that the type checker has access to all types.
51
    // TODO: This is a temporary solution, and we should consider a better way to handle this.
52
    try {
4✔
53
      await loadSourceModuleTypes(new Set<string>(['rune', 'curve']), context);
4✔
54
    } catch (error) {
NEW
55
      context.errors.push(error);
×
56
      return {
×
57
        ok: false,
58
        verboseErrors: false,
59
      };
60
    }
61
  }
62

63
  // Parse all files into ASTs and build the import graph.
64
  const linkerResult = await parseProgramsAndConstructImportGraph(
1,186✔
65
    files,
66
    entrypointFilePath,
67
    context,
68
    options?.importOptions,
69
    !!options?.shouldAddFileName,
70
  );
71
  // Return 'undefined' if there are errors while parsing.
72
  if (!linkerResult.ok) {
1,186✔
73
    return linkerResult;
159✔
74
  }
75

76
  const { programs, topoOrder, sourceModulesToImport } = linkerResult;
1,027✔
77

78
  try {
1,027✔
79
    await loadSourceModules(
1,027✔
80
      sourceModulesToImport,
81
      context,
82
      options.importOptions?.loadTabs ?? true,
2,054✔
83
    );
84
    // Run type checking on the programs after loading the source modules and their types.
85
    const linkerResult = await parseProgramsAndConstructImportGraph(
1,027✔
86
      files,
87
      entrypointFilePath,
88
      context,
89
      options?.importOptions,
90
      !!options?.shouldAddFileName,
91
    );
92
    // Return 'undefined' if there are errors while parsing.
93
    if (!linkerResult.ok) {
1,027!
NEW
94
      return linkerResult;
×
95
    }
96

97
    analyzeImportsAndExports(
1,027✔
98
      programs,
99
      entrypointFilePath,
100
      topoOrder,
101
      context,
102
      options?.importOptions,
103
    );
104

105
    const program = bundler(programs, entrypointFilePath, topoOrder, context);
1,186✔
106
    return {
1,186✔
107
      ok: true,
108
      program,
109
      files: linkerResult.files,
110
      verboseErrors: linkerResult.verboseErrors,
111
    };
112
  } catch (error) {
113
    context.errors.push(error);
2✔
114
    return {
2✔
115
      ok: false,
116
      verboseErrors: linkerResult.verboseErrors,
117
    };
118
  }
119
};
120

121
export default preprocessFileImports;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc