* updated version number

* alpha sort, added unboxOrDefault

* removed dead code

* PartialResult -> PotentiallyIncompleteResult

* back to partialResult

* moving settings around

* moving settings around v2

* final changes to settings

* alpha sort imports

* added ExpiredCancellationToken, writing cancellation propagation logic

* renaming all `catch (x)` to `catch (caught)`, boxOk -> ok

* initial commit
This commit is contained in:
JordanBoltonMN 2023-02-27 10:18:14 -06:00 коммит произвёл GitHub
Родитель 965c6f1d7a
Коммит 79dec1c2e1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
55 изменённых файлов: 664 добавлений и 612 удалений

4
package-lock.json сгенерированный
Просмотреть файл

@ -1,12 +1,12 @@
{
"name": "@microsoft/powerquery-parser",
"version": "0.11.2",
"version": "0.12.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@microsoft/powerquery-parser",
"version": "0.11.2",
"version": "0.12.0",
"license": "MIT",
"dependencies": {
"grapheme-splitter": "^1.0.4",

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

@ -1,6 +1,6 @@
{
"name": "@microsoft/powerquery-parser",
"version": "0.11.2",
"version": "0.12.0",
"description": "A parser for the Power Query/M formula language.",
"author": "Microsoft",
"license": "MIT",

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

@ -6,7 +6,7 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-unused-vars */
import { Assert, DefaultSettings, Lexer, ResultUtils, Task, TaskUtils } from ".";
import { DefaultSettings, Lexer, ResultUtils, Task, TaskUtils } from ".";
parseText(`let x = 1 in try x otherwise 2`);
@ -73,7 +73,7 @@ function lexText(text: string): void {
// Be aware that this is a Result due to the potential of errors such as
// a cancellation request from the CancellationToken.
triedLex = Lexer.tryAppendLine(lexerState, "// hello world", "\n");
Assert.isOk(triedLex);
ResultUtils.assertIsOk(triedLex);
lexerState = triedLex.value;
// Updating a line number is also easy.

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

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { ErrorResult, OkResult, Result, ResultUtils } from "./result";
import { CommonError } from ".";
export function asDefined<T>(value: T | undefined, message?: string, details?: object): NonNullable<T> {
@ -56,33 +55,3 @@ export function isUndefined<T>(value: T | undefined, message?: string, details?:
throw new CommonError.InvariantError(message ?? `assert failed, expected value to be undefined`, details);
}
}
export function isOk<T, E>(result: Result<T, E>): asserts result is OkResult<T> {
if (!ResultUtils.isOk(result)) {
throw new CommonError.InvariantError(`assert failed, result expected to be an Ok`, {
error: result.error,
});
}
}
export function isError<T, E>(result: Result<T, E>): asserts result is ErrorResult<E> {
if (!ResultUtils.isError(result)) {
throw new CommonError.InvariantError(`assert failed, result expected to be an Err`);
}
}
export function unboxOk<T, E>(result: Result<T, E>): T {
isOk(result);
return result.value;
}
export function unboxError<T, E>(result: Result<T, E>): E {
isError(result);
return result.error;
}
export function shouldNeverBeReachedTypescript(): CommonError.InvariantError {
return new CommonError.InvariantError(`this should never be reached but TypeScript can't tell that`);
}

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

@ -4,33 +4,6 @@
import { CommonError } from "..";
import { ICancellationToken } from "./ICancellationToken";
// Cancelled after X milliseconds.
export class TimedCancellationToken implements ICancellationToken {
private readonly threshold: number;
private cancelReason: string | undefined;
private wasForceCancelled: boolean;
constructor(private readonly milliseconds: number) {
this.threshold = Date.now() + milliseconds;
this.wasForceCancelled = false;
}
public throwIfCancelled(): void {
if (this.isCancelled()) {
throw new CommonError.CancellationError(this, this.cancelReason ?? `Exceeded ${this.milliseconds}ms`);
}
}
public isCancelled(): boolean {
return this.wasForceCancelled || Date.now() >= this.threshold;
}
public cancel(reason: string): void {
this.wasForceCancelled = true;
this.cancelReason = reason;
}
}
// Cancelled after X calls are made to isCancelled.
// Not really useful other than as an example of how to create your own cancellation token.
export class CounterCancellationToken implements ICancellationToken {
@ -63,3 +36,41 @@ export class CounterCancellationToken implements ICancellationToken {
this.cancelReason = reason;
}
}
// Cancelled after X milliseconds.
export class TimedCancellationToken implements ICancellationToken {
private readonly threshold: number;
private cancelReason: string | undefined;
private wasForceCancelled: boolean;
constructor(private readonly milliseconds: number) {
this.threshold = Date.now() + milliseconds;
this.wasForceCancelled = false;
}
public throwIfCancelled(): void {
if (this.isCancelled()) {
throw new CommonError.CancellationError(this, this.cancelReason ?? `Exceeded ${this.milliseconds}ms`);
}
}
public isCancelled(): boolean {
return this.wasForceCancelled || Date.now() >= this.threshold;
}
public cancel(reason: string): void {
this.wasForceCancelled = true;
this.cancelReason = reason;
}
}
export const ExpiredCancellationToken: ICancellationToken = new TimedCancellationToken(0);
// In case you need to provide a cancellation token but don't want to support cancellation.
export const NoOpCancellationToken: ICancellationToken = {
isCancelled: () => false,
// eslint-disable-next-line @typescript-eslint/no-empty-function
throwIfCancelled: () => {},
// eslint-disable-next-line @typescript-eslint/no-empty-function
cancel: () => {},
};

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

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { ICancellationToken } from "./cancellationToken";
import { TraceManager } from "./trace";
export interface CommonSettings {
readonly cancellationToken: ICancellationToken | undefined;
readonly initialCorrelationId: number | undefined;
readonly locale: string;
readonly traceManager: TraceManager;
}

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

@ -36,21 +36,28 @@ export class UnknownError extends Error {
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function assertIsCommonError(error: any): error is CommonError {
export function assertIsCommonError(error: unknown): 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 {
export function isCommonError(error: unknown): 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 isCancellationError(error: Error): error is CancellationError {
return error instanceof CancellationError;
}
export function isTInnerCommonError(error: unknown): error is TInnerCommonError {
return error instanceof CancellationError || error instanceof InvariantError || error instanceof UnknownError;
}
export function throwIfCancellationError(error: Error): void {
if (isCancellationError(error)) {
throw error;
}
}
export function ensureCommonError(error: Error, locale: string): CommonError {

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

@ -13,6 +13,7 @@ export * as Traverse from "./traversal";
export * as TypeScriptUtils from "./typeScriptTypeUtils";
export * from "./cancellationToken";
export * from "./commonSettings";
export * from "./immutableSet";
export * from "./orderedMap";
export * from "./partialResult";

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

@ -1,28 +1,55 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// A tri-state Result. The additional third state is for when a job was partially completed before an error occured,
// and the work done wants to be saved/returned.
export type PartialResult<O, M, E> = PartialOk<O> | PartialMixed<M, E> | PartialError<E>;
// A tri-state Result, also known as a partial.
// The third state is for when a job was partially completed but an error occured partway through.
//
// Example usage:
// type DividedNumbersPartial = { results: number[], errorIndex: number };
// type DividedNumbersPartialResult = PartialResult<number[], DividedNumbersPartial, Error>;
//
// function divideNumbers(numbers: [number, number][]): DividedNumbersPartialResult {
// try {
// const results: number[] = [];
// for (let i = 0; i < numbers.length; i++) {
// const [numerator, denominator] = numbers[i];
//
// if (denominator === 0) {
// return PartialResultUtils.incomplete({ results, errorIndex: i });
// }
//
// results.push(numerator / denominator);
// }
//
// return PartialResultUtils.ok(results);
// }
// catch (error) {
// return PartialResultUtils.error(error);
// }
// }
export type PartialResult<Ok, Partial, Error> =
| PartialResultOk<Ok>
| PartialResultIncomplete<Partial>
| PartialResultError<Error>;
export const enum PartialResultKind {
Ok = "Ok",
Mixed = "Mixed",
Incomplete = "Incomplete",
Error = "Error",
}
export interface PartialOk<O> {
export interface PartialResultOk<Value> {
readonly kind: PartialResultKind.Ok;
readonly value: O;
readonly value: Value;
}
export interface PartialMixed<M, E> {
readonly kind: PartialResultKind.Mixed;
readonly value: M;
readonly error: E;
export interface PartialResultIncomplete<Partial> {
readonly kind: PartialResultKind.Incomplete;
readonly partial: Partial;
}
export interface PartialError<E> {
export interface PartialResultError<Error> {
readonly kind: PartialResultKind.Error;
readonly error: E;
readonly error: Error;
}

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

@ -1,38 +1,47 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { PartialError, PartialMixed, PartialOk, PartialResult, PartialResultKind } from "./partialResult";
import {
PartialResult,
PartialResultError,
PartialResultIncomplete,
PartialResultKind,
PartialResultOk,
} from "./partialResult";
export function createOk<O>(value: O): PartialOk<O> {
export function ok<Ok>(value: Ok): PartialResultOk<Ok> {
return {
kind: PartialResultKind.Ok,
value,
};
}
export function createMixed<M, E>(value: M, error: E): PartialMixed<M, E> {
export function incomplete<Partial>(partial: Partial): PartialResultIncomplete<Partial> {
return {
kind: PartialResultKind.Mixed,
value,
error,
kind: PartialResultKind.Incomplete,
partial,
};
}
export function createError<E>(error: E): PartialError<E> {
export function error<Error>(error: Error): PartialResultError<Error> {
return {
kind: PartialResultKind.Error,
error,
};
}
export function isOk<O, M, E>(result: PartialResult<O, M, E>): result is PartialOk<O> {
export function isOk<Ok, Partial, Error>(result: PartialResult<Ok, Partial, Error>): result is PartialResultOk<Ok> {
return result.kind === PartialResultKind.Ok;
}
export function isMixed<O, M, E>(result: PartialResult<O, M, E>): result is PartialMixed<M, E> {
return result.kind === PartialResultKind.Mixed;
export function isIncomplete<Ok, Partial, Error>(
result: PartialResult<Ok, Partial, Error>,
): result is PartialResultIncomplete<Partial> {
return result.kind === PartialResultKind.Incomplete;
}
export function isError<O, M, E>(result: PartialResult<O, M, E>): result is PartialError<E> {
export function isError<Ok, Partial, Error>(
result: PartialResult<Ok, Partial, Error>,
): result is PartialResultError<Error> {
return result.kind === PartialResultKind.Error;
}

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

@ -4,20 +4,69 @@
import { Assert, CommonError } from "..";
import { ErrorResult, OkResult, Result, ResultKind } from "./result";
export function boxOk<T>(value: T): OkResult<T> {
export function assertIsOk<T, E>(result: Result<T, E>): asserts result is OkResult<T> {
if (!isOk(result)) {
throw new CommonError.InvariantError(`assert failed, result expected to be an Ok`, {
error: result.error,
});
}
}
export function assertIsError<T, E>(result: Result<T, E>): asserts result is ErrorResult<E> {
if (!isError(result)) {
throw new CommonError.InvariantError(`assert failed, result expected to be an Error`);
}
}
export function assertUnboxOk<T, E>(result: Result<T, E>): T {
assertIsOk(result);
return result.value;
}
export function assertUnboxError<T, E>(result: Result<T, E>): E {
assertIsError(result);
return result.error;
}
export function ok<T>(value: T): OkResult<T> {
return {
kind: ResultKind.Ok,
value,
};
}
export function boxError<E>(error: E): ErrorResult<E> {
export function error<E>(error: E): ErrorResult<E> {
return {
kind: ResultKind.Error,
error,
};
}
export function ensureResult<T>(callback: () => T, locale: string): Result<T, CommonError.CommonError> {
try {
return ok(callback());
} catch (caught: unknown) {
Assert.isInstanceofError(caught);
return error(CommonError.ensureCommonError(caught, locale));
}
}
export async function ensureResultAsync<T>(
callback: () => Promise<T>,
locale: string,
): Promise<Result<T, CommonError.CommonError>> {
try {
return ok(await callback());
} catch (caught: unknown) {
Assert.isInstanceofError(caught);
return error(CommonError.ensureCommonError(caught, locale));
}
}
export function isOk<T, E>(result: Result<T, E>): result is OkResult<T> {
return result.kind === ResultKind.Ok;
}
@ -26,25 +75,10 @@ export function isError<T, E>(result: Result<T, E>): result is ErrorResult<E> {
return result.kind === ResultKind.Error;
}
export function ensureResult<T>(callback: () => T, locale: string): Result<T, CommonError.CommonError> {
try {
return boxOk(callback());
} catch (error) {
Assert.isInstanceofError(error);
return boxError(CommonError.ensureCommonError(error, locale));
}
}
export async function ensureResultAsync<T>(
callback: () => Promise<T>,
locale: string,
): Promise<Result<T, CommonError.CommonError>> {
try {
return boxOk(await callback());
} catch (error) {
Assert.isInstanceofError(error);
return boxError(CommonError.ensureCommonError(error, locale));
export function unboxOrDefault<T, E>(result: Result<T, E>, defaultValue: T): T {
if (isOk(result)) {
return result.value;
} else {
return defaultValue;
}
}

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

@ -118,7 +118,7 @@ export abstract class TraceManager {
// 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, correlationId: number | undefined, details?: object): Trace {
return this.create(phase, task, correlationId, details);
return this.trace(phase, task, correlationId, details);
}
// Defaults to simple concatenation.
@ -135,7 +135,7 @@ 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, correlationId: number | undefined, details?: object): Trace {
protected trace(phase: string, task: string, correlationId: number | undefined, details?: object): Trace {
return new Trace(this.emit.bind(this), phase, task, this.idFactory(), correlationId, details);
}
@ -149,7 +149,7 @@ export abstract class TraceManager {
): string {
try {
return JSON.stringify(obj, replacer, space);
} catch (e) {
} catch {
return "[JSON.stringify Error]";
}
}
@ -172,7 +172,7 @@ export class BenchmarkTraceManager extends ReportTraceManager {
super(outputFn, valueDelimiter);
}
protected override create(
protected override trace(
phase: string,
task: string,
correlationId: number | undefined,
@ -187,7 +187,7 @@ export class NoOpTraceManager extends TraceManager {
// eslint-disable-next-line @typescript-eslint/no-empty-function
emit(_tracer: Trace, _message: string, _details?: object): void {}
protected override create(
protected override trace(
_phase: string,
_task: string,
_correlationId: number | undefined,

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

@ -79,6 +79,8 @@ export interface INode {
export type TNode = TDocument | TAuxiliaryNodes;
export type TLeaf = GeneralizedIdentifier | Identifier | LiteralExpression | PrimitiveType | TConstant;
// ----------------------------------------
// ---------- Non-standard Nodes ----------
// ----------------------------------------

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

@ -8,6 +8,14 @@ export interface SimplifiedType {
readonly primitiveTypeConstantKind: Constant.PrimitiveTypeConstant;
}
export function assertIsLeaf(node: Ast.TNode): asserts node is Ast.TLeaf {
Assert.isTrue(node.isLeaf, "Assert(node.isLeaf)", { nodeId: node.id, nodeKind: node.kind });
}
export function isLeaf(node: Ast.TNode): node is Ast.TLeaf {
return node.isLeaf;
}
export function literalKindFrom(
tokenKind: TokenKind | undefined,
): Ast.LiteralKind.Numeric | Ast.LiteralKind.Logical | Ast.LiteralKind.Null | Ast.LiteralKind.Text | undefined {

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

@ -8,5 +8,5 @@ import * as Token from "./token";
export { Comment, Token };
export * from "./ast";
export * from "./constant";
export * from "./type";
export * from "./keyword";
export * from "./type";

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

@ -169,15 +169,22 @@ export type LineToken = IToken<LineTokenKind, number>;
export type Token = IToken<TokenKind, TokenPosition>;
// 0-indexed
// Inclusive start, exclusive end
export interface TokenPosition {
// What code unit it's on for the line
readonly lineCodeUnit: number;
// What line it's on
readonly lineNumber: number;
// What code unit it's on for the whole document
readonly codeUnit: number;
}
// 0-indexed
// Inclusive start, exclusive end
export interface TokenRange {
readonly tokenIndexStart: number;
readonly tokenIndexEnd: number; // exclusive
readonly tokenIndexEnd: number;
readonly positionStart: TokenPosition;
readonly positionEnd: TokenPosition;
}

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

@ -8,7 +8,7 @@ import { simplify } from "./simplify";
import { Type } from "..";
import { TypeUtilsTraceConstant } from "./typeTraceConstant";
export function createPrimitiveType<T extends Type.TypeKind>(isNullable: boolean, typeKind: T): Type.TPrimitiveType {
export function primitiveType<T extends Type.TypeKind>(isNullable: boolean, typeKind: T): Type.TPrimitiveType {
const key: string = primitiveTypeMapKey(isNullable, typeKind);
return Assert.asDefined(PrimitiveTypeConstantMap.get(key), `unknown key for PrimitiveTypeConstantMap`, {
@ -19,12 +19,12 @@ export function createPrimitiveType<T extends Type.TypeKind>(isNullable: boolean
// If the given types can be simplified/deduped down to a single type then that is returned instead.
// Otherwise returns an instance of `Type.AnyUnion`.
export function createAnyUnion(
export function anyUnion(
unionedTypePairs: ReadonlyArray<Type.TPowerQueryType>,
traceManager: TraceManager,
correlationId: number | undefined,
): Type.TPowerQueryType {
const trace: Trace = traceManager.entry(TypeUtilsTraceConstant.CreateAnyUnion, createAnyUnion.name, correlationId);
const trace: Trace = traceManager.entry(TypeUtilsTraceConstant.AnyUnion, anyUnion.name, correlationId);
const simplified: ReadonlyArray<Type.TPowerQueryType> = simplify(unionedTypePairs, traceManager, trace.id);
@ -46,7 +46,7 @@ export function createAnyUnion(
return result;
}
export function createDefinedFunction(
export function definedFunction(
isNullable: boolean,
parameters: ReadonlyArray<Type.FunctionParameter>,
returnType: Type.TPowerQueryType,
@ -60,10 +60,7 @@ export function createDefinedFunction(
};
}
export function createDefinedList(
isNullable: boolean,
elements: ReadonlyArray<Type.TPowerQueryType>,
): Type.DefinedList {
export function definedList(isNullable: boolean, elements: ReadonlyArray<Type.TPowerQueryType>): Type.DefinedList {
return {
kind: Type.TypeKind.List,
extendedKind: Type.ExtendedTypeKind.DefinedList,
@ -72,7 +69,7 @@ export function createDefinedList(
};
}
export function createDefinedListType(
export function definedListType(
isNullable: boolean,
itemTypes: ReadonlyArray<Type.TPowerQueryType>,
): Type.DefinedListType {
@ -84,7 +81,7 @@ export function createDefinedListType(
};
}
export function createDefinedRecord(
export function definedRecord(
isNullable: boolean,
fields: Map<string, Type.TPowerQueryType>,
isOpen: boolean,
@ -98,11 +95,7 @@ export function createDefinedRecord(
};
}
export function createDefinedTable(
isNullable: boolean,
fields: Type.OrderedFields,
isOpen: boolean,
): Type.DefinedTable {
export function definedTable(isNullable: boolean, fields: Type.OrderedFields, isOpen: boolean): Type.DefinedTable {
return {
kind: Type.TypeKind.Table,
extendedKind: Type.ExtendedTypeKind.DefinedTable,
@ -112,7 +105,7 @@ export function createDefinedTable(
};
}
export function createFunctionType(
export function functionType(
isNullable: boolean,
parameters: ReadonlyArray<Type.FunctionParameter>,
returnType: Type.TPowerQueryType,
@ -126,7 +119,7 @@ export function createFunctionType(
};
}
export function createLogicalLiteral(isNullable: boolean, literal: string | boolean): Type.LogicalLiteral {
export function logicalLiteral(isNullable: boolean, literal: string | boolean): Type.LogicalLiteral {
let parsedLiteral: string;
let normalizedLiteral: boolean;
@ -149,7 +142,7 @@ export function createLogicalLiteral(isNullable: boolean, literal: string | bool
};
}
export function createListType(isNullable: boolean, itemType: Type.TPowerQueryType): Type.ListType {
export function listType(isNullable: boolean, itemType: Type.TPowerQueryType): Type.ListType {
return {
kind: Type.TypeKind.Type,
extendedKind: Type.ExtendedTypeKind.ListType,
@ -158,7 +151,7 @@ export function createListType(isNullable: boolean, itemType: Type.TPowerQueryTy
};
}
export function createNumberLiteral(isNullable: boolean, literal: string | number): Type.NumberLiteral {
export function numberLiteral(isNullable: boolean, literal: string | number): Type.NumberLiteral {
let parsedLiteral: string;
let normalizedLiteral: number;
@ -179,7 +172,7 @@ export function createNumberLiteral(isNullable: boolean, literal: string | numbe
};
}
export function createPrimaryPrimitiveType(
export function primaryPrimitiveType(
isNullable: boolean,
primitiveType: Type.TPrimitiveType,
): Type.PrimaryPrimitiveType {
@ -191,7 +184,7 @@ export function createPrimaryPrimitiveType(
};
}
export function createRecordType(
export function recordType(
isNullable: boolean,
fields: Map<string, Type.TPowerQueryType>,
isOpen: boolean,
@ -205,7 +198,7 @@ export function createRecordType(
};
}
export function createTableType(
export function tableType(
isNullable: boolean,
fields: Map<string, Type.TPowerQueryType>,
isOpen: boolean,
@ -219,19 +212,7 @@ export function createTableType(
};
}
export function createTextLiteral(isNullable: boolean, literal: string): Type.TextLiteral {
literal = StringUtils.ensureQuoted(literal);
return {
isNullable,
kind: Type.TypeKind.Text,
extendedKind: Type.ExtendedTypeKind.TextLiteral,
literal,
normalizedLiteral: literal,
};
}
export function createTableTypePrimary(
export function tableTypePrimary(
isNullable: boolean,
primaryExpression: Type.TPowerQueryType,
): Type.TableTypePrimaryExpression {
@ -242,3 +223,15 @@ export function createTableTypePrimary(
primaryExpression,
};
}
export function textLiteral(isNullable: boolean, literal: string): Type.TextLiteral {
literal = StringUtils.ensureQuoted(literal);
return {
isNullable,
kind: Type.TypeKind.Text,
extendedKind: Type.ExtendedTypeKind.TextLiteral,
literal,
normalizedLiteral: literal,
};
}

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

@ -2,8 +2,8 @@
// Licensed under the MIT license.
export const enum TypeUtilsTraceConstant {
AnyUnion = "CreateAnyUnion",
Categorize = "Categorize",
CreateAnyUnion = "CreateAnyUnion",
IsCompatible = "IsCompatible",
NameOf = "NameOf",
Simplify = "Simplify",

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

@ -5,9 +5,9 @@ import { Ast, AstUtils } from "../..";
import { NodeIdMap, NodeIdMapUtils, ParseContext, XorNode, XorNodeKind } from "../../../parser";
import { Trace, TraceManager } from "../../../common/trace";
import { Assert } from "../../../common";
import { createPrimitiveType } from "./factories";
import { isCompatible } from "./isCompatible";
import { isEqualType } from "./isEqualType";
import { primitiveType } from "./factories";
import { Type } from "..";
import { typeKindFromPrimitiveTypeConstantKind } from "./primitive";
import { TypeUtilsTraceConstant } from "./typeTraceConstant";
@ -95,7 +95,7 @@ export function isValidInvocation(
const argType: Type.TPowerQueryType | undefined = args[index];
if (argType !== undefined) {
const parameterType: Type.TPowerQueryType = createPrimitiveType(
const parameterType: Type.TPowerQueryType = primitiveType(
parameter.isNullable,
Assert.asDefined(parameter.type),
);

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

@ -129,27 +129,24 @@ 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;
export function isLexError(error: unknown): error is LexError {
return error 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;
export function isTLexError(error: unknown): error is TLexError {
return error instanceof LexError || error instanceof CommonError.CommonError;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function isTInnerLexError(x: any): x is TInnerLexError {
export function isTInnerLexError(error: unknown): error is TInnerLexError {
return (
x instanceof BadLineNumberError ||
x instanceof BadRangeError ||
x instanceof BadStateError ||
x instanceof EndOfStreamError ||
x instanceof ErrorLineMapError ||
x instanceof ExpectedError ||
x instanceof UnexpectedEofError ||
x instanceof UnexpectedReadError ||
x instanceof UnterminatedMultilineTokenError
error instanceof BadLineNumberError ||
error instanceof BadRangeError ||
error instanceof BadStateError ||
error instanceof EndOfStreamError ||
error instanceof ErrorLineMapError ||
error instanceof ExpectedError ||
error instanceof UnexpectedEofError ||
error instanceof UnexpectedReadError ||
error instanceof UnterminatedMultilineTokenError
);
}

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

@ -4,5 +4,6 @@
import * as LexError from "./error";
export { LexError };
export * from "./lexerSnapshot";
export * from "./lexer";
export * from "./lexerSnapshot";
export * from "./lexSettings";

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

@ -0,0 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { CommonSettings } from "../common";
export type LexSettings = CommonSettings;

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

@ -16,7 +16,7 @@ import {
} from "../common";
import { Keyword, TextUtils, Token } from "../language";
import { LexError } from ".";
import { LexSettings } from "../settings";
import { LexSettings } from "./lexSettings";
// Call Lexer.stateFrom to instantiate a new State instance.
// Lexer functions will return a new state object.
@ -219,6 +219,13 @@ export function errorLineMap(state: State): ErrorLineMap | undefined {
return errorLines.size !== 0 ? errorLines : undefined;
}
type PartialLexResult = PartialResult<TokenizeChanges, PartialLex, LexError.TLexError>;
interface PartialLex {
readonly tokenizeChanges: TokenizeChanges;
readonly error: LexError.TLexError;
}
interface TokenizeChanges {
readonly tokens: ReadonlyArray<Token.LineToken>;
readonly lineModeEnd: LineMode;
@ -289,19 +296,19 @@ function ensureCommonOrLexerResult<T>(
locale: string,
): Result<T, CommonError.CommonError | LexError.LexError> {
try {
return ResultUtils.boxOk(functionToWrap());
} catch (error) {
Assert.isInstanceofError(error);
return ResultUtils.ok(functionToWrap());
} catch (caught: unknown) {
Assert.isInstanceofError(caught);
let convertedError: CommonError.CommonError | LexError.LexError;
if (LexError.isTInnerLexError(error)) {
convertedError = new LexError.LexError(error);
if (LexError.isTInnerLexError(caught)) {
convertedError = new LexError.LexError(caught);
} else {
convertedError = CommonError.ensureCommonError(error, locale);
convertedError = CommonError.ensureCommonError(caught, locale);
}
return ResultUtils.boxError(convertedError);
return ResultUtils.error(convertedError);
}
}
@ -626,14 +633,14 @@ function tokenize(
if (currentPosition === textLength) {
continueLexing = false;
}
} catch (exception) {
} catch (caught: unknown) {
let error: LexError.TLexError;
if (LexError.isTInnerLexError(exception)) {
error = new LexError.LexError(exception);
if (LexError.isTInnerLexError(caught)) {
error = new LexError.LexError(caught);
} else {
Assert.isInstanceofError(exception);
error = CommonError.ensureCommonError(exception, locale);
Assert.isInstanceofError(caught);
error = CommonError.ensureCommonError(caught, locale);
}
continueLexing = false;
@ -641,22 +648,22 @@ function tokenize(
}
}
let partialTokenizeResult: PartialResult<TokenizeChanges, TokenizeChanges, LexError.TLexError>;
let partialTokenizeResult: PartialLexResult;
if (lexError) {
if (newTokens.length) {
partialTokenizeResult = PartialResultUtils.createMixed(
{
partialTokenizeResult = PartialResultUtils.incomplete<PartialLex>({
tokenizeChanges: {
tokens: newTokens,
lineModeEnd: lineMode,
},
lexError,
);
error: lexError,
});
} else {
partialTokenizeResult = PartialResultUtils.createError(lexError);
partialTokenizeResult = PartialResultUtils.error(lexError);
}
} else {
partialTokenizeResult = PartialResultUtils.createOk({
partialTokenizeResult = PartialResultUtils.ok({
tokens: newTokens,
lineModeEnd: lineMode,
});
@ -666,13 +673,10 @@ function tokenize(
}
// Takes the return from a tokenizeX function to updates the TLine's state.
function updateLineState(
line: TLine,
tokenizePartialResult: PartialResult<TokenizeChanges, TokenizeChanges, LexError.TLexError>,
): TLine {
switch (tokenizePartialResult.kind) {
function updateLineState(line: TLine, potentiallyIncompleteResult: PartialLexResult): TLine {
switch (potentiallyIncompleteResult.kind) {
case PartialResultKind.Ok: {
const tokenizeChanges: TokenizeChanges = tokenizePartialResult.value;
const tokenizeChanges: TokenizeChanges = potentiallyIncompleteResult.value;
const newTokens: ReadonlyArray<Token.LineToken> = line.tokens.concat(tokenizeChanges.tokens);
return {
@ -685,8 +689,8 @@ function updateLineState(
};
}
case PartialResultKind.Mixed: {
const tokenizeChanges: TokenizeChanges = tokenizePartialResult.value;
case PartialResultKind.Incomplete: {
const tokenizeChanges: TokenizeChanges = potentiallyIncompleteResult.partial.tokenizeChanges;
const newTokens: ReadonlyArray<Token.LineToken> = line.tokens.concat(tokenizeChanges.tokens);
return {
@ -696,7 +700,7 @@ function updateLineState(
lineModeStart: line.lineModeStart,
lineModeEnd: tokenizeChanges.lineModeEnd,
tokens: newTokens,
error: tokenizePartialResult.error,
error: potentiallyIncompleteResult.partial.error,
};
}
@ -708,11 +712,11 @@ function updateLineState(
lineTerminator: line.lineTerminator,
lineModeEnd: line.lineModeEnd,
tokens: line.tokens,
error: tokenizePartialResult.error,
error: potentiallyIncompleteResult.error,
};
default:
throw Assert.isNever(tokenizePartialResult);
throw Assert.isNever(potentiallyIncompleteResult);
}
}

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

@ -65,18 +65,18 @@ export class LexerSnapshot {
export function trySnapshot(state: Lexer.State): TriedLexerSnapshot {
try {
return ResultUtils.boxOk(createSnapshot(state));
} catch (e) {
return ResultUtils.ok(createSnapshot(state));
} catch (caught: unknown) {
let error: LexError.TLexError;
if (LexError.isTInnerLexError(e)) {
error = new LexError.LexError(e);
if (LexError.isTInnerLexError(caught)) {
error = new LexError.LexError(caught);
} else {
Assert.isInstanceofError(e);
error = CommonError.ensureCommonError(e, state.locale);
Assert.isInstanceofError(caught);
error = CommonError.ensureCommonError(caught, state.locale);
}
return ResultUtils.boxError(error);
return ResultUtils.error(error);
}
}

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

@ -19,7 +19,7 @@ export function assertIsNodeKind<T extends Ast.TNode>(
}
}
export function createState(): ParseContext.State {
export function newState(): ParseContext.State {
return {
nodeIdMapCollection: {
astNodeById: new Map(),

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

@ -9,7 +9,7 @@ import {
TAmbiguousBracketNode,
TAmbiguousParenthesisNode,
} from "./disambiguation";
import { ArrayUtils, Assert, Result, ResultUtils, TypeScriptUtils } from "../../common";
import { ArrayUtils, Assert, CommonError, Result, ResultUtils, TypeScriptUtils } from "../../common";
import { Ast, AstUtils, Constant, Token } from "../../language";
import { Parser, ParseStateCheckpoint } from "../parser";
import { ParseState, ParseStateUtils } from "../parseState";
@ -49,13 +49,16 @@ export async function readAmbiguous<T extends Ast.TNode>(
try {
// eslint-disable-next-line no-await-in-loop
node = await parseCallback(variantState, parser, trace.id);
variantResult = ResultUtils.boxOk(node);
} catch (error) {
variantResult = ResultUtils.ok(node);
} catch (error: unknown) {
Assert.isInstanceofError(error);
CommonError.throwIfCancellationError(error);
if (!ParseError.isTInnerParseError(error)) {
throw error;
}
variantResult = ResultUtils.boxError(new ParseError.ParseError(error, variantState));
variantResult = ResultUtils.error(new ParseError.ParseError(error, variantState));
}
const candiate: AmbiguousParse<T> = {
@ -225,7 +228,7 @@ export async function disambiguateParenthesis(
// so we need to consume test if the trailing 'as number' is followed by a FatArrow.
if (ParseStateUtils.isTokenKind(state, Token.TokenKind.KeywordAs, offsetTokenIndex + 1)) {
// eslint-disable-next-line no-await-in-loop
const checkpoint: ParseStateCheckpoint = await parser.createCheckpoint(state);
const checkpoint: ParseStateCheckpoint = await parser.checkpoint(state);
unsafeMoveTo(state, offsetTokenIndex + 2);
try {

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

@ -174,36 +174,32 @@ export interface TokenWithColumnNumber {
readonly columnNumber: number;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function assertIsParseError(error: any): error is ParseError {
export function assertIsParseError(error: unknown): 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 {
export function isParseError(error: unknown): error is ParseError {
return error instanceof ParseError;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function isTParseError(error: any): error is TParseError {
export function isTParseError(error: unknown): 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 {
export function isTInnerParseError(error: unknown): error is TInnerParseError {
return (
x instanceof ExpectedAnyTokenKindError ||
x instanceof ExpectedClosingTokenKind ||
x instanceof ExpectedCsvContinuationError ||
x instanceof ExpectedGeneralizedIdentifierError ||
x instanceof ExpectedTokenKindError ||
x instanceof InvalidCatchFunctionError ||
x instanceof InvalidPrimitiveTypeError ||
x instanceof RequiredParameterAfterOptionalParameterError ||
x instanceof UnterminatedSequence ||
x instanceof UnusedTokensRemainError
error instanceof ExpectedAnyTokenKindError ||
error instanceof ExpectedClosingTokenKind ||
error instanceof ExpectedCsvContinuationError ||
error instanceof ExpectedGeneralizedIdentifierError ||
error instanceof ExpectedTokenKindError ||
error instanceof InvalidCatchFunctionError ||
error instanceof InvalidPrimitiveTypeError ||
error instanceof RequiredParameterAfterOptionalParameterError ||
error instanceof UnterminatedSequence ||
error instanceof UnusedTokensRemainError
);
}

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

@ -4,7 +4,8 @@
export * as ParseError from "./error";
export * from "./context";
export * from "./disambiguation";
export * from "./parser";
export * from "./parseState";
export * from "./nodeIdMap";
export * from "./parser";
export * from "./parsers";
export * from "./parseSettings";
export * from "./parseState";

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

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { Ast } from "../language";
import { CommonSettings } from "../common";
import { LexerSnapshot } from "../lexer";
import { Parser } from "./parser";
import { ParseState } from "./parseState";
export interface ParseSettings extends CommonSettings {
readonly parser: Parser;
readonly newParseState: (lexerSnapshot: LexerSnapshot, overrides: Partial<ParseState> | undefined) => ParseState;
readonly parserEntryPoint:
| ((state: ParseState, parser: Parser, correlationId: number | undefined) => Promise<Ast.TNode>)
| undefined;
}

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

@ -11,11 +11,11 @@ import { NoOpTraceManagerInstance } from "../../common/trace";
import { ParseState } from "./parseState";
import { SequenceKind } from "../error";
export function createState(lexerSnapshot: LexerSnapshot, overrides: Partial<ParseState> | undefined): ParseState {
export function newState(lexerSnapshot: LexerSnapshot, overrides: Partial<ParseState> | undefined): ParseState {
const tokenIndex: number = overrides?.tokenIndex ?? 0;
const currentToken: Token.Token | undefined = lexerSnapshot.tokens[tokenIndex];
const currentTokenKind: Token.TokenKind | undefined = currentToken?.kind;
const contextState: ParseContext.State = overrides?.contextState ?? ParseContextUtils.createState();
const contextState: ParseContext.State = overrides?.contextState ?? ParseContextUtils.newState();
const currentContextNodeId: number | undefined =
contextState.nodeIdMapCollection.contextNodeById.size > 0
@ -34,7 +34,7 @@ export function createState(lexerSnapshot: LexerSnapshot, overrides: Partial<Par
locale: overrides?.locale ?? DefaultLocale,
cancellationToken: overrides?.cancellationToken,
traceManager: overrides?.traceManager ?? NoOpTraceManagerInstance,
contextState: overrides?.contextState ?? ParseContextUtils.createState(),
contextState: overrides?.contextState ?? ParseContextUtils.newState(),
currentToken,
currentContextNode,
currentTokenKind,

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

@ -29,7 +29,7 @@ export interface Parser {
// If the checkpoint is used on a parser that didn't create the checkpoint it results in undefiend behavior.
// If the checkpoint is used on a parser whose state is earlier than what the checkpoint recorded
// it results in undefined behavior.
readonly createCheckpoint: (state: ParseState) => Promise<ParseStateCheckpoint>;
readonly checkpoint: (state: ParseState) => Promise<ParseStateCheckpoint>;
readonly restoreCheckpoint: (state: ParseState, checkpoint: ParseStateCheckpoint) => Promise<void>;
// 12.1.6 Identifiers

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

@ -4,12 +4,11 @@
import { Assert, CommonError, ResultUtils } from "../../common";
import { NodeIdMap, NodeIdMapUtils } from "../nodeIdMap";
import { ParseContext, ParseContextUtils } from "../context";
import { ParseError, ParseSettings } from "..";
import { Parser, ParseStateCheckpoint, TriedParse } from "./parser";
import { ParseState, ParseStateUtils } from "../parseState";
import { Ast } from "../../language";
import { LexerSnapshot } from "../../lexer";
import { ParseError } from "..";
import { ParseSettings } from "../../settings";
import { Trace } from "../../common/trace";
export async function tryParse(parseSettings: ParseSettings, lexerSnapshot: LexerSnapshot): Promise<TriedParse> {
@ -32,21 +31,22 @@ export async function tryParse(parseSettings: ParseSettings, lexerSnapshot: Lexe
return await tryParseDocument(updatedSettings, lexerSnapshot);
}
const parseState: ParseState = updatedSettings.createParseState(lexerSnapshot, defaultOverrides(updatedSettings));
const parseState: ParseState = updatedSettings.newParseState(lexerSnapshot, defaultOverrides(updatedSettings));
try {
const root: Ast.TNode = await parserEntryPoint(parseState, updatedSettings.parser, trace.id);
ParseStateUtils.assertIsDoneParsing(parseState);
return ResultUtils.boxOk({
return ResultUtils.ok({
lexerSnapshot,
root,
state: parseState,
});
} catch (error) {
Assert.isInstanceofError(error);
} catch (caught: unknown) {
Assert.isInstanceofError(caught);
CommonError.throwIfCancellationError(caught);
return ResultUtils.boxError(ensureParseError(parseState, error, updatedSettings.locale));
return ResultUtils.error(ensureParseError(parseState, caught, updatedSettings.locale));
}
}
@ -64,7 +64,7 @@ export async function tryParseDocument(
let root: Ast.TNode;
const expressionDocumentState: ParseState = parseSettings.createParseState(
const expressionDocumentState: ParseState = parseSettings.newParseState(
lexerSnapshot,
defaultOverrides(parseSettings),
);
@ -74,15 +74,16 @@ export async function tryParseDocument(
ParseStateUtils.assertIsDoneParsing(expressionDocumentState);
trace.exit();
return ResultUtils.boxOk({
return ResultUtils.ok({
lexerSnapshot,
root,
state: expressionDocumentState,
});
} catch (expressionDocumentError) {
} catch (expressionDocumentError: unknown) {
Assert.isInstanceofError(expressionDocumentError);
CommonError.throwIfCancellationError(expressionDocumentError);
const sectionDocumentState: ParseState = parseSettings.createParseState(
const sectionDocumentState: ParseState = parseSettings.newParseState(
lexerSnapshot,
defaultOverrides(parseSettings),
);
@ -92,13 +93,14 @@ export async function tryParseDocument(
ParseStateUtils.assertIsDoneParsing(sectionDocumentState);
trace.exit();
return ResultUtils.boxOk({
return ResultUtils.ok({
lexerSnapshot,
root,
state: sectionDocumentState,
});
} catch (sectionDocumentError) {
} catch (sectionDocumentError: unknown) {
Assert.isInstanceofError(sectionDocumentError);
CommonError.throwIfCancellationError(expressionDocumentError);
let betterParsedState: ParseState;
let betterParsedError: Error;
@ -113,22 +115,22 @@ export async function tryParseDocument(
trace.exit();
return ResultUtils.boxError(ensureParseError(betterParsedState, betterParsedError, parseSettings.locale));
return ResultUtils.error(ensureParseError(betterParsedState, betterParsedError, parseSettings.locale));
}
}
}
// If you have a custom parser + parser state,
// then you'll have to create your own (create|restore)Checkpoint functions.
// then you'll have to create your own checkpoint/restoreCheckpoint functions.
//
// Due to performance reasons the backup no longer can include a naive deep copy of the context state.
// Instead it's assumed that a backup is made immediately before a try/catch read block.
// This means the state begins in a parsing context and the backup will either be immediately consumed or dropped.
// Therefore we only care about the delta between before and after the try/catch block.
// Thanks to the invariants above and the fact the ids for nodes are an auto-incrementing integer
// we can easily just drop all delete all context nodes past the id of when the backup was created.
// we can easily delete all context nodes past the id of when the backup was created.
// eslint-disable-next-line require-await
export async function createCheckpoint(state: ParseState): Promise<ParseStateCheckpoint> {
export async function checkpoint(state: ParseState): Promise<ParseStateCheckpoint> {
return {
tokenIndex: state.tokenIndex,
contextStateIdCounter: state.contextState.idCounter,

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

@ -27,7 +27,7 @@ export const CombinatorialParser: Parser = {
...NaiveParseSteps,
applyState: ParseStateUtils.applyState,
copyState: ParseStateUtils.copyState,
createCheckpoint: ParserUtils.createCheckpoint,
checkpoint: ParserUtils.checkpoint,
restoreCheckpoint: ParserUtils.restoreCheckpoint,
// 12.2.3.2 Logical expressions

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

@ -222,17 +222,18 @@ export async function readDocument(
try {
document = await parser.readExpression(state, parser, trace.id);
ParseStateUtils.assertIsDoneParsing(state);
} catch (expressionError) {
} catch (expressionError: unknown) {
Assert.isInstanceofError(expressionError);
CommonError.throwIfCancellationError(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 = await parser.createCheckpoint(state);
const expressionCheckpoint: ParseStateCheckpoint = await parser.checkpoint(state);
const expressionErrorContextState: ParseContext.State = state.contextState;
// Reset the parser's state.
state.tokenIndex = 0;
state.contextState = ParseContextUtils.createState();
state.contextState = ParseContextUtils.newState();
state.currentContextNode = undefined;
if (state.lexerSnapshot.tokens.length) {
@ -243,8 +244,9 @@ export async function readDocument(
try {
document = await readSectionDocument(state, parser, trace.id);
ParseStateUtils.assertIsDoneParsing(state);
} catch (sectionError) {
} catch (sectionError: unknown) {
Assert.isInstanceofError(sectionError);
CommonError.throwIfCancellationError(sectionError);
let triedError: Error;
@ -2433,17 +2435,17 @@ async function tryReadPrimaryType(
let attempt: TriedReadPrimaryType;
if (ParseStateUtils.isOnTokenKind(state, Token.TokenKind.LeftBracket)) {
attempt = ResultUtils.boxOk(await parser.readRecordType(state, parser, trace.id));
attempt = ResultUtils.ok(await parser.readRecordType(state, parser, trace.id));
} else if (ParseStateUtils.isOnTokenKind(state, Token.TokenKind.LeftBrace)) {
attempt = ResultUtils.boxOk(await parser.readListType(state, parser, trace.id));
attempt = ResultUtils.ok(await parser.readListType(state, parser, trace.id));
} else if (isTableTypeNext) {
attempt = ResultUtils.boxOk(await parser.readTableType(state, parser, trace.id));
attempt = ResultUtils.ok(await parser.readTableType(state, parser, trace.id));
} else if (isFunctionTypeNext) {
attempt = ResultUtils.boxOk(await parser.readFunctionType(state, parser, trace.id));
attempt = ResultUtils.ok(await parser.readFunctionType(state, parser, trace.id));
} else if (ParseStateUtils.isOnConstantKind(state, Constant.LanguageConstant.Nullable)) {
attempt = ResultUtils.boxOk(await parser.readNullableType(state, parser, trace.id));
attempt = ResultUtils.ok(await parser.readNullableType(state, parser, trace.id));
} else {
const checkpoint: ParseStateCheckpoint = await parser.createCheckpoint(state);
const checkpoint: ParseStateCheckpoint = await parser.checkpoint(state);
const triedReadPrimitiveType: TriedReadPrimaryType = await tryReadPrimitiveType(state, parser, trace.id);
if (ResultUtils.isError(triedReadPrimitiveType)) {
@ -2857,7 +2859,7 @@ async function tryReadPrimitiveType(
ParseStateUtils.startContext(state, nodeKind);
const checkpoint: ParseStateCheckpoint = await parser.createCheckpoint(state);
const checkpoint: ParseStateCheckpoint = await parser.checkpoint(state);
const expectedTokenKinds: ReadonlyArray<Token.TokenKind> = [
Token.TokenKind.Identifier,
@ -2876,7 +2878,7 @@ async function tryReadPrimitiveType(
[TraceConstant.IsError]: true,
});
return ResultUtils.boxError(error);
return ResultUtils.error(error);
}
let primitiveTypeKind: Constant.PrimitiveTypeConstant;
@ -2910,7 +2912,7 @@ async function tryReadPrimitiveType(
const token: Token.Token = ParseStateUtils.assertGetTokenAt(state, state.tokenIndex);
await parser.restoreCheckpoint(state, checkpoint);
return ResultUtils.boxError(
return ResultUtils.error(
new ParseError.InvalidPrimitiveTypeError(
token,
state.lexerSnapshot.graphemePositionStartFrom(token),
@ -2934,7 +2936,7 @@ async function tryReadPrimitiveType(
[TraceConstant.IsError]: true,
});
return ResultUtils.boxError(
return ResultUtils.error(
new CommonError.InvariantError(`unknown currentTokenKind, not found in [${expectedTokenKinds}]`, details),
);
}
@ -2953,7 +2955,7 @@ async function tryReadPrimitiveType(
[TraceConstant.IsError]: false,
});
return ResultUtils.boxOk(primitiveType);
return ResultUtils.ok(primitiveType);
}
// -------------------------------------

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

@ -12,6 +12,6 @@ export const RecursiveDescentParser: Parser = {
applyState: ParseStateUtils.applyState,
copyState: ParseStateUtils.copyState,
createCheckpoint: ParserUtils.createCheckpoint,
checkpoint: ParserUtils.checkpoint,
restoreCheckpoint: ParserUtils.restoreCheckpoint,
};

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

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { CombinatorialParser, ParseSettings, ParseState, ParseStateUtils } from "./parser";
import { LexerSnapshot, LexSettings } from "./lexer";
import { DefaultLocale } from "./localization";
import { NoOpTraceManagerInstance } from "./common/trace";
export type Settings = LexSettings & ParseSettings;
export const DefaultSettings: Settings = {
newParseState: (lexerSnapshot: LexerSnapshot, overrides: Partial<ParseState> | undefined) =>
ParseStateUtils.newState(lexerSnapshot, overrides),
locale: DefaultLocale,
cancellationToken: undefined,
initialCorrelationId: undefined,
parserEntryPoint: undefined,
parser: CombinatorialParser,
traceManager: NoOpTraceManagerInstance,
};

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

@ -1,7 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import * as SettingsUtils from "./settingsUtils";
export { SettingsUtils };
export * from "./settings";

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

@ -1,39 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { CombinatorialParser, Parser, ParseState, ParseStateUtils } from "../parser";
import { NoOpTraceManagerInstance, TraceManager } from "../common/trace";
import { Ast } from "../language";
import { DefaultLocale } from "../localization";
import { ICancellationToken } from "../common";
import { LexerSnapshot } from "../lexer";
export interface CommonSettings {
readonly cancellationToken: ICancellationToken | undefined;
readonly initialCorrelationId: number | undefined;
readonly locale: string;
readonly traceManager: TraceManager;
}
export type LexSettings = CommonSettings;
export interface ParseSettings extends CommonSettings {
readonly parser: Parser;
readonly createParseState: (lexerSnapshot: LexerSnapshot, overrides: Partial<ParseState> | undefined) => ParseState;
readonly parserEntryPoint:
| ((state: ParseState, parser: Parser, correlationId: number | undefined) => Promise<Ast.TNode>)
| undefined;
}
export type Settings = LexSettings & ParseSettings;
export const DefaultSettings: Settings = {
createParseState: (lexerSnapshot: LexerSnapshot, overrides: Partial<ParseState> | undefined) =>
ParseStateUtils.createState(lexerSnapshot, overrides),
locale: DefaultLocale,
cancellationToken: undefined,
initialCorrelationId: undefined,
parserEntryPoint: undefined,
parser: CombinatorialParser,
traceManager: NoOpTraceManagerInstance,
};

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

@ -1,12 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { DefaultSettings, Settings } from "./settings";
import { ICancellationToken } from "../common";
export function createDefaultSettings(cancellationToken: ICancellationToken | undefined): Settings {
return {
...DefaultSettings,
cancellationToken,
};
}

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

@ -3,7 +3,6 @@
import { CommonError, ResultKind, ResultUtils } from "../common";
import { Lexer, Parser } from "..";
import { LexSettings, ParseSettings } from "../settings/settings";
import {
LexTaskError,
LexTaskOk,
@ -16,8 +15,9 @@ import {
TriedParseTask,
TTask,
} from "./task";
import { ParserUtils, ParseState } from "../parser";
import { ParserUtils, ParseSettings, ParseState } from "../parser";
import { Ast } from "../language";
import { LexSettings } from "../lexer";
import { Trace } from "../common/trace";
export function assertIsError(task: TTask): asserts task is LexTaskError | ParseTaskCommonError | ParseTaskParseError {

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

@ -4,19 +4,18 @@
import "mocha";
import {
Assert,
CommonError,
DefaultSettings,
Lexer,
Result,
ResultUtils,
Settings,
SettingsUtils,
TimedCancellationToken,
TypeScriptUtils,
} from "../../..";
function assertGetCancellationError<T, E>(tried: Result<T, E>): CommonError.CancellationError {
Assert.isError(tried);
ResultUtils.assertIsError(tried);
if (!CommonError.isCommonError(tried.error)) {
throw new Error(`expected error to be a ${CommonError.CommonError.name}`);
@ -33,21 +32,24 @@ function assertGetCancellationError<T, E>(tried: Result<T, E>): CommonError.Canc
function assertGetLexerStateWithCancellationToken(): Lexer.State {
const triedLex: Lexer.TriedLex = Lexer.tryLex(DefaultSettings, "foo");
Assert.isOk(triedLex);
ResultUtils.assertIsOk(triedLex);
const state: TypeScriptUtils.StripReadonly<Lexer.State> = triedLex.value;
state.cancellationToken = new TimedCancellationToken(0);
return state;
}
function settingsWithCancellationToken(): Settings {
return SettingsUtils.createDefaultSettings(new TimedCancellationToken(0));
function defaultSettingsWithExpiredCancellationToken(): Settings {
return {
...DefaultSettings,
cancellationToken: new TimedCancellationToken(0),
};
}
describe("CancellationToken", () => {
describe(`lexer`, () => {
it(`Lexer.tryLex`, () => {
const triedLex: Lexer.TriedLex = Lexer.tryLex(settingsWithCancellationToken(), "foo");
const triedLex: Lexer.TriedLex = Lexer.tryLex(defaultSettingsWithExpiredCancellationToken(), "foo");
assertGetCancellationError(triedLex);
});

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

@ -3,7 +3,7 @@
import { expect } from "chai";
import { Assert, DefaultSettings, Language, Lexer } from "../../..";
import { Assert, DefaultSettings, Language, Lexer, ResultUtils } from "../../..";
export type AbridgedComments = ReadonlyArray<[Language.Comment.CommentKind, string]>;
@ -122,7 +122,7 @@ export function assertGetSnapshotAbridgedComments(
export function assertGetLexOk(text: string): Lexer.State {
const triedLex: Lexer.TriedLex = Lexer.tryLex(DefaultSettings, text);
Assert.isOk(triedLex);
ResultUtils.assertIsOk(triedLex);
const lexerState: Lexer.State = triedLex.value;
if (Lexer.isErrorState(lexerState)) {
@ -139,7 +139,7 @@ export function assertGetLexOk(text: string): Lexer.State {
export function assertGetLexerSnapshot(text: string): Lexer.LexerSnapshot {
const state: Lexer.State = assertGetLexOk(text);
const triedSnapshot: Lexer.TriedLexerSnapshot = Lexer.trySnapshot(state);
Assert.isOk(triedSnapshot);
ResultUtils.assertIsOk(triedSnapshot);
return triedSnapshot.value;
}

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

@ -4,14 +4,14 @@
import "mocha";
import { expect } from "chai";
import { Assert, DefaultSettings, Lexer, ResultUtils } from "../../..";
import { DefaultSettings, Lexer, ResultUtils } from "../../..";
function assertBadLineNumberKind(lineNumber: number, expectedKind: Lexer.LexError.BadLineNumberKind): void {
const triedLex: Lexer.TriedLex = Lexer.tryLex(DefaultSettings, `foo`);
Assert.isOk(triedLex);
ResultUtils.assertIsOk(triedLex);
const triedUpdate: Lexer.TriedLex = Lexer.tryUpdateLine(triedLex.value, lineNumber, `bar`);
Assert.isError(triedUpdate);
ResultUtils.assertIsError(triedUpdate);
const error: Lexer.LexError.LexError = triedUpdate.error;
@ -65,7 +65,7 @@ function assertBadRangeKind(range: Lexer.Range, expectedKind: Lexer.LexError.Bad
const state: Lexer.State = triedLex.value;
const TriedLex: Lexer.TriedLex = Lexer.tryUpdateRange(state, range, `bar`);
Assert.isError(TriedLex);
ResultUtils.assertIsError(TriedLex);
const error: Lexer.LexError.LexError = TriedLex.error;
@ -85,10 +85,10 @@ function assertUnterminatedMultilineTokenKind(
expectedKind: Lexer.LexError.UnterminatedMultilineTokenKind,
): void {
const triedLex: Lexer.TriedLex = Lexer.tryLex(DefaultSettings, text);
Assert.isOk(triedLex);
ResultUtils.assertIsOk(triedLex);
const lexerState: Lexer.State = triedLex.value;
const triedSnapshot: Lexer.TriedLexerSnapshot = Lexer.trySnapshot(lexerState);
Assert.isError(triedSnapshot);
ResultUtils.assertIsError(triedSnapshot);
const error: Lexer.LexError.TLexError = triedSnapshot.error;

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

@ -4,7 +4,7 @@
import "mocha";
import { expect } from "chai";
import { Assert, Lexer } from "../../..";
import { Lexer, ResultUtils } from "../../..";
import { assertGetLexOk } from "./common";
const LINE_TERMINATOR: string = `\n`;
@ -25,7 +25,7 @@ function assertAbridgedTLexerLine(state: Lexer.State, expected: AbridgedTLexerLi
function assertGetLexerUpdateRangeOk(originalText: string, newText: string, range: Lexer.Range): Lexer.State {
const state: Lexer.State = assertGetLexOk(originalText);
const triedLexerUpdate: Lexer.TriedLex = Lexer.tryUpdateRange(state, range, newText);
Assert.isOk(triedLexerUpdate);
ResultUtils.assertIsOk(triedLexerUpdate);
return triedLexerUpdate.value;
}
@ -41,7 +41,7 @@ function assertGetLexerUpdateLine(
assertAbridgedTLexerLine(state, expectedOriginal);
const triedLexerUpdate: Lexer.TriedLex = Lexer.tryUpdateLine(state, lineNumber, newText);
Assert.isOk(triedLexerUpdate);
ResultUtils.assertIsOk(triedLexerUpdate);
state = triedLexerUpdate.value;
assertAbridgedTLexerLine(triedLexerUpdate.value, expectedUpdate);
@ -224,7 +224,7 @@ describe(`Lexer.Incremental`, () => {
const state: Lexer.State = assertGetLexerUpdateRangeOk(original, "X", range);
const triedSnapshot: Lexer.TriedLexerSnapshot = Lexer.trySnapshot(state);
Assert.isOk(triedSnapshot);
ResultUtils.assertIsOk(triedSnapshot);
const snapshot: Lexer.LexerSnapshot = triedSnapshot.value;
expect(snapshot.text).equals(`foo\nbXr\nbaz`, "expected snapshot text doesn't match");
});
@ -247,7 +247,7 @@ describe(`Lexer.Incremental`, () => {
expect(state.lines.length).to.equal(3);
const triedSnapshot: Lexer.TriedLexerSnapshot = Lexer.trySnapshot(state);
Assert.isOk(triedSnapshot);
ResultUtils.assertIsOk(triedSnapshot);
const snapshot: Lexer.LexerSnapshot = triedSnapshot.value;
expect(snapshot.text).equals(`fOO\nBaz\nboo`, "expected snapshot text doesn't match");
});
@ -271,7 +271,7 @@ describe(`Lexer.Incremental`, () => {
expect(state.lines.length).to.equal(2);
const triedSnapshot: Lexer.TriedLexerSnapshot = Lexer.trySnapshot(state);
Assert.isOk(triedSnapshot);
ResultUtils.assertIsOk(triedSnapshot);
const snapshot: Lexer.LexerSnapshot = triedSnapshot.value;
expect(snapshot.text).equals("faz\nboo", "expected snapshot text doesn't match");
});

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

@ -18,10 +18,10 @@ import { TestAssertUtils } from "../../testUtils";
const DefaultSettingsWithStrict: Settings = {
...DefaultSettings,
createParseState: (lexerSnapshot: Lexer.LexerSnapshot, overrides: Partial<ParseState> | undefined) => {
newParseState: (lexerSnapshot: Lexer.LexerSnapshot, overrides: Partial<ParseState> | undefined) => {
overrides = overrides ?? {};
return ParseStateUtils.createState(lexerSnapshot, {
return ParseStateUtils.newState(lexerSnapshot, {
...overrides,
disambiguationBehavior: overrides.disambiguationBehavior ?? Disambiguation.DismabiguationBehavior.Strict,
});

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

@ -4,7 +4,7 @@
import "mocha";
import { expect } from "chai";
import { Assert, Language, TaskUtils, Traverse } from "../../../powerquery-parser";
import { Assert, Language, ResultUtils, TaskUtils, Traverse } from "../../../powerquery-parser";
import { ChildIdsById, IdsByNodeKind, ParentIdById } from "../../../powerquery-parser/parser/nodeIdMap/nodeIdMap";
import { DefaultSettings, Task } from "../../..";
import { NodeIdMap, TXorNode, XorNodeUtils } from "../../../powerquery-parser/parser";
@ -97,7 +97,7 @@ async function expectLinksMatch(
undefined,
);
Assert.isOk(triedTraverse);
ResultUtils.assertIsOk(triedTraverse);
assertTraverseMatchesState(traverseState, nodeIdMapCollection);
const astIds: ReadonlyArray<number> = [...nodeIdMapCollection.astNodeById.keys()];

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

@ -10,6 +10,7 @@ import {
DefaultSettings,
Language,
Parser,
ResultUtils,
Settings,
Task,
TaskUtils,
@ -53,7 +54,7 @@ async function collectAbridgeNodeFromAst(text: string): Promise<ReadonlyArray<Ab
undefined,
);
Assert.isOk(triedTraverse);
ResultUtils.assertIsOk(triedTraverse);
return triedTraverse.value;
}
@ -82,7 +83,7 @@ async function collectAbridgeNodeFromContext(text: string): Promise<ReadonlyArra
undefined,
);
Assert.isOk(triedTraverse);
ResultUtils.assertIsOk(triedTraverse);
return triedTraverse.value;
}
@ -118,7 +119,7 @@ async function assertGetNthNodeOfKind<N extends Language.Ast.TNode>(
nthNodeEarlyExit,
);
Assert.isOk(triedTraverse);
ResultUtils.assertIsOk(triedTraverse);
return Assert.asDefined(triedTraverse.value) as N;
}

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

@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { Assert, Lexer } from "../../../";
import { DefaultLocale, Language } from "../../../powerquery-parser";
import { DefaultLocale, Language, ResultUtils } from "../../../powerquery-parser";
import { Lexer } from "../../../";
export class Tokenizer implements TokensProvider {
constructor(private readonly lineTerminator: string) {}
@ -40,7 +40,7 @@ export class Tokenizer implements TokensProvider {
const lexerState: Lexer.State = tokenizerState.lexerState;
const triedLex: Lexer.TriedLex = Lexer.tryAppendLine(lexerState, line, this.lineTerminator);
Assert.isOk(triedLex);
ResultUtils.assertIsOk(triedLex);
const newLexerState: Lexer.State = triedLex.value;
return {

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

@ -4,7 +4,7 @@
import "mocha";
import { expect } from "chai";
import { Assert, DefaultSettings, Lexer } from "../../..";
import { DefaultSettings, Lexer, ResultUtils } from "../../..";
import { ILineTokens, IState, IToken, Tokenizer } from "./common";
const tokenizer: Tokenizer = new Tokenizer("\n");
@ -23,19 +23,19 @@ class MockDocument2 {
constructor(initialText: string) {
const triedLex: Lexer.TriedLex = Lexer.tryLex(DefaultSettings, initialText);
Assert.isOk(triedLex);
ResultUtils.assertIsOk(triedLex);
this.lexerState = triedLex.value;
}
public applyChange(text: string, range: Lexer.Range): void {
const triedLexerUpdate: Lexer.TriedLex = Lexer.tryUpdateRange(this.lexerState, range, text);
Assert.isOk(triedLexerUpdate);
ResultUtils.assertIsOk(triedLexerUpdate);
this.lexerState = triedLexerUpdate.value;
}
public getText(): string {
const triedLexerSnapshot: Lexer.TriedLexerSnapshot = Lexer.trySnapshot(this.lexerState);
Assert.isOk(triedLexerSnapshot);
ResultUtils.assertIsOk(triedLexerSnapshot);
return triedLexerSnapshot.value.text;
}

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

@ -11,7 +11,7 @@ import { TypeKind } from "../../../../powerquery-parser/language/type/type";
const noopCreateAnyUnion: (unionedTypePairs: ReadonlyArray<Type.TPowerQueryType>) => Type.TPowerQueryType = (
unionedTypePairs: ReadonlyArray<Type.TPowerQueryType>,
) => TypeUtils.createAnyUnion(unionedTypePairs, NoOpTraceManagerInstance, undefined);
) => TypeUtils.anyUnion(unionedTypePairs, NoOpTraceManagerInstance, undefined);
const noopIsCompatible: (left: Type.TPowerQueryType, right: Type.TPowerQueryType) => boolean | undefined = (
left: Type.TPowerQueryType,
@ -72,7 +72,7 @@ describe(`localIsCompatible`, () => {
const actual: ReadonlyArray<[Type.TypeKind, boolean | undefined]> = typeKinds.map((typeKind: TypeKind) => [
typeKind,
noopIsCompatible(TypeUtils.createPrimitiveType(false, typeKind), Type.AnyInstance),
noopIsCompatible(TypeUtils.primitiveType(false, typeKind), Type.AnyInstance),
]);
expect(actual).deep.equal(expected);
@ -80,7 +80,7 @@ describe(`localIsCompatible`, () => {
it(`${Type.TypeKind.None} not compatible with any`, () => {
const actual: boolean | undefined = noopIsCompatible(
TypeUtils.createPrimitiveType(false, Type.TypeKind.None),
TypeUtils.primitiveType(false, Type.TypeKind.None),
Type.AnyInstance,
);
@ -109,12 +109,12 @@ describe(`localIsCompatible`, () => {
describe(`${Type.ExtendedTypeKind.DefinedList}`, () => {
describe(`identity`, () => {
it(`empty`, () => {
const definedList: Type.DefinedList = TypeUtils.createDefinedList(false, []);
const definedList: Type.DefinedList = TypeUtils.definedList(false, []);
expect(noopIsCompatible(definedList, definedList)).to.equal(true, undefined);
});
it(`non-empty`, () => {
const definedList: Type.DefinedList = TypeUtils.createDefinedList(false, [
const definedList: Type.DefinedList = TypeUtils.definedList(false, [
Type.TextInstance,
Type.NumberInstance,
]);
@ -125,31 +125,25 @@ describe(`localIsCompatible`, () => {
describe(`list item literal is compatible with parent type`, () => {
it(`${Type.ExtendedTypeKind.LogicalLiteral}`, () => {
const left: Type.DefinedList = TypeUtils.createDefinedList(false, [
TypeUtils.createLogicalLiteral(false, true),
]);
const left: Type.DefinedList = TypeUtils.definedList(false, [TypeUtils.logicalLiteral(false, true)]);
const right: Type.DefinedList = TypeUtils.createDefinedList(false, [Type.LogicalInstance]);
const right: Type.DefinedList = TypeUtils.definedList(false, [Type.LogicalInstance]);
expect(noopIsCompatible(left, right)).to.equal(true, undefined);
});
it(`${Type.ExtendedTypeKind.NumberLiteral}`, () => {
const left: Type.DefinedList = TypeUtils.createDefinedList(false, [
TypeUtils.createNumberLiteral(false, `1`),
]);
const left: Type.DefinedList = TypeUtils.definedList(false, [TypeUtils.numberLiteral(false, `1`)]);
const right: Type.DefinedList = TypeUtils.createDefinedList(false, [Type.NumberInstance]);
const right: Type.DefinedList = TypeUtils.definedList(false, [Type.NumberInstance]);
expect(noopIsCompatible(left, right)).to.equal(true, undefined);
});
it(`${Type.ExtendedTypeKind.TextLiteral}`, () => {
const left: Type.DefinedList = TypeUtils.createDefinedList(false, [
TypeUtils.createTextLiteral(false, `"foo"`),
]);
const left: Type.DefinedList = TypeUtils.definedList(false, [TypeUtils.textLiteral(false, `"foo"`)]);
const right: Type.DefinedList = TypeUtils.createDefinedList(false, [Type.TextInstance]);
const right: Type.DefinedList = TypeUtils.definedList(false, [Type.TextInstance]);
expect(noopIsCompatible(left, right)).to.equal(true, undefined);
});
@ -157,17 +151,17 @@ describe(`localIsCompatible`, () => {
describe(`null`, () => {
it(`null is not compatible with non-nullable`, () => {
const definedList: Type.DefinedList = TypeUtils.createDefinedList(false, []);
const definedList: Type.DefinedList = TypeUtils.definedList(false, []);
expect(noopIsCompatible(Type.NullInstance, definedList)).to.equal(false, undefined);
});
it(`non-nullable is not compatible with null`, () => {
const definedList: Type.DefinedList = TypeUtils.createDefinedList(false, []);
const definedList: Type.DefinedList = TypeUtils.definedList(false, []);
expect(noopIsCompatible(definedList, Type.NullInstance)).to.equal(false, undefined);
});
it(`null is compatible with nullable`, () => {
const definedList: Type.DefinedList = TypeUtils.createDefinedList(true, []);
const definedList: Type.DefinedList = TypeUtils.definedList(true, []);
expect(noopIsCompatible(Type.NullInstance, definedList)).to.equal(true, undefined);
});
});
@ -176,12 +170,12 @@ describe(`localIsCompatible`, () => {
describe(`${Type.ExtendedTypeKind.DefinedRecord}`, () => {
describe(`identity`, () => {
it(`empty`, () => {
const definedRecord: Type.DefinedRecord = TypeUtils.createDefinedRecord(false, new Map(), false);
const definedRecord: Type.DefinedRecord = TypeUtils.definedRecord(false, new Map(), false);
expect(noopIsCompatible(definedRecord, definedRecord)).to.equal(true, undefined);
});
it(`non-empty`, () => {
const definedRecord: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const definedRecord: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map([["number", Type.NumberInstance]]),
false,
@ -193,13 +187,13 @@ describe(`localIsCompatible`, () => {
describe(`field member literal is compatible with parent type`, () => {
it(`${Type.ExtendedTypeKind.LogicalLiteral}`, () => {
const left: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const left: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map([["logical", TypeUtils.createLogicalLiteral(false, true)]]),
new Map([["logical", TypeUtils.logicalLiteral(false, true)]]),
false,
);
const right: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const right: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map([["logical", Type.LogicalInstance]]),
false,
@ -209,13 +203,13 @@ describe(`localIsCompatible`, () => {
});
it(`${Type.ExtendedTypeKind.NumberLiteral}`, () => {
const left: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const left: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map([["number", TypeUtils.createNumberLiteral(false, 1)]]),
new Map([["number", TypeUtils.numberLiteral(false, 1)]]),
false,
);
const right: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const right: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map([["number", Type.NumberInstance]]),
false,
@ -225,13 +219,13 @@ describe(`localIsCompatible`, () => {
});
it(`${Type.ExtendedTypeKind.TextLiteral}`, () => {
const left: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const left: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map([["text", TypeUtils.createTextLiteral(false, `""`)]]),
new Map([["text", TypeUtils.textLiteral(false, `""`)]]),
false,
);
const right: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const right: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map([["text", Type.TextInstance]]),
false,
@ -243,17 +237,17 @@ describe(`localIsCompatible`, () => {
describe(`null`, () => {
it(`null is not compatible with non-nullable`, () => {
const definedRecord: Type.DefinedRecord = TypeUtils.createDefinedRecord(false, new Map(), false);
const definedRecord: Type.DefinedRecord = TypeUtils.definedRecord(false, new Map(), false);
expect(noopIsCompatible(Type.NullInstance, definedRecord)).to.equal(false, undefined);
});
it(`non-nullable is not compatible with null`, () => {
const definedRecord: Type.DefinedRecord = TypeUtils.createDefinedRecord(false, new Map(), false);
const definedRecord: Type.DefinedRecord = TypeUtils.definedRecord(false, new Map(), false);
expect(noopIsCompatible(definedRecord, Type.NullInstance)).to.equal(false, undefined);
});
it(`null is compatible with nullable`, () => {
const definedRecord: Type.DefinedRecord = TypeUtils.createDefinedRecord(true, new Map(), false);
const definedRecord: Type.DefinedRecord = TypeUtils.definedRecord(true, new Map(), false);
expect(noopIsCompatible(Type.NullInstance, definedRecord)).to.equal(true, undefined);
});
});
@ -262,12 +256,12 @@ describe(`localIsCompatible`, () => {
describe(`${Type.ExtendedTypeKind.DefinedTable}`, () => {
describe(`identity`, () => {
it(`empty`, () => {
const definedTable: Type.DefinedTable = TypeUtils.createDefinedTable(false, new OrderedMap(), false);
const definedTable: Type.DefinedTable = TypeUtils.definedTable(false, new OrderedMap(), false);
expect(noopIsCompatible(definedTable, definedTable)).to.equal(true, undefined);
});
it(`non-empty`, () => {
const definedTable: Type.DefinedTable = TypeUtils.createDefinedTable(
const definedTable: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap([["number", Type.NumberInstance]]),
false,
@ -279,13 +273,13 @@ describe(`localIsCompatible`, () => {
describe(`field member literal is compatible with parent type`, () => {
it(`${Type.ExtendedTypeKind.LogicalLiteral}`, () => {
const left: Type.DefinedTable = TypeUtils.createDefinedTable(
const left: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap([["logical", TypeUtils.createLogicalLiteral(false, true)]]),
new OrderedMap([["logical", TypeUtils.logicalLiteral(false, true)]]),
false,
);
const right: Type.DefinedTable = TypeUtils.createDefinedTable(
const right: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap([["logical", Type.LogicalInstance]]),
false,
@ -295,13 +289,13 @@ describe(`localIsCompatible`, () => {
});
it(`${Type.ExtendedTypeKind.NumberLiteral}`, () => {
const left: Type.DefinedTable = TypeUtils.createDefinedTable(
const left: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap([["number", TypeUtils.createNumberLiteral(false, 1)]]),
new OrderedMap([["number", TypeUtils.numberLiteral(false, 1)]]),
false,
);
const right: Type.DefinedTable = TypeUtils.createDefinedTable(
const right: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap([["number", Type.NumberInstance]]),
false,
@ -311,13 +305,13 @@ describe(`localIsCompatible`, () => {
});
it(`${Type.ExtendedTypeKind.TextLiteral}`, () => {
const left: Type.DefinedTable = TypeUtils.createDefinedTable(
const left: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap([["text", TypeUtils.createTextLiteral(false, `""`)]]),
new OrderedMap([["text", TypeUtils.textLiteral(false, `""`)]]),
false,
);
const right: Type.DefinedTable = TypeUtils.createDefinedTable(
const right: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap([["text", Type.TextInstance]]),
false,
@ -329,17 +323,17 @@ describe(`localIsCompatible`, () => {
describe(`null`, () => {
it(`null is not compatible with non-nullable`, () => {
const definedTable: Type.DefinedTable = TypeUtils.createDefinedTable(false, new OrderedMap(), false);
const definedTable: Type.DefinedTable = TypeUtils.definedTable(false, new OrderedMap(), false);
expect(noopIsCompatible(Type.NullInstance, definedTable)).to.equal(false, undefined);
});
it(`non-nullable is not compatible with null`, () => {
const definedTable: Type.DefinedTable = TypeUtils.createDefinedTable(false, new OrderedMap(), false);
const definedTable: Type.DefinedTable = TypeUtils.definedTable(false, new OrderedMap(), false);
expect(noopIsCompatible(definedTable, Type.NullInstance)).to.equal(false, undefined);
});
it(`null is compatible with nullable`, () => {
const definedTable: Type.DefinedTable = TypeUtils.createDefinedTable(true, new OrderedMap(), false);
const definedTable: Type.DefinedTable = TypeUtils.definedTable(true, new OrderedMap(), false);
expect(noopIsCompatible(Type.NullInstance, definedTable)).to.equal(true, undefined);
});
});
@ -356,21 +350,21 @@ describe(`localIsCompatible`, () => {
describe(`${Type.ExtendedTypeKind.NumberLiteral}`, () => {
it(`1`, () => {
expect(noopIsCompatible(TypeUtils.createNumberLiteral(false, `1`), Type.NumberInstance)).to.equal(
expect(noopIsCompatible(TypeUtils.numberLiteral(false, `1`), Type.NumberInstance)).to.equal(
true,
undefined,
);
});
it(`--1`, () => {
expect(noopIsCompatible(TypeUtils.createNumberLiteral(false, `--1`), Type.NumberInstance)).to.equal(
expect(noopIsCompatible(TypeUtils.numberLiteral(false, `--1`), Type.NumberInstance)).to.equal(
true,
undefined,
);
});
it(`+1`, () => {
expect(noopIsCompatible(TypeUtils.createNumberLiteral(false, `+1`), Type.NumberInstance)).to.equal(
expect(noopIsCompatible(TypeUtils.numberLiteral(false, `+1`), Type.NumberInstance)).to.equal(
true,
undefined,
);
@ -378,7 +372,7 @@ describe(`localIsCompatible`, () => {
});
it(`${Type.ExtendedTypeKind.TextLiteral}`, () => {
expect(noopIsCompatible(TypeUtils.createTextLiteral(false, `"foo"`), Type.TextInstance)).to.equal(
expect(noopIsCompatible(TypeUtils.textLiteral(false, `"foo"`), Type.TextInstance)).to.equal(
true,
undefined,
);
@ -387,17 +381,15 @@ describe(`localIsCompatible`, () => {
describe(`literals are compatible with literals`, () => {
it(`1`, () => {
expect(
noopIsCompatible(TypeUtils.createNumberLiteral(false, `1`), TypeUtils.createNumberLiteral(false, `1`)),
).to.equal(true, undefined);
expect(noopIsCompatible(TypeUtils.numberLiteral(false, `1`), TypeUtils.numberLiteral(false, `1`))).to.equal(
true,
undefined,
);
});
it(`"foo"`, () => {
expect(
noopIsCompatible(
TypeUtils.createTextLiteral(false, `"foo"`),
TypeUtils.createTextLiteral(false, `"foo"`),
),
noopIsCompatible(TypeUtils.textLiteral(false, `"foo"`), TypeUtils.textLiteral(false, `"foo"`)),
).to.equal(true, undefined);
});
});

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

@ -82,7 +82,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`${Type.NumberInstance.kind} literal`, () => {
expect(noopNameOf(TypeUtils.createNumberLiteral(false, 1))).to.equal("1");
expect(noopNameOf(TypeUtils.numberLiteral(false, 1))).to.equal("1");
});
it(`${Type.RecordInstance.kind}`, () => {
@ -98,7 +98,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`${Type.TextInstance.kind} literal`, () => {
expect(noopNameOf(TypeUtils.createTextLiteral(false, `"foo"`))).to.equal(`"foo"`);
expect(noopNameOf(TypeUtils.textLiteral(false, `"foo"`))).to.equal(`"foo"`);
});
it(`${Type.TimeInstance.kind}`, () => {
@ -182,7 +182,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`${Type.NullableNumberInstance.kind} literal`, () => {
const actual: string = noopNameOf(TypeUtils.createNumberLiteral(true, `1`));
const actual: string = noopNameOf(TypeUtils.numberLiteral(true, `1`));
expect(actual).to.equal(`nullable 1`, undefined);
});
@ -202,7 +202,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`${Type.TextInstance.kind} literal`, () => {
const actual: string = noopNameOf(TypeUtils.createTextLiteral(true, `"foo"`));
const actual: string = noopNameOf(TypeUtils.textLiteral(true, `"foo"`));
expect(actual).to.equal(`nullable "foo"`, undefined);
});
@ -226,7 +226,7 @@ describe(`TypeUtils.nameOf`, () => {
describe(`extended`, () => {
describe(`${Type.ExtendedTypeKind.AnyUnion}`, () => {
it(`primitives`, () => {
const type: Type.TPowerQueryType = TypeUtils.createAnyUnion(
const type: Type.TPowerQueryType = TypeUtils.anyUnion(
[Type.NumberInstance, Type.ListInstance],
NoOpTraceManagerInstance,
undefined,
@ -236,11 +236,11 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`complex`, () => {
const type: Type.TPowerQueryType = TypeUtils.createAnyUnion(
const type: Type.TPowerQueryType = TypeUtils.anyUnion(
[
TypeUtils.createDefinedRecord(false, new Map([[`foo`, Type.NumberInstance]]), false),
TypeUtils.createDefinedList(false, [Type.TextInstance]),
TypeUtils.createDefinedTable(false, new OrderedMap([[`bar`, Type.TextInstance]]), true),
TypeUtils.definedRecord(false, new Map([[`foo`, Type.NumberInstance]]), false),
TypeUtils.definedList(false, [Type.TextInstance]),
TypeUtils.definedTable(false, new OrderedMap([[`bar`, Type.TextInstance]]), true),
],
NoOpTraceManagerInstance,
undefined,
@ -253,20 +253,20 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.DefinedFunction}`, () => {
it(`() => any`, () => {
const type: Type.DefinedFunction = TypeUtils.createDefinedFunction(false, [], Type.AnyInstance);
const type: Type.DefinedFunction = TypeUtils.definedFunction(false, [], Type.AnyInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`() => any`);
});
it(`() => nullable any`, () => {
const type: Type.DefinedFunction = TypeUtils.createDefinedFunction(false, [], Type.NullableAnyInstance);
const type: Type.DefinedFunction = TypeUtils.definedFunction(false, [], Type.NullableAnyInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`() => nullable any`, undefined);
});
it(`(x, optional y) => 1`, () => {
const type: Type.DefinedFunction = TypeUtils.createDefinedFunction(
const type: Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -282,7 +282,7 @@ describe(`TypeUtils.nameOf`, () => {
nameLiteral: "y",
},
],
TypeUtils.createNumberLiteral(false, 1),
TypeUtils.numberLiteral(false, 1),
);
const actual: string = noopNameOf(type);
@ -291,7 +291,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`(param1 as number, param2 as nullable number, optional param3 as number, optional param4 as nullable number) => any`, () => {
const type: Type.DefinedFunction = TypeUtils.createDefinedFunction(
const type: Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -333,20 +333,20 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.DefinedList}`, () => {
it(`{}`, () => {
const type: Type.DefinedList = TypeUtils.createDefinedList(false, []);
const type: Type.DefinedList = TypeUtils.definedList(false, []);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`{}`);
});
it(`nullable {}`, () => {
const type: Type.DefinedList = TypeUtils.createDefinedList(true, []);
const type: Type.DefinedList = TypeUtils.definedList(true, []);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`nullable {}`, undefined);
});
it(`{number, nullable text}`, () => {
const type: Type.DefinedList = TypeUtils.createDefinedList(false, [
const type: Type.DefinedList = TypeUtils.definedList(false, [
Type.NumberInstance,
Type.NullableTextInstance,
]);
@ -359,20 +359,20 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.DefinedListType}`, () => {
it(`type {}`, () => {
const type: Type.DefinedListType = TypeUtils.createDefinedListType(false, []);
const type: Type.DefinedListType = TypeUtils.definedListType(false, []);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type {}`);
});
it(`nullable type {}`, () => {
const type: Type.DefinedListType = TypeUtils.createDefinedListType(true, []);
const type: Type.DefinedListType = TypeUtils.definedListType(true, []);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`nullable type {}`, undefined);
});
it(`type {number, nullable text}`, () => {
const type: Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const type: Type.DefinedListType = TypeUtils.definedListType(false, [
Type.NumberInstance,
Type.NullableTextInstance,
]);
@ -385,19 +385,19 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.DefinedRecord}`, () => {
it(`[]`, () => {
const type: Type.DefinedRecord = TypeUtils.createDefinedRecord(false, new Map(), false);
const type: Type.DefinedRecord = TypeUtils.definedRecord(false, new Map(), false);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`[]`);
});
it(`[...]`, () => {
const type: Type.DefinedRecord = TypeUtils.createDefinedRecord(false, new Map(), true);
const type: Type.DefinedRecord = TypeUtils.definedRecord(false, new Map(), true);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`[...]`);
});
it(`[foo = number, bar = nullable text]`, () => {
const type: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const type: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map<string, Type.TPowerQueryType>([
[`foo`, Type.NumberInstance],
@ -412,7 +412,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`[foo = number, bar = nullable text, ...]`, () => {
const type: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const type: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map<string, Type.TPowerQueryType>([
[`foo`, Type.NumberInstance],
@ -429,19 +429,19 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.DefinedTable}`, () => {
it(`table []`, () => {
const type: Type.DefinedTable = TypeUtils.createDefinedTable(false, new OrderedMap(), false);
const type: Type.DefinedTable = TypeUtils.definedTable(false, new OrderedMap(), false);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`table []`);
});
it(`table [...]`, () => {
const type: Type.DefinedTable = TypeUtils.createDefinedTable(false, new OrderedMap(), true);
const type: Type.DefinedTable = TypeUtils.definedTable(false, new OrderedMap(), true);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`table [...]`);
});
it(`table [foo = number, bar = nullable text]`, () => {
const type: Type.DefinedTable = TypeUtils.createDefinedTable(
const type: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap<string, Type.TPowerQueryType>([
[`foo`, Type.NumberInstance],
@ -456,7 +456,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`table [foo = number, bar = nullable text, ...]`, () => {
const type: Type.DefinedTable = TypeUtils.createDefinedTable(
const type: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap<string, Type.TPowerQueryType>([
[`foo`, Type.NumberInstance],
@ -471,7 +471,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`table [#"foo" = number, #"space space"]`, () => {
const type: Type.DefinedTable = TypeUtils.createDefinedTable(
const type: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap<string, Type.TPowerQueryType>([
[`foo`, Type.NumberInstance],
@ -488,13 +488,13 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.FunctionType}`, () => {
it(`type function () any`, () => {
const type: Type.FunctionType = TypeUtils.createFunctionType(false, [], Type.AnyInstance);
const type: Type.FunctionType = TypeUtils.functionType(false, [], Type.AnyInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type function () any`);
});
it(`type function () any`, () => {
const type: Type.FunctionType = TypeUtils.createFunctionType(
const type: Type.FunctionType = TypeUtils.functionType(
false,
[
{
@ -536,7 +536,7 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.ListType}`, () => {
it(`type {text}`, () => {
const type: Type.ListType = TypeUtils.createListType(false, Type.TextInstance);
const type: Type.ListType = TypeUtils.listType(false, Type.TextInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type {text}`);
});
@ -544,7 +544,7 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.PrimaryPrimitiveType}`, () => {
it(`type text`, () => {
const type: Type.PrimaryPrimitiveType = TypeUtils.createPrimaryPrimitiveType(false, Type.TextInstance);
const type: Type.PrimaryPrimitiveType = TypeUtils.primaryPrimitiveType(false, Type.TextInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type text`);
});
@ -552,7 +552,7 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.RecordType}`, () => {
it(`type [foo = number]`, () => {
const type: Type.RecordType = TypeUtils.createRecordType(
const type: Type.RecordType = TypeUtils.recordType(
false,
new Map([[`foo`, Type.NumberInstance]]),
false,
@ -563,13 +563,13 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`type [...]`, () => {
const type: Type.RecordType = TypeUtils.createRecordType(false, new Map(), true);
const type: Type.RecordType = TypeUtils.recordType(false, new Map(), true);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type [...]`);
});
it(`type [foo = number, bar = nullable text]`, () => {
const type: Type.RecordType = TypeUtils.createRecordType(
const type: Type.RecordType = TypeUtils.recordType(
false,
new Map<string, Type.TPowerQueryType>([
[`foo`, Type.NumberInstance],
@ -584,7 +584,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`type [foo = number, bar = nullable text, ...]`, () => {
const type: Type.RecordType = TypeUtils.createRecordType(
const type: Type.RecordType = TypeUtils.recordType(
false,
new Map<string, Type.TPowerQueryType>([
[`foo`, Type.NumberInstance],
@ -601,24 +601,20 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.TableType}`, () => {
it(`type table [foo = number]`, () => {
const type: Type.TableType = TypeUtils.createTableType(
false,
new Map([[`foo`, Type.NumberInstance]]),
false,
);
const type: Type.TableType = TypeUtils.tableType(false, new Map([[`foo`, Type.NumberInstance]]), false);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type table [foo: number]`);
});
it(`type table [...]`, () => {
const type: Type.TableType = TypeUtils.createTableType(false, new Map(), true);
const type: Type.TableType = TypeUtils.tableType(false, new Map(), true);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type table [...]`);
});
it(`type table [foo = number, bar = nullable text]`, () => {
const type: Type.TableType = TypeUtils.createTableType(
const type: Type.TableType = TypeUtils.tableType(
false,
new Map<string, Type.TPowerQueryType>([
[`foo`, Type.NumberInstance],
@ -633,7 +629,7 @@ describe(`TypeUtils.nameOf`, () => {
});
it(`type table [foo = number, bar = nullable text, ...]`, () => {
const type: Type.TableType = TypeUtils.createTableType(
const type: Type.TableType = TypeUtils.tableType(
false,
new Map<string, Type.TPowerQueryType>([
[`foo`, Type.NumberInstance],
@ -651,10 +647,7 @@ describe(`TypeUtils.nameOf`, () => {
describe(`${Type.ExtendedTypeKind.TableTypePrimaryExpression}`, () => {
// Assumes `foo` is text.
it(`type table foo`, () => {
const type: Type.TableTypePrimaryExpression = TypeUtils.createTableTypePrimary(
false,
Type.TextInstance,
);
const type: Type.TableTypePrimaryExpression = TypeUtils.tableTypePrimary(false, Type.TextInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type table text`);

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

@ -52,7 +52,7 @@ describe(`TypeUtils.typeCheck`, () => {
it(`extraneous parameter`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [Language.Type.ActionInstance];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[],
Language.Type.ActionInstance,
@ -73,7 +73,7 @@ describe(`TypeUtils.typeCheck`, () => {
it(`missing required parameter`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -101,7 +101,7 @@ describe(`TypeUtils.typeCheck`, () => {
it(`missing optional parameter`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -129,7 +129,7 @@ describe(`TypeUtils.typeCheck`, () => {
it(`type === null translates to any`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [Language.Type.NumberInstance];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -157,7 +157,7 @@ describe(`TypeUtils.typeCheck`, () => {
it(`paramter.type === any allows any type`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [Language.Type.NumberInstance];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -185,7 +185,7 @@ describe(`TypeUtils.typeCheck`, () => {
it(`an any argument allowed for non-any parameters`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [Language.Type.AnyInstance];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -211,9 +211,9 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`valid parameter`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [TypeUtils.createNumberLiteral(false, 1)];
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [TypeUtils.numberLiteral(false, 1)];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -240,11 +240,11 @@ describe(`TypeUtils.typeCheck`, () => {
it(`valid multiple parameters`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [
TypeUtils.createNumberLiteral(false, 1),
TypeUtils.createTextLiteral(false, `"cat"`),
TypeUtils.numberLiteral(false, 1),
TypeUtils.textLiteral(false, `"cat"`),
];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -276,9 +276,9 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`invalid parameter`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [TypeUtils.createTextLiteral(false, `""`)];
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [TypeUtils.textLiteral(false, `""`)];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -314,7 +314,7 @@ describe(`TypeUtils.typeCheck`, () => {
it(`allow null for nullable parameter`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [Language.Type.NullInstance];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -342,7 +342,7 @@ describe(`TypeUtils.typeCheck`, () => {
it(`disallow null for non-nullable parameter`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [Language.Type.NullInstance];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -370,7 +370,7 @@ describe(`TypeUtils.typeCheck`, () => {
it(`disallow nullable for non-nullable parameter`, () => {
const args: ReadonlyArray<Language.Type.TPowerQueryType> = [Language.Type.NullableTextInstance];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -401,7 +401,7 @@ describe(`TypeUtils.typeCheck`, () => {
Language.Type.FunctionInstance,
];
const definedFunction: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const definedFunction: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -450,12 +450,12 @@ describe(`TypeUtils.typeCheck`, () => {
describe(`Table.RenameColumns`, () => {
it(`list with two text elements, valid`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
Language.Type.TextInstance,
Language.Type.TextInstance,
]);
const schemaType: Language.Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const schemaType: Language.Type.DefinedListType = TypeUtils.definedListType(false, [
Language.Type.TextInstance,
Language.Type.TextInstance,
]);
@ -473,13 +473,13 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`list with two text elements, invalid`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
Language.Type.TextInstance,
Language.Type.TextInstance,
Language.Type.TextInstance,
]);
const schemaType: Language.Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const schemaType: Language.Type.DefinedListType = TypeUtils.definedListType(false, [
Language.Type.TextInstance,
Language.Type.TextInstance,
]);
@ -497,13 +497,13 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`list of list with two text elements, valid single list`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
]);
const schemaType: Language.Type.ListType = TypeUtils.createListType(
const schemaType: Language.Type.ListType = TypeUtils.listType(
false,
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
);
const actual: TypeUtils.CheckedDefinedList = noopTypeCheckListWithListType(valueType, schemaType);
@ -519,16 +519,16 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`list of list with two text elements, valid multiple list`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
]);
const schemaType: Language.Type.ListType = TypeUtils.createListType(
const schemaType: Language.Type.ListType = TypeUtils.listType(
false,
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
);
const actual: TypeUtils.CheckedDefinedList = noopTypeCheckListWithListType(valueType, schemaType);
@ -544,11 +544,11 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`list of list with two text elements, empty list`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, []);
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, []);
const schemaType: Language.Type.ListType = TypeUtils.createListType(
const schemaType: Language.Type.ListType = TypeUtils.listType(
false,
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
);
const actual: TypeUtils.CheckedDefinedList = noopTypeCheckListWithListType(valueType, schemaType);
@ -564,13 +564,13 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`list of list with two text elements, invalid single list`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
TypeUtils.createDefinedList(false, [Language.Type.NumberInstance, Language.Type.TextInstance]),
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
TypeUtils.definedList(false, [Language.Type.NumberInstance, Language.Type.TextInstance]),
]);
const schemaType: Language.Type.ListType = TypeUtils.createListType(
const schemaType: Language.Type.ListType = TypeUtils.listType(
false,
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
);
const actual: TypeUtils.CheckedDefinedList = noopTypeCheckListWithListType(valueType, schemaType);
@ -586,16 +586,16 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`list of list with two text elements, invalid multiple list`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.NumberInstance]),
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.NumberInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
]);
const schemaType: Language.Type.ListType = TypeUtils.createListType(
const schemaType: Language.Type.ListType = TypeUtils.listType(
false,
TypeUtils.createDefinedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
TypeUtils.definedList(false, [Language.Type.TextInstance, Language.Type.TextInstance]),
);
const actual: TypeUtils.CheckedDefinedList = noopTypeCheckListWithListType(valueType, schemaType);
@ -613,12 +613,12 @@ describe(`TypeUtils.typeCheck`, () => {
describe(`${Language.Type.ExtendedTypeKind.DefinedListType}`, () => {
it(`valid`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
Language.Type.TextInstance,
Language.Type.NumberInstance,
]);
const schemaType: Language.Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const schemaType: Language.Type.DefinedListType = TypeUtils.definedListType(false, [
Language.Type.TextInstance,
Language.Type.NumberInstance,
]);
@ -636,12 +636,12 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`invalid`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
Language.Type.TextInstance,
Language.Type.DateInstance,
]);
const schemaType: Language.Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const schemaType: Language.Type.DefinedListType = TypeUtils.definedListType(false, [
Language.Type.TextInstance,
Language.Type.NumberInstance,
]);
@ -659,12 +659,12 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`extraneous`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
Language.Type.TextInstance,
Language.Type.NumberInstance,
]);
const schemaType: Language.Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const schemaType: Language.Type.DefinedListType = TypeUtils.definedListType(false, [
Language.Type.TextInstance,
]);
@ -681,9 +681,9 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`missing`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, []);
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, []);
const schemaType: Language.Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const schemaType: Language.Type.DefinedListType = TypeUtils.definedListType(false, [
Language.Type.TextInstance,
Language.Type.NumberInstance,
]);
@ -703,12 +703,12 @@ describe(`TypeUtils.typeCheck`, () => {
describe(`${Language.Type.ExtendedTypeKind.ListType}`, () => {
it(`valid`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
Language.Type.TextInstance,
Language.Type.TextInstance,
]);
const schemaType: Language.Type.ListType = TypeUtils.createListType(false, Language.Type.TextInstance);
const schemaType: Language.Type.ListType = TypeUtils.listType(false, Language.Type.TextInstance);
const actual: TypeUtils.CheckedDefinedList = noopTypeCheckListWithListType(valueType, schemaType);
@ -723,12 +723,12 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`invalid`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
Language.Type.TextInstance,
Language.Type.DateInstance,
]);
const schemaType: Language.Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const schemaType: Language.Type.DefinedListType = TypeUtils.definedListType(false, [
Language.Type.TextInstance,
Language.Type.NumberInstance,
]);
@ -746,12 +746,12 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`extraneous`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, [
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, [
Language.Type.TextInstance,
Language.Type.NumberInstance,
]);
const schemaType: Language.Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const schemaType: Language.Type.DefinedListType = TypeUtils.definedListType(false, [
Language.Type.TextInstance,
]);
@ -768,9 +768,9 @@ describe(`TypeUtils.typeCheck`, () => {
});
it(`missing`, () => {
const valueType: Language.Type.DefinedList = TypeUtils.createDefinedList(false, []);
const valueType: Language.Type.DefinedList = TypeUtils.definedList(false, []);
const schemaType: Language.Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const schemaType: Language.Type.DefinedListType = TypeUtils.definedListType(false, [
Language.Type.TextInstance,
Language.Type.NumberInstance,
]);
@ -790,13 +790,13 @@ describe(`TypeUtils.typeCheck`, () => {
describe(`${Language.Type.ExtendedTypeKind.FunctionType}`, () => {
it(`return type`, () => {
const valueType: Language.Type.DefinedFunction = TypeUtils.createDefinedFunction(
const valueType: Language.Type.DefinedFunction = TypeUtils.definedFunction(
false,
[],
Language.Type.NullableTextInstance,
);
const schemaType: Language.Type.FunctionType = TypeUtils.createFunctionType(
const schemaType: Language.Type.FunctionType = TypeUtils.functionType(
false,
[],
Language.Type.NullableTextInstance,
@ -822,7 +822,7 @@ describe(`TypeUtils.typeCheck`, () => {
describe(`${Language.Type.ExtendedTypeKind.RecordType}`, () => {
it(`${Language.Type.ExtendedTypeKind.DefinedRecord}`, () => {
const valueType: Language.Type.DefinedRecord = TypeUtils.createDefinedRecord(
const valueType: Language.Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map<string, Language.Type.TPowerQueryType>([
["number", Language.Type.NullableNumberInstance],
@ -832,7 +832,7 @@ describe(`TypeUtils.typeCheck`, () => {
false,
);
const schemaType: Language.Type.RecordType = TypeUtils.createRecordType(
const schemaType: Language.Type.RecordType = TypeUtils.recordType(
false,
new Map<string, Language.Type.TPowerQueryType>([
["number", Language.Type.NumberInstance],
@ -862,7 +862,7 @@ describe(`TypeUtils.typeCheck`, () => {
describe(`${Language.Type.ExtendedTypeKind.TableType}`, () => {
it(`${Language.Type.ExtendedTypeKind.DefinedTable}`, () => {
const valueType: Language.Type.DefinedTable = TypeUtils.createDefinedTable(
const valueType: Language.Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap<string, Language.Type.TPowerQueryType>([
["number", Language.Type.NullableNumberInstance],
@ -872,7 +872,7 @@ describe(`TypeUtils.typeCheck`, () => {
false,
);
const schemaType: Language.Type.TableType = TypeUtils.createTableType(
const schemaType: Language.Type.TableType = TypeUtils.tableType(
false,
new Map<string, Language.Type.TPowerQueryType>([
["number", Language.Type.NumberInstance],

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

@ -36,7 +36,7 @@ function createAbridgedTypes(types: ReadonlyArray<Type.TPowerQueryType>): Readon
const noopCreateAnyUnion: (types: ReadonlyArray<Type.TPowerQueryType>) => Type.TPowerQueryType = (
types: ReadonlyArray<Type.TPowerQueryType>,
) => TypeUtils.createAnyUnion(types, NoOpTraceManagerInstance, undefined);
) => TypeUtils.anyUnion(types, NoOpTraceManagerInstance, undefined);
const noopNameOf: (type: Type.TPowerQueryType) => string = (type: Type.TPowerQueryType) =>
TypeUtils.nameOf(type, NoOpTraceManagerInstance, undefined);
@ -80,7 +80,7 @@ describe(`TypeUtils`, () => {
it(`simplify literal and primitive to primitive`, () => {
const actual: ReadonlyArray<AbridgedType> = createAbridgedTypes(
noopSimplify([Type.NumberInstance, TypeUtils.createNumberLiteral(false, 1)]),
noopSimplify([Type.NumberInstance, TypeUtils.numberLiteral(false, 1)]),
);
const expected: ReadonlyArray<AbridgedType> = [Type.NumberInstance];
@ -89,13 +89,13 @@ describe(`TypeUtils`, () => {
it(`retain multiple unique literals`, () => {
const actual: ReadonlyArray<AbridgedType> = noopSimplify([
TypeUtils.createNumberLiteral(false, 1),
TypeUtils.createNumberLiteral(false, 2),
TypeUtils.numberLiteral(false, 1),
TypeUtils.numberLiteral(false, 2),
]);
const expected: ReadonlyArray<AbridgedType> = [
TypeUtils.createNumberLiteral(false, 1),
TypeUtils.createNumberLiteral(false, 2),
TypeUtils.numberLiteral(false, 1),
TypeUtils.numberLiteral(false, 2),
];
expect(actual).deep.equal(expected);
@ -121,11 +121,11 @@ describe(`TypeUtils`, () => {
it(`dedupe duplicate literals`, () => {
const actual: ReadonlyArray<AbridgedType> = noopSimplify([
TypeUtils.createNumberLiteral(false, 1),
TypeUtils.createNumberLiteral(false, 1),
TypeUtils.numberLiteral(false, 1),
TypeUtils.numberLiteral(false, 1),
]);
const expected: ReadonlyArray<AbridgedType> = [TypeUtils.createNumberLiteral(false, 1)];
const expected: ReadonlyArray<AbridgedType> = [TypeUtils.numberLiteral(false, 1)];
expect(actual).deep.equal(expected);
});
@ -138,7 +138,7 @@ describe(`TypeUtils`, () => {
expect(simplified.length).to.equal(1);
const actual: AbridgedType = typeToAbridged(simplified[0]);
const expected: AbridgedType = TypeUtils.createPrimitiveType(false, Type.TypeKind.Record);
const expected: AbridgedType = TypeUtils.primitiveType(false, Type.TypeKind.Record);
expect(actual).deep.equal(expected);
});
@ -423,9 +423,9 @@ describe(`TypeUtils`, () => {
it(`complex`, () => {
const type: Type.TPowerQueryType = noopCreateAnyUnion([
TypeUtils.createDefinedRecord(false, new Map([["foo", Type.NumberInstance]]), false),
TypeUtils.createDefinedList(false, [Type.TextInstance]),
TypeUtils.createDefinedTable(false, new OrderedMap([["bar", Type.TextInstance]]), true),
TypeUtils.definedRecord(false, new Map([["foo", Type.NumberInstance]]), false),
TypeUtils.definedList(false, [Type.TextInstance]),
TypeUtils.definedTable(false, new OrderedMap([["bar", Type.TextInstance]]), true),
]);
const actual: string = noopNameOf(type);
@ -435,17 +435,13 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.DefinedFunction}`, () => {
it(`() => any`, () => {
const type: Type.DefinedFunction = TypeUtils.createDefinedFunction(false, [], Type.AnyInstance);
const type: Type.DefinedFunction = TypeUtils.definedFunction(false, [], Type.AnyInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`() => any`);
});
it(`() => nullable any`, () => {
const type: Type.DefinedFunction = TypeUtils.createDefinedFunction(
false,
[],
Type.NullableAnyInstance,
);
const type: Type.DefinedFunction = TypeUtils.definedFunction(false, [], Type.NullableAnyInstance);
const actual: string = noopNameOf(type);
// tslint:disable-next-line: chai-vague-errors
@ -453,7 +449,7 @@ describe(`TypeUtils`, () => {
});
it(`(param1 as number, param2 as nullable number, optional param3 as number, optional param4 as nullable number) => any`, () => {
const type: Type.DefinedFunction = TypeUtils.createDefinedFunction(
const type: Type.DefinedFunction = TypeUtils.definedFunction(
false,
[
{
@ -495,20 +491,20 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.DefinedList}`, () => {
it(`{}`, () => {
const type: Type.DefinedList = TypeUtils.createDefinedList(false, []);
const type: Type.DefinedList = TypeUtils.definedList(false, []);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`{}`);
});
it(`nullable {}`, () => {
const type: Type.DefinedList = TypeUtils.createDefinedList(true, []);
const type: Type.DefinedList = TypeUtils.definedList(true, []);
const actual: string = noopNameOf(type);
// tslint:disable-next-line: chai-vague-errors
expect(actual).to.equal(`nullable {}`);
});
it(`{number, nullable text}`, () => {
const type: Type.DefinedList = TypeUtils.createDefinedList(false, [
const type: Type.DefinedList = TypeUtils.definedList(false, [
Type.NumberInstance,
Type.NullableTextInstance,
]);
@ -521,20 +517,20 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.DefinedListType}`, () => {
it(`type {}`, () => {
const type: Type.DefinedListType = TypeUtils.createDefinedListType(false, []);
const type: Type.DefinedListType = TypeUtils.definedListType(false, []);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type {}`);
});
it(`nullable type {}`, () => {
const type: Type.DefinedListType = TypeUtils.createDefinedListType(true, []);
const type: Type.DefinedListType = TypeUtils.definedListType(true, []);
const actual: string = noopNameOf(type);
// tslint:disable-next-line: chai-vague-errors
expect(actual).to.equal(`nullable type {}`);
});
it(`type {number, nullable text}`, () => {
const type: Type.DefinedListType = TypeUtils.createDefinedListType(false, [
const type: Type.DefinedListType = TypeUtils.definedListType(false, [
Type.NumberInstance,
Type.NullableTextInstance,
]);
@ -547,19 +543,19 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.DefinedRecord}`, () => {
it(`[]`, () => {
const type: Type.DefinedRecord = TypeUtils.createDefinedRecord(false, new Map(), false);
const type: Type.DefinedRecord = TypeUtils.definedRecord(false, new Map(), false);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`[]`);
});
it(`[...]`, () => {
const type: Type.DefinedRecord = TypeUtils.createDefinedRecord(false, new Map(), true);
const type: Type.DefinedRecord = TypeUtils.definedRecord(false, new Map(), true);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`[...]`);
});
it(`[foo = number, bar = nullable text]`, () => {
const type: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const type: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map<string, Type.TPowerQueryType>([
["foo", Type.NumberInstance],
@ -574,7 +570,7 @@ describe(`TypeUtils`, () => {
});
it(`[foo = number, bar = nullable text, ...]`, () => {
const type: Type.DefinedRecord = TypeUtils.createDefinedRecord(
const type: Type.DefinedRecord = TypeUtils.definedRecord(
false,
new Map<string, Type.TPowerQueryType>([
["foo", Type.NumberInstance],
@ -591,19 +587,19 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.DefinedTable}`, () => {
it(`table []`, () => {
const type: Type.DefinedTable = TypeUtils.createDefinedTable(false, new OrderedMap(), false);
const type: Type.DefinedTable = TypeUtils.definedTable(false, new OrderedMap(), false);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`table []`);
});
it(`table [...]`, () => {
const type: Type.DefinedTable = TypeUtils.createDefinedTable(false, new OrderedMap(), true);
const type: Type.DefinedTable = TypeUtils.definedTable(false, new OrderedMap(), true);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`table [...]`);
});
it(`table [foo = number, bar = nullable text]`, () => {
const type: Type.DefinedTable = TypeUtils.createDefinedTable(
const type: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap<string, Type.TPowerQueryType>([
["foo", Type.NumberInstance],
@ -618,7 +614,7 @@ describe(`TypeUtils`, () => {
});
it(`table [foo = number, bar = nullable text, ...]`, () => {
const type: Type.DefinedTable = TypeUtils.createDefinedTable(
const type: Type.DefinedTable = TypeUtils.definedTable(
false,
new OrderedMap<string, Type.TPowerQueryType>([
["foo", Type.NumberInstance],
@ -635,13 +631,13 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.FunctionType}`, () => {
it(`type function () any`, () => {
const type: Type.FunctionType = TypeUtils.createFunctionType(false, [], Type.AnyInstance);
const type: Type.FunctionType = TypeUtils.functionType(false, [], Type.AnyInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type function () any`);
});
it(`type function () any`, () => {
const type: Type.FunctionType = TypeUtils.createFunctionType(
const type: Type.FunctionType = TypeUtils.functionType(
false,
[
{
@ -683,7 +679,7 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.ListType}`, () => {
it(`type {text}`, () => {
const type: Type.ListType = TypeUtils.createListType(false, Type.TextInstance);
const type: Type.ListType = TypeUtils.listType(false, Type.TextInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type {text}`);
});
@ -691,10 +687,7 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.PrimaryPrimitiveType}`, () => {
it(`type text`, () => {
const type: Type.PrimaryPrimitiveType = TypeUtils.createPrimaryPrimitiveType(
false,
Type.TextInstance,
);
const type: Type.PrimaryPrimitiveType = TypeUtils.primaryPrimitiveType(false, Type.TextInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type text`);
@ -703,7 +696,7 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.RecordType}`, () => {
it(`type [foo = number]`, () => {
const type: Type.RecordType = TypeUtils.createRecordType(
const type: Type.RecordType = TypeUtils.recordType(
false,
new Map([["foo", Type.NumberInstance]]),
false,
@ -714,13 +707,13 @@ describe(`TypeUtils`, () => {
});
it(`type [...]`, () => {
const type: Type.RecordType = TypeUtils.createRecordType(false, new Map(), true);
const type: Type.RecordType = TypeUtils.recordType(false, new Map(), true);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type [...]`);
});
it(`type [foo = number, bar = nullable text]`, () => {
const type: Type.RecordType = TypeUtils.createRecordType(
const type: Type.RecordType = TypeUtils.recordType(
false,
new Map<string, Type.TPowerQueryType>([
["foo", Type.NumberInstance],
@ -735,7 +728,7 @@ describe(`TypeUtils`, () => {
});
it(`type [foo = number, bar = nullable text, ...]`, () => {
const type: Type.RecordType = TypeUtils.createRecordType(
const type: Type.RecordType = TypeUtils.recordType(
false,
new Map<string, Type.TPowerQueryType>([
["foo", Type.NumberInstance],
@ -752,7 +745,7 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.TableType}`, () => {
it(`type table [foo = number]`, () => {
const type: Type.TableType = TypeUtils.createTableType(
const type: Type.TableType = TypeUtils.tableType(
false,
new Map([["foo", Type.NumberInstance]]),
false,
@ -763,13 +756,13 @@ describe(`TypeUtils`, () => {
});
it(`type table [...]`, () => {
const type: Type.TableType = TypeUtils.createTableType(false, new Map(), true);
const type: Type.TableType = TypeUtils.tableType(false, new Map(), true);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type table [...]`);
});
it(`type table [foo = number, bar = nullable text]`, () => {
const type: Type.TableType = TypeUtils.createTableType(
const type: Type.TableType = TypeUtils.tableType(
false,
new Map<string, Type.TPowerQueryType>([
["foo", Type.NumberInstance],
@ -784,7 +777,7 @@ describe(`TypeUtils`, () => {
});
it(`type table [foo = number, bar = nullable text, ...]`, () => {
const type: Type.TableType = TypeUtils.createTableType(
const type: Type.TableType = TypeUtils.tableType(
false,
new Map<string, Type.TPowerQueryType>([
["foo", Type.NumberInstance],
@ -802,10 +795,7 @@ describe(`TypeUtils`, () => {
describe(`${Type.ExtendedTypeKind.TableTypePrimaryExpression}`, () => {
// Assumes `foo` is text.
it(`type table foo`, () => {
const type: Type.TableTypePrimaryExpression = TypeUtils.createTableTypePrimary(
false,
Type.TextInstance,
);
const type: Type.TableTypePrimaryExpression = TypeUtils.tableTypePrimary(false, Type.TextInstance);
const actual: string = noopNameOf(type);
expect(actual).to.equal(`type table text`);

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

@ -3,8 +3,10 @@
import "mocha";
import { Assert, Lexer, LexSettings, Parser, ParseSettings, Task } from "../..";
import { TaskUtils } from "../../powerquery-parser";
import { Assert, Lexer, Parser, Task } from "../..";
import { ResultUtils, TaskUtils } from "../../powerquery-parser";
import { LexSettings } from "../../powerquery-parser/lexer";
import { ParseSettings } from "../../powerquery-parser/parser";
export async function assertGetLexParseOk(
settings: LexSettings & ParseSettings,
@ -31,7 +33,7 @@ export async function assertGetParseError(
text: string,
): Promise<Parser.ParseError.ParseError> {
const triedParse: Parser.TriedParse = await assertGetTriedParse(settings, text);
Assert.isError(triedParse);
ResultUtils.assertIsError(triedParse);
if (!Parser.ParseError.isParseError(triedParse.error)) {
throw new Error(`expected triedParse to return a ParseError.ParseError: ${triedParse.error.message}`);
@ -42,7 +44,7 @@ export async function assertGetParseError(
export async function assertGetParseOk(settings: LexSettings & ParseSettings, text: string): Promise<Parser.ParseOk> {
const triedParse: Parser.TriedParse = await assertGetTriedParse(settings, text);
Assert.isOk(triedParse);
ResultUtils.assertIsOk(triedParse);
return triedParse.value;
}
@ -51,12 +53,12 @@ export async function assertGetParseOk(settings: LexSettings & ParseSettings, te
// If I use tryLexParse I might get a CommonError which could have come either from lexing or parsing.
async function assertGetTriedParse(settings: LexSettings & ParseSettings, text: string): Promise<Parser.TriedParse> {
const triedLex: Lexer.TriedLex = Lexer.tryLex(settings, text);
Assert.isOk(triedLex);
ResultUtils.assertIsOk(triedLex);
const lexerState: Lexer.State = triedLex.value;
Assert.isUndefined(Lexer.errorLineMap(lexerState));
const triedSnapshot: Lexer.TriedLexerSnapshot = Lexer.trySnapshot(lexerState);
Assert.isOk(triedSnapshot);
ResultUtils.assertIsOk(triedSnapshot);
const lexerSnapshot: Lexer.LexerSnapshot = triedSnapshot.value;
return await Parser.ParserUtils.tryParse(settings, lexerSnapshot);

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

@ -5,7 +5,9 @@ import "mocha";
import * as fs from "fs";
import * as path from "path";
import { LexSettings, ParseSettings, Task } from "../..";
import { LexSettings } from "../../powerquery-parser/lexer";
import { ParseSettings } from "../../powerquery-parser/parser";
import { Task } from "../..";
import { TaskUtils } from "../../powerquery-parser";
const PowerQueryExtensions: ReadonlyArray<string> = [".m", ".mout", ".pq", "pqm"];