Skip to content

Commit

Permalink
Move compiler utils to /utils exports (microsoft#2919)
Browse files Browse the repository at this point in the history
Provide a new exports `/utils` where we can export utils that are
commonly used in libraries and emitters but not tied to typespec
directly(deepClone, deepEquals, etc.)
  • Loading branch information
timotheeguerin authored and markcowl committed Mar 8, 2024
1 parent f8eb256 commit ee68d5a
Show file tree
Hide file tree
Showing 48 changed files with 238 additions and 194 deletions.
8 changes: 8 additions & 0 deletions .chronus/changes/compiler-utils-exports-2024-1-15-16-52-29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: deprecation
packages:
- "@typespec/compiler"
---

[API] Create a new export `@typespec/compiler/utils` exports. Deprecate export from `@typespec/compiler` of utils like `DuplicateTracker`, `Queue`, `createTwoKeyMap`, etc.
6 changes: 6 additions & 0 deletions .chronus/changes/compiler-utils-exports-2024-1-15-16-52-30.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: internal
packages:
- "@typespec/openapi3"
---
8 changes: 8 additions & 0 deletions .chronus/changes/compiler-utils-exports-2024-1-15-17-15-11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: fix
packages:
- "@typespec/eslint-config-typespec"
---

Exclude `temp` folder
4 changes: 4 additions & 0 deletions packages/compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
"./utils": {
"types": "./dist/src/utils/index.d.ts",
"default": "./dist/src/utils/index.js"
},
"./testing": {
"types": "./dist/src/testing/index.d.ts",
"default": "./dist/src/testing/index.js"
Expand Down
4 changes: 2 additions & 2 deletions packages/compiler/src/config/config-loader.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { createSourceFile } from "../core/diagnostics.js";
import { createDiagnostic } from "../core/messages.js";
import { getDirectoryPath, isPathAbsolute, joinPaths, resolvePath } from "../core/path-utils.js";
import { createJSONSchemaValidator } from "../core/schema-validator.js";
import { createSourceFile } from "../core/source-file.js";
import { CompilerHost, Diagnostic, NoTarget, SourceFile } from "../core/types.js";
import { deepClone, deepFreeze, doIO, omitUndefined } from "../core/util.js";
import { deepClone, deepFreeze, doIO, omitUndefined } from "../utils/misc.js";
import { getLocationInYamlScript } from "../yaml/index.js";
import { parseYaml } from "../yaml/parser.js";
import { YamlScript } from "../yaml/types.js";
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/config/config-to-options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createDiagnosticCollector, getDirectoryPath, normalizePath } from "../core/index.js";
import { CompilerOptions } from "../core/options.js";
import { CompilerHost, Diagnostic } from "../core/types.js";
import { deepClone, doIO, omitUndefined } from "../core/util.js";
import { deepClone, doIO, omitUndefined } from "../utils/misc.js";
import { expandConfigVariables } from "./config-interpolation.js";
import { loadTypeSpecConfigForPath, validateConfigPathsAbsolute } from "./config-loader.js";
import { EmitterOptions, TypeSpecConfig } from "./types.js";
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/core/binder.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { mutate } from "../utils/misc.js";
import { compilerAssert } from "./diagnostics.js";
import { getLocationContext } from "./helpers/index.js";
import { visitChildren } from "./parser.js";
Expand Down Expand Up @@ -35,7 +36,6 @@ import {
UnionStatementNode,
UsingStatementNode,
} from "./types.js";
import { mutate } from "./util.js";

// Use a regular expression to define the prefix for TypeSpec-exposed functions
// defined in JavaScript modules
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/core/checker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { $docFromComment, getIndexer } from "../lib/decorators.js";
import { MultiKeyMap, Mutable, createRekeyableMap, isArray, mutate } from "../utils/misc.js";
import { createSymbol, createSymbolTable } from "./binder.js";
import { getDeprecationDetails, markDeprecated } from "./deprecation.js";
import { ProjectionError, compilerAssert, reportDeprecated } from "./diagnostics.js";
Expand Down Expand Up @@ -150,7 +151,6 @@ import {
ValueType,
VoidType,
} from "./types.js";
import { MultiKeyMap, Mutable, createRekeyableMap, isArray, mutate } from "./util.js";

export type CreateTypeProps = Omit<Type, "isFinished" | keyof TypePrototype>;

Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/core/cli/actions/compile/args.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { resolveCompilerOptions } from "../../../../config/config-to-options.js";
import { omitUndefined } from "../../../../utils/misc.js";
import { createDiagnosticCollector } from "../../../diagnostics.js";
import { CompilerOptions } from "../../../options.js";
import { resolvePath } from "../../../path-utils.js";
import { CompilerHost, Diagnostic } from "../../../types.js";
import { omitUndefined } from "../../../util.js";

export interface CompileCliArgs {
"output-dir"?: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/core/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ try {
}

import yargs from "yargs";
import { typespecVersion } from "../../utils/misc.js";
import { installTypeSpecDependencies } from "../install.js";
import { typespecVersion } from "../util.js";
import { compileAction } from "./actions/compile/compile.js";
import { formatAction } from "./actions/format.js";
import { printInfoAction } from "./actions/info.js";
Expand Down
88 changes: 1 addition & 87 deletions packages/compiler/src/core/diagnostics.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CharCode } from "./charcode.js";
import { formatLog } from "./logger/index.js";
import type { Program } from "./program.js";
import { createSourceFile } from "./source-file.js";
import {
Diagnostic,
DiagnosticResult,
Expand All @@ -9,7 +9,6 @@ import {
Node,
NodeFlags,
NoTarget,
SourceFile,
SourceLocation,
SymbolFlags,
SyntaxKind,
Expand Down Expand Up @@ -52,42 +51,6 @@ export function formatDiagnostic(diagnostic: Diagnostic) {
);
}

export function createSourceFile(text: string, path: string): SourceFile {
let lineStarts: number[] | undefined = undefined;

return {
text,
path,
getLineStarts,
getLineAndCharacterOfPosition,
};

function getLineStarts() {
return (lineStarts = lineStarts ?? scanLineStarts(text));
}

function getLineAndCharacterOfPosition(position: number) {
const starts = getLineStarts();

let line = binarySearch(starts, position);

// When binarySearch returns < 0 indicating that the value was not found, it
// returns the bitwise complement of the index where the value would need to
// be inserted to keep the array sorted. So flipping the bits back to this
// positive index tells us what the line number would be if we were to
// create a new line starting at the given position, and subtracting 1 from
// that therefore gives us the line number we're after.
if (line < 0) {
line = ~line - 1;
}

return {
line,
character: position - starts[line],
};
}
}

export interface SourceLocationOptions {
/**
* If trying to resolve the location of a type with an ID, show the location of the ID node instead of the entire type.
Expand Down Expand Up @@ -241,55 +204,6 @@ export function compilerAssert(
throw new Error(message);
}

function scanLineStarts(text: string): number[] {
const starts = [];
let start = 0;
let pos = 0;

while (pos < text.length) {
const ch = text.charCodeAt(pos);
pos++;
switch (ch) {
case CharCode.CarriageReturn:
if (text.charCodeAt(pos) === CharCode.LineFeed) {
pos++;
}
// fallthrough
case CharCode.LineFeed:
starts.push(start);
start = pos;
break;
}
}

starts.push(start);
return starts;
}

/**
* Search sorted array of numbers for the given value. If found, return index
* in array where value was found. If not found, return a negative number that
* is the bitwise complement of the index where value would need to be inserted
* to keep the array sorted.
*/
function binarySearch(array: readonly number[], value: number) {
let low = 0;
let high = array.length - 1;
while (low <= high) {
const middle = low + ((high - low) >> 1);
const v = array[middle];
if (v < value) {
low = middle + 1;
} else if (v > value) {
high = middle - 1;
} else {
return middle;
}
}

return ~low;
}

/**
* Assert that the input type has one of the kinds provided
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/core/entrypoint-resolution.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { doIO, loadFile, resolveTspMain } from "../utils/misc.js";
import { DiagnosticHandler } from "./diagnostics.js";
import { resolvePath } from "./path-utils.js";
import { CompilerHost } from "./types.js";
import { doIO, loadFile, resolveTspMain } from "./util.js";

/**
* Resolve the path to the main file
Expand Down
3 changes: 2 additions & 1 deletion packages/compiler/src/core/helpers/discriminator-utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Discriminator, getDiscriminatedTypes } from "../../lib/decorators.js";
import { DuplicateTracker } from "../../utils/duplicate-tracker.js";
import { isDefined } from "../../utils/misc.js";
import { createDiagnostic } from "../messages.js";
import { Program } from "../program.js";
import { isTemplateDeclarationOrInstance } from "../type-utils.js";
import { Diagnostic, Model, Type, Union } from "../types.js";
import { DuplicateTracker, isDefined } from "../util.js";

export interface DiscriminatedUnion {
propertyName: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/core/helpers/usage-resolver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isArray } from "../../utils/misc.js";
import { Enum, Interface, Model, Namespace, Operation, Tuple, Type, Union } from "../types.js";
import { isArray } from "../util.js";

// prettier-ignore
export enum UsageFlags {
Expand Down
8 changes: 1 addition & 7 deletions packages/compiler/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ export * from "./path-utils.js";
export * from "./program.js";
export * from "./scanner.js";
export * from "./semantic-walker.js";
export { createSourceFile, getSourceFileKindFromExt } from "./source-file.js";
export * from "./type-utils.js";
export * from "./types.js";
export {
DuplicateTracker,
Queue,
TwoLevelMap,
createRekeyableMap,
getSourceFileKindFromExt,
} from "./util.js";
4 changes: 2 additions & 2 deletions packages/compiler/src/core/node-host.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { realpath } from "fs";
import { mkdir, readdir, readFile, rm, stat, writeFile } from "fs/promises";
import { fileURLToPath, pathToFileURL } from "url";
import { createSourceFile } from "./diagnostics.js";
import { findProjectRoot } from "../utils/misc.js";
import { fetch } from "./fetch.js";
import { createConsoleSink } from "./logger/index.js";
import { joinPaths } from "./path-utils.js";
import { createSourceFile, getSourceFileKindFromExt } from "./source-file.js";
import { CompilerHost, RmOptions } from "./types.js";
import { findProjectRoot, getSourceFileKindFromExt } from "./util.js";

export const CompilerPackageRoot = (await findProjectRoot(stat, fileURLToPath(import.meta.url)))!;

Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/core/parser.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isArray, mutate } from "../utils/misc.js";
import { trim } from "./charcode.js";
import { compilerAssert } from "./diagnostics.js";
import { CompilerDiagnostics, createDiagnostic } from "./messages.js";
Expand Down Expand Up @@ -109,7 +110,6 @@ import {
ValueOfExpressionNode,
VoidKeywordNode,
} from "./types.js";
import { isArray, mutate } from "./util.js";

/**
* Callback to parse each element in a delimited list
Expand Down
21 changes: 11 additions & 10 deletions packages/compiler/src/core/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@ import { EmitterOptions } from "../config/types.js";
import { createAssetEmitter } from "../emitter-framework/asset-emitter.js";
import { validateEncodedNamesConflicts } from "../lib/encoded-names.js";
import { MANIFEST } from "../manifest.js";
import {
deepEquals,
doIO,
findProjectRoot,
isDefined,
mapEquals,
mutate,
resolveTspMain,
} from "../utils/misc.js";
import { createBinder } from "./binder.js";
import { Checker, createChecker } from "./checker.js";
import { compilerAssert, createSourceFile } from "./diagnostics.js";
import { compilerAssert } from "./diagnostics.js";
import {
resolveTypeSpecEntrypoint,
resolveTypeSpecEntrypointForDir,
Expand All @@ -26,6 +35,7 @@ import { CompilerOptions } from "./options.js";
import { isImportStatement, parse, parseStandaloneTypeReference } from "./parser.js";
import { getDirectoryPath, joinPaths } from "./path-utils.js";
import { createProjector } from "./projector.js";
import { createSourceFile } from "./source-file.js";
import {
CompilerHost,
Diagnostic,
Expand Down Expand Up @@ -56,15 +66,6 @@ import {
TypeSpecLibrary,
TypeSpecScriptNode,
} from "./types.js";
import {
deepEquals,
doIO,
findProjectRoot,
isDefined,
mapEquals,
mutate,
resolveTspMain,
} from "./util.js";

export interface ProjectedProgram extends Program {
projector: Projector;
Expand Down
4 changes: 2 additions & 2 deletions packages/compiler/src/core/projector.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createRekeyableMap, mutate } from "../utils/misc.js";
import { finishTypeForProgram } from "./checker.js";
import { compilerAssert } from "./diagnostics.js";
import { createStateAccessors, isProjectedProgram, Program, ProjectedProgram } from "./program.js";
import { Program, ProjectedProgram, createStateAccessors, isProjectedProgram } from "./program.js";
import { getParentTemplateNode, isNeverType, isTemplateInstance } from "./type-utils.js";
import {
DecoratorApplication,
Expand All @@ -21,7 +22,6 @@ import {
Union,
UnionVariant,
} from "./types.js";
import { createRekeyableMap, mutate } from "./util.js";

/**
* Creates a projector which returns a projected view of either the global namespace or the
Expand Down
3 changes: 2 additions & 1 deletion packages/compiler/src/core/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import {
isWhiteSpaceSingleLine,
utf16CodeUnits,
} from "./charcode.js";
import { DiagnosticHandler, compilerAssert, createSourceFile } from "./diagnostics.js";
import { DiagnosticHandler, compilerAssert } from "./diagnostics.js";
import { CompilerDiagnostics, createDiagnostic } from "./messages.js";
import { createSourceFile } from "./source-file.js";
import { DiagnosticReport, SourceFile, TextRange } from "./types.js";

// All conflict markers consist of the same character repeated seven times. If it is
Expand Down
Loading

0 comments on commit ee68d5a

Please sign in to comment.