* 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:
JordanBoltonMN 2021-12-29 08:36:06 -08:00 коммит произвёл GitHub
Родитель a8f8c47431
Коммит a8f99ccb08
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
51 изменённых файлов: 1445 добавлений и 854 удалений

3
.eslintignore Normal file
Просмотреть файл

@ -0,0 +1,3 @@
node_modules
lib
**/*.js

36
.eslintrc.js Normal file
Просмотреть файл

@ -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",
},
};

1296
package-lock.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,

Просмотреть файл

@ -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/**/*"]
}
}