Skip to content

Commit

Permalink
Merge pull request #44 from rbuckton/deprecatePrex
Browse files Browse the repository at this point in the history
deprecate 'prex' usage in favor of '@esfx/cancelable'
  • Loading branch information
rbuckton authored Apr 10, 2020
2 parents 9d99769 + ad2ef0f commit 878f115
Show file tree
Hide file tree
Showing 34 changed files with 920 additions and 364 deletions.
67 changes: 67 additions & 0 deletions package-lock.json

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

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
"typescript": "^3.8.3"
},
"dependencies": {
"prex": "^0.4.2"
"prex": "^0.4.2",
"@esfx/async-canceltoken": "^1.0.0-pre.13",
"@esfx/cancelable": "^1.0.0-pre.13"
}
}
13 changes: 10 additions & 3 deletions src/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { CancellationToken } from "prex";
import { Cancelable } from "@esfx/cancelable";
import { SyntaxKind } from "./tokens";
import { Symbol, SymbolKind, SymbolTable } from "./symbols";
import { SourceFile, Production, Parameter, Node, Declaration } from "./nodes";
import { toCancelToken } from "./core";

export class BindingTable {
public readonly globals: SymbolTable = new SymbolTable();
Expand Down Expand Up @@ -197,8 +200,12 @@ export class Binder {
private parentNode: Node | undefined;
private parentSymbol: Symbol | undefined;

public bindSourceFile(file: SourceFile, bindings: BindingTable, cancellationToken = CancellationToken.none): void {
cancellationToken.throwIfCancellationRequested();
public bindSourceFile(file: SourceFile, bindings: BindingTable, cancelable?: Cancelable): void;
/** @deprecated since 2.1.0 - `prex.CancellationToken` may no longer be accepted in future releases. Please use a token that implements `@esfx/cancelable.Cancelable` */
public bindSourceFile(file: SourceFile, bindings: BindingTable, cancelable?: CancellationToken | Cancelable): void;
public bindSourceFile(file: SourceFile, bindings: BindingTable, cancelable?: CancellationToken | Cancelable): void {
toCancelToken(cancelable)?.throwIfSignaled();

if (bindings.globals.resolveSymbol(file.filename, SymbolKind.SourceFile)) {
// skip files that have already been bound.
return;
Expand All @@ -220,7 +227,7 @@ export class Binder {

private bindParameter(bindings: BindingTable, scope: SymbolTable, node: Parameter): void {
const symbol = this.declareSymbol(bindings, scope, node.name.text, node, SymbolKind.Parameter);
this.bindChildren(bindings, node, this.parentSymbol, scope);
this.bindChildren(bindings, node, symbol, scope);
}

private bindChildren(bindings: BindingTable, parentNode: Node, parentSymbol: Symbol | undefined, scope: SymbolTable): void {
Expand Down
29 changes: 17 additions & 12 deletions src/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Hash, createHash } from "crypto";

import { createHash } from "crypto";
import { CancellationToken } from "prex";
import { Cancelable } from "@esfx/cancelable";
import { CancelToken } from "@esfx/async-canceltoken";
import { Diagnostics, DiagnosticMessages, Diagnostic, formatList, NullDiagnosticMessages } from "./diagnostics";
import { SyntaxKind, tokenToString } from "./tokens";
import { Symbol, SymbolKind, SymbolTable } from "./symbols";
import { Binder, BindingTable } from "./binder";
import { Symbol, SymbolKind } from "./symbols";
import { BindingTable } from "./binder";
import { StringWriter } from "./stringwriter";
import { CompilerOptions } from "./options";
import {
Expand Down Expand Up @@ -59,8 +62,7 @@ import {
PlaceholderSymbol
} from "./nodes";
import { NodeNavigator } from "./navigator";
import { skipTrivia } from "./scanner";

import { toCancelToken } from "./core";

// TODO: Check a Nonterminal as a call
// TODO: Check all Productions to ensure they have the same parameters.
Expand All @@ -74,24 +76,28 @@ export class Checker {
private noChecks!: boolean;
private noStrictParametricProductions!: boolean;
private productionParametersByName!: Map<Production, Set<string>>;
private cancellationToken!: CancellationToken;
private cancelToken?: CancelToken;

constructor(options?: CompilerOptions) {
this.options = options;
}

public checkSourceFile(sourceFile: SourceFile, bindings: BindingTable, diagnostics: DiagnosticMessages, cancellationToken = CancellationToken.none): void {
cancellationToken.throwIfCancellationRequested();
public checkSourceFile(sourceFile: SourceFile, bindings: BindingTable, diagnostics: DiagnosticMessages, cancelable?: Cancelable): void;
/** @deprecated since 2.1.0 - `prex.CancellationToken` may no longer be accepted in future releases. Please use a token that implements `@esfx/cancelable.Cancelable` */
public checkSourceFile(sourceFile: SourceFile, bindings: BindingTable, diagnostics: DiagnosticMessages, cancelable?: CancellationToken | Cancelable): void;
public checkSourceFile(sourceFile: SourceFile, bindings: BindingTable, diagnostics: DiagnosticMessages, cancelable?: CancellationToken | CancelToken | Cancelable): void {
const cancelToken = toCancelToken(cancelable);
cancelToken?.throwIfSignaled();
if (!this.checkedFileSet.has(sourceFile.filename)) {
const savedNoStrictParametricProductions = this.noStrictParametricProductions;
const savedNoChecks = this.noChecks;
const savedCancellationToken = this.cancellationToken;
const savedCancellationToken = this.cancelToken;
const savedSourceFile = this.sourceFile;
const savedProductionParametersByName = this.productionParametersByName;
const savedBindings = this.bindings;
const savedDiagnostics = this.diagnostics;
try {
this.cancellationToken = cancellationToken;
this.cancelToken = cancelToken;
this.sourceFile = sourceFile;
this.productionParametersByName = new Map<Production, Set<string>>();
this.noStrictParametricProductions = this.options && this.options.noStrictParametricProductions || false;
Expand All @@ -118,7 +124,7 @@ export class Checker {
finally {
this.noStrictParametricProductions = savedNoStrictParametricProductions;
this.noChecks = savedNoChecks;
this.cancellationToken = savedCancellationToken;
this.cancelToken = savedCancellationToken;
this.sourceFile = savedSourceFile;
this.productionParametersByName = savedProductionParametersByName;
this.bindings = savedBindings;
Expand Down Expand Up @@ -1036,7 +1042,6 @@ export class Checker {
const production = <Production>this.bindings.getDeclarations(productionSymbol)[0];
const parameterList = production.parameterList;
const parameterListElements = parameterList && parameterList.elements;
const parameterCount = parameterListElements ? parameterListElements.length : 0;
const argumentList = node.argumentList;
const argumentListElements = argumentList && argumentList.elements;
const nameSet = new Set<string>();
Expand Down
20 changes: 11 additions & 9 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as path from "path";

import * as performance from "./performance";
import { EOL } from "os";
import { readFileSync, writeFileSync } from "fs";
import { Package } from "./read-package";
import { CompilerOptions, EmitFormat, getDefaultOptions, KnownOptions, ParsedArguments, parse, usage, NewLineKind } from "./options";
import { Grammar } from "./grammar";
Expand Down Expand Up @@ -55,7 +54,7 @@ interface ParsedCommandLine extends ParsedArguments, CompilerOptions {
version: boolean;
}

function main(): void {
async function main(): Promise<void> {
const opts = parse<ParsedCommandLine>(knownOptions);
if (!opts || opts.help) {
printUsage();
Expand All @@ -64,7 +63,7 @@ function main(): void {
printVersion();
}
else {
performCompilation(opts);
await performCompilation(opts);
}
}

Expand All @@ -86,7 +85,7 @@ function printVersion(): void {
console.log(node_package.version);
}

function performCompilation(options: ParsedCommandLine): void {
async function performCompilation(options: ParsedCommandLine): Promise<void> {
const compilerOptions = getDefaultOptions();
if (options.out) compilerOptions.out = options.out;
if (options.noChecks) compilerOptions.noChecks = true;
Expand All @@ -101,12 +100,12 @@ function performCompilation(options: ParsedCommandLine): void {

const inputFiles = options.rest;
const grammar = new Grammar(inputFiles, compilerOptions);
grammar.bindSync();
grammar.checkSync();
await grammar.bind();
await grammar.check();

if (!compilerOptions.noEmit) {
if (!compilerOptions.noEmitOnError || grammar.diagnostics.size <= 0) {
grammar.emitSync();
await grammar.emit();
}
}

Expand All @@ -129,4 +128,7 @@ function performCompilation(options: ParsedCommandLine): void {
}
}

main();
main().catch(e => {
console.error(e);
process.exit(-1);
});
60 changes: 60 additions & 0 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
* limitations under the License.
*/

import { CancellationToken } from "prex";
import { Cancelable, CancelSubscription } from "@esfx/cancelable";
import { CancelToken } from "@esfx/async-canceltoken";

// NOTE: grammarkdown requires a minimum of ES5.
if (typeof Object.create !== "function") throw new Error("Grammarkdown requires a minimum host engine of ES5.");

Expand Down Expand Up @@ -292,3 +296,59 @@ function getEnumMembers(enumObject: any): [number, string][] {
}
return enumObject[enumMembers] = stableSort<[number, string]>(result, (x, y) => compare(x[0], y[0]));
}

export function toCancelToken(cancelable: Cancelable | CancellationToken): CancelToken;
export function toCancelToken(cancelable: Cancelable | CancellationToken | null | undefined): CancelToken | undefined;
export function toCancelToken(cancelable: Cancelable | CancellationToken | null | undefined) {
if (Cancelable.hasInstance(cancelable)) {
return CancelToken.from(cancelable);
}
else if (cancelable) {
if (cancelable.cancellationRequested) return CancelToken.canceled;
if (!cancelable.canBeCanceled) return CancelToken.none;
const source = CancelToken.source();
cancelable.register(() => source.cancel());
return source.token;
}
}

export function wrapCancelToken(cancelToken: CancelToken): CancelToken & CancellationToken;
export function wrapCancelToken(cancelToken: CancelToken | undefined): CancelToken & CancellationToken | undefined;
export function wrapCancelToken(cancelToken: CancelToken | undefined) {
if (cancelToken) {
if (!("cancellationRequested" in cancelToken)) {
return Object.create(cancelToken, {
cancellationRequested: {
configurable: true,
get: function (this: CancelToken) { return this.signaled; }
},
canBeCanceled: {
configurable: true,
get: function (this: CancelToken) { return this.canBeSignaled; }
},
throwIfCancellationRequested: {
configurable: true,
writable: true,
value: CancelToken.prototype.throwIfSignaled
},
register: {
configurable: true,
writable: true,
value: function (this: CancelToken, callback: () => void) {
const subscription = this.subscribe(callback);
return Object.create(subscription, {
unregister: {
configurable: true,
writable: true,
value: function(this: CancelSubscription) {
this.unsubscribe();
}
}
});
}
}
});
}
}
return cancelToken;
}
11 changes: 1 addition & 10 deletions src/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { binarySearch, compareStrings, compare, Range, Position } from "./core";
import { CharacterCodes, SyntaxKind, tokenToString } from "./tokens";
import { Node, SourceFile } from "./nodes";
import { skipTrivia } from "./scanner";

export interface Diagnostic {
code: number;
Expand Down Expand Up @@ -360,7 +360,6 @@ export class DiagnosticMessages {
if (indices.length <= 1) {
return indices;
}
const numIndices = indices.length;
const firstDiagnosticIndex = indices[0];
const newIndices: number[] = [firstDiagnosticIndex];
let previousDiagnosticIndex = firstDiagnosticIndex;
Expand Down Expand Up @@ -547,14 +546,6 @@ export class LineMap {
lineStarts.push(lineStart);
this.lineStarts = lineStarts;
}

private isLineBreak(ch: number): boolean {
return ch === CharacterCodes.CarriageReturn
|| ch === CharacterCodes.LineFeed
|| ch === CharacterCodes.LineSeparator
|| ch === CharacterCodes.ParagraphSeparator
|| ch === CharacterCodes.NextLine;
}
}

function getDiagnosticRange(diagnosticNode: Node | undefined, diagnosticPos: number, sourceFile: SourceFile | undefined): Range {
Expand Down
Loading

0 comments on commit 878f115

Please sign in to comment.