Migrate to eslint (#284)
* upgrading to tslint * more lint stuff * more lint fixes * all errors are gone * reduced eslint ignores * fixed todos * more shenanigans * added a few rules
This commit is contained in:
Родитель
a8f8c47431
Коммит
a8f99ccb08
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
lib
|
||||
**/*.js
|
|
@ -0,0 +1,36 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
project: "./tsconfig.json",
|
||||
},
|
||||
plugins: ["@typescript-eslint", "security", "prettier"],
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"plugin:security/recommended",
|
||||
],
|
||||
rules: {
|
||||
"@typescript-eslint/no-inferrable-types": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
|
||||
"@typescript-eslint/space-infix-ops": "error",
|
||||
"@typescript-eslint/switch-exhaustiveness-check": "error",
|
||||
"@typescript-eslint/typedef": [
|
||||
"error",
|
||||
{
|
||||
arrayDestructuring: true,
|
||||
arrowParameter: true,
|
||||
memberVariableDeclaration: true,
|
||||
objectDestructuring: true,
|
||||
parameter: true,
|
||||
propertyDeclaration: true,
|
||||
variableDeclaration: true,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/unified-signatures": "error",
|
||||
"prettier/prettier": ["error"],
|
||||
"security/detect-non-literal-fs-filename": "off",
|
||||
"security/detect-object-injection": "off",
|
||||
},
|
||||
};
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
34
package.json
34
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@microsoft/powerquery-parser",
|
||||
"version": "0.4.19",
|
||||
"version": "0.4.20",
|
||||
"description": "A parser for the Power Query/M formula language.",
|
||||
"author": "Microsoft",
|
||||
"license": "MIT",
|
||||
|
@ -13,9 +13,7 @@
|
|||
"test": "mocha --reporter mocha-multi-reporters --reporter-options configFile=src/test/mochaConfig.json -r ts-node/register src/test/libraryTest/**/*.ts",
|
||||
"test:benchmark": "npx ts-node src\\test\\resourceTest\\benchmark\\createBenchmarks.ts",
|
||||
"test:resources": "mocha --reporter mocha-multi-reporters --reporter-options configFile=src/test/mochaConfig.json -r ts-node/register src/test/resourceTest/**/*.ts",
|
||||
"lint": "npm run lint:prettier && npm run lint:tslint",
|
||||
"lint:prettier": ".\\node_modules\\.bin\\prettier --config \".prettierrc\" --list-different src\\**\\*.ts",
|
||||
"lint:tslint": ".\\node_modules\\.bin\\tslint src\\**\\*.ts",
|
||||
"lint": "eslint src --ext ts",
|
||||
"prepublishOnly": "git clean -xdf && npm install && npm run lint && npm run build && npm run test && npm run test:resources"
|
||||
},
|
||||
"homepage": "https://github.com/microsoft/powerquery-parser#readme",
|
||||
|
@ -32,22 +30,24 @@
|
|||
"grapheme-splitter": "^1.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.2.11",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^13.11.1",
|
||||
"chai": "^4.2.0",
|
||||
"@types/chai": "^4.3.0",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/node": "^17.0.5",
|
||||
"@typescript-eslint/eslint-plugin": "5.8.1",
|
||||
"@typescript-eslint/parser": "5.8.1",
|
||||
"chai": "^4.3.4",
|
||||
"eslint": "8.5.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-plugin-prettier": "4.0.0",
|
||||
"eslint-plugin-security": "1.4.0",
|
||||
"mocha": "^9.1.3",
|
||||
"mocha-junit-reporter": "^2.0.2",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"mocha-multi-reporters": "^1.5.1",
|
||||
"performance-now": "^2.1.0",
|
||||
"prettier": "^2.0.4",
|
||||
"ts-loader": "^6.2.2",
|
||||
"ts-node": "^8.8.2",
|
||||
"tslint": "^6.1.1",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"tslint-microsoft-contrib": "^6.2.0",
|
||||
"tslint-plugin-prettier": "^2.3.0",
|
||||
"typescript": "^4.3.5"
|
||||
"prettier": "^2.5.1",
|
||||
"ts-loader": "^9.2.6",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "^4.5.4"
|
||||
},
|
||||
"files": [
|
||||
"lib/powerquery-parser/**/*"
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
/* tslint:disable:no-console */
|
||||
|
||||
import { Assert, DefaultSettings, Lexer, ResultUtils, Task, TaskUtils } from ".";
|
||||
|
||||
parseText(`let x = 1 in try x otherwise 2`);
|
||||
|
||||
// @ts-ignore
|
||||
function parseText(text: string): void {
|
||||
// Try lexing and parsing the argument which returns a Result object.
|
||||
// A Result<T, E> is the union (Ok<T> | Error<E>).
|
||||
|
@ -34,7 +31,9 @@ function parseText(text: string): void {
|
|||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function lexText(text: string): void {
|
||||
// Notice that the Lexer.State variable is declared using let instead of const.
|
||||
// This is because calling Lexer functions return a new state object.
|
||||
|
|
|
@ -13,13 +13,23 @@ export function all<T>(
|
|||
return true;
|
||||
}
|
||||
|
||||
export function assertIn<T>(collection: ReadonlyArray<T>, item: T, maybeMessage?: string, maybeDetails?: {}): number {
|
||||
export function assertIn<T>(
|
||||
collection: ReadonlyArray<T>,
|
||||
item: T,
|
||||
maybeMessage?: string,
|
||||
maybeDetails?: object,
|
||||
): number {
|
||||
const index: number = collection.indexOf(item);
|
||||
Assert.isTrue(index !== -1, maybeMessage, maybeDetails ?? { item });
|
||||
return index;
|
||||
}
|
||||
|
||||
export function assertGet<T>(collection: ReadonlyArray<T>, index: number, maybeMessage?: string, maybeDetails?: {}): T {
|
||||
export function assertGet<T>(
|
||||
collection: ReadonlyArray<T>,
|
||||
index: number,
|
||||
maybeMessage?: string,
|
||||
maybeDetails?: object,
|
||||
): T {
|
||||
return Assert.asDefined(collection[index], maybeMessage, maybeDetails);
|
||||
}
|
||||
|
||||
|
@ -27,14 +37,18 @@ export function assertIndexOfPredicate<T>(
|
|||
collection: ReadonlyArray<T>,
|
||||
predicateFn: (element: T) => boolean,
|
||||
maybeMessage?: string,
|
||||
maybeDetails?: {},
|
||||
maybeDetails?: object,
|
||||
): number {
|
||||
const index: number = indexOfPredicate(collection, predicateFn);
|
||||
Assert.isTrue(index !== -1, maybeMessage, maybeDetails);
|
||||
return index;
|
||||
}
|
||||
|
||||
export function assertNonZeroLength<T>(collection: ReadonlyArray<T>, maybeMessage?: string, maybeDetails?: {}): void {
|
||||
export function assertNonZeroLength<T>(
|
||||
collection: ReadonlyArray<T>,
|
||||
maybeMessage?: string,
|
||||
maybeDetails?: object,
|
||||
): void {
|
||||
Assert.isTrue(
|
||||
collection.length > 0,
|
||||
maybeMessage ?? `collection should have at least one element in it`,
|
||||
|
@ -131,7 +145,7 @@ export function isSubset<T>(
|
|||
|
||||
export function range(size: number, startAt: number = 0): ReadonlyArray<number> {
|
||||
// tslint:disable-next-line: prefer-array-literal
|
||||
return [...Array(size).keys()].map(i => i + startAt);
|
||||
return [...Array(size).keys()].map((index: number) => index + startAt);
|
||||
}
|
||||
|
||||
export function replaceAtIndex<T>(collection: ReadonlyArray<T>, value: T, index: number): T[] {
|
||||
|
|
|
@ -4,18 +4,23 @@
|
|||
import { CommonError } from ".";
|
||||
import { ErrorResult, OkResult, Result, ResultUtils } from "./result";
|
||||
|
||||
export function asDefined<T>(maybeValue: T | undefined, maybeMessage?: string, maybeDetails?: {}): NonNullable<T> {
|
||||
export function asDefined<T>(maybeValue: T | undefined, maybeMessage?: string, maybeDetails?: object): NonNullable<T> {
|
||||
isDefined(maybeValue, maybeMessage, maybeDetails);
|
||||
return maybeValue;
|
||||
}
|
||||
|
||||
export function isTrue(value: boolean, maybeMessage?: string, maybeDetails?: {}): asserts value is true {
|
||||
export function asInstanceofError<T>(value: T): Error {
|
||||
isInstanceofError(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
export function isTrue(value: boolean, maybeMessage?: string, maybeDetails?: object): asserts value is true {
|
||||
if (value !== true) {
|
||||
throw new CommonError.InvariantError(maybeMessage ?? `assert failed, expected value to be true`, maybeDetails);
|
||||
}
|
||||
}
|
||||
|
||||
export function isFalse(value: boolean, maybeMessage?: string, maybeDetails?: {}): asserts value is false {
|
||||
export function isFalse(value: boolean, maybeMessage?: string, maybeDetails?: object): asserts value is false {
|
||||
if (value !== false) {
|
||||
throw new CommonError.InvariantError(maybeMessage ?? `assert failed, expected value to be false`, maybeDetails);
|
||||
}
|
||||
|
@ -25,10 +30,16 @@ export function isNever(_: never): never {
|
|||
throw new CommonError.InvariantError(`Should never be reached. Stack trace: ${new Error().stack}`);
|
||||
}
|
||||
|
||||
export function isInstanceofError<T>(value: T | Error): asserts value is Error {
|
||||
if (!(value instanceof Error)) {
|
||||
throw new CommonError.InvariantError(`Expected value to be instanceof Error`, { typeof: typeof value });
|
||||
}
|
||||
}
|
||||
|
||||
export function isDefined<T>(
|
||||
maybeValue: T | undefined,
|
||||
maybeMessage?: string,
|
||||
maybeDetails?: {},
|
||||
maybeDetails?: object,
|
||||
): asserts maybeValue is NonNullable<T> {
|
||||
if (maybeValue === undefined) {
|
||||
throw new CommonError.InvariantError(
|
||||
|
@ -41,7 +52,7 @@ export function isDefined<T>(
|
|||
export function isUndefined<T>(
|
||||
maybeValue: T | undefined,
|
||||
maybeMessage?: string,
|
||||
maybeDetails?: {},
|
||||
maybeDetails?: object,
|
||||
): asserts maybeValue is undefined {
|
||||
if (maybeValue !== undefined) {
|
||||
throw new CommonError.InvariantError(
|
||||
|
|
|
@ -22,38 +22,42 @@ export class CancellationError extends Error {
|
|||
}
|
||||
|
||||
export class InvariantError extends Error {
|
||||
constructor(readonly invariantBroken: string, readonly maybeDetails: any | undefined = undefined) {
|
||||
constructor(readonly invariantBroken: string, readonly maybeDetails?: object) {
|
||||
super(Localization.error_common_invariantError(Templates.DefaultTemplates, invariantBroken, maybeDetails));
|
||||
Object.setPrototypeOf(this, InvariantError.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class UnknownError extends Error {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
constructor(locale: string, readonly innerError: any) {
|
||||
super(Localization.error_common_unknown(LocalizationUtils.getLocalizationTemplates(locale), innerError));
|
||||
Object.setPrototypeOf(this, UnknownError.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function assertIsCommonError(error: any): error is CommonError {
|
||||
Assert.isTrue(isCommonError(error), "isCommonError(error)");
|
||||
return true;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isCommonError(error: any): error is CommonError {
|
||||
return error instanceof CommonError;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isTInnerCommonError(x: any): x is TInnerCommonError {
|
||||
return x instanceof CancellationError || x instanceof InvariantError || x instanceof UnknownError;
|
||||
}
|
||||
|
||||
export function ensureCommonError(locale: string, err: Error): CommonError {
|
||||
if (err instanceof CommonError) {
|
||||
return err;
|
||||
} else if (isTInnerCommonError(err)) {
|
||||
return new CommonError(err);
|
||||
export function ensureCommonError(locale: string, error: Error): CommonError {
|
||||
if (error instanceof CommonError) {
|
||||
return error;
|
||||
} else if (isTInnerCommonError(error)) {
|
||||
return new CommonError(error);
|
||||
} else {
|
||||
return new CommonError(new UnknownError(locale, err));
|
||||
return new CommonError(new UnknownError(locale, error));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ export class ImmutableSet<T> {
|
|||
}
|
||||
|
||||
public addMany(values: Iterable<T>): ImmutableSet<T> {
|
||||
// tslint:disable-next-line: no-this-assignment
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
let result: ImmutableSet<T> = this;
|
||||
|
||||
for (const value of values) {
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
import { Assert } from ".";
|
||||
|
||||
export function assertDelete<K, V>(map: Map<K, V>, key: K, maybeMessage?: string, maybeDetails?: {}): void {
|
||||
export function assertDelete<K, V>(map: Map<K, V>, key: K, maybeMessage?: string, maybeDetails?: object): void {
|
||||
Assert.isTrue(map.delete(key), maybeMessage ?? `failed to delete, key is absent`, maybeDetails ?? { key });
|
||||
}
|
||||
|
||||
export function assertGet<K, V>(map: Map<K, V>, key: K, maybeMessage?: string, maybeDetails?: {}): V {
|
||||
export function assertGet<K, V>(map: Map<K, V>, key: K, maybeMessage?: string, maybeDetails?: object): V {
|
||||
return Assert.asDefined(map.get(key), maybeMessage ?? `key not found in given map`, maybeDetails ?? { key });
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ export class OrderedMap<K, V> implements Map<K, V> {
|
|||
this.order = [...entries.keys()];
|
||||
this.size = entries.size;
|
||||
} else {
|
||||
this.order = entries.map(pair => pair[0]);
|
||||
this.order = entries.map((pair: readonly [K, V]) => pair[0]);
|
||||
this.size = entries.length;
|
||||
}
|
||||
}
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { CommonError } from "..";
|
||||
import { Assert, CommonError } from "..";
|
||||
import { ErrorResult, OkResult, Result, ResultKind } from "./result";
|
||||
|
||||
export function boxOk<T>(value: T): OkResult<T> {
|
||||
|
@ -29,7 +29,9 @@ export function isError<T, E>(result: Result<T, E>): result is ErrorResult<E> {
|
|||
export function ensureResult<T>(locale: string, callbackFn: () => T): Result<T, CommonError.CommonError> {
|
||||
try {
|
||||
return boxOk(callbackFn());
|
||||
} catch (err) {
|
||||
return boxError(CommonError.ensureCommonError(locale, err));
|
||||
} catch (error) {
|
||||
Assert.isInstanceofError(error);
|
||||
|
||||
return boxError(CommonError.ensureCommonError(locale, error));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Assert } from ".";
|
||||
|
||||
export function assertAddUnique<T>(collection: Set<T>, item: T, maybeMessage?: string, maybeDetails?: {}): void {
|
||||
export function assertAddUnique<T>(collection: Set<T>, item: T, maybeMessage?: string, maybeDetails?: object): void {
|
||||
Assert.isFalse(
|
||||
collection.has(item),
|
||||
maybeMessage ?? `collection expected to not already contain the given item`,
|
||||
|
@ -9,7 +9,7 @@ export function assertAddUnique<T>(collection: Set<T>, item: T, maybeMessage?: s
|
|||
collection.add(item);
|
||||
}
|
||||
|
||||
export function assertDelete<T>(collection: Set<T>, item: T, maybeMessage?: string, maybeDetails?: {}): void {
|
||||
export function assertDelete<T>(collection: Set<T>, item: T, maybeMessage?: string, maybeDetails?: object): void {
|
||||
Assert.isTrue(
|
||||
collection.delete(item),
|
||||
maybeMessage ?? `collection expected to contain the given item`,
|
||||
|
|
|
@ -55,7 +55,10 @@ export function columnNumberFrom(text: string, requiredCodeUnit: number): number
|
|||
}
|
||||
}
|
||||
|
||||
const details: {} = {
|
||||
const details: {
|
||||
text: string;
|
||||
requiredCodeUnit: number;
|
||||
} = {
|
||||
text,
|
||||
requiredCodeUnit,
|
||||
};
|
||||
|
|
|
@ -57,16 +57,16 @@ export abstract class TraceManager {
|
|||
|
||||
constructor(protected readonly valueDelimiter: string = ",", protected readonly newline: "\n" | "\r\n" = "\r\n") {}
|
||||
|
||||
abstract emit(trace: Trace, message: string, maybeDetails?: {}): void;
|
||||
abstract emit(trace: Trace, message: string, maybeDetails?: object): void;
|
||||
|
||||
// Creates a new Trace instance and call its entry method.
|
||||
// Traces should be created at the start of a function, and further calls are made on Trace instance.
|
||||
public entry(phase: string, task: string, maybeDetails?: {}): Trace {
|
||||
public entry(phase: string, task: string, maybeDetails?: object): Trace {
|
||||
return this.create(phase, task, maybeDetails);
|
||||
}
|
||||
|
||||
// Defaults to simple concatenation.
|
||||
protected formatMessage(trace: Trace, message: string, maybeDetails?: {}): string {
|
||||
protected formatMessage(trace: Trace, message: string, maybeDetails?: object): string {
|
||||
const details: string = maybeDetails !== undefined ? this.safeJsonStringify(maybeDetails) : TraceConstant.Empty;
|
||||
|
||||
return [trace.phase, trace.task, trace.id, message, details].join(this.valueDelimiter) + this.newline;
|
||||
|
@ -75,13 +75,18 @@ export abstract class TraceManager {
|
|||
// The return to the TraceManager.start function.
|
||||
// Subclass this when the TraceManager needs a different subclass of Trace.
|
||||
// Eg. BenchmarkTraceManager returns a BenchmarkTrace instance.
|
||||
protected create(phase: string, task: string, maybeDetails?: {}): Trace {
|
||||
protected create(phase: string, task: string, maybeDetails?: object): Trace {
|
||||
return new Trace(this.emit.bind(this), phase, task, this.createIdFn(), maybeDetails);
|
||||
}
|
||||
|
||||
// Copied signature from `JSON.stringify`.
|
||||
// Subclass this by providing values for `replacer` and/or `space`.
|
||||
protected safeJsonStringify(obj: {}, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string {
|
||||
// Subclass this by providing values for `replacer` and/or `space`.
|
||||
protected safeJsonStringify(
|
||||
obj: object,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
replacer?: (this: any, key: string, value: any) => any,
|
||||
space?: string | number,
|
||||
): string {
|
||||
try {
|
||||
return JSON.stringify(obj, replacer, space);
|
||||
} catch (e) {
|
||||
|
@ -96,7 +101,7 @@ export class ReportTraceManager extends TraceManager {
|
|||
super(valueDelimiter);
|
||||
}
|
||||
|
||||
emit(trace: Trace, message: string, maybeDetails?: {}): void {
|
||||
emit(trace: Trace, message: string, maybeDetails?: object): void {
|
||||
this.outputFn(this.formatMessage(trace, message, maybeDetails));
|
||||
}
|
||||
}
|
||||
|
@ -107,40 +112,41 @@ export class BenchmarkTraceManager extends ReportTraceManager {
|
|||
super(outputFn, valueDelimiter);
|
||||
}
|
||||
|
||||
override create(phase: string, task: string, maybeDetails?: {}): BenchmarkTrace {
|
||||
protected override create(phase: string, task: string, maybeDetails?: object): BenchmarkTrace {
|
||||
return new BenchmarkTrace(this.emit.bind(this), phase, task, this.createIdFn(), maybeDetails);
|
||||
}
|
||||
}
|
||||
|
||||
// The TraceManager for DefaultSettings.
|
||||
export class NoOpTraceManager extends TraceManager {
|
||||
emit(_tracer: Trace, _message: string, _maybeDetails?: {}): void {}
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
emit(_tracer: Trace, _message: string, _maybeDetails?: object): void {}
|
||||
|
||||
protected create(phase: string, task: string): Trace {
|
||||
return new NoOpTrace(this.emit.bind(this), phase, task, this.createIdFn());
|
||||
protected override create(phase: string, task: string, maybeDetails?: object): Trace {
|
||||
return new NoOpTrace(this.emit.bind(this), phase, task, this.createIdFn(), maybeDetails);
|
||||
}
|
||||
}
|
||||
|
||||
export class Trace {
|
||||
constructor(
|
||||
protected readonly emitTraceFn: (trace: Trace, message: string, maybeDetails?: {}) => void,
|
||||
protected readonly emitTraceFn: (trace: Trace, message: string, maybeDetails?: object) => void,
|
||||
public readonly phase: string,
|
||||
public readonly task: string,
|
||||
public readonly id: string,
|
||||
maybeDetails?: {},
|
||||
maybeDetails?: object,
|
||||
) {
|
||||
this.entry(maybeDetails);
|
||||
}
|
||||
|
||||
public entry(maybeDetails?: {}): void {
|
||||
public entry(maybeDetails?: object): void {
|
||||
this.trace(TraceConstant.Entry, maybeDetails);
|
||||
}
|
||||
|
||||
public trace(message: string, maybeDetails?: {}) {
|
||||
public trace(message: string, maybeDetails?: object) {
|
||||
this.emitTraceFn(this, message, maybeDetails);
|
||||
}
|
||||
|
||||
public exit(maybeDetails?: {}): void {
|
||||
public exit(maybeDetails?: object): void {
|
||||
this.trace(TraceConstant.Exit, maybeDetails);
|
||||
}
|
||||
}
|
||||
|
@ -151,16 +157,16 @@ export class BenchmarkTrace extends Trace {
|
|||
protected readonly timeStart: number = performanceNow();
|
||||
|
||||
constructor(
|
||||
emitTraceFn: (trace: Trace, message: string, maybeDetails?: {}) => void,
|
||||
emitTraceFn: (trace: Trace, message: string, maybeDetails?: object) => void,
|
||||
phase: string,
|
||||
task: string,
|
||||
id: string,
|
||||
maybeDetails?: {},
|
||||
maybeDetails?: object,
|
||||
) {
|
||||
super(emitTraceFn, phase, task, id, maybeDetails);
|
||||
}
|
||||
|
||||
public trace(message: string, maybeDetails?: {}) {
|
||||
public override trace(message: string, maybeDetails?: object) {
|
||||
const timeNow: number = performanceNow();
|
||||
|
||||
super.trace(message, {
|
||||
|
@ -172,7 +178,8 @@ export class BenchmarkTrace extends Trace {
|
|||
}
|
||||
|
||||
export class NoOpTrace extends Trace {
|
||||
public trace(_message: string, _maybeDetails?: {}) {}
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public override trace(_message: string, _maybeDetails?: object) {}
|
||||
}
|
||||
|
||||
function createAutoIncrementId(): () => string {
|
||||
|
|
|
@ -117,7 +117,7 @@ export function assertGetAllAstChildren<State extends ITraversalState<ResultType
|
|||
|
||||
if (maybeChildIds) {
|
||||
const childIds: ReadonlyArray<number> = maybeChildIds;
|
||||
return childIds.map(nodeId => NodeIdMapUtils.assertUnboxAst(nodeIdMapCollection.astNodeById, nodeId));
|
||||
return childIds.map((nodeId: number) => NodeIdMapUtils.assertUnboxAst(nodeIdMapCollection.astNodeById, nodeId));
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -263,11 +263,17 @@ export type TIsExpression = IsExpression | TAsExpression;
|
|||
|
||||
export type TNullablePrimitiveType = NullablePrimitiveType | PrimitiveType;
|
||||
|
||||
export interface NullablePrimitiveType
|
||||
extends IPairedConstant<NodeKind.NullablePrimitiveType, Constant.LanguageConstant.Nullable, PrimitiveType> {}
|
||||
export type NullablePrimitiveType = IPairedConstant<
|
||||
NodeKind.NullablePrimitiveType,
|
||||
Constant.LanguageConstant.Nullable,
|
||||
PrimitiveType
|
||||
>;
|
||||
|
||||
export interface IsNullablePrimitiveType
|
||||
extends IPairedConstant<NodeKind.IsNullablePrimitiveType, Constant.KeywordConstant.Is, TNullablePrimitiveType> {}
|
||||
export type IsNullablePrimitiveType = IPairedConstant<
|
||||
NodeKind.IsNullablePrimitiveType,
|
||||
Constant.KeywordConstant.Is,
|
||||
TNullablePrimitiveType
|
||||
>;
|
||||
|
||||
export interface PrimitiveType extends INode {
|
||||
readonly kind: NodeKind.PrimitiveType;
|
||||
|
@ -305,13 +311,12 @@ export type TArithmeticExpression = ArithmeticExpression | TMetadataExpression;
|
|||
|
||||
export type TMetadataExpression = MetadataExpression | TUnaryExpression;
|
||||
|
||||
export interface MetadataExpression
|
||||
extends IBinOpExpression<
|
||||
NodeKind.MetadataExpression,
|
||||
TUnaryExpression,
|
||||
Constant.KeywordConstant.Meta,
|
||||
TUnaryExpression
|
||||
> {}
|
||||
export type MetadataExpression = IBinOpExpression<
|
||||
NodeKind.MetadataExpression,
|
||||
TUnaryExpression,
|
||||
Constant.KeywordConstant.Meta,
|
||||
TUnaryExpression
|
||||
>;
|
||||
|
||||
// -----------------------------------------------
|
||||
// ---------- 12.2.3.9 Unary expression ----------
|
||||
|
@ -376,6 +381,8 @@ export interface IdentifierExpression extends INode {
|
|||
// ---------- 12.2.3.14 Parenthesized expression ----------
|
||||
// --------------------------------------------------------
|
||||
|
||||
// Can't be a type as it'll be a recursive definition
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface ParenthesizedExpression extends IParenthesisWrapped<NodeKind.ParenthesizedExpression, TExpression> {}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
@ -392,6 +399,8 @@ export interface NotImplementedExpression extends INode {
|
|||
// ---------- 12.2.3.16 Invoke expression ----------
|
||||
// -------------------------------------------------
|
||||
|
||||
// Can't be a type as it'll be a recursive definition
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface InvokeExpression extends IParenthesisWrapped<NodeKind.InvokeExpression, ICsvArray<TExpression>> {}
|
||||
|
||||
// -----------------------------------------------
|
||||
|
@ -400,6 +409,8 @@ export interface InvokeExpression extends IParenthesisWrapped<NodeKind.InvokeExp
|
|||
|
||||
export type TListItem = TExpression | RangeExpression;
|
||||
|
||||
// Can't be a type as it'll be a recursive definition
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface ListExpression extends IBraceWrapped<NodeKind.ListExpression, ICsvArray<TListItem>> {}
|
||||
|
||||
export interface RangeExpression extends INode {
|
||||
|
@ -414,8 +425,10 @@ export interface RangeExpression extends INode {
|
|||
// ---------- 12.2.3.18 Record expression ----------
|
||||
// -------------------------------------------------
|
||||
|
||||
export interface RecordExpression
|
||||
extends IBracketWrapped<NodeKind.RecordExpression, ICsvArray<GeneralizedIdentifierPairedExpression>> {}
|
||||
export type RecordExpression = IBracketWrapped<
|
||||
NodeKind.RecordExpression,
|
||||
ICsvArray<GeneralizedIdentifierPairedExpression>
|
||||
>;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// ---------- 12.2.3.19 Item access expression ----------
|
||||
|
@ -459,8 +472,7 @@ export interface FunctionExpression extends INode {
|
|||
// ---------- 12.2.3.22 Each expression ----------
|
||||
// -----------------------------------------------
|
||||
|
||||
export interface EachExpression
|
||||
extends IPairedConstant<NodeKind.EachExpression, Constant.KeywordConstant.Each, TExpression> {}
|
||||
export type EachExpression = IPairedConstant<NodeKind.EachExpression, Constant.KeywordConstant.Each, TExpression>;
|
||||
|
||||
// ----------------------------------------------
|
||||
// ---------- 12.2.3.23 Let expression ----------
|
||||
|
@ -508,10 +520,11 @@ export interface FunctionType extends INode {
|
|||
readonly functionReturnType: AsType;
|
||||
}
|
||||
|
||||
// Can't be a type as it'll be a recursive definition
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface ListType extends IBraceWrapped<NodeKind.ListType, TType> {}
|
||||
|
||||
export interface NullableType
|
||||
extends IPairedConstant<NodeKind.NullableType, Constant.LanguageConstant.Nullable, TType> {}
|
||||
export type NullableType = IPairedConstant<NodeKind.NullableType, Constant.LanguageConstant.Nullable, TType>;
|
||||
|
||||
export interface RecordType extends INode {
|
||||
readonly kind: NodeKind.RecordType;
|
||||
|
@ -530,8 +543,11 @@ export interface TableType extends INode {
|
|||
// ---------- 12.2.3.26 Error raising expression ----------
|
||||
// --------------------------------------------------------
|
||||
|
||||
export interface ErrorRaisingExpression
|
||||
extends IPairedConstant<NodeKind.ErrorRaisingExpression, Constant.KeywordConstant.Error, TExpression> {}
|
||||
export type ErrorRaisingExpression = IPairedConstant<
|
||||
NodeKind.ErrorRaisingExpression,
|
||||
Constant.KeywordConstant.Error,
|
||||
TExpression
|
||||
>;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// ---------- 12.2.3.27 Error handling expression ----------
|
||||
|
@ -545,8 +561,11 @@ export interface ErrorHandlingExpression extends INode {
|
|||
readonly maybeOtherwiseExpression: OtherwiseExpression | undefined;
|
||||
}
|
||||
|
||||
export interface OtherwiseExpression
|
||||
extends IPairedConstant<NodeKind.OtherwiseExpression, Constant.KeywordConstant.Otherwise, TExpression> {}
|
||||
export type OtherwiseExpression = IPairedConstant<
|
||||
NodeKind.OtherwiseExpression,
|
||||
Constant.KeywordConstant.Otherwise,
|
||||
TExpression
|
||||
>;
|
||||
|
||||
export interface RecursivePrimaryExpression extends INode {
|
||||
readonly kind: NodeKind.RecursivePrimaryExpression;
|
||||
|
@ -555,8 +574,7 @@ export interface RecursivePrimaryExpression extends INode {
|
|||
readonly recursiveExpressions: IArrayWrapper<InvokeExpression | ItemAccessExpression | TFieldAccessExpression>;
|
||||
}
|
||||
|
||||
export interface TypePrimaryType
|
||||
extends IPairedConstant<NodeKind.TypePrimaryType, Constant.KeywordConstant.Type, TPrimaryType> {}
|
||||
export type TypePrimaryType = IPairedConstant<NodeKind.TypePrimaryType, Constant.KeywordConstant.Type, TPrimaryType>;
|
||||
|
||||
// -----------------------------------------------
|
||||
// ---------- 12.2.4 Literal Attributes ----------
|
||||
|
@ -584,7 +602,7 @@ export interface IArrayWrapper<T> extends INode {
|
|||
readonly elements: ReadonlyArray<T>;
|
||||
}
|
||||
|
||||
export interface ICsvArray<T extends TCsvType> extends IArrayWrapper<ICsv<T>> {}
|
||||
export type ICsvArray<T extends TCsvType> = IArrayWrapper<ICsv<T>>;
|
||||
|
||||
export interface ICsv<T> extends INode {
|
||||
readonly kind: NodeKind.Csv;
|
||||
|
@ -612,7 +630,7 @@ export interface IWrapped<
|
|||
Kind extends TWrappedNodeKind,
|
||||
Open extends Constant.WrapperConstant,
|
||||
Content,
|
||||
Close extends Constant.WrapperConstant
|
||||
Close extends Constant.WrapperConstant,
|
||||
> extends INode {
|
||||
readonly kind: Kind;
|
||||
readonly openWrapperConstant: IConstant<Open>;
|
||||
|
@ -620,19 +638,26 @@ export interface IWrapped<
|
|||
readonly closeWrapperConstant: IConstant<Close>;
|
||||
}
|
||||
|
||||
export interface IBraceWrapped<Kind extends TWrappedNodeKind, Content>
|
||||
extends IWrapped<Kind, Constant.WrapperConstant.LeftBrace, Content, Constant.WrapperConstant.RightBrace> {}
|
||||
export type IBraceWrapped<Kind extends TWrappedNodeKind, Content> = IWrapped<
|
||||
Kind,
|
||||
Constant.WrapperConstant.LeftBrace,
|
||||
Content,
|
||||
Constant.WrapperConstant.RightBrace
|
||||
>;
|
||||
|
||||
export interface IBracketWrapped<Kind extends TWrappedNodeKind, Content>
|
||||
extends IWrapped<Kind, Constant.WrapperConstant.LeftBracket, Content, Constant.WrapperConstant.RightBracket> {}
|
||||
export type IBracketWrapped<Kind extends TWrappedNodeKind, Content> = IWrapped<
|
||||
Kind,
|
||||
Constant.WrapperConstant.LeftBracket,
|
||||
Content,
|
||||
Constant.WrapperConstant.RightBracket
|
||||
>;
|
||||
|
||||
export interface IParenthesisWrapped<Kind extends TWrappedNodeKind, Content>
|
||||
extends IWrapped<
|
||||
Kind,
|
||||
Constant.WrapperConstant.LeftParenthesis,
|
||||
Content,
|
||||
Constant.WrapperConstant.RightParenthesis
|
||||
> {}
|
||||
export type IParenthesisWrapped<Kind extends TWrappedNodeKind, Content> = IWrapped<
|
||||
Kind,
|
||||
Constant.WrapperConstant.LeftParenthesis,
|
||||
Content,
|
||||
Constant.WrapperConstant.RightParenthesis
|
||||
>;
|
||||
|
||||
// --------------------------------------
|
||||
// ---------- IBinOpExpression ----------
|
||||
|
@ -669,7 +694,7 @@ export interface IBinOpExpression<
|
|||
Kind extends TBinOpExpressionNodeKind,
|
||||
Left,
|
||||
OperatorKind extends Constant.TBinOpExpressionOperator,
|
||||
Right
|
||||
Right,
|
||||
> extends INode {
|
||||
readonly kind: Kind;
|
||||
readonly left: Left;
|
||||
|
@ -681,66 +706,64 @@ export interface IBinOpExpression<
|
|||
| IBinOpExpression<Kind, Right, OperatorKind, Right>;
|
||||
}
|
||||
|
||||
export interface ArithmeticExpression
|
||||
extends IBinOpExpression<
|
||||
NodeKind.ArithmeticExpression,
|
||||
TArithmeticExpression,
|
||||
Constant.ArithmeticOperator,
|
||||
TArithmeticExpression
|
||||
> {}
|
||||
export type ArithmeticExpression = IBinOpExpression<
|
||||
NodeKind.ArithmeticExpression,
|
||||
TArithmeticExpression,
|
||||
Constant.ArithmeticOperator,
|
||||
TArithmeticExpression
|
||||
>;
|
||||
|
||||
export interface AsExpression
|
||||
extends IBinOpExpression<
|
||||
NodeKind.AsExpression,
|
||||
TEqualityExpression,
|
||||
Constant.KeywordConstant.As,
|
||||
TNullablePrimitiveType
|
||||
> {}
|
||||
export type AsExpression = IBinOpExpression<
|
||||
NodeKind.AsExpression,
|
||||
TEqualityExpression,
|
||||
Constant.KeywordConstant.As,
|
||||
TNullablePrimitiveType
|
||||
>;
|
||||
|
||||
export interface EqualityExpression
|
||||
extends IBinOpExpression<
|
||||
NodeKind.EqualityExpression,
|
||||
TEqualityExpression,
|
||||
Constant.EqualityOperator,
|
||||
TEqualityExpression
|
||||
> {}
|
||||
export type EqualityExpression = IBinOpExpression<
|
||||
NodeKind.EqualityExpression,
|
||||
TEqualityExpression,
|
||||
Constant.EqualityOperator,
|
||||
TEqualityExpression
|
||||
>;
|
||||
|
||||
export interface IsExpression
|
||||
extends IBinOpExpression<
|
||||
NodeKind.IsExpression,
|
||||
TAsExpression,
|
||||
Constant.KeywordConstant.Is,
|
||||
TNullablePrimitiveType
|
||||
> {}
|
||||
export type IsExpression = IBinOpExpression<
|
||||
NodeKind.IsExpression,
|
||||
TAsExpression,
|
||||
Constant.KeywordConstant.Is,
|
||||
TNullablePrimitiveType
|
||||
>;
|
||||
|
||||
export interface LogicalExpression
|
||||
extends IBinOpExpression<
|
||||
NodeKind.LogicalExpression,
|
||||
TLogicalExpression,
|
||||
Constant.LogicalOperator,
|
||||
TLogicalExpression
|
||||
> {}
|
||||
export type LogicalExpression = IBinOpExpression<
|
||||
NodeKind.LogicalExpression,
|
||||
TLogicalExpression,
|
||||
Constant.LogicalOperator,
|
||||
TLogicalExpression
|
||||
>;
|
||||
|
||||
export interface RelationalExpression
|
||||
extends IBinOpExpression<
|
||||
NodeKind.RelationalExpression,
|
||||
TRelationalExpression,
|
||||
Constant.RelationalOperator,
|
||||
TRelationalExpression
|
||||
> {}
|
||||
export type RelationalExpression = IBinOpExpression<
|
||||
NodeKind.RelationalExpression,
|
||||
TRelationalExpression,
|
||||
Constant.RelationalOperator,
|
||||
TRelationalExpression
|
||||
>;
|
||||
|
||||
// ------------------------------------------
|
||||
// ---------- Key value pair nodes ----------
|
||||
// ------------------------------------------
|
||||
|
||||
export interface GeneralizedIdentifierPairedAnyLiteral
|
||||
extends IKeyValuePair<NodeKind.GeneralizedIdentifierPairedAnyLiteral, GeneralizedIdentifier, TAnyLiteral> {}
|
||||
export type GeneralizedIdentifierPairedAnyLiteral = IKeyValuePair<
|
||||
NodeKind.GeneralizedIdentifierPairedAnyLiteral,
|
||||
GeneralizedIdentifier,
|
||||
TAnyLiteral
|
||||
>;
|
||||
|
||||
// Can't be a type as it'll be a recursive definition
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface GeneralizedIdentifierPairedExpression
|
||||
extends IKeyValuePair<NodeKind.GeneralizedIdentifierPairedExpression, GeneralizedIdentifier, TExpression> {}
|
||||
|
||||
export interface IdentifierPairedExpression
|
||||
extends IKeyValuePair<NodeKind.IdentifierPairedExpression, Identifier, TExpression> {}
|
||||
export type IdentifierPairedExpression = IKeyValuePair<NodeKind.IdentifierPairedExpression, Identifier, TExpression>;
|
||||
|
||||
// ---------------------------------------
|
||||
// ---------- Parameter related ----------
|
||||
|
@ -748,8 +771,10 @@ export interface IdentifierPairedExpression
|
|||
|
||||
export type TParameterType = AsType | AsNullablePrimitiveType | undefined;
|
||||
|
||||
export interface IParameterList<T extends TParameterType>
|
||||
extends IParenthesisWrapped<NodeKind.ParameterList, ICsvArray<IParameter<T>>> {}
|
||||
export type IParameterList<T extends TParameterType> = IParenthesisWrapped<
|
||||
NodeKind.ParameterList,
|
||||
ICsvArray<IParameter<T>>
|
||||
>;
|
||||
|
||||
export interface IParameter<T extends TParameterType> extends INode {
|
||||
readonly kind: NodeKind.Parameter;
|
||||
|
@ -759,10 +784,13 @@ export interface IParameter<T extends TParameterType> extends INode {
|
|||
readonly maybeParameterType: T;
|
||||
}
|
||||
|
||||
export interface AsNullablePrimitiveType
|
||||
extends IPairedConstant<NodeKind.AsNullablePrimitiveType, Constant.KeywordConstant.As, TNullablePrimitiveType> {}
|
||||
export type AsNullablePrimitiveType = IPairedConstant<
|
||||
NodeKind.AsNullablePrimitiveType,
|
||||
Constant.KeywordConstant.As,
|
||||
TNullablePrimitiveType
|
||||
>;
|
||||
|
||||
export interface AsType extends IPairedConstant<NodeKind.AsType, Constant.KeywordConstant.As, TType> {}
|
||||
export type AsType = IPairedConstant<NodeKind.AsType, Constant.KeywordConstant.As, TType>;
|
||||
|
||||
// ------------------------------
|
||||
// ---------- Constant ----------
|
||||
|
@ -786,13 +814,12 @@ export type TConstant = IConstant<Constant.TConstant>;
|
|||
|
||||
export type TNullCoalescingExpression = NullCoalescingExpression | TLogicalExpression;
|
||||
|
||||
export interface NullCoalescingExpression
|
||||
extends IBinOpExpression<
|
||||
NodeKind.NullCoalescingExpression,
|
||||
TLogicalExpression,
|
||||
Constant.MiscConstant.NullCoalescingOperator,
|
||||
TLogicalExpression
|
||||
> {}
|
||||
export type NullCoalescingExpression = IBinOpExpression<
|
||||
NodeKind.NullCoalescingExpression,
|
||||
TLogicalExpression,
|
||||
Constant.MiscConstant.NullCoalescingOperator,
|
||||
TLogicalExpression
|
||||
>;
|
||||
|
||||
// ----------------------------------------
|
||||
// ---------- Re-used interfaces ----------
|
||||
|
|
|
@ -69,11 +69,10 @@ export function simplifyType(type: Ast.TType): SimplifiedType {
|
|||
break;
|
||||
|
||||
default:
|
||||
const details: {} = {
|
||||
throw new CommonError.InvariantError("this should never be reached", {
|
||||
nodeId: type.id,
|
||||
nodeKind: type.kind,
|
||||
};
|
||||
throw new CommonError.InvariantError("this should never be reached", details);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -165,9 +165,9 @@ export interface IToken<Kind, Position> {
|
|||
readonly data: string;
|
||||
}
|
||||
|
||||
export interface LineToken extends IToken<LineTokenKind, number> {}
|
||||
export type LineToken = IToken<LineTokenKind, number>;
|
||||
|
||||
export interface Token extends IToken<TokenKind, TokenPosition> {}
|
||||
export type Token = IToken<TokenKind, TokenPosition>;
|
||||
|
||||
export interface TokenPosition {
|
||||
readonly lineCodeUnit: number;
|
||||
|
|
|
@ -45,7 +45,9 @@ export type TLiteralKind =
|
|||
export type TAny = Any | AnyUnion;
|
||||
export type TList = List | DefinedList;
|
||||
export type TLogical = Logical | LogicalLiteral;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export type TFunction = Function | DefinedFunction;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export type TNumber = Number | NumberLiteral;
|
||||
export type TRecord = Record | DefinedRecord;
|
||||
export type TTable = Table | DefinedTable;
|
||||
|
@ -91,12 +93,14 @@ export type TPrimitiveType =
|
|||
| DateTime
|
||||
| DateTimeZone
|
||||
| Duration
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
| Function
|
||||
| List
|
||||
| Logical
|
||||
| None
|
||||
| NotApplicable
|
||||
| Null
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
| Number
|
||||
| Record
|
||||
| Table
|
||||
|
|
|
@ -523,9 +523,9 @@ function isCompatibleWithType(
|
|||
}
|
||||
|
||||
function isDefinedListTypeCompatibleWithListType(definedList: Type.DefinedListType, listType: Type.ListType): boolean {
|
||||
const itemTypeCompatabilities: ReadonlyArray<boolean | undefined> = definedList.itemTypes.map(itemType =>
|
||||
isCompatible(itemType, listType.itemType),
|
||||
const itemTypeCompatabilities: ReadonlyArray<boolean | undefined> = definedList.itemTypes.map(
|
||||
(itemType: Type.TPowerQueryType) => isCompatible(itemType, listType.itemType),
|
||||
);
|
||||
|
||||
return itemTypeCompatabilities.find(value => value === undefined || value === false) !== undefined;
|
||||
return !!itemTypeCompatabilities.find((value: boolean | undefined) => value === undefined || value === false);
|
||||
}
|
||||
|
|
|
@ -87,7 +87,8 @@ function simplifyAnyCategory(maybeCategory: AnyCategory | undefined): ReadonlyAr
|
|||
if (!maybeCategory?.flattenedAnyUnions) {
|
||||
return [];
|
||||
} else {
|
||||
return [...maybeCategory?.flattenedAnyUnions.values()];
|
||||
const flattnedAnyUnions: ImmutableSet<Type.TPowerQueryType> = maybeCategory?.flattenedAnyUnions;
|
||||
return [...flattnedAnyUnions.values()];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ export function typeCheckTable(valueType: Type.DefinedTable, schemaType: Type.Ta
|
|||
|
||||
function typeCheckGenericNumber<
|
||||
Value extends Type.TPowerQueryType | Type.FunctionParameter | undefined,
|
||||
Schema extends Type.TPowerQueryType | Type.FunctionParameter
|
||||
Schema extends Type.TPowerQueryType | Type.FunctionParameter,
|
||||
>(
|
||||
valueElements: ReadonlyArray<Value>,
|
||||
schemaItemTypes: ReadonlyArray<Schema>,
|
||||
|
|
|
@ -167,7 +167,6 @@ function inspectContextParameter(
|
|||
nodeIdMapCollection: NodeIdMap.Collection,
|
||||
parameter: ParseContext.Node<Ast.TParameter>,
|
||||
): Type.FunctionParameter | undefined {
|
||||
let isOptional: boolean;
|
||||
let isNullable: boolean;
|
||||
let maybeType: Type.TypeKind | undefined;
|
||||
|
||||
|
@ -187,7 +186,7 @@ function inspectContextParameter(
|
|||
0,
|
||||
Ast.NodeKind.Constant,
|
||||
);
|
||||
isOptional = maybeOptional !== undefined;
|
||||
const isOptional: boolean = maybeOptional !== undefined;
|
||||
|
||||
const maybeParameterType: Ast.AsNullablePrimitiveType | undefined = NodeIdMapUtils.maybeUnboxNthChildIfAstChecked(
|
||||
nodeIdMapCollection,
|
||||
|
|
|
@ -128,14 +128,17 @@ export class UnterminatedMultilineTokenError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isLexError(x: any): x is LexError {
|
||||
return x instanceof LexError;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isTLexError(x: any): x is TLexError {
|
||||
return x instanceof LexError || x instanceof CommonError.CommonError;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isTInnerLexError(x: any): x is TInnerLexError {
|
||||
return (
|
||||
x instanceof BadLineNumberError ||
|
||||
|
|
|
@ -214,7 +214,7 @@ export function isErrorLine(line: TLine): line is TErrorLine {
|
|||
}
|
||||
|
||||
export function maybeErrorLineMap(state: State): ErrorLineMap | undefined {
|
||||
const errorLines: ErrorLineMap = state.lines.reduce((errorLineMap: ErrorLineMap, line, index: number) => {
|
||||
const errorLines: ErrorLineMap = state.lines.reduce((errorLineMap: ErrorLineMap, line: TLine, index: number) => {
|
||||
if (isErrorLine(line)) {
|
||||
errorLineMap.set(index, line);
|
||||
}
|
||||
|
@ -295,12 +295,14 @@ function ensureCommonOrLexerResult<T>(
|
|||
): Result<T, CommonError.CommonError | LexError.LexError> {
|
||||
try {
|
||||
return ResultUtils.boxOk(functionToWrap());
|
||||
} catch (err) {
|
||||
} catch (error) {
|
||||
Assert.isInstanceofError(error);
|
||||
|
||||
let convertedError: CommonError.CommonError | LexError.LexError;
|
||||
if (LexError.isTInnerLexError(err)) {
|
||||
convertedError = new LexError.LexError(err);
|
||||
if (LexError.isTInnerLexError(error)) {
|
||||
convertedError = new LexError.LexError(error);
|
||||
} else {
|
||||
convertedError = CommonError.ensureCommonError(locale, err);
|
||||
convertedError = CommonError.ensureCommonError(locale, error);
|
||||
}
|
||||
return ResultUtils.boxError(convertedError);
|
||||
}
|
||||
|
@ -620,8 +622,10 @@ function tokenize(
|
|||
if (LexError.isTInnerLexError(e)) {
|
||||
error = new LexError.LexError(e);
|
||||
} else {
|
||||
Assert.isInstanceofError(e);
|
||||
error = CommonError.ensureCommonError(locale, e);
|
||||
}
|
||||
|
||||
continueLexing = false;
|
||||
maybeError = error;
|
||||
}
|
||||
|
@ -743,10 +747,9 @@ function tokenizeQuotedIdentifierContentOrEnd(line: TLine, currentPosition: numb
|
|||
};
|
||||
|
||||
default:
|
||||
const details: {} = { read };
|
||||
throw new CommonError.InvariantError(
|
||||
`expected the return to be either ${Token.LineTokenKind.TextLiteralContent} or ${Token.LineTokenKind.TextLiteralEnd}`,
|
||||
details,
|
||||
{ read },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { LexError } from ".";
|
||||
import { Lexer } from "..";
|
||||
import { CommonError, ICancellationToken, Result, ResultUtils, StringUtils } from "../common";
|
||||
import { Assert, CommonError, ICancellationToken, Result, ResultUtils, StringUtils } from "../common";
|
||||
import { Comment, Token } from "../language";
|
||||
|
||||
// The lexer is a multiline aware lexer.
|
||||
|
@ -69,6 +69,7 @@ export function trySnapshot(state: Lexer.State): TriedLexerSnapshot {
|
|||
if (LexError.isTInnerLexError(e)) {
|
||||
error = new LexError.LexError(e);
|
||||
} else {
|
||||
Assert.isInstanceofError(e);
|
||||
error = CommonError.ensureCommonError(state.locale, e);
|
||||
}
|
||||
return ResultUtils.boxError(error);
|
||||
|
@ -135,15 +136,16 @@ function createSnapshot(state: Lexer.State): LexerSnapshot {
|
|||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
default: {
|
||||
const positionStart: Token.TokenPosition = flatToken.positionStart;
|
||||
const positionEnd: Token.TokenPosition = flatToken.positionEnd;
|
||||
tokens.push({
|
||||
kind: (flatToken.kind as unknown) as Token.TokenKind,
|
||||
kind: flatToken.kind as unknown as Token.TokenKind,
|
||||
data: flatToken.data,
|
||||
positionStart,
|
||||
positionEnd,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
flatIndex += 1;
|
||||
|
@ -199,7 +201,7 @@ function readMultilineComment(
|
|||
LexError.UnterminatedMultilineTokenKind.MultilineComment,
|
||||
);
|
||||
} else if (maybeTokenEnd.kind !== Token.LineTokenKind.MultilineCommentEnd) {
|
||||
const details: {} = { foundTokenEnd: maybeTokenEnd };
|
||||
const details: { foundTokenEnd: FlatLineToken | undefined } = { foundTokenEnd: maybeTokenEnd };
|
||||
const message: string = `once a multiline token starts it should either reach a paired end token, or eof`;
|
||||
throw new CommonError.InvariantError(message, details);
|
||||
} else {
|
||||
|
@ -240,7 +242,7 @@ function readQuotedIdentifier(
|
|||
LexError.UnterminatedMultilineTokenKind.QuotedIdentifier,
|
||||
);
|
||||
} else if (maybeTokenEnd.kind !== Token.LineTokenKind.QuotedIdentifierEnd) {
|
||||
const details: {} = { foundTokenEnd: maybeTokenEnd };
|
||||
const details: { foundTokenEnd: FlatLineToken } = { foundTokenEnd: maybeTokenEnd };
|
||||
const message: string = `once a multiline token starts it should either reach a paired end token, or eof`;
|
||||
throw new CommonError.InvariantError(message, details);
|
||||
} else {
|
||||
|
@ -280,7 +282,7 @@ function readTextLiteral(
|
|||
LexError.UnterminatedMultilineTokenKind.Text,
|
||||
);
|
||||
} else if (maybeTokenEnd.kind !== Token.LineTokenKind.TextLiteralEnd) {
|
||||
const details: {} = { foundTokenEnd: maybeTokenEnd };
|
||||
const details: { foundTokenEnd: FlatLineToken } = { foundTokenEnd: maybeTokenEnd };
|
||||
const message: string = `once a multiline token starts it should either reach a paired end token, or eof`;
|
||||
throw new CommonError.InvariantError(message, details);
|
||||
} else {
|
||||
|
|
|
@ -14,9 +14,9 @@ interface ILocalization {
|
|||
readonly error_common_invariantError: (
|
||||
templates: ILocalizationTemplates,
|
||||
reason: string,
|
||||
maybeJsonifyableDetails: any | undefined,
|
||||
maybeJsonifyableDetails: object | undefined,
|
||||
) => string;
|
||||
readonly error_common_unknown: (templates: ILocalizationTemplates, message: any) => string;
|
||||
readonly error_common_unknown: (templates: ILocalizationTemplates, message: string) => string;
|
||||
readonly error_lex_badLineNumber: (templates: ILocalizationTemplates, kind: LexError.BadLineNumberKind) => string;
|
||||
readonly error_lex_badRange: (templates: ILocalizationTemplates, kind: LexError.BadRangeKind) => string;
|
||||
readonly error_lex_badState: (templates: ILocalizationTemplates) => string;
|
||||
|
@ -196,7 +196,7 @@ export const Localization: ILocalization = {
|
|||
error_common_invariantError: (
|
||||
templates: ILocalizationTemplates,
|
||||
invariantBroken: string,
|
||||
maybeJsonifyableDetails: any | undefined,
|
||||
maybeJsonifyableDetails: object | undefined,
|
||||
) => {
|
||||
if (maybeJsonifyableDetails !== undefined) {
|
||||
return StringUtils.assertGetFormatted(
|
||||
|
@ -214,7 +214,7 @@ export const Localization: ILocalization = {
|
|||
}
|
||||
},
|
||||
|
||||
error_common_unknown: (templates: ILocalizationTemplates, innerError: any) => {
|
||||
error_common_unknown: (templates: ILocalizationTemplates, innerError: string) => {
|
||||
return StringUtils.assertGetFormatted(templates.error_common_unknown, new Map([["innerError", innerError]]));
|
||||
},
|
||||
|
||||
|
|
|
@ -41,11 +41,11 @@ export function readAmbiguous<T extends Ast.TNode>(
|
|||
try {
|
||||
maybeNode = parseFn(variantState, parser);
|
||||
variantResult = ResultUtils.boxOk(maybeNode);
|
||||
} catch (err) {
|
||||
if (!ParseError.isTInnerParseError(err)) {
|
||||
throw err;
|
||||
} catch (error) {
|
||||
if (!ParseError.isTInnerParseError(error)) {
|
||||
throw error;
|
||||
}
|
||||
variantResult = ResultUtils.boxError(new ParseError.ParseError(err, variantState));
|
||||
variantResult = ResultUtils.boxError(new ParseError.ParseError(error, variantState));
|
||||
}
|
||||
|
||||
const candiate: AmbiguousParse<T> = {
|
||||
|
|
|
@ -140,19 +140,23 @@ export interface TokenWithColumnNumber {
|
|||
readonly columnNumber: number;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function assertIsParseError(error: any): error is ParseError {
|
||||
Assert.isTrue(isParseError(error), "isParseError(error)");
|
||||
return true;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isParseError(error: any): error is ParseError {
|
||||
return error instanceof ParseError;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isTParseError(error: any): error is TParseError {
|
||||
return isParseError(error) || CommonError.isCommonError(error);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isTInnerParseError(x: any): x is TInnerParseError {
|
||||
return (
|
||||
x instanceof ExpectedAnyTokenKindError ||
|
||||
|
|
|
@ -53,7 +53,7 @@ export function assertIterChildrenAst(
|
|||
parentId: number,
|
||||
): ReadonlyArray<Ast.TNode> {
|
||||
const astNodeById: NodeIdMap.AstNodeById = nodeIdMapCollection.astNodeById;
|
||||
return assertIterChildIds(nodeIdMapCollection.childIdsById, parentId).map(childId =>
|
||||
return assertIterChildIds(nodeIdMapCollection.childIdsById, parentId).map((childId: number) =>
|
||||
NodeIdMapUtils.assertUnboxAst(astNodeById, childId),
|
||||
);
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ export function assertIterXor(
|
|||
nodeIdMapCollection: NodeIdMap.Collection,
|
||||
nodeIds: ReadonlyArray<number>,
|
||||
): ReadonlyArray<TXorNode> {
|
||||
return nodeIds.map(nodeId => NodeIdMapUtils.assertGetXor(nodeIdMapCollection, nodeId));
|
||||
return nodeIds.map((nodeId: number) => NodeIdMapUtils.assertGetXor(nodeIdMapCollection, nodeId));
|
||||
}
|
||||
|
||||
// If any exist, returns all Ast nodes under the given node.
|
||||
|
@ -93,7 +93,7 @@ export function maybeIterChildrenAst(
|
|||
const childIds: ReadonlyArray<number> = maybeChildIds;
|
||||
|
||||
const astNodeById: NodeIdMap.AstNodeById = nodeIdMapCollection.astNodeById;
|
||||
return childIds.map(childId => NodeIdMapUtils.assertUnboxAst(astNodeById, childId));
|
||||
return childIds.map((childId: number) => NodeIdMapUtils.assertUnboxAst(astNodeById, childId));
|
||||
}
|
||||
|
||||
export function maybeNextSiblingXor(nodeIdMapCollection: NodeIdMap.Collection, nodeId: number): TXorNode | undefined {
|
||||
|
@ -192,13 +192,12 @@ export function iterFieldProjectionNames(
|
|||
const result: string[] = [];
|
||||
|
||||
for (const selector of iterFieldProjection(nodeIdMapCollection, fieldProjection)) {
|
||||
const maybeIdentifier:
|
||||
| XorNode<Ast.GeneralizedIdentifier>
|
||||
| undefined = NodeIdMapUtils.maybeUnboxWrappedContentChecked<Ast.GeneralizedIdentifier>(
|
||||
nodeIdMapCollection,
|
||||
selector.node.id,
|
||||
Ast.NodeKind.GeneralizedIdentifier,
|
||||
);
|
||||
const maybeIdentifier: XorNode<Ast.GeneralizedIdentifier> | undefined =
|
||||
NodeIdMapUtils.maybeUnboxWrappedContentChecked<Ast.GeneralizedIdentifier>(
|
||||
nodeIdMapCollection,
|
||||
selector.node.id,
|
||||
Ast.NodeKind.GeneralizedIdentifier,
|
||||
);
|
||||
if (maybeIdentifier && XorNodeUtils.isAstXor(maybeIdentifier)) {
|
||||
result.push(maybeIdentifier.node.literal);
|
||||
}
|
||||
|
@ -220,9 +219,13 @@ export function iterFunctionExpressionParameters(
|
|||
);
|
||||
}
|
||||
|
||||
const maybeParameterList: XorNode<Ast.TParameterList> | undefined = NodeIdMapUtils.maybeNthChildChecked<
|
||||
Ast.TParameterList
|
||||
>(nodeIdMapCollection, functionExpression.node.id, 0, Ast.NodeKind.ParameterList);
|
||||
const maybeParameterList: XorNode<Ast.TParameterList> | undefined =
|
||||
NodeIdMapUtils.maybeNthChildChecked<Ast.TParameterList>(
|
||||
nodeIdMapCollection,
|
||||
functionExpression.node.id,
|
||||
0,
|
||||
Ast.NodeKind.ParameterList,
|
||||
);
|
||||
if (maybeParameterList === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
@ -350,9 +353,13 @@ export function iterSection(
|
|||
});
|
||||
}
|
||||
|
||||
const maybeSectionMemberArrayWrapper: XorNode<Ast.TArrayWrapper> | undefined = NodeIdMapUtils.maybeNthChildChecked<
|
||||
Ast.TArrayWrapper
|
||||
>(nodeIdMapCollection, section.node.id, 4, Ast.NodeKind.ArrayWrapper);
|
||||
const maybeSectionMemberArrayWrapper: XorNode<Ast.TArrayWrapper> | undefined =
|
||||
NodeIdMapUtils.maybeNthChildChecked<Ast.TArrayWrapper>(
|
||||
nodeIdMapCollection,
|
||||
section.node.id,
|
||||
4,
|
||||
Ast.NodeKind.ArrayWrapper,
|
||||
);
|
||||
if (maybeSectionMemberArrayWrapper === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
@ -360,14 +367,13 @@ export function iterSection(
|
|||
|
||||
const partial: SectionKeyValuePair[] = [];
|
||||
for (const sectionMember of assertIterChildrenXor(nodeIdMapCollection, sectionMemberArrayWrapper.node.id)) {
|
||||
const maybeKeyValuePair:
|
||||
| XorNode<Ast.IdentifierPairedExpression>
|
||||
| undefined = NodeIdMapUtils.maybeNthChildChecked<Ast.IdentifierPairedExpression>(
|
||||
nodeIdMapCollection,
|
||||
sectionMember.node.id,
|
||||
2,
|
||||
Ast.NodeKind.IdentifierPairedExpression,
|
||||
);
|
||||
const maybeKeyValuePair: XorNode<Ast.IdentifierPairedExpression> | undefined =
|
||||
NodeIdMapUtils.maybeNthChildChecked<Ast.IdentifierPairedExpression>(
|
||||
nodeIdMapCollection,
|
||||
sectionMember.node.id,
|
||||
2,
|
||||
Ast.NodeKind.IdentifierPairedExpression,
|
||||
);
|
||||
if (maybeKeyValuePair === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
@ -401,7 +407,7 @@ export function iterSection(
|
|||
|
||||
function iterKeyValuePairs<
|
||||
Key extends Ast.GeneralizedIdentifier | Ast.Identifier,
|
||||
KVP extends TKeyValuePair & IKeyValuePair<Key>
|
||||
KVP extends TKeyValuePair & IKeyValuePair<Key>,
|
||||
>(nodeIdMapCollection: NodeIdMap.Collection, arrayWrapper: TXorNode, pairKind: KVP["pairKind"]): ReadonlyArray<KVP> {
|
||||
const partial: KVP[] = [];
|
||||
for (const keyValuePair of iterArrayWrapper(nodeIdMapCollection, arrayWrapper)) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { NodeIdMap, NodeIdMapIterator, NodeIdMapUtils, XorNodeUtils } from "..";
|
||||
import { MapUtils, TypeScriptUtils } from "../../../common";
|
||||
import { Assert, MapUtils, TypeScriptUtils } from "../../../common";
|
||||
import { Ast } from "../../../language";
|
||||
import { ParseContext } from "../../context";
|
||||
import { Collection } from "../nodeIdMap";
|
||||
|
@ -78,7 +78,7 @@ function createDelta(
|
|||
// Build up the change delta.
|
||||
for (const xorNode of xorNodes) {
|
||||
const oldId: number = xorNode.node.id;
|
||||
const newId: number = newIdByOldId.get(oldId)!;
|
||||
const newId: number = Assert.asDefined(newIdByOldId.get(oldId));
|
||||
|
||||
if (XorNodeUtils.isAstXor(xorNode)) {
|
||||
partialCollection.astNodeById.set(newId, xorNode.node);
|
||||
|
|
|
@ -61,7 +61,7 @@ export function maybeRightMostLeaf(
|
|||
let maybeRightMost: Ast.TNode | undefined;
|
||||
|
||||
while (nodeIdsToExplore.length) {
|
||||
const nodeId: number = nodeIdsToExplore.pop()!;
|
||||
const nodeId: number = Assert.asDefined(nodeIdsToExplore.pop());
|
||||
const maybeAstNode: Ast.TNode | undefined = astNodeById.get(nodeId);
|
||||
|
||||
let addChildren: boolean = false;
|
||||
|
|
|
@ -33,7 +33,11 @@ export function assertGetRecursiveExpressionPreviousSibling<T extends Ast.TNode>
|
|||
);
|
||||
const indexOfPrimaryExpressionId: number = childIds.indexOf(xorNode.node.id);
|
||||
if (indexOfPrimaryExpressionId === -1 || indexOfPrimaryExpressionId === 0) {
|
||||
const details: {} = {
|
||||
const details: {
|
||||
xorNodeId: number;
|
||||
arrayWrapperId: number;
|
||||
indexOfPrimaryExpressionId: number;
|
||||
} = {
|
||||
xorNodeId: xorNode.node.id,
|
||||
arrayWrapperId: arrayWrapper.node.id,
|
||||
indexOfPrimaryExpressionId,
|
||||
|
@ -82,9 +86,13 @@ export function maybeInvokeExpressionIdentifier(
|
|||
// Grab the RecursivePrimaryExpression's head if it's an IdentifierExpression
|
||||
const recursiveArrayXorNode: TXorNode = assertGetParentXor(nodeIdMapCollection, invokeExprXorNode.node.id);
|
||||
const recursiveExprXorNode: TXorNode = assertGetParentXor(nodeIdMapCollection, recursiveArrayXorNode.node.id);
|
||||
const maybeHeadXorNode: XorNode<Ast.IdentifierExpression> | undefined = maybeNthChildChecked<
|
||||
Ast.IdentifierExpression
|
||||
>(nodeIdMapCollection, recursiveExprXorNode.node.id, 0, Ast.NodeKind.IdentifierExpression);
|
||||
const maybeHeadXorNode: XorNode<Ast.IdentifierExpression> | undefined =
|
||||
maybeNthChildChecked<Ast.IdentifierExpression>(
|
||||
nodeIdMapCollection,
|
||||
recursiveExprXorNode.node.id,
|
||||
0,
|
||||
Ast.NodeKind.IdentifierExpression,
|
||||
);
|
||||
|
||||
// It's not an identifier expression so there's nothing we can do.
|
||||
if (maybeHeadXorNode === undefined) {
|
||||
|
@ -95,7 +103,10 @@ export function maybeInvokeExpressionIdentifier(
|
|||
// The only place for an identifier in a RecursivePrimaryExpression is as the head, therefore an InvokeExpression
|
||||
// only has a name if the InvokeExpression is the 0th element in the RecursivePrimaryExpressionArray.
|
||||
if (XorNodeUtils.isContextXor(headXorNode)) {
|
||||
const details: {} = {
|
||||
const details: {
|
||||
identifierExpressionNodeId: number;
|
||||
invokeExpressionNodeId: number;
|
||||
} = {
|
||||
identifierExpressionNodeId: headXorNode.node.id,
|
||||
invokeExpressionNodeId: invokeExprXorNode.node.id,
|
||||
};
|
||||
|
@ -135,9 +146,8 @@ export function maybeInvokeExpressionIdentifierLiteral(
|
|||
): string | undefined {
|
||||
assertGetXorChecked(nodeIdMapCollection, nodeId, Ast.NodeKind.InvokeExpression);
|
||||
|
||||
const maybeIdentifierExpressionXorNode:
|
||||
| XorNode<Ast.IdentifierExpression>
|
||||
| undefined = maybeInvokeExpressionIdentifier(nodeIdMapCollection, nodeId);
|
||||
const maybeIdentifierExpressionXorNode: XorNode<Ast.IdentifierExpression> | undefined =
|
||||
maybeInvokeExpressionIdentifier(nodeIdMapCollection, nodeId);
|
||||
if (maybeIdentifierExpressionXorNode === undefined || XorNodeUtils.isContextXor(maybeIdentifierExpressionXorNode)) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ export function isOnConstantKind(state: ParseState, constantKind: Constant.TCons
|
|||
if (isOnTokenKind(state, Token.TokenKind.Identifier)) {
|
||||
const currentToken: Token.Token = state.lexerSnapshot.tokens[state.tokenIndex];
|
||||
if (currentToken?.data === undefined) {
|
||||
const details: {} = { currentToken };
|
||||
const details: { currentToken: Token.Token } = { currentToken };
|
||||
throw new CommonError.InvariantError(`expected data on Token`, details);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { ParseError } from "..";
|
||||
import { CommonError, ResultUtils } from "../../common";
|
||||
import { Assert, CommonError, ResultUtils } from "../../common";
|
||||
import { Ast } from "../../language";
|
||||
import { LexerSnapshot } from "../../lexer";
|
||||
import { ParseSettings } from "../../settings";
|
||||
|
@ -23,12 +23,15 @@ export function tryParse(parseSettings: ParseSettings, lexerSnapshot: LexerSnaps
|
|||
try {
|
||||
const root: Ast.TNode = maybeParserEntryPointFn(parseState, parseSettings.parser);
|
||||
ParseStateUtils.assertIsDoneParsing(parseState);
|
||||
|
||||
return ResultUtils.boxOk({
|
||||
lexerSnapshot,
|
||||
root,
|
||||
state: parseState,
|
||||
});
|
||||
} catch (error) {
|
||||
Assert.isInstanceofError(error);
|
||||
|
||||
return ResultUtils.boxError(ensureParseError(parseState, error, parseSettings.locale));
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +52,8 @@ export function tryParseDocument(parseSettings: ParseSettings, lexerSnapshot: Le
|
|||
state: expressionDocumentState,
|
||||
});
|
||||
} catch (expressionDocumentError) {
|
||||
Assert.isInstanceofError(expressionDocumentError);
|
||||
|
||||
const sectionDocumentState: ParseState = parseSettings.createParseState(
|
||||
lexerSnapshot,
|
||||
defaultOverrides(parseSettings),
|
||||
|
@ -62,6 +67,8 @@ export function tryParseDocument(parseSettings: ParseSettings, lexerSnapshot: Le
|
|||
state: sectionDocumentState,
|
||||
});
|
||||
} catch (sectionDocumentError) {
|
||||
Assert.isInstanceofError(sectionDocumentError);
|
||||
|
||||
let betterParsedState: ParseState;
|
||||
let betterParsedError: Error;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { NaiveParseSteps } from ".";
|
||||
import { NodeIdMap, ParseContextUtils } from "..";
|
||||
import { ArrayUtils, Assert, TypeScriptUtils } from "../../common";
|
||||
import { ArrayUtils, Assert, MapUtils, TypeScriptUtils } from "../../common";
|
||||
import { Ast, AstUtils, Constant, ConstantUtils, Token } from "../../language";
|
||||
import { Disambiguation, DisambiguationUtils } from "../disambiguation";
|
||||
import { Parser, ParserUtils } from "../parser";
|
||||
|
@ -68,7 +68,7 @@ function readBinOpExpression(
|
|||
): Ast.TBinOpExpression | Ast.TUnaryExpression | Ast.TNullablePrimitiveType {
|
||||
state.maybeCancellationToken?.throwIfCancelled();
|
||||
ParseStateUtils.startContext(state, nodeKind);
|
||||
const placeholderContextId: number = state.maybeCurrentContextNode!.id;
|
||||
const placeholderContextId: number = Assert.asDefined(state.maybeCurrentContextNode).id;
|
||||
|
||||
// operators/operatorConstants are of length N
|
||||
// expressions are of length N + 1
|
||||
|
@ -78,16 +78,15 @@ function readBinOpExpression(
|
|||
parser.readUnaryExpression(state, parser),
|
||||
];
|
||||
|
||||
let maybeOperator:
|
||||
| Constant.TBinOpExpressionOperator
|
||||
| undefined = ConstantUtils.maybeBinOpExpressionOperatorKindFrom(state.maybeCurrentTokenKind);
|
||||
let maybeOperator: Constant.TBinOpExpressionOperator | undefined =
|
||||
ConstantUtils.maybeBinOpExpressionOperatorKindFrom(state.maybeCurrentTokenKind);
|
||||
while (maybeOperator !== undefined) {
|
||||
const operator: Constant.TBinOpExpressionOperator = maybeOperator;
|
||||
operators.push(operator);
|
||||
operatorConstants.push(
|
||||
NaiveParseSteps.readTokenKindAsConstant<Constant.TBinOpExpressionOperator>(
|
||||
state,
|
||||
state.maybeCurrentTokenKind!,
|
||||
Assert.asDefined(state.maybeCurrentTokenKind),
|
||||
maybeOperator,
|
||||
),
|
||||
);
|
||||
|
@ -115,7 +114,11 @@ function readBinOpExpression(
|
|||
// which might be previously built TBinOpExpression nodes.
|
||||
const nodeIdMapCollection: NodeIdMap.Collection = state.contextState.nodeIdMapCollection;
|
||||
const newNodeThreshold: number = state.contextState.idCounter;
|
||||
let placeholderContextChildren: ReadonlyArray<number> = nodeIdMapCollection.childIdsById.get(placeholderContextId)!;
|
||||
let placeholderContextChildren: ReadonlyArray<number> = MapUtils.assertGet(
|
||||
nodeIdMapCollection.childIdsById,
|
||||
placeholderContextId,
|
||||
);
|
||||
|
||||
while (operators.length) {
|
||||
let minPrecedenceIndex: number = -1;
|
||||
let minPrecedence: number = Number.MAX_SAFE_INTEGER;
|
||||
|
|
|
@ -42,7 +42,7 @@ interface WrappedRead<
|
|||
Kind extends Ast.TWrappedNodeKind,
|
||||
Open extends Constant.WrapperConstant,
|
||||
Content,
|
||||
Close extends Constant.WrapperConstant
|
||||
Close extends Constant.WrapperConstant,
|
||||
> extends Ast.IWrapped<Kind, Open, Content, Close> {
|
||||
readonly maybeOptionalConstant: Ast.IConstant<Constant.MiscConstant.QuestionMark> | undefined;
|
||||
}
|
||||
|
@ -196,6 +196,8 @@ export function readDocument(state: ParseState, parser: Parser): Ast.TDocument {
|
|||
document = parser.readExpression(state, parser);
|
||||
ParseStateUtils.assertIsDoneParsing(state);
|
||||
} catch (expressionError) {
|
||||
Assert.isInstanceofError(expressionError);
|
||||
|
||||
// Fast backup deletes context state, but we want to preserve it for the case
|
||||
// where both parsing an expression and section document error out.
|
||||
const expressionCheckpoint: ParseStateCheckpoint = parser.createCheckpoint(state);
|
||||
|
@ -215,6 +217,8 @@ export function readDocument(state: ParseState, parser: Parser): Ast.TDocument {
|
|||
document = readSectionDocument(state, parser);
|
||||
ParseStateUtils.assertIsDoneParsing(state);
|
||||
} catch (sectionError) {
|
||||
Assert.isInstanceofError(sectionError);
|
||||
|
||||
let triedError: Error;
|
||||
if (expressionCheckpoint.tokenIndex > /* sectionErrorState */ state.tokenIndex) {
|
||||
triedError = expressionError;
|
||||
|
@ -325,13 +329,8 @@ export function readSectionMember(state: ParseState, parser: Parser): Ast.Sectio
|
|||
ParseStateUtils.startContext(state, nodeKind);
|
||||
|
||||
const maybeLiteralAttributes: Ast.RecordLiteral | undefined = maybeReadLiteralAttributes(state, parser);
|
||||
const maybeSharedConstant:
|
||||
| Ast.IConstant<Constant.KeywordConstant.Shared>
|
||||
| undefined = maybeReadTokenKindAsConstant(
|
||||
state,
|
||||
Token.TokenKind.KeywordShared,
|
||||
Constant.KeywordConstant.Shared,
|
||||
);
|
||||
const maybeSharedConstant: Ast.IConstant<Constant.KeywordConstant.Shared> | undefined =
|
||||
maybeReadTokenKindAsConstant(state, Token.TokenKind.KeywordShared, Constant.KeywordConstant.Shared);
|
||||
const namePairedExpression: Ast.IdentifierPairedExpression = parser.readIdentifierPairedExpression(state, parser);
|
||||
const semicolonConstant: Ast.IConstant<Constant.MiscConstant.Semicolon> = readTokenKindAsConstant(
|
||||
state,
|
||||
|
@ -449,7 +448,8 @@ export function readLogicalExpression(state: ParseState, parser: Parser): Ast.TL
|
|||
state,
|
||||
Ast.NodeKind.LogicalExpression,
|
||||
() => parser.readIsExpression(state, parser),
|
||||
maybeCurrentTokenKind => ConstantUtils.maybeLogicalOperatorKindFrom(maybeCurrentTokenKind),
|
||||
(maybeCurrentTokenKind: Token.TokenKind | undefined) =>
|
||||
ConstantUtils.maybeLogicalOperatorKindFrom(maybeCurrentTokenKind),
|
||||
() => parser.readIsExpression(state, parser),
|
||||
);
|
||||
trace.exit({ [NaiveTraceConstant.TokenIndex]: state.tokenIndex });
|
||||
|
@ -476,7 +476,7 @@ export function readIsExpression(state: ParseState, parser: Parser): Ast.TIsExpr
|
|||
state,
|
||||
Ast.NodeKind.IsExpression,
|
||||
() => parser.readAsExpression(state, parser),
|
||||
maybeCurrentTokenKind =>
|
||||
(maybeCurrentTokenKind: Token.TokenKind | undefined) =>
|
||||
maybeCurrentTokenKind === Token.TokenKind.KeywordIs ? Constant.KeywordConstant.Is : undefined,
|
||||
() => parser.readNullablePrimitiveType(state, parser),
|
||||
);
|
||||
|
@ -527,7 +527,7 @@ export function readAsExpression(state: ParseState, parser: Parser): Ast.TAsExpr
|
|||
state,
|
||||
Ast.NodeKind.AsExpression,
|
||||
() => parser.readEqualityExpression(state, parser),
|
||||
maybeCurrentTokenKind =>
|
||||
(maybeCurrentTokenKind: Token.TokenKind | undefined) =>
|
||||
maybeCurrentTokenKind === Token.TokenKind.KeywordAs ? Constant.KeywordConstant.As : undefined,
|
||||
() => parser.readNullablePrimitiveType(state, parser),
|
||||
);
|
||||
|
@ -555,7 +555,8 @@ export function readEqualityExpression(state: ParseState, parser: Parser): Ast.T
|
|||
state,
|
||||
Ast.NodeKind.EqualityExpression,
|
||||
() => parser.readRelationalExpression(state, parser),
|
||||
maybeCurrentTokenKind => ConstantUtils.maybeEqualityOperatorKindFrom(maybeCurrentTokenKind),
|
||||
(maybeCurrentTokenKind: Token.TokenKind | undefined) =>
|
||||
ConstantUtils.maybeEqualityOperatorKindFrom(maybeCurrentTokenKind),
|
||||
() => parser.readRelationalExpression(state, parser),
|
||||
);
|
||||
trace.exit({ [NaiveTraceConstant.TokenIndex]: state.tokenIndex });
|
||||
|
@ -582,7 +583,8 @@ export function readRelationalExpression(state: ParseState, parser: Parser): Ast
|
|||
state,
|
||||
Ast.NodeKind.RelationalExpression,
|
||||
() => parser.readArithmeticExpression(state, parser),
|
||||
maybeCurrentTokenKind => ConstantUtils.maybeRelationalOperatorKindFrom(maybeCurrentTokenKind),
|
||||
(maybeCurrentTokenKind: Token.TokenKind | undefined) =>
|
||||
ConstantUtils.maybeRelationalOperatorKindFrom(maybeCurrentTokenKind),
|
||||
() => parser.readArithmeticExpression(state, parser),
|
||||
);
|
||||
trace.exit({ [NaiveTraceConstant.TokenIndex]: state.tokenIndex });
|
||||
|
@ -609,7 +611,8 @@ export function readArithmeticExpression(state: ParseState, parser: Parser): Ast
|
|||
state,
|
||||
Ast.NodeKind.ArithmeticExpression,
|
||||
() => parser.readMetadataExpression(state, parser),
|
||||
maybeCurrentTokenKind => ConstantUtils.maybeArithmeticOperatorKindFrom(maybeCurrentTokenKind),
|
||||
(maybeCurrentTokenKind: Token.TokenKind | undefined) =>
|
||||
ConstantUtils.maybeArithmeticOperatorKindFrom(maybeCurrentTokenKind),
|
||||
() => parser.readMetadataExpression(state, parser),
|
||||
);
|
||||
trace.exit({ [NaiveTraceConstant.TokenIndex]: state.tokenIndex });
|
||||
|
@ -922,17 +925,17 @@ export function readLiteralExpression(state: ParseState, _parser: Parser): Ast.L
|
|||
Token.TokenKind.NullLiteral,
|
||||
Token.TokenKind.TextLiteral,
|
||||
];
|
||||
const maybeErr: ParseError.ExpectedAnyTokenKindError | undefined = ParseStateUtils.testIsOnAnyTokenKind(
|
||||
const maybeError: ParseError.ExpectedAnyTokenKindError | undefined = ParseStateUtils.testIsOnAnyTokenKind(
|
||||
state,
|
||||
expectedTokenKinds,
|
||||
);
|
||||
if (maybeErr) {
|
||||
if (maybeError) {
|
||||
trace.exit({
|
||||
[NaiveTraceConstant.TokenIndex]: state.tokenIndex,
|
||||
[TraceConstant.IsThrowing]: true,
|
||||
});
|
||||
|
||||
throw maybeErr;
|
||||
throw maybeError;
|
||||
}
|
||||
|
||||
const literalKind: Ast.LiteralKind = Assert.asDefined(
|
||||
|
@ -970,9 +973,8 @@ export function readIdentifierExpression(state: ParseState, parser: Parser): Ast
|
|||
state.maybeCancellationToken?.throwIfCancelled();
|
||||
ParseStateUtils.startContext(state, nodeKind);
|
||||
|
||||
const maybeInclusiveConstant:
|
||||
| Ast.IConstant<Constant.MiscConstant.AtSign>
|
||||
| undefined = maybeReadTokenKindAsConstant(state, Token.TokenKind.AtSign, Constant.MiscConstant.AtSign);
|
||||
const maybeInclusiveConstant: Ast.IConstant<Constant.MiscConstant.AtSign> | undefined =
|
||||
maybeReadTokenKindAsConstant(state, Token.TokenKind.AtSign, Constant.MiscConstant.AtSign);
|
||||
const identifier: Ast.Identifier = parser.readIdentifier(state, parser);
|
||||
|
||||
const identifierExpression: Ast.IdentifierExpression = {
|
||||
|
@ -1395,12 +1397,13 @@ export function readLetExpression(state: ParseState, parser: Parser): Ast.LetExp
|
|||
Token.TokenKind.KeywordLet,
|
||||
Constant.KeywordConstant.Let,
|
||||
);
|
||||
const identifierPairedExpression: Ast.ICsvArray<Ast.IdentifierPairedExpression> = parser.readIdentifierPairedExpressions(
|
||||
state,
|
||||
parser,
|
||||
!ParseStateUtils.isNextTokenKind(state, Token.TokenKind.KeywordIn),
|
||||
ParseStateUtils.testCsvContinuationLetExpression,
|
||||
);
|
||||
const identifierPairedExpression: Ast.ICsvArray<Ast.IdentifierPairedExpression> =
|
||||
parser.readIdentifierPairedExpressions(
|
||||
state,
|
||||
parser,
|
||||
!ParseStateUtils.isNextTokenKind(state, Token.TokenKind.KeywordIn),
|
||||
ParseStateUtils.testCsvContinuationLetExpression,
|
||||
);
|
||||
const inConstant: Ast.IConstant<Constant.KeywordConstant.In> = readTokenKindAsConstant(
|
||||
state,
|
||||
Token.TokenKind.KeywordIn,
|
||||
|
@ -1638,13 +1641,13 @@ export function readFieldSpecificationList(
|
|||
ParseStateUtils.startContext(state, fieldArrayNodeKind);
|
||||
|
||||
while (continueReadingValues) {
|
||||
const maybeErr: ParseError.TInnerParseError | undefined = testPostCommaError(state);
|
||||
if (maybeErr) {
|
||||
const maybeError: ParseError.TInnerParseError | undefined = testPostCommaError(state);
|
||||
if (maybeError) {
|
||||
trace.exit({
|
||||
[NaiveTraceConstant.TokenIndex]: state.tokenIndex,
|
||||
[TraceConstant.IsThrowing]: true,
|
||||
});
|
||||
throw maybeErr;
|
||||
throw maybeError;
|
||||
}
|
||||
|
||||
if (ParseStateUtils.isOnTokenKind(state, Token.TokenKind.Ellipsis)) {
|
||||
|
@ -1675,9 +1678,8 @@ export function readFieldSpecificationList(
|
|||
const fieldSpecificationNodeKind: Ast.NodeKind.FieldSpecification = Ast.NodeKind.FieldSpecification;
|
||||
ParseStateUtils.startContext(state, fieldSpecificationNodeKind);
|
||||
|
||||
const maybeOptionalConstant:
|
||||
| Ast.IConstant<Constant.LanguageConstant.Optional>
|
||||
| undefined = maybeReadConstantKind(state, Constant.LanguageConstant.Optional);
|
||||
const maybeOptionalConstant: Ast.IConstant<Constant.LanguageConstant.Optional> | undefined =
|
||||
maybeReadConstantKind(state, Constant.LanguageConstant.Optional);
|
||||
|
||||
const name: Ast.GeneralizedIdentifier = parser.readGeneralizedIdentifier(state, parser);
|
||||
|
||||
|
@ -1696,9 +1698,8 @@ export function readFieldSpecificationList(
|
|||
};
|
||||
ParseStateUtils.endContext(state, field);
|
||||
|
||||
const maybeCommaConstant:
|
||||
| Ast.IConstant<Constant.MiscConstant.Comma>
|
||||
| undefined = maybeReadTokenKindAsConstant(state, Token.TokenKind.Comma, Constant.MiscConstant.Comma);
|
||||
const maybeCommaConstant: Ast.IConstant<Constant.MiscConstant.Comma> | undefined =
|
||||
maybeReadTokenKindAsConstant(state, Token.TokenKind.Comma, Constant.MiscConstant.Comma);
|
||||
continueReadingValues = maybeCommaConstant !== undefined;
|
||||
|
||||
const csv: Ast.ICsv<Ast.FieldSpecification> = {
|
||||
|
@ -2158,12 +2159,12 @@ function tryReadPrimitiveType(state: ParseState, parser: Parser): TriedReadPrimi
|
|||
Token.TokenKind.KeywordType,
|
||||
Token.TokenKind.NullLiteral,
|
||||
];
|
||||
const maybeErr: ParseError.ExpectedAnyTokenKindError | undefined = ParseStateUtils.testIsOnAnyTokenKind(
|
||||
const maybeError: ParseError.ExpectedAnyTokenKindError | undefined = ParseStateUtils.testIsOnAnyTokenKind(
|
||||
state,
|
||||
expectedTokenKinds,
|
||||
);
|
||||
if (maybeErr) {
|
||||
const error: ParseError.ExpectedAnyTokenKindError = maybeErr;
|
||||
if (maybeError) {
|
||||
const error: ParseError.ExpectedAnyTokenKindError = maybeError;
|
||||
trace.exit({
|
||||
[NaiveTraceConstant.TokenIndex]: state.tokenIndex,
|
||||
[TraceConstant.IsError]: true,
|
||||
|
@ -2198,7 +2199,7 @@ function tryReadPrimitiveType(state: ParseState, parser: Parser): TriedReadPrimi
|
|||
readToken(state);
|
||||
break;
|
||||
|
||||
default:
|
||||
default: {
|
||||
const token: Token.Token = ParseStateUtils.assertGetTokenAt(state, state.tokenIndex);
|
||||
parser.restoreCheckpoint(state, checkpoint);
|
||||
|
||||
|
@ -2209,6 +2210,7 @@ function tryReadPrimitiveType(state: ParseState, parser: Parser): TriedReadPrimi
|
|||
state.lexerSnapshot.graphemePositionStartFrom(token),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (ParseStateUtils.isOnTokenKind(state, Token.TokenKind.KeywordType)) {
|
||||
primitiveTypeKind = Constant.PrimitiveTypeConstant.Type;
|
||||
|
@ -2217,7 +2219,7 @@ function tryReadPrimitiveType(state: ParseState, parser: Parser): TriedReadPrimi
|
|||
primitiveTypeKind = Constant.PrimitiveTypeConstant.Null;
|
||||
readToken(state);
|
||||
} else {
|
||||
const details: {} = { tokenKind: state.maybeCurrentTokenKind };
|
||||
const details: { tokenKind: Token.TokenKind | undefined } = { tokenKind: state.maybeCurrentTokenKind };
|
||||
parser.restoreCheckpoint(state, checkpoint);
|
||||
trace.exit({
|
||||
[NaiveTraceConstant.TokenIndex]: state.tokenIndex,
|
||||
|
@ -2355,7 +2357,7 @@ function recursiveReadBinOpExpression<
|
|||
Kind extends Ast.TBinOpExpressionNodeKind,
|
||||
Left,
|
||||
Op extends Constant.TBinOpExpressionOperator,
|
||||
Right
|
||||
Right,
|
||||
>(
|
||||
state: ParseState,
|
||||
nodeKind: Kind,
|
||||
|
@ -2382,7 +2384,7 @@ function recursiveReadBinOpExpression<
|
|||
}
|
||||
const operatorConstant: Ast.TConstant & Ast.IConstant<Op> = readTokenKindAsConstant(
|
||||
state,
|
||||
state.maybeCurrentTokenKind!,
|
||||
Assert.asDefined(state.maybeCurrentTokenKind),
|
||||
maybeOperator,
|
||||
);
|
||||
const right: Right | Ast.IBinOpExpression<Kind, Right, Op, Right> = recursiveReadBinOpExpressionHelper<
|
||||
|
@ -2399,7 +2401,7 @@ function recursiveReadBinOpExpression<
|
|||
operatorConstant,
|
||||
right,
|
||||
};
|
||||
ParseStateUtils.endContext(state, (binOpExpression as unknown) as Ast.TNode);
|
||||
ParseStateUtils.endContext(state, binOpExpression as unknown as Ast.TNode);
|
||||
trace.exit({
|
||||
[NaiveTraceConstant.TokenIndex]: state.tokenIndex,
|
||||
[NaiveTraceConstant.IsOperatorPresent]: true,
|
||||
|
@ -2414,7 +2416,7 @@ function recursiveReadBinOpExpression<
|
|||
function recursiveReadBinOpExpressionHelper<
|
||||
Kind extends Ast.TBinOpExpressionNodeKind,
|
||||
OperatorKind extends Constant.TBinOpExpressionOperator,
|
||||
Right
|
||||
Right,
|
||||
>(
|
||||
state: ParseState,
|
||||
nodeKind: Kind,
|
||||
|
@ -2439,7 +2441,7 @@ function recursiveReadBinOpExpressionHelper<
|
|||
}
|
||||
const operatorConstant: Ast.TConstant & Ast.IConstant<OperatorKind> = readTokenKindAsConstant(
|
||||
state,
|
||||
state.maybeCurrentTokenKind!,
|
||||
Assert.asDefined(state.maybeCurrentTokenKind),
|
||||
maybeOperator,
|
||||
);
|
||||
const right: Right | Ast.IBinOpExpression<Kind, Right, OperatorKind, Right> = recursiveReadBinOpExpressionHelper<
|
||||
|
@ -2456,7 +2458,7 @@ function recursiveReadBinOpExpressionHelper<
|
|||
operatorConstant,
|
||||
right,
|
||||
};
|
||||
ParseStateUtils.endContext(state, (binOpExpression as unknown) as Ast.TNode);
|
||||
ParseStateUtils.endContext(state, binOpExpression as unknown as Ast.TNode);
|
||||
trace.exit({
|
||||
[NaiveTraceConstant.TokenIndex]: state.tokenIndex,
|
||||
[NaiveTraceConstant.IsOperatorPresent]: true,
|
||||
|
@ -2483,14 +2485,14 @@ function readCsvArray<T extends Ast.TCsvType>(
|
|||
const csvNodeKind: Ast.NodeKind.Csv = Ast.NodeKind.Csv;
|
||||
ParseStateUtils.startContext(state, csvNodeKind);
|
||||
|
||||
const maybeErr: ParseError.TInnerParseError | undefined = testPostCommaError(state);
|
||||
if (maybeErr) {
|
||||
const maybeError: ParseError.TInnerParseError | undefined = testPostCommaError(state);
|
||||
if (maybeError) {
|
||||
trace.exit({
|
||||
[NaiveTraceConstant.TokenIndex]: state.tokenIndex,
|
||||
[TraceConstant.IsThrowing]: true,
|
||||
});
|
||||
|
||||
throw maybeErr;
|
||||
throw maybeError;
|
||||
}
|
||||
|
||||
const node: T = valueReader();
|
||||
|
@ -2555,7 +2557,7 @@ function readKeyValuePair<Kind extends Ast.TKeyValuePairNodeKind, Key, Value>(
|
|||
equalConstant,
|
||||
value,
|
||||
};
|
||||
ParseStateUtils.endContext(state, (keyValuePair as unknown) as Ast.TKeyValuePair);
|
||||
ParseStateUtils.endContext(state, keyValuePair as unknown as Ast.TKeyValuePair);
|
||||
trace.exit({ [NaiveTraceConstant.TokenIndex]: state.tokenIndex });
|
||||
|
||||
return keyValuePair;
|
||||
|
@ -2582,7 +2584,7 @@ function readPairedConstant<Kind extends Ast.TPairedConstantNodeKind, ConstantKi
|
|||
constant,
|
||||
paired,
|
||||
};
|
||||
ParseStateUtils.endContext(state, (pairedConstant as unknown) as Ast.TPairedConstant);
|
||||
ParseStateUtils.endContext(state, pairedConstant as unknown as Ast.TPairedConstant);
|
||||
trace.exit({ [NaiveTraceConstant.TokenIndex]: state.tokenIndex });
|
||||
|
||||
return pairedConstant;
|
||||
|
@ -2591,7 +2593,7 @@ function readPairedConstant<Kind extends Ast.TPairedConstantNodeKind, ConstantKi
|
|||
function maybeReadPairedConstant<
|
||||
Kind extends Ast.TPairedConstantNodeKind,
|
||||
ConstantKind extends Constant.TConstant,
|
||||
Paired
|
||||
Paired,
|
||||
>(
|
||||
state: ParseState,
|
||||
nodeKind: Kind,
|
||||
|
@ -2645,19 +2647,19 @@ function genericReadParameterList<T extends Ast.TParameterType>(
|
|||
ParseStateUtils.startContext(state, Ast.NodeKind.Csv);
|
||||
ParseStateUtils.startContext(state, Ast.NodeKind.Parameter);
|
||||
|
||||
const maybeErr: ParseError.TInnerParseError | undefined = testCsvContinuationDanglingCommaForParenthesis(state);
|
||||
if (maybeErr) {
|
||||
const maybeError: ParseError.TInnerParseError | undefined =
|
||||
testCsvContinuationDanglingCommaForParenthesis(state);
|
||||
if (maybeError) {
|
||||
trace.exit({
|
||||
[NaiveTraceConstant.TokenIndex]: state.tokenIndex,
|
||||
[TraceConstant.IsThrowing]: true,
|
||||
});
|
||||
|
||||
throw maybeErr;
|
||||
throw maybeError;
|
||||
}
|
||||
|
||||
const maybeOptionalConstant:
|
||||
| Ast.IConstant<Constant.LanguageConstant.Optional>
|
||||
| undefined = maybeReadConstantKind(state, Constant.LanguageConstant.Optional);
|
||||
const maybeOptionalConstant: Ast.IConstant<Constant.LanguageConstant.Optional> | undefined =
|
||||
maybeReadConstantKind(state, Constant.LanguageConstant.Optional);
|
||||
|
||||
if (reachedOptionalParameter && !maybeOptionalConstant) {
|
||||
const token: Token.Token = ParseStateUtils.assertGetTokenAt(state, state.tokenIndex);
|
||||
|
@ -2742,7 +2744,7 @@ function readWrapped<
|
|||
Kind extends Ast.TWrappedNodeKind,
|
||||
Open extends Constant.WrapperConstant,
|
||||
Content,
|
||||
Close extends Constant.WrapperConstant
|
||||
Close extends Constant.WrapperConstant,
|
||||
>(
|
||||
state: ParseState,
|
||||
nodeKind: Kind,
|
||||
|
@ -2778,7 +2780,7 @@ function readWrapped<
|
|||
closeWrapperConstant,
|
||||
maybeOptionalConstant,
|
||||
};
|
||||
ParseStateUtils.endContext(state, (wrapped as unknown) as Ast.TWrapped);
|
||||
ParseStateUtils.endContext(state, wrapped as unknown as Ast.TWrapped);
|
||||
trace.exit({ [NaiveTraceConstant.TokenIndex]: state.tokenIndex });
|
||||
|
||||
return wrapped;
|
||||
|
@ -2828,14 +2830,17 @@ export function readTokenKindAsConstant<ConstantKind extends Constant.TConstant>
|
|||
state.maybeCancellationToken?.throwIfCancelled();
|
||||
ParseStateUtils.startContext(state, Ast.NodeKind.Constant);
|
||||
|
||||
const maybeErr: ParseError.ExpectedTokenKindError | undefined = ParseStateUtils.testIsOnTokenKind(state, tokenKind);
|
||||
if (maybeErr !== undefined) {
|
||||
const maybeError: ParseError.ExpectedTokenKindError | undefined = ParseStateUtils.testIsOnTokenKind(
|
||||
state,
|
||||
tokenKind,
|
||||
);
|
||||
if (maybeError !== undefined) {
|
||||
trace.exit({
|
||||
[NaiveTraceConstant.TokenIndex]: state.tokenIndex,
|
||||
[TraceConstant.IsError]: true,
|
||||
});
|
||||
|
||||
throw maybeErr;
|
||||
throw maybeError;
|
||||
}
|
||||
|
||||
const tokenData: string = readToken(state);
|
||||
|
@ -2892,9 +2897,12 @@ export function maybeReadTokenKindAsConstant<ConstantKind extends Constant.TCons
|
|||
}
|
||||
|
||||
function readTokenKind(state: ParseState, tokenKind: Token.TokenKind): string {
|
||||
const maybeErr: ParseError.ExpectedTokenKindError | undefined = ParseStateUtils.testIsOnTokenKind(state, tokenKind);
|
||||
if (maybeErr) {
|
||||
throw maybeErr;
|
||||
const maybeError: ParseError.ExpectedTokenKindError | undefined = ParseStateUtils.testIsOnTokenKind(
|
||||
state,
|
||||
tokenKind,
|
||||
);
|
||||
if (maybeError) {
|
||||
throw maybeError;
|
||||
}
|
||||
|
||||
return readToken(state);
|
||||
|
|
|
@ -5,7 +5,7 @@ import { NaiveParseSteps } from ".";
|
|||
import { Parser, ParserUtils } from "../parser";
|
||||
import { ParseStateUtils } from "../parseState";
|
||||
|
||||
export let RecursiveDescentParser: Parser = {
|
||||
export const RecursiveDescentParser: Parser = {
|
||||
...NaiveParseSteps,
|
||||
applyState: ParseStateUtils.applyState,
|
||||
copyState: ParseStateUtils.copyState,
|
||||
|
|
|
@ -36,8 +36,11 @@ export function assertGetAbridgedSnapshotMatch(
|
|||
const snapshot: Lexer.LexerSnapshot = assertGetLexerSnapshot(text);
|
||||
const expectedTokens: AbridgedTokens = expected.tokens;
|
||||
const expectedComments: AbridgedComments = expected.comments;
|
||||
const actualTokens: AbridgedTokens = snapshot.tokens.map(token => [token.kind, token.data]);
|
||||
const actualComments: AbridgedComments = snapshot.comments.map(comment => [comment.kind, comment.data]);
|
||||
const actualTokens: AbridgedTokens = snapshot.tokens.map((token: Language.Token.Token) => [token.kind, token.data]);
|
||||
const actualComments: AbridgedComments = snapshot.comments.map((comment: Language.Comment.TComment) => [
|
||||
comment.kind,
|
||||
comment.data,
|
||||
]);
|
||||
|
||||
expect(actualTokens).deep.equal(expectedTokens);
|
||||
expect(actualComments).deep.equal(expectedComments);
|
||||
|
@ -65,7 +68,10 @@ export function assertGetLineTokenMatch(text: string, expected: AbridgedLineToke
|
|||
}
|
||||
}
|
||||
const actual: AbridgedLineTokens = tmp;
|
||||
const tokenDetails: {} = {
|
||||
const tokenDetails: {
|
||||
actual: AbridgedLineTokens;
|
||||
expected: AbridgedLineTokens;
|
||||
} = {
|
||||
actual,
|
||||
expected,
|
||||
};
|
||||
|
@ -113,7 +119,7 @@ export function assertGetLexOk(text: string): Lexer.State {
|
|||
const errorLineMap: Lexer.ErrorLineMap = Assert.asDefined(Lexer.maybeErrorLineMap(lexerState));
|
||||
const errorLines: ReadonlyArray<number> = [...errorLineMap.keys()];
|
||||
|
||||
const details: {} = { errorLines };
|
||||
const details: { errorLines: ReadonlyArray<number> } = { errorLines };
|
||||
throw new Error(`AssertFailed: Lexer.isErrorState(state) ${JSON.stringify(details, undefined, 4)}`);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { DefaultSettings, Language, Parser, Task } from "../../..";
|
||||
import { Assert, DefaultSettings, Language, Parser, Task } from "../../..";
|
||||
import { TestAssertUtils } from "../../testUtils";
|
||||
|
||||
interface ChildIdsByIdEntry {
|
||||
|
@ -20,7 +20,7 @@ function createActual(lexParseOk: Task.ParseTaskOk): ChildIdsByIdEntry[] {
|
|||
actual.push({
|
||||
childNodeIds: value,
|
||||
id: key,
|
||||
kind: astNodeById.get(key)!.kind,
|
||||
kind: Assert.asDefined(astNodeById.get(key)).kind,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -135,10 +135,8 @@ function expectLinksMatch(triedLexParse: Task.TriedLexParseTask, expected: Abrid
|
|||
"mismatch between expected and actual for childIdsById",
|
||||
);
|
||||
|
||||
const actualIdsByNodeKind: ReadonlyArray<[
|
||||
Language.Ast.NodeKind,
|
||||
ReadonlyArray<number>,
|
||||
]> = createSimplifiedIdsByNodeKind(nodeIdMapCollection.idsByNodeKind);
|
||||
const actualIdsByNodeKind: ReadonlyArray<[Language.Ast.NodeKind, ReadonlyArray<number>]> =
|
||||
createSimplifiedIdsByNodeKind(nodeIdMapCollection.idsByNodeKind);
|
||||
expect(actualIdsByNodeKind).to.deep.equal(
|
||||
expected.idsByNodeKind,
|
||||
"mismatch between expected and actual for idsByNodeKind",
|
||||
|
|
|
@ -18,7 +18,7 @@ import { TestAssertUtils } from "../../testUtils";
|
|||
|
||||
type AbridgedNode = [Language.Ast.NodeKind, number | undefined];
|
||||
|
||||
interface CollectAbridgeNodeState extends Traverse.ITraversalState<AbridgedNode[]> {}
|
||||
type CollectAbridgeNodeState = Traverse.ITraversalState<AbridgedNode[]>;
|
||||
|
||||
interface NthNodeOfKindState extends Traverse.ITraversalState<Language.Ast.TNode | undefined> {
|
||||
readonly nodeKind: Language.Ast.NodeKind;
|
||||
|
|
|
@ -21,7 +21,7 @@ export class Tokenizer implements TokensProvider {
|
|||
// All variants of LineNodeKind are strings.
|
||||
return {
|
||||
startIndex: lineToken.positionStart,
|
||||
scopes: (lineToken.kind as unknown) as string,
|
||||
scopes: lineToken.kind as unknown as string,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ describe("Incremental updates", () => {
|
|||
|
||||
for (let index: number = lineNumber + 1; index < document.lineTokens.length; index += 1) {
|
||||
const lineTokens: ReadonlyArray<IToken> = document.lineTokens[index];
|
||||
lineTokens.forEach(token => {
|
||||
lineTokens.forEach((token: IToken) => {
|
||||
expect(token.scopes).equals("TextContent", "expecting remaining tokens to be strings");
|
||||
});
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ describe("Incremental updates", () => {
|
|||
|
||||
for (let index: number = lineNumber + 1; index < document.lineTokens.length; index += 1) {
|
||||
const lineTokens: ReadonlyArray<IToken> = document.lineTokens[index];
|
||||
lineTokens.forEach(token => {
|
||||
lineTokens.forEach((token: IToken) => {
|
||||
expect(token.scopes).equals("MultilineCommentContent", "expecting remaining tokens to be comments");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { ILineTokens, IState, Tokenizer, TokenizerState } from "./common";
|
||||
import { ILineTokens, IState, IToken, Tokenizer, TokenizerState } from "./common";
|
||||
|
||||
const tokenizer: Tokenizer = new Tokenizer(`\n`);
|
||||
const initialState: TokenizerState = tokenizer.getInitialState() as TokenizerState;
|
||||
|
@ -21,7 +21,7 @@ function tokenizeLines(query: string, expectedTokenCounts: number[]): void {
|
|||
|
||||
state = r.endState as TokenizerState;
|
||||
|
||||
r.tokens.forEach(token => {
|
||||
r.tokens.forEach((token: IToken) => {
|
||||
expect(token.startIndex).is.lessThan(lines[index].length);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import { expect } from "chai";
|
|||
import "mocha";
|
||||
import { OrderedMap } from "../../../../powerquery-parser";
|
||||
import { Type, TypeUtils } from "../../../../powerquery-parser/language";
|
||||
import { TypeKind } from "../../../../powerquery-parser/language/type/type";
|
||||
|
||||
describe(`TypeUtils.isCompatible`, () => {
|
||||
describe(`${Type.TypeKind.AnyNonNull}`, () => {
|
||||
|
@ -55,8 +56,11 @@ describe(`TypeUtils.isCompatible`, () => {
|
|||
Type.TypeKind.Time,
|
||||
Type.TypeKind.Type,
|
||||
];
|
||||
const expected: ReadonlyArray<[Type.TypeKind, boolean]> = typeKinds.map(typeKind => [typeKind, true]);
|
||||
const actual: ReadonlyArray<[Type.TypeKind, boolean | undefined]> = typeKinds.map(typeKind => [
|
||||
const expected: ReadonlyArray<[Type.TypeKind, boolean]> = typeKinds.map((typeKind: TypeKind) => [
|
||||
typeKind,
|
||||
true,
|
||||
]);
|
||||
const actual: ReadonlyArray<[Type.TypeKind, boolean | undefined]> = typeKinds.map((typeKind: TypeKind) => [
|
||||
typeKind,
|
||||
TypeUtils.isCompatible(TypeUtils.createPrimitiveType(false, typeKind), Type.AnyInstance),
|
||||
]);
|
||||
|
|
|
@ -9,8 +9,10 @@ const PowerQueryExtensions: ReadonlyArray<string> = [".m", ".mout", ".pq", "pqm"
|
|||
export function getPowerQueryFilesRecursively(rootDirectory: string): ReadonlyArray<string> {
|
||||
const dirs: ReadonlyArray<string> = getDirectoryPaths(rootDirectory);
|
||||
let files: ReadonlyArray<string> = dirs
|
||||
.map(getPowerQueryFilesRecursively) // go through each directory
|
||||
.reduce((a, b) => a.concat(b), []); // map returns a 2d array (array of file arrays) so flatten
|
||||
// go through each directory
|
||||
.map(getPowerQueryFilesRecursively)
|
||||
// map returns a 2d array (array of file arrays) so flatten
|
||||
.reduce((a: ReadonlyArray<string>, b: ReadonlyArray<string>) => a.concat(b), []);
|
||||
|
||||
// Get files in root folder
|
||||
files = files.concat(getPowerQueryFilePaths(rootDirectory));
|
||||
|
@ -70,7 +72,7 @@ function getDirectoryPaths(rootDirectory: string): ReadonlyArray<string> {
|
|||
fs
|
||||
// tslint:disable-next-line: non-literal-fs-path
|
||||
.readdirSync(rootDirectory)
|
||||
.map(name => path.join(rootDirectory, name))
|
||||
.map((name: string) => path.join(rootDirectory, name))
|
||||
.filter(isDirectory)
|
||||
);
|
||||
}
|
||||
|
@ -81,7 +83,7 @@ function getPowerQueryFilePaths(filePath: string): ReadonlyArray<string> {
|
|||
fs
|
||||
// tslint:disable-next-line: non-literal-fs-path
|
||||
.readdirSync(filePath)
|
||||
.map(name => path.join(filePath, name))
|
||||
.map((name: string) => path.join(filePath, name))
|
||||
.filter(isPowerQueryFile)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"downlevelIteration": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noEmitOnError": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
|
|
165
tslint.json
165
tslint.json
|
@ -1,165 +0,0 @@
|
|||
{
|
||||
"rulesDirectory": ["tslint-config-prettier", "tslint-microsoft-contrib", "tslint-plugin-prettier"],
|
||||
"rules": {
|
||||
"no-angle-bracket-type-assertion": true,
|
||||
"no-internal-module": true,
|
||||
"no-namespace": true,
|
||||
"object-literal-shorthand": true,
|
||||
"prettier": true,
|
||||
// Internal
|
||||
"blank-lines-between-switch-cases": true,
|
||||
"deprecated-reason": true,
|
||||
"format-imports": true,
|
||||
"format-string-resources": true,
|
||||
"format-todos": true,
|
||||
"no-jsx-element": true,
|
||||
"no-methods-in-interfaces": true,
|
||||
"no-partial-default-props": true,
|
||||
"no-redux-combine-reducer": true,
|
||||
"safe-members-for-props": true,
|
||||
"sort-string-resources": true,
|
||||
"use-create-error-with-stack": true,
|
||||
"validate-imports": true,
|
||||
// tslint-microsoft-contrib rules we use with some configuration
|
||||
"comment-format": [true, "check-space"],
|
||||
/*
|
||||
"file-header": [
|
||||
true,
|
||||
{
|
||||
"match": "TODO",
|
||||
"allow-single-line-comments": true
|
||||
}
|
||||
],
|
||||
*/
|
||||
"function-name": [
|
||||
true,
|
||||
{
|
||||
// default
|
||||
"method-regex": "^[a-z][\\w\\d]+$",
|
||||
// default
|
||||
"private-method-regex": "^[a-z][\\w\\d]+$",
|
||||
// default
|
||||
"protected-method-regex": "^[a-z][\\w\\d]+$",
|
||||
// changed from uppercase to lowercase
|
||||
"static-method-regex": "^[a-z][\\w\\d]+$",
|
||||
// changed from lowercase to also allow uppercase (functional components)
|
||||
"function-regex": "^([a-z]|[A-Z])[\\w\\d]+$"
|
||||
}
|
||||
],
|
||||
// TODO: Remove once prettier formats comments correctly: https://github.com/prettier/prettier/issues/265
|
||||
"max-line-length": [
|
||||
true,
|
||||
{
|
||||
"ignore-pattern": "^(?!.*/(/|\\*) .* .*).*$",
|
||||
"limit": 120
|
||||
}
|
||||
],
|
||||
"member-ordering": [
|
||||
true,
|
||||
{
|
||||
"order": [
|
||||
"public-static-field",
|
||||
"public-instance-field",
|
||||
"protected-static-field",
|
||||
"protected-instance-field",
|
||||
"private-static-field",
|
||||
"private-instance-field",
|
||||
"constructor",
|
||||
"public-static-method",
|
||||
"public-instance-method",
|
||||
"protected-static-method",
|
||||
"protected-instance-method",
|
||||
"private-static-method",
|
||||
"private-instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-implicit-dependencies": [true, "dev"],
|
||||
"no-import-side-effect": [
|
||||
true,
|
||||
{
|
||||
"ignore-module": "mocha"
|
||||
}
|
||||
],
|
||||
"no-restricted-globals": [true, "name", "length", "event"],
|
||||
"no-void-expression": [true, "ignore-arrow-function-shorthand"],
|
||||
"one-variable-per-declaration": [true, "ignore-for-loop"],
|
||||
"triple-equals": [true, "allow-undefined-check"],
|
||||
"typedef": [
|
||||
true,
|
||||
"member-variable-declaration",
|
||||
"property-declaration",
|
||||
"variable-declaration",
|
||||
"call-signature",
|
||||
"parameter"
|
||||
],
|
||||
"variable-name": [
|
||||
true,
|
||||
"ban-keywords",
|
||||
"check-format",
|
||||
"allow-pascal-case",
|
||||
"allow-snake-case",
|
||||
"allow-leading-underscore"
|
||||
],
|
||||
// tslint-microsoft-contrib rules we don't use
|
||||
"binary-expression-operand-order": false,
|
||||
"completed-docs": false,
|
||||
"encoding": false,
|
||||
"export-name": false,
|
||||
"import-name": false,
|
||||
"interface-name": false,
|
||||
"max-classes-per-file": false,
|
||||
"max-func-body-length": false,
|
||||
"missing-jsdoc": false, // this will also be deprecated in tslint-microsoft-contrib 5.2.1
|
||||
"mocha-no-side-effect-code": false,
|
||||
"newline-before-return": false,
|
||||
"no-redundant-jsdoc": false,
|
||||
"no-any": false,
|
||||
"no-cookies": false,
|
||||
"no-duplicate-imports": false,
|
||||
"no-increment-decrement": false,
|
||||
"no-parameter-properties": false,
|
||||
"no-reserved-keywords": false,
|
||||
"no-suspicious-comment": false,
|
||||
"no-use-before-declare": false,
|
||||
"ordered-imports": true,
|
||||
"prefer-for-of": false,
|
||||
"prefer-type-cast": false,
|
||||
"prefer-method-signature": false,
|
||||
// tslint-microsoft-contrib rules we're temporarily disabling
|
||||
"await-promise": false,
|
||||
"cyclomatic-complexity": false,
|
||||
"import-spacing": false,
|
||||
"insecure-random": false,
|
||||
"match-default-export-name": false,
|
||||
"no-backbone-get-set-outside-model": false,
|
||||
"no-empty-interface": false,
|
||||
"no-floating-promises": false,
|
||||
"no-for-in": false,
|
||||
"no-function-expression": false,
|
||||
"no-invalid-template-strings": false,
|
||||
"no-invalid-this": false,
|
||||
"no-non-null-assertion": false,
|
||||
"no-object-literal-type-assertion": false,
|
||||
"no-parameter-reassignment": false,
|
||||
"no-relative-imports": false,
|
||||
"no-single-line-block-comment": false,
|
||||
"no-unnecessary-callback-wrapper": false,
|
||||
"no-unnecessary-class": false,
|
||||
"no-unnecessary-initializer": false,
|
||||
"no-unnecessary-local-variable": false,
|
||||
"no-unnecessary-type-assertion": false,
|
||||
"no-unsafe-any": false,
|
||||
"only-arrow-functions": false,
|
||||
"prefer-template": false,
|
||||
"promise-function-async": false,
|
||||
"restrict-plus-operands": false,
|
||||
"strict-boolean-expressions": false,
|
||||
"type-literal-delimiter": false,
|
||||
"use-default-type-parameter": false
|
||||
},
|
||||
"extends": ["tslint-microsoft-contrib", "tslint-config-prettier"],
|
||||
"linterOptions": {
|
||||
"exclude": ["./node_modules/**/*"]
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче