Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/powerquery-parser",
"version": "0.19.0",
"version": "0.19.1",
"description": "A parser for the Power Query/M formula language.",
"author": "Microsoft",
"license": "MIT",
Expand Down
6 changes: 5 additions & 1 deletion src/powerquery-parser/common/arrayUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ export function all<T>(
}

export function assertGet<T>(collection: ReadonlyArray<T>, index: number, message?: string, details?: object): T {
return Assert.asDefined(collection[index], message, details);
return Assert.asDefined(
collection[index],
message ?? "index out of bounds",
details ?? { index, collectionLength: collection.length },
);
}

export function assertIncludes<T>(collection: ReadonlyArray<T>, element: T, message?: string, details?: object): void {
Expand Down
12 changes: 10 additions & 2 deletions src/powerquery-parser/common/stringUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
import GraphemeSplitter = require("grapheme-splitter");
import { Assert, CommonError, Pattern } from ".";

export function assertGet(text: string, index: number, message?: string, details?: object): string {
return Assert.asDefined(
text[index],
message ?? "index out of bounds",
details ?? { index, textLength: text.length },
);
}

export const graphemeSplitter: GraphemeSplitter = new GraphemeSplitter();

export interface FoundQuotes {
Expand Down Expand Up @@ -162,7 +170,7 @@ export function findQuotes(text: string, indexStart: number): FoundQuotes | unde
}

export function newlineKindAt(text: string, index: number): NewlineKind | undefined {
const chr1: string = text[index];
const chr1: string | undefined = text[index];

switch (chr1) {
case `\u000d`: {
Expand Down Expand Up @@ -199,7 +207,7 @@ export function isHex(text: string): boolean {
}

export function getSign(text: string): [boolean, number] {
let char: string = text[0];
let char: string | undefined = text[0];
let charOffset: number = 0;
let isPositive: boolean = true;

Expand Down
2 changes: 1 addition & 1 deletion src/powerquery-parser/language/identifierUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ function getGeneralizedIdentifierLength(text: string, index: number): number | u
let continueMatching: boolean = true;

while (continueMatching) {
const currentChr: string = text[index];
const currentChr: string | undefined = text[index];

if (currentChr === " ") {
index += 1;
Expand Down
4 changes: 2 additions & 2 deletions src/powerquery-parser/language/type/typeUtils/factories.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { Assert, CommonError, StringUtils } from "../../../common";
import { ArrayUtils, Assert, CommonError, StringUtils } from "../../../common";
import { PrimitiveTypeConstantMap, primitiveTypeMapKey } from "./primitive";
import { Trace, TraceManager } from "../../../common/trace";
import { simplify } from "./simplify";
Expand Down Expand Up @@ -31,7 +31,7 @@ export function anyUnion(
if (simplified.length === 1) {
trace.exit();

return simplified[0];
return ArrayUtils.assertGet(simplified, 0);
}

const result: Type.AnyUnion = {
Expand Down
4 changes: 2 additions & 2 deletions src/powerquery-parser/language/type/typeUtils/isCompatible.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { Assert, CommonError, MapUtils } from "../../../common";
import { ArrayUtils, Assert, CommonError, MapUtils } from "../../../common";
import { isEqualFunctionSignature, isEqualType } from "./isEqualType";
import { isFieldSpecificationList, isFunctionSignature } from "./isType";
import { Trace, TraceManager } from "../../../common/trace";
Expand Down Expand Up @@ -777,7 +777,7 @@ function isCompatibleDefinedListOrDefinedListType<T extends Type.DefinedList | T
const numElements: number = leftElements.length;

for (let index: number = 0; index < numElements; index += 1) {
if (!isCompatible(leftElements[index], rightElements[index], traceManager, trace.id)) {
if (!isCompatible(ArrayUtils.assertGet(leftElements, index), ArrayUtils.assertGet(rightElements, index), traceManager, trace.id)) {
trace.exit();

return false;
Expand Down
10 changes: 5 additions & 5 deletions src/powerquery-parser/language/type/typeUtils/isEqualType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function isEqualTypes(
const numTypes: number = leftTypes.length;

for (let index: number = 0; index < numTypes; index += 1) {
if (!isTypeInArray(leftTypes, rightTypes[index])) {
if (!isTypeInArray(leftTypes, ArrayUtils.assertGet(rightTypes, index))) {
return false;
}
}
Expand Down Expand Up @@ -144,7 +144,7 @@ export function isEqualDefinedList(left: Type.DefinedList, right: Type.DefinedLi

return ArrayUtils.all(
left.elements.map((leftType: Type.TPowerQueryType, index: number) =>
isEqualType(leftType, rightElements[index]),
isEqualType(leftType, ArrayUtils.assertGet(rightElements, index)),
),
);
}
Expand All @@ -160,7 +160,7 @@ export function isEqualDefinedListType(left: Type.DefinedListType, right: Type.D

return ArrayUtils.all(
left.itemTypes.map((leftType: Type.TPowerQueryType, index: number) =>
isEqualType(leftType, rightElements[index]),
isEqualType(leftType, ArrayUtils.assertGet(rightElements, index)),
),
);
}
Expand Down Expand Up @@ -224,8 +224,8 @@ export function isEqualFunctionParameters(
const numParameters: number = left.length;

for (let index: number = 0; index < numParameters; index += 1) {
const nthLeft: Type.FunctionParameter = left[index];
const nthRight: Type.FunctionParameter = right[index];
const nthLeft: Type.FunctionParameter = ArrayUtils.assertGet(left, index);
const nthRight: Type.FunctionParameter = ArrayUtils.assertGet(right, index);

if (!isEqualFunctionParameter(nthLeft, nthRight)) {
return false;
Expand Down
6 changes: 3 additions & 3 deletions src/powerquery-parser/language/type/typeUtils/typeCheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export function typeCheckInvocation(

for (let index: number = 0; index < numParameters; index += 1) {
const arg: Type.TPowerQueryType | undefined = args[index];
const parameter: Type.FunctionParameter = parameters[index];
const parameter: Type.FunctionParameter = ArrayUtils.assertGet(parameters, index);

if (isCompatibleWithFunctionParameter(arg, parameter)) {
validArgs.push(index);
Expand Down Expand Up @@ -257,8 +257,8 @@ function typeCheckGenericNumber<
const mismatches: Map<number, IMismatch<Value, Schema>> = new Map();

for (let index: number = 0; index < upperBound; index += 1) {
const element: Value = valueElements[index];
const schemaItemType: Schema = schemaItemTypes[index];
const element: Value = ArrayUtils.assertGet(valueElements, index);
const schemaItemType: Schema = ArrayUtils.assertGet(schemaItemTypes, index);

if (comparer(element, schemaItemType, traceManager, trace.id)) {
validIndices.push(index);
Expand Down
4 changes: 2 additions & 2 deletions src/powerquery-parser/language/type/typeUtils/typeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { Ast, AstUtils } from "../..";
import { NodeIdMap, NodeIdMapUtils, ParseContext, XorNode, XorNodeKind } from "../../../parser";
import { Trace, TraceManager } from "../../../common/trace";
import { Assert } from "../../../common";
import { ArrayUtils, Assert } from "../../../common";
import { isCompatible } from "./isCompatible";
import { isEqualType } from "./isEqualType";
import { primitiveType } from "./factories";
Expand Down Expand Up @@ -91,7 +91,7 @@ export function isValidInvocation(
const numParameters: number = parameters.length;

for (let index: number = 1; index < numParameters; index += 1) {
const parameter: Type.FunctionParameter = Assert.asDefined(parameters[index]);
const parameter: Type.FunctionParameter = ArrayUtils.assertGet(parameters, index);
const argType: Type.TPowerQueryType | undefined = args[index];

if (argType !== undefined) {
Expand Down
34 changes: 17 additions & 17 deletions src/powerquery-parser/lexer/lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ export function equalLines(leftLines: ReadonlyArray<TLine>, rightLines: Readonly
const numLines: number = leftLines.length;

for (let lineIndex: number = 0; lineIndex < numLines; lineIndex += 1) {
const left: TLine = leftLines[lineIndex];
const right: TLine = rightLines[lineIndex];
const left: TLine = ArrayUtils.assertGet(leftLines, lineIndex);
const right: TLine = ArrayUtils.assertGet(rightLines, lineIndex);
const leftTokens: ReadonlyArray<Token.LineToken> = left.tokens;
const rightTokens: ReadonlyArray<Token.LineToken> = right.tokens;

Expand All @@ -168,7 +168,7 @@ export function equalLines(leftLines: ReadonlyArray<TLine>, rightLines: Readonly
const numTokens: number = leftTokens.length;

for (let tokenIndex: number = 0; tokenIndex < numTokens; tokenIndex += 1) {
if (!equalTokens(leftTokens[tokenIndex], rightTokens[tokenIndex])) {
if (!equalTokens(ArrayUtils.assertGet(leftTokens, tokenIndex), ArrayUtils.assertGet(rightTokens, tokenIndex))) {
return false;
}
}
Expand Down Expand Up @@ -265,7 +265,7 @@ function splitOnLineTerminators(startingText: string): SplitLine[] {
let indexWasExpanded: boolean = false;

for (const lineTerminator of lineTerminators) {
const splitLine: SplitLine = lines[index];
const splitLine: SplitLine = ArrayUtils.assertGet(lines, index);
const text: string = splitLine.text;

if (text.indexOf(lineTerminator) !== -1) {
Expand All @@ -276,7 +276,7 @@ function splitOnLineTerminators(startingText: string): SplitLine[] {
lineTerminator,
}));

split[split.length - 1].lineTerminator = splitLine.lineTerminator;
ArrayUtils.assertGet(split, split.length - 1).lineTerminator = splitLine.lineTerminator;

lines = [...lines.slice(0, index), ...split, ...lines.slice(index + 1)];
}
Expand All @@ -287,7 +287,7 @@ function splitOnLineTerminators(startingText: string): SplitLine[] {
}
}

lines[lines.length - 1].lineTerminator = "";
ArrayUtils.assertGet(lines, lines.length - 1).lineTerminator = "";

return lines;
}
Expand Down Expand Up @@ -356,7 +356,7 @@ function updateLine(state: State, lineNumber: number, text: string): State {
throw error;
}

const line: TLine = state.lines[lineNumber];
const line: TLine = ArrayUtils.assertGet(state.lines, lineNumber);
const range: Range = rangeFrom(line, lineNumber);

return updateRange(state, range, text);
Expand All @@ -374,14 +374,14 @@ function updateRange(state: State, range: Range, text: string): State {
const splitLines: SplitLine[] = splitOnLineTerminators(text);

const rangeStart: RangePosition = range.start;
const lineStart: TLine = state.lines[rangeStart.lineNumber];
const lineStart: TLine = ArrayUtils.assertGet(state.lines, rangeStart.lineNumber);
const textPrefix: string = lineStart.text.substring(0, rangeStart.lineCodeUnit);
splitLines[0].text = textPrefix + splitLines[0].text;
ArrayUtils.assertGet(splitLines, 0).text = textPrefix + ArrayUtils.assertGet(splitLines, 0).text;

const rangeEnd: RangePosition = range.end;
const lineEnd: TLine = state.lines[rangeEnd.lineNumber];
const lineEnd: TLine = ArrayUtils.assertGet(state.lines, rangeEnd.lineNumber);
const textSuffix: string = lineEnd.text.substr(rangeEnd.lineCodeUnit);
const lastSplitLine: SplitLine = splitLines[splitLines.length - 1];
const lastSplitLine: SplitLine = ArrayUtils.assertGet(splitLines, splitLines.length - 1);
lastSplitLine.text = lastSplitLine.text + textSuffix;

// make sure we have a line terminator
Expand All @@ -400,7 +400,7 @@ function updateRange(state: State, range: Range, text: string): State {
const lines: ReadonlyArray<TLine> = [
...state.lines.slice(0, rangeStart.lineNumber),
...newLines,
...retokenizeLines(state, rangeEnd.lineNumber + 1, newLines[newLines.length - 1].lineModeEnd),
...retokenizeLines(state, rangeEnd.lineNumber + 1, ArrayUtils.assertGet(newLines, newLines.length - 1).lineModeEnd),
];

return {
Expand Down Expand Up @@ -485,7 +485,7 @@ function retokenizeLines(state: State, lineNumber: number, previousLineModeEnd:

const retokenizedLines: TLine[] = [];

if (previousLineModeEnd !== lines[lineNumber].lineModeStart) {
if (previousLineModeEnd !== ArrayUtils.assertGet(lines, lineNumber).lineModeStart) {
let currentLine: TLine | undefined = lines[lineNumber];

while (currentLine) {
Expand Down Expand Up @@ -793,7 +793,7 @@ function tokenizeTextLiteralContentOrEnd(line: TLine, currentPosition: number):
function tokenizeDefault(line: TLine, lineNumber: number, positionStart: number, locale: string): LineModeAlteringRead {
const text: string = line.text;

const chr1: string = text[positionStart];
const chr1: string = StringUtils.assertGet(text, positionStart);
let token: Token.LineToken;
let lineMode: LineMode = LineMode.Default;

Expand Down Expand Up @@ -855,7 +855,7 @@ function tokenizeDefault(line: TLine, lineNumber: number, positionStart: number,
} else if ("1" <= chr2 && chr2 <= "9") {
token = readNumericLiteral(text, lineNumber, positionStart, locale);
} else if (chr2 === ".") {
const chr3: string = text[positionStart + 2];
const chr3: string | undefined = text[positionStart + 2];

if (chr3 === ".") {
token = readConstant(Token.LineTokenKind.Ellipsis, text, positionStart, 3);
Expand Down Expand Up @@ -1321,8 +1321,8 @@ function testBadRangeError(state: State, range: Range): LexError.BadRangeError |
const rangeStart: RangePosition = range.start;
const rangeEnd: RangePosition = range.end;

const lineStart: TLine = lines[rangeStart.lineNumber];
const lineEnd: TLine = lines[rangeEnd.lineNumber];
const lineStart: TLine = ArrayUtils.assertGet(lines, rangeStart.lineNumber);
const lineEnd: TLine = ArrayUtils.assertGet(lines, rangeEnd.lineNumber);

if (rangeStart.lineCodeUnit > lineStart.text.length) {
kind = LexError.BadRangeKind.LineCodeUnitStart_GreaterThan_LineLength;
Expand Down
4 changes: 2 additions & 2 deletions src/powerquery-parser/lexer/lexerSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function createSnapshot(state: Lexer.State): LexerSnapshot {
while (flatIndex < numFlatTokens) {
state.cancellationToken?.throwIfCancelled();

const flatToken: FlatLineToken = flatTokens[flatIndex];
const flatToken: FlatLineToken = ArrayUtils.assertGet(flatTokens, flatIndex);
const lineTokenKind: Token.LineTokenKind = flatToken.kind;

switch (lineTokenKind) {
Expand Down Expand Up @@ -553,7 +553,7 @@ function collectWhileContent<KindVariant extends Token.LineTokenKind>(
while (flatIndex < numTokens) {
cancellationToken?.throwIfCancelled();

const token: FlatLineToken = flatTokens[flatIndex];
const token: FlatLineToken = ArrayUtils.assertGet(flatTokens, flatIndex);

if (token.kind !== contentKind) {
break;
Expand Down
2 changes: 1 addition & 1 deletion src/powerquery-parser/parser/context/contextUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ export function deleteContext(state: ParseContext.State, nodeId: number): ParseC
// Not a leaf node.
if (childIds !== undefined) {
ArrayUtils.assertNonZeroLength(childIds);
const childId: number = childIds[0];
const childId: number = ArrayUtils.assertGet(childIds, 0);

// Not a leaf node, is the Root node.
// Promote the child to the root if it's a Context node.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export async function disambiguateParenthesis(
let offsetTokenIndex: number = initialTokenIndex + 1;

while (offsetTokenIndex < totalTokens) {
const offsetTokenKind: Token.TokenKind = tokens[offsetTokenIndex].kind;
const offsetTokenKind: Token.TokenKind = ArrayUtils.assertGet(tokens, offsetTokenIndex).kind;

if (offsetTokenKind === Token.TokenKind.LeftParenthesis) {
nestedDepth += 1;
Expand Down Expand Up @@ -305,7 +305,7 @@ export function disambiguateBracket(
offsetTokenIndex += 1;

while (offsetTokenIndex < totalTokens) {
offsetTokenKind = tokens[offsetTokenIndex].kind;
offsetTokenKind = ArrayUtils.assertGet(tokens, offsetTokenIndex).kind;

if (offsetTokenKind === Token.TokenKind.Equal) {
result = BracketDisambiguation.RecordExpression;
Expand Down Expand Up @@ -472,7 +472,7 @@ function unsafeMoveTo(state: ParseState, tokenIndex: number): void {
state.tokenIndex = tokenIndex;

if (tokenIndex < tokens.length) {
state.currentToken = tokens[tokenIndex];
state.currentToken = ArrayUtils.assertGet(tokens, tokenIndex);
state.currentTokenKind = state.currentToken.kind;
} else {
state.currentToken = undefined;
Expand Down
4 changes: 2 additions & 2 deletions src/powerquery-parser/parser/nodeIdMap/nodeIdMapIterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { Ast, Constant, IdentifierUtils } from "../../language";
import { NodeIdMap, NodeIdMapUtils, TXorNode, XorNodeKind, XorNodeUtils } from ".";
import { Assert } from "../../common";
import { ArrayUtils, Assert } from "../../common";
import { parameterIdentifier } from "./nodeIdMapUtils";
import { XorNode } from "./xorNode";

Expand Down Expand Up @@ -128,7 +128,7 @@ export function nthSiblingXor(
return undefined;
}

return NodeIdMapUtils.xor(nodeIdMapCollection, childIds[attributeIndex]);
return NodeIdMapUtils.xor(nodeIdMapCollection, ArrayUtils.assertGet(childIds, attributeIndex));
}

// ------------------------------------------
Expand Down
Loading
Loading