Migrate from tslint to eslint for linting (#1905)

This commit is contained in:
Kitson Kelly 2019-03-10 04:30:38 +11:00 committed by Ryan Dahl
parent 8c7a12d1b2
commit 034e2cc028
90 changed files with 1041 additions and 1104 deletions

3
.eslintignore Normal file
View File

@ -0,0 +1,3 @@
/js/deps/
/js/gen/
/tests/error_syntax.js

23
.eslintrc.json Normal file
View File

@ -0,0 +1,23 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": ["@typescript-eslint"],
"extends": [
"plugin:@typescript-eslint/recommended",
"prettier",
"prettier/@typescript-eslint"
],
"rules": {
"@typescript-eslint/array-type": ["error", "array-simple"],
"@typescript-eslint/explicit-member-accessibility": ["off"],
"@typescript-eslint/no-non-null-assertion": ["off"],
"@typescript-eslint/no-parameter-properties": ["off"],
"@typescript-eslint/no-unused-vars": [
"error",
{ "argsIgnorePattern": "^_" }
]
}
}

View File

@ -39,6 +39,20 @@ function createResolvable() {
return Object.assign(promise, methods);
}
function setRecord(i, off, value) {
if (i >= NUM_RECORDS) {
throw Error("out of range");
}
shared32[INDEX_RECORDS + RECORD_SIZE * i + off] = value;
}
function getRecord(i, off) {
if (i >= NUM_RECORDS) {
throw Error("out of range");
}
return shared32[INDEX_RECORDS + RECORD_SIZE * i + off];
}
/** Returns Promise<number> */
function sendAsync(op, arg, zeroCopyData) {
const id = nextPromiseId++;
@ -64,20 +78,6 @@ function sendSync(op, arg) {
return getRecord(0, RECORD_OFFSET_RESULT);
}
function setRecord(i, off, value) {
if (i >= NUM_RECORDS) {
throw Error("out of range");
}
shared32[INDEX_RECORDS + RECORD_SIZE * i + off] = value;
}
function getRecord(i, off) {
if (i >= NUM_RECORDS) {
throw Error("out of range");
}
return shared32[INDEX_RECORDS + RECORD_SIZE * i + off];
}
function handleAsyncMsgFromRust() {
for (let i = 0; i < shared32[INDEX_NUM_RECORDS]; i++) {
let id = getRecord(i, RECORD_OFFSET_PROMISE_ID);
@ -134,10 +134,10 @@ async function main() {
libdeno.print("http_bench.js start");
const listener_rid = listen();
libdeno.print(`listening http://127.0.0.1:4544/ rid = ${listener_rid}`);
const listenerRid = listen();
libdeno.print(`listening http://127.0.0.1:4544/ rid = ${listenerRid}`);
while (true) {
const rid = await accept(listener_rid);
const rid = await accept(listenerRid);
// libdeno.print(`accepted ${rid}`);
if (rid < 0) {
libdeno.print(`accept error ${rid}`);

View File

@ -1,10 +1,9 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
// tslint:disable-next-line:no-reference
// eslint-disable-next-line @typescript-eslint/no-triple-slash-reference
/// <reference path="./plugins.d.ts" />
// There is a rollup plugin that will inline any module ending with `!string`
// tslint:disable:max-line-length
// Generated default library
import libDts from "gen/lib/lib.deno_runtime.d.ts!string";
@ -39,7 +38,6 @@ import libEsnextBigintDts from "/third_party/node_modules/typescript/lib/lib.esn
import libEsnextDts from "/third_party/node_modules/typescript/lib/lib.esnext.d.ts!string";
import libEsnextIntlDts from "/third_party/node_modules/typescript/lib/lib.esnext.intl.d.ts!string";
import libEsnextSymbolDts from "/third_party/node_modules/typescript/lib/lib.esnext.symbol.d.ts!string";
// tslint:enable:max-line-length
// @internal
export const assetSourceCode: { [key: string]: string } = {

View File

@ -5,6 +5,75 @@ import { TextEncoder } from "./text_encoding";
export const bytesSymbol = Symbol("bytes");
function convertLineEndingsToNative(s: string): string {
// TODO(qti3e) Implement convertLineEndingsToNative.
// https://w3c.github.io/FileAPI/#convert-line-endings-to-native
return s;
}
function toUint8Arrays(
blobParts: domTypes.BlobPart[],
doNormalizeLineEndingsToNative: boolean
): Uint8Array[] {
const ret: Uint8Array[] = [];
const enc = new TextEncoder();
for (const element of blobParts) {
if (typeof element === "string") {
let str = element;
if (doNormalizeLineEndingsToNative) {
str = convertLineEndingsToNative(element);
}
ret.push(enc.encode(str));
// eslint-disable-next-line @typescript-eslint/no-use-before-define
} else if (element instanceof DenoBlob) {
ret.push(element[bytesSymbol]);
} else if (element instanceof Uint8Array) {
ret.push(element);
} else if (element instanceof Uint16Array) {
const uint8 = new Uint8Array(element.buffer);
ret.push(uint8);
} else if (element instanceof Uint32Array) {
const uint8 = new Uint8Array(element.buffer);
ret.push(uint8);
} else if (ArrayBuffer.isView(element)) {
// Convert view to Uint8Array.
const uint8 = new Uint8Array(element.buffer);
ret.push(uint8);
} else if (element instanceof ArrayBuffer) {
// Create a new Uint8Array view for the given ArrayBuffer.
const uint8 = new Uint8Array(element);
ret.push(uint8);
} else {
ret.push(enc.encode(String(element)));
}
}
return ret;
}
function processBlobParts(
blobParts: domTypes.BlobPart[],
options: domTypes.BlobPropertyBag
): Uint8Array {
const normalizeLineEndingsToNative = options.ending === "native";
// ArrayBuffer.transfer is not yet implemented in V8, so we just have to
// pre compute size of the array buffer and do some sort of static allocation
// instead of dynamic allocation.
const uint8Arrays = toUint8Arrays(blobParts, normalizeLineEndingsToNative);
const byteLength = uint8Arrays
.map(u8 => u8.byteLength)
.reduce((a, b) => a + b, 0);
const ab = new ArrayBuffer(byteLength);
const bytes = new Uint8Array(ab);
let courser = 0;
for (const u8 of uint8Arrays) {
bytes.set(u8, courser);
courser += u8.byteLength;
}
return bytes;
}
export class DenoBlob implements domTypes.Blob {
private readonly [bytesSymbol]: Uint8Array;
readonly size: number = 0;
@ -56,71 +125,3 @@ export class DenoBlob implements domTypes.Blob {
});
}
}
function processBlobParts(
blobParts: domTypes.BlobPart[],
options: domTypes.BlobPropertyBag
): Uint8Array {
const normalizeLineEndingsToNative = options.ending === "native";
// ArrayBuffer.transfer is not yet implemented in V8, so we just have to
// pre compute size of the array buffer and do some sort of static allocation
// instead of dynamic allocation.
const uint8Arrays = toUint8Arrays(blobParts, normalizeLineEndingsToNative);
const byteLength = uint8Arrays
.map(u8 => u8.byteLength)
.reduce((a, b) => a + b, 0);
const ab = new ArrayBuffer(byteLength);
const bytes = new Uint8Array(ab);
let courser = 0;
for (const u8 of uint8Arrays) {
bytes.set(u8, courser);
courser += u8.byteLength;
}
return bytes;
}
function toUint8Arrays(
blobParts: domTypes.BlobPart[],
doNormalizeLineEndingsToNative: boolean
): Uint8Array[] {
const ret: Uint8Array[] = [];
const enc = new TextEncoder();
for (const element of blobParts) {
if (typeof element === "string") {
let str = element;
if (doNormalizeLineEndingsToNative) {
str = convertLineEndingsToNative(element);
}
ret.push(enc.encode(str));
} else if (element instanceof DenoBlob) {
ret.push(element[bytesSymbol]);
} else if (element instanceof Uint8Array) {
ret.push(element);
} else if (element instanceof Uint16Array) {
const uint8 = new Uint8Array(element.buffer);
ret.push(uint8);
} else if (element instanceof Uint32Array) {
const uint8 = new Uint8Array(element.buffer);
ret.push(uint8);
} else if (ArrayBuffer.isView(element)) {
// Convert view to Uint8Array.
const uint8 = new Uint8Array(element.buffer);
ret.push(uint8);
} else if (element instanceof ArrayBuffer) {
// Create a new Uint8Array view for the given ArrayBuffer.
const uint8 = new Uint8Array(element);
ret.push(uint8);
} else {
ret.push(enc.encode(String(element)));
}
}
return ret;
}
function convertLineEndingsToNative(s: string): string {
// TODO(qti3e) Implement convertLineEndingsToNative.
// https://w3c.github.io/FileAPI/#convert-line-endings-to-native
return s;
}

View File

@ -66,14 +66,14 @@ export class Buffer implements Reader, Writer {
}
/** empty() returns whether the unread portion of the buffer is empty. */
empty() {
empty(): boolean {
return this.buf.byteLength <= this.off;
}
/** length is a getter that returns the number of bytes of the unread
* portion of the buffer
*/
get length() {
get length(): number {
return this.buf.byteLength - this.off;
}

View File

@ -13,7 +13,7 @@ const N = 100;
let testBytes: Uint8Array | null;
let testString: string | null;
function init() {
function init(): void {
if (testBytes == null) {
testBytes = new Uint8Array(N);
for (let i = 0; i < N; i++) {
@ -24,7 +24,7 @@ function init() {
}
}
function check(buf: Deno.Buffer, s: string) {
function check(buf: Deno.Buffer, s: string): void {
const bytes = buf.bytes();
assertEquals(buf.length, bytes.byteLength);
const decoder = new TextDecoder();
@ -69,6 +69,13 @@ async function empty(buf: Buffer, s: string, fub: Uint8Array): Promise<void> {
check(buf, "");
}
function repeat(c: string, bytes: number): Uint8Array {
assertEquals(c.length, 1);
const ui8 = new Uint8Array(bytes);
ui8.fill(c.charCodeAt(0));
return ui8;
}
test(function bufferNewBuffer() {
init();
const buf = new Buffer(testBytes.buffer as ArrayBuffer);
@ -140,7 +147,7 @@ test(async function bufferTooLargeByteWrites() {
const growLen = Number.MAX_VALUE;
const xBytes = repeat("x", 0);
const buf = new Buffer(xBytes.buffer as ArrayBuffer);
const { nread, eof } = await buf.read(tmp);
await buf.read(tmp);
let err;
try {
@ -186,13 +193,6 @@ test(async function bufferReadFrom() {
}
});
function repeat(c: string, bytes: number): Uint8Array {
assertEquals(c.length, 1);
const ui8 = new Uint8Array(bytes);
ui8.fill(c.charCodeAt(0));
return ui8;
}
test(async function bufferTestGrow() {
const tmp = new Uint8Array(72);
for (let startLen of [0, 100, 1000, 10000, 100000]) {
@ -200,7 +200,7 @@ test(async function bufferTestGrow() {
for (let growLen of [0, 100, 1000, 10000, 100000]) {
const buf = new Buffer(xBytes.buffer as ArrayBuffer);
// If we read, this affects buf.off, which is good to test.
const { nread, eof } = await buf.read(tmp);
const { nread } = await buf.read(tmp);
buf.grow(growLen);
const yBytes = repeat("y", growLen);
await buf.write(yBytes);

View File

@ -15,12 +15,12 @@ export interface BuildInfo {
// 'build' is injected by rollup.config.js at compile time.
export const build: BuildInfo = {
// tslint:disable:no-any
/* eslint-disable @typescript-eslint/no-explicit-any */
// These string will be replaced by rollup
arch: `ROLLUP_REPLACE_ARCH` as any,
os: `ROLLUP_REPLACE_OS` as any,
gnArgs: `ROLLUP_REPLACE_GN_ARGS`
// tslint:disable:any
/* eslint-enable @typescript-eslint/no-explicit-any */
};
// TODO(kevinkassimo): deprecate Deno.platform

View File

@ -3,6 +3,19 @@ import * as msg from "gen/msg_generated";
import * as flatbuffers from "./flatbuffers";
import * as dispatch from "./dispatch";
function req(
path: string,
mode: number
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const path_ = builder.createString(path);
msg.Chmod.startChmod(builder);
msg.Chmod.addPath(builder, path_);
msg.Chmod.addMode(builder, mode);
const inner = msg.Chmod.endChmod(builder);
return [builder, msg.Any.Chmod, inner];
}
/** Changes the permission of a specific file/directory of specified path
* synchronously.
*
@ -19,16 +32,3 @@ export function chmodSync(path: string, mode: number): void {
export async function chmod(path: string, mode: number): Promise<void> {
await dispatch.sendAsync(...req(path, mode));
}
function req(
path: string,
mode: number
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const path_ = builder.createString(path);
msg.Chmod.startChmod(builder);
msg.Chmod.addPath(builder, path_);
msg.Chmod.addMode(builder, mode);
const inner = msg.Chmod.endChmod(builder);
return [builder, msg.Any.Chmod, inner];
}

View File

@ -61,7 +61,6 @@ interface Os {
*/
interface Ts {
createLanguageService: typeof ts.createLanguageService;
/* tslint:disable-next-line:max-line-length */
formatDiagnosticsWithColorAndContext: typeof ts.formatDiagnosticsWithColorAndContext;
formatDiagnostics: typeof ts.formatDiagnostics;
}
@ -529,7 +528,6 @@ window.compilerMain = function compilerMain() {
};
};
/* tslint:disable-next-line:no-default-export */
export default function denoMain() {
export default function denoMain(): void {
os.start("TS");
}

View File

@ -2,7 +2,8 @@
import { test, assert, assertEquals } from "./test_util.ts";
// We use a silly amount of `any` in these tests...
// tslint:disable:no-any
/* eslint-disable @typescript-eslint/no-explicit-any */
const { Compiler, jsonEsmTemplate } = (Deno as any)._compiler;
@ -106,7 +107,6 @@ const modBModuleInfo = mockModuleInfo(
undefined
);
// tslint:disable:max-line-length
const fooBarTsOutput = `import * as deno from "deno";
console.log(deno);
export const foo = "bar";
@ -119,7 +119,6 @@ const loadConfigSource = `import * as config from "./config.json";
console.log(config.foo.baz);
`;
const configJsonSource = `{"foo":{"bar": true,"baz": ["qat", 1]}}`;
// tslint:enable:max-line-length
const moduleMap: {
[containFile: string]: { [moduleSpecifier: string]: ModuleInfo };
@ -244,10 +243,6 @@ const moduleCache: {
"/root/project/modB.ts": modBModuleInfo
};
const emittedFiles = {
"/root/project/foo/qat.ts": "console.log('foo');"
};
let getEmitOutputStack: string[] = [];
let logStack: any[][] = [];
let codeCacheStack: Array<{
@ -351,7 +346,7 @@ const mocks = {
/**
* Setup the mocks for a test
*/
function setup() {
function setup(): void {
// monkey patch mocks on instance
Object.assign(compilerInstance, mocks);
}
@ -359,7 +354,7 @@ function setup() {
/**
* Teardown the mocks for a test
*/
function teardown() {
function teardown(): void {
// reset compiler internal state
(compilerInstance as any)._moduleMetaDataMap.clear();
(compilerInstance as any)._fileNamesMap.clear();

View File

@ -33,12 +33,14 @@ export class CSI {
static kClearScreenDown = "\x1b[0J";
}
function cursorTo(stream: File, x: number, y?: number) {
/* eslint-disable @typescript-eslint/no-use-before-define */
function cursorTo(stream: File, _x: number, _y?: number): void {
const uint8 = new TextEncoder().encode(CSI.kClear);
stream.write(uint8);
}
function clearScreenDown(stream: File) {
function clearScreenDown(stream: File): void {
const uint8 = new TextEncoder().encode(CSI.kClearScreenDown);
stream.write(uint8);
}
@ -56,7 +58,7 @@ function getClassInstanceName(instance: unknown): string {
return "";
}
function createFunctionString(value: Function, ctx: ConsoleContext): string {
function createFunctionString(value: Function, _ctx: ConsoleContext): string {
// Might be Function/AsyncFunction/GeneratorFunction
const cstrName = Object.getPrototypeOf(value).constructor.name;
if (value.name && value.name !== "anonymous") {
@ -103,6 +105,54 @@ function createIterableString<T>(
return `${iPrefix}${config.delims[0]}${iContent}${config.delims[1]}`;
}
function stringify(
value: unknown,
ctx: ConsoleContext,
level: number,
maxLevel: number
): string {
switch (typeof value) {
case "string":
return value;
case "number":
case "boolean":
case "undefined":
case "symbol":
return String(value);
case "bigint":
return `${value}n`;
case "function":
return createFunctionString(value as Function, ctx);
case "object":
if (value === null) {
return "null";
}
if (ctx.has(value)) {
return "[Circular]";
}
return createObjectString(value, ctx, level, maxLevel);
default:
return "[Not Implemented]";
}
}
// Print strings when they are inside of arrays or objects with quotes
function stringifyWithQuotes(
value: unknown,
ctx: ConsoleContext,
level: number,
maxLevel: number
): string {
switch (typeof value) {
case "string":
return `"${value}"`;
default:
return stringify(value, ctx, level, maxLevel);
}
}
function createArrayString(
value: unknown[],
ctx: ConsoleContext,
@ -183,30 +233,31 @@ function createWeakMapString(): string {
return "WeakMap { [items unknown] }"; // as seen in Node
}
function createDateString(value: Date) {
function createDateString(value: Date): string {
// without quotes, ISO format
return value.toISOString();
}
function createRegExpString(value: RegExp) {
function createRegExpString(value: RegExp): string {
return value.toString();
}
// tslint:disable-next-line:ban-types
function createStringWrapperString(value: String) {
/* eslint-disable @typescript-eslint/ban-types */
function createStringWrapperString(value: String): string {
return `[String: "${value.toString()}"]`;
}
// tslint:disable-next-line:ban-types
function createBooleanWrapperString(value: Boolean) {
function createBooleanWrapperString(value: Boolean): string {
return `[Boolean: ${value.toString()}]`;
}
// tslint:disable-next-line:ban-types
function createNumberWrapperString(value: Number) {
function createNumberWrapperString(value: Number): string {
return `[Number: ${value.toString()}]`;
}
/* eslint-enable @typescript-eslint/ban-types */
// TODO: Promise, requires v8 bindings to get info
// TODO: Proxy
@ -261,22 +312,19 @@ function createObjectString(
} else if (Array.isArray(value)) {
return createArrayString(value, ...args);
} else if (value instanceof Number) {
// tslint:disable-next-line:ban-types
return createNumberWrapperString(value as Number);
return createNumberWrapperString(value);
} else if (value instanceof Boolean) {
// tslint:disable-next-line:ban-types
return createBooleanWrapperString(value as Boolean);
return createBooleanWrapperString(value);
} else if (value instanceof String) {
// tslint:disable-next-line:ban-types
return createStringWrapperString(value as String);
return createStringWrapperString(value);
} else if (value instanceof RegExp) {
return createRegExpString(value as RegExp);
return createRegExpString(value);
} else if (value instanceof Date) {
return createDateString(value as Date);
return createDateString(value);
} else if (value instanceof Set) {
return createSetString(value as Set<unknown>, ...args);
return createSetString(value, ...args);
} else if (value instanceof Map) {
return createMapString(value as Map<unknown, unknown>, ...args);
return createMapString(value, ...args);
} else if (value instanceof WeakSet) {
return createWeakSetString();
} else if (value instanceof WeakMap) {
@ -293,54 +341,6 @@ function createObjectString(
}
}
function stringify(
value: unknown,
ctx: ConsoleContext,
level: number,
maxLevel: number
): string {
switch (typeof value) {
case "string":
return value;
case "number":
case "boolean":
case "undefined":
case "symbol":
return String(value);
case "bigint":
return `${value}n`;
case "function":
return createFunctionString(value as Function, ctx);
case "object":
if (value === null) {
return "null";
}
if (ctx.has(value)) {
return "[Circular]";
}
return createObjectString(value, ctx, level, maxLevel);
default:
return "[Not Implemented]";
}
}
// Print strings when they are inside of arrays or objects with quotes
function stringifyWithQuotes(
value: unknown,
ctx: ConsoleContext,
level: number,
maxLevel: number
): string {
switch (typeof value) {
case "string":
return `"${value}"`;
default:
return stringify(value, ctx, level, maxLevel);
}
}
/** TODO Do not expose this from "deno" namespace.
* @internal
*/
@ -394,7 +394,6 @@ export function stringifyArgs(
args[++a],
new Set<unknown>(),
0,
// tslint:disable-next-line:triple-equals
options.depth != undefined ? options.depth : DEFAULT_MAX_DEPTH
);
break;
@ -443,7 +442,6 @@ export function stringifyArgs(
value,
new Set<unknown>(),
0,
// tslint:disable-next-line:triple-equals
options.depth != undefined ? options.depth : DEFAULT_MAX_DEPTH
);
}
@ -581,9 +579,9 @@ export class Console {
const indexKeys: string[] = [];
const values: string[] = [];
const stringifyValue = (value: unknown) =>
const stringifyValue = (value: unknown): string =>
stringifyWithQuotes(value, new Set<unknown>(), 0, 1);
const toTable = (header: string[], body: string[][]) =>
const toTable = (header: string[], body: string[][]): void =>
this.log(cliTable(header, body));
const createColumn = (value: unknown, shift?: number): string[] => [
...(shift ? [...new Array(shift)].map(() => "") : []),
@ -725,7 +723,7 @@ export class Console {
* inspect() converts input into string that has the same format
* as printed by console.log(...);
*/
export function inspect(value: unknown, options?: ConsoleOptions) {
export function inspect(value: unknown, options?: ConsoleOptions): string {
const opts = options || {};
if (typeof value === "string") {
return value;
@ -734,7 +732,6 @@ export function inspect(value: unknown, options?: ConsoleOptions) {
value,
new Set<unknown>(),
0,
// tslint:disable-next-line:triple-equals
opts.depth != undefined ? opts.depth : DEFAULT_MAX_DEPTH
);
}

View File

@ -51,7 +51,7 @@ function renderRow(row: string[], columnWidths: number[]): string {
}
export function cliTable(head: string[], columns: string[][]): string {
const rows = [];
const rows: string[][] = [];
const columnWidths = head.map((h: string) => countBytes(h));
const longestColumn = columns.reduce(
(n: number, a: string[]) => Math.max(n, a.length),
@ -64,10 +64,7 @@ export function cliTable(head: string[], columns: string[][]): string {
if (rows[j] === undefined) {
rows[j] = [];
}
// tslint:disable-next-line:no-any
const value = ((rows[j][i] as any) = column.hasOwnProperty(j)
? column[j]
: "");
const value = (rows[j][i] = column.hasOwnProperty(j) ? column[j] : "");
const width = columnWidths[i] || 0;
const counted = countBytes(value);
columnWidths[i] = Math.max(width, counted);

View File

@ -3,13 +3,12 @@ import { assert, assertEquals, test } from "./test_util.ts";
// Some of these APIs aren't exposed in the types and so we have to cast to any
// in order to "trick" TypeScript.
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { Console, libdeno, stringifyArgs, inspect, write, stdout } = Deno as any;
const console = new Console(libdeno.print);
// tslint:disable-next-line:no-any
function stringify(...args: any[]): string {
function stringify(...args: unknown[]): string {
return stringifyArgs(args).replace(/\n$/, "");
}
@ -35,15 +34,15 @@ test(function consoleTestStringifyComplexObjects() {
test(function consoleTestStringifyCircular() {
class Base {
a = 1;
m1() {}
m1(): void {}
}
class Extended extends Base {
b = 2;
m2() {}
m2(): void {}
}
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const nestedObj: any = {
num: 1,
bool: true,
@ -73,18 +72,14 @@ test(function consoleTestStringifyCircular() {
};
nestedObj.o = circularObj;
// tslint:disable-next-line:max-line-length
const nestedObjExpected = `{ num: 1, bool: true, str: "a", method: [Function: method], asyncMethod: [AsyncFunction: asyncMethod], generatorMethod: [GeneratorFunction: generatorMethod], un: undefined, nu: null, arrowFunc: [Function: arrowFunc], extendedClass: Extended { a: 1, b: 2 }, nFunc: [Function], extendedCstr: [Function: Extended], o: { num: 2, bool: false, str: "b", method: [Function: method], un: undefined, nu: null, nested: [Circular], emptyObj: {}, arr: [ 1, "s", false, null, [Circular] ], baseClass: Base { a: 1 } } }`;
assertEquals(stringify(1), "1");
assertEquals(stringify(1n), "1n");
assertEquals(stringify("s"), "s");
assertEquals(stringify(false), "false");
// tslint:disable-next-line:no-construct
assertEquals(stringify(new Number(1)), "[Number: 1]");
// tslint:disable-next-line:no-construct
assertEquals(stringify(new Boolean(true)), "[Boolean: true]");
// tslint:disable-next-line:no-construct
assertEquals(stringify(new String("deno")), `[String: "deno"]`);
assertEquals(stringify(/[0-9]*/), "/[0-9]*/");
assertEquals(
@ -119,7 +114,6 @@ test(function consoleTestStringifyCircular() {
assertEquals(stringify(JSON), "{}");
assertEquals(
stringify(console),
// tslint:disable-next-line:max-line-length
"Console { printFunc: [Function], log: [Function], debug: [Function], info: [Function], dir: [Function], warn: [Function], error: [Function], assert: [Function], count: [Function], countReset: [Function], table: [Function], time: [Function], timeLog: [Function], timeEnd: [Function], group: [Function], groupCollapsed: [Function], groupEnd: [Function], clear: [Function], indentLevel: 0, collapsedAt: null }"
);
// test inspect is working the same
@ -127,7 +121,7 @@ test(function consoleTestStringifyCircular() {
});
test(function consoleTestStringifyWithDepth() {
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const nestedObj: any = { a: { b: { c: { d: { e: { f: 42 } } } } } };
assertEquals(
stringifyArgs([nestedObj], { depth: 3 }),
@ -313,22 +307,23 @@ test(function consoleDetachedLog() {
class StringBuffer {
chunks: string[] = [];
add(x: string) {
add(x: string): void {
this.chunks.push(x);
}
toString() {
toString(): string {
return this.chunks.join("");
}
}
type ConsoleExamineFunc = (
csl: any, // tslint:disable-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
csl: any,
out: StringBuffer,
err?: StringBuffer,
both?: StringBuffer
) => void;
function mockConsole(f: ConsoleExamineFunc) {
function mockConsole(f: ConsoleExamineFunc): void {
const out = new StringBuffer();
const err = new StringBuffer();
const both = new StringBuffer();

View File

@ -3,6 +3,20 @@ import * as msg from "gen/msg_generated";
import * as flatbuffers from "./flatbuffers";
import * as dispatch from "./dispatch";
function req(
from: string,
to: string
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const from_ = builder.createString(from);
const to_ = builder.createString(to);
msg.CopyFile.startCopyFile(builder);
msg.CopyFile.addFrom(builder, from_);
msg.CopyFile.addTo(builder, to_);
const inner = msg.CopyFile.endCopyFile(builder);
return [builder, msg.Any.CopyFile, inner];
}
/** Copies the contents of a file to another by name synchronously.
* Creates a new file if target does not exists, and if target exists,
* overwrites original content of the target file.
@ -29,17 +43,3 @@ export function copyFileSync(from: string, to: string): void {
export async function copyFile(from: string, to: string): Promise<void> {
await dispatch.sendAsync(...req(from, to));
}
function req(
from: string,
to: string
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const from_ = builder.createString(from);
const to_ = builder.createString(to);
msg.CopyFile.startCopyFile(builder);
msg.CopyFile.addFrom(builder, from_);
msg.CopyFile.addTo(builder, to_);
const inner = msg.CopyFile.endCopyFile(builder);
return [builder, msg.Any.CopyFile, inner];
}

View File

@ -7,13 +7,13 @@ function readFileString(filename: string): string {
return dec.decode(dataRead);
}
function writeFileString(filename: string, s: string) {
function writeFileString(filename: string, s: string): void {
const enc = new TextEncoder();
const data = enc.encode(s);
Deno.writeFileSync(filename, data, { perm: 0o666 });
}
function assertSameContent(filename1: string, filename2: string) {
function assertSameContent(filename1: string, filename2: string): void {
const data1 = Deno.readFileSync(filename1);
const data2 = Deno.readFileSync(filename2);
assertEquals(data1, data2);

View File

@ -4,13 +4,12 @@ import * as event from "./event";
import { getPrivateValue } from "./util";
// WeakMaps are recommended for private attributes (see MDN link below)
// tslint:disable-next-line:max-line-length
// https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/Guides/Contributor_s_Guide/Private_Properties#Using_WeakMaps
export const customEventAttributes = new WeakMap();
export class CustomEventInit extends event.EventInit
implements domTypes.CustomEventInit {
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
detail: any;
constructor({
@ -34,7 +33,7 @@ export class CustomEvent extends event.Event implements domTypes.CustomEvent {
customEventAttributes.set(this, { detail });
}
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
get detail(): any {
return getPrivateValue(this, customEventAttributes, "detail");
}
@ -43,9 +42,9 @@ export class CustomEvent extends event.Event implements domTypes.CustomEvent {
type: string,
bubbles?: boolean,
cancelable?: boolean,
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
detail?: any
) {
): void {
if (this.dispatched) {
return;
}

View File

@ -10,11 +10,11 @@ const promiseTable = new Map<number, util.Resolvable<msg.Base>>();
let fireTimers: () => void;
export function setFireTimersCallback(fn: () => void) {
export function setFireTimersCallback(fn: () => void): void {
fireTimers = fn;
}
export function handleAsyncMsgFromRust(ui8: Uint8Array) {
export function handleAsyncMsgFromRust(ui8: Uint8Array): void {
// If a the buffer is empty, recv() on the native side timed out and we
// did not receive a message.
if (ui8 && ui8.length) {
@ -35,6 +35,25 @@ export function handleAsyncMsgFromRust(ui8: Uint8Array) {
fireTimers();
}
function sendInternal(
builder: flatbuffers.Builder,
innerType: msg.Any,
inner: flatbuffers.Offset,
data: undefined | ArrayBufferView,
sync = true
): [number, null | Uint8Array] {
const cmdId = nextCmdId++;
msg.Base.startBase(builder);
msg.Base.addInner(builder, inner);
msg.Base.addInnerType(builder, innerType);
msg.Base.addSync(builder, sync);
msg.Base.addCmdId(builder, cmdId);
builder.finish(msg.Base.endBase(builder));
const res = libdeno.send(builder.asUint8Array(), data);
builder.inUse = false;
return [cmdId, res];
}
// @internal
export function sendAsync(
builder: flatbuffers.Builder,
@ -68,22 +87,3 @@ export function sendSync(
return baseRes;
}
}
function sendInternal(
builder: flatbuffers.Builder,
innerType: msg.Any,
inner: flatbuffers.Offset,
data: undefined | ArrayBufferView,
sync = true
): [number, null | Uint8Array] {
const cmdId = nextCmdId++;
msg.Base.startBase(builder);
msg.Base.addInner(builder, inner);
msg.Base.addInnerType(builder, innerType);
msg.Base.addSync(builder, sync);
msg.Base.addCmdId(builder, cmdId);
builder.finish(msg.Base.endBase(builder));
const res = libdeno.send(builder.asUint8Array(), data);
builder.inUse = false;
return [cmdId, res];
}

View File

@ -15,6 +15,8 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
*******************************************************************************/
/* eslint-disable @typescript-eslint/no-explicit-any */
export type BufferSource = ArrayBufferView | ArrayBuffer;
export type HeadersInit =
@ -50,7 +52,6 @@ export interface DomIterable<K, V> {
[Symbol.iterator](): IterableIterator<[K, V]>;
forEach(
callback: (value: V, key: K, parent: this) => void,
// tslint:disable-next-line:no-any
thisArg?: any
): void;
}
@ -129,7 +130,6 @@ export interface URLSearchParams {
*/
forEach(
callbackfn: (value: string, key: string, parent: URLSearchParams) => void,
// tslint:disable-next-line:no-any
thisArg?: any
): void;
}
@ -145,7 +145,6 @@ export interface EventInit {
}
export interface CustomEventInit extends EventInit {
// tslint:disable-next-line:no-any
detail?: any;
}
@ -188,13 +187,11 @@ export interface Event {
}
export interface CustomEvent extends Event {
// tslint:disable-next-line:no-any
readonly detail: any;
initCustomEvent(
type: string,
bubbles?: boolean,
cancelable?: boolean,
// tslint:disable-next-line:no-any
detail?: any | null
): void;
}
@ -228,11 +225,9 @@ export interface AddEventListenerOptions extends EventListenerOptions {
interface AbortSignal extends EventTarget {
readonly aborted: boolean;
// tslint:disable-next-line:no-any
onabort: ((this: AbortSignal, ev: ProgressEvent) => any) | null;
addEventListener<K extends keyof AbortSignalEventMap>(
type: K,
// tslint:disable-next-line:no-any
listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any,
options?: boolean | AddEventListenerOptions
): void;
@ -243,7 +238,6 @@ interface AbortSignal extends EventTarget {
): void;
removeEventListener<K extends keyof AbortSignalEventMap>(
type: K,
// tslint:disable-next-line:no-any
listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any,
options?: boolean | EventListenerOptions
): void;
@ -266,7 +260,6 @@ export interface EventListenerObject {
export interface ReadableStreamReader {
cancel(): Promise<void>;
// tslint:disable-next-line:no-any
read(): Promise<any>;
releaseLock(): void;
}
@ -321,7 +314,6 @@ export interface Body {
/** Takes a `Response` stream and reads it to completion. It returns a promise
* that resolves with the result of parsing the body text as JSON.
*/
// tslint:disable-next-line:no-any
json(): Promise<any>;
/** Takes a `Response` stream and reads it to completion. It returns a promise
* that resolves with a `USVString` (text).
@ -363,7 +355,6 @@ export interface Headers extends DomIterable<string, string> {
values(): IterableIterator<string>;
forEach(
callbackfn: (value: string, key: string, parent: this) => void,
// tslint:disable-next-line:no-any
thisArg?: any
): void;
/** The Symbol.iterator well-known symbol specifies the default
@ -427,7 +418,6 @@ export interface RequestInit {
referrer?: string;
referrerPolicy?: ReferrerPolicy;
signal?: AbortSignal | null;
// tslint:disable-next-line:no-any
window?: any;
}

View File

@ -24,14 +24,6 @@ export class DenoError<T extends ErrorKind> extends Error {
}
}
// @internal
export function maybeThrowError(base: Base): void {
const err = maybeError(base);
if (err != null) {
throw err;
}
}
// @internal
export function maybeError(base: Base): null | DenoError<ErrorKind> {
const kind = base.errorKind();
@ -41,3 +33,11 @@ export function maybeError(base: Base): null | DenoError<ErrorKind> {
return new DenoError(kind, base.error()!);
}
}
// @internal
export function maybeThrowError(base: Base): void {
const err = maybeError(base);
if (err != null) {
throw err;
}
}

View File

@ -3,7 +3,6 @@ import * as domTypes from "./dom_types";
import { getPrivateValue } from "./util";
// WeakMaps are recommended for private attributes (see MDN link below)
// tslint:disable-next-line:max-line-length
// https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/Guides/Contributor_s_Guide/Private_Properties#Using_WeakMaps
export const eventAttributes = new WeakMap();

View File

@ -12,7 +12,7 @@ export class EventTarget implements domTypes.EventTarget {
public addEventListener(
type: string,
listener: domTypes.EventListenerOrEventListenerObject | null,
options?: boolean | domTypes.AddEventListenerOptions
_options?: boolean | domTypes.AddEventListenerOptions
): void {
if (!(type in this.listeners)) {
this.listeners[type] = [];
@ -25,7 +25,7 @@ export class EventTarget implements domTypes.EventTarget {
public removeEventListener(
type: string,
callback: domTypes.EventListenerOrEventListenerObject | null,
options?: domTypes.EventListenerOptions | boolean
_options?: domTypes.EventListenerOptions | boolean
): void {
if (type in this.listeners && callback !== null) {
this.listeners[type] = this.listeners[type].filter(

View File

@ -14,7 +14,7 @@ test(function constructedEventTargetCanBeUsedAsExpected() {
const event = new Event("foo", { bubbles: true, cancelable: false });
let callCount = 0;
function listener(e) {
function listener(e): void {
assertEquals(e, event);
++callCount;
}
@ -34,20 +34,20 @@ test(function constructedEventTargetCanBeUsedAsExpected() {
test(function anEventTargetCanBeSubclassed() {
class NicerEventTarget extends EventTarget {
on(type, callback?, options?) {
on(type, callback?, options?): void {
this.addEventListener(type, callback, options);
}
off(type, callback?, options?) {
off(type, callback?, options?): void {
this.removeEventListener(type, callback, options);
}
}
const target = new NicerEventTarget();
const event = new Event("foo", { bubbles: true, cancelable: false });
new Event("foo", { bubbles: true, cancelable: false });
let callCount = 0;
function listener() {
function listener(): void {
++callCount;
}

View File

@ -26,7 +26,7 @@ function getHeaderValueParams(value: string): Map<string, string> {
return params;
}
function hasHeaderValueOf(s: string, value: string) {
function hasHeaderValueOf(s: string, value: string): boolean {
return new RegExp(`^${value}[\t\s]*;?`).test(s);
}
@ -204,7 +204,7 @@ class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser {
}
}
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async json(): Promise<any> {
const text = await this.text();
return JSON.parse(text);
@ -272,7 +272,7 @@ class Response implements domTypes.Response {
return this.body.formData();
}
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async json(): Promise<any> {
return this.body.json();
}
@ -336,6 +336,15 @@ function msgHttpRequest(
return msg.HttpHeader.endHttpHeader(builder);
}
function deserializeHeaderFields(m: msg.HttpHeader): Array<[string, string]> {
const out: Array<[string, string]> = [];
for (let i = 0; i < m.fieldsLength(); i++) {
const item = m.fields(i)!;
out.push([item.key()!, item.value()!]);
}
return out;
}
/** Fetch a resource from the network. */
export async function fetch(
input: domTypes.Request | string,
@ -420,12 +429,3 @@ export async function fetch(
const response = new Response(status, headersList, bodyRid);
return response;
}
function deserializeHeaderFields(m: msg.HttpHeader): Array<[string, string]> {
const out: Array<[string, string]> = [];
for (let i = 0; i < m.fieldsLength(); i++) {
const item = m.fields(i)!;
out.push([item.key()!, item.value()!]);
}
return out;
}

View File

@ -83,15 +83,15 @@ export class FileInfoImpl implements FileInfo {
this.path = path ? path : null;
}
isFile() {
isFile(): boolean {
return this._isFile;
}
isDirectory() {
isDirectory(): boolean {
return !this._isFile && !this._isSymlink;
}
isSymlink() {
isSymlink(): boolean {
return this._isSymlink;
}
}

View File

@ -1,7 +1,7 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { test, assert, assertEquals } from "./test_util.ts";
function testFirstArgument(arg1, expectedSize) {
function testFirstArgument(arg1, expectedSize): void {
const file = new File(arg1, "name");
assert(file instanceof File);
assertEquals(file.name, "name");
@ -22,7 +22,6 @@ test(function fileUnicodeStringFileBits() {
});
test(function fileStringObjectFileBits() {
// tslint:disable-next-line no-construct
testFirstArgument([new String("string object")], 13);
});
@ -77,7 +76,7 @@ test(function fileObjectInFileBits() {
testFirstArgument([{}], 15);
});
function testSecondArgument(arg2, expectedFileName) {
function testSecondArgument(arg2, expectedFileName): void {
const file = new File(["bits"], arg2);
assert(file instanceof File);
assertEquals(file.name, expectedFileName);

View File

@ -5,68 +5,6 @@ import * as msg from "gen/msg_generated";
import { assert } from "./util";
import * as flatbuffers from "./flatbuffers";
/** The Deno abstraction for reading and writing files. */
export class File implements Reader, Writer, Seeker, Closer {
constructor(readonly rid: number) {}
write(p: Uint8Array): Promise<number> {
return write(this.rid, p);
}
read(p: Uint8Array): Promise<ReadResult> {
return read(this.rid, p);
}
seek(offset: number, whence: SeekMode): Promise<void> {
return seek(this.rid, offset, whence);
}
close(): void {
close(this.rid);
}
}
/** An instance of `File` for stdin. */
export const stdin = new File(0);
/** An instance of `File` for stdout. */
export const stdout = new File(1);
/** An instance of `File` for stderr. */
export const stderr = new File(2);
export type OpenMode =
/** Read-only. Default. Starts at beginning of file. */
| "r"
/** Read-write. Start at beginning of file. */
| "r+"
/** Write-only. Opens and truncates existing file or creates new one for
* writing only.
*/
| "w"
/** Read-write. Opens and truncates existing file or creates new one for
* writing and reading.
*/
| "w+"
/** Write-only. Opens existing file or creates new one. Each write appends
* content to the end of file.
*/
| "a"
/** Read-write. Behaves like "a" and allows to read from file. */
| "a+"
/** Write-only. Exclusive create - creates new file only if one doesn't exist
* already.
*/
| "x"
/** Read-write. Behaves like `x` and allows to read from file. */
| "x+";
/** A factory function for creating instances of `File` associated with the
* supplied file name.
* @internal
*/
export function create(filename: string): Promise<File> {
return open(filename, "w+");
}
/** Open a file and return an instance of the `File` object.
*
* (async () => {
@ -90,6 +28,7 @@ export async function open(
const res = new msg.OpenRes();
assert(baseRes!.inner(res) != null);
const rid = res.rid();
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return new File(rid);
}
@ -152,3 +91,65 @@ export function close(rid: number): void {
const inner = msg.Close.endClose(builder);
dispatch.sendSync(builder, msg.Any.Close, inner);
}
/** The Deno abstraction for reading and writing files. */
export class File implements Reader, Writer, Seeker, Closer {
constructor(readonly rid: number) {}
write(p: Uint8Array): Promise<number> {
return write(this.rid, p);
}
read(p: Uint8Array): Promise<ReadResult> {
return read(this.rid, p);
}
seek(offset: number, whence: SeekMode): Promise<void> {
return seek(this.rid, offset, whence);
}
close(): void {
close(this.rid);
}
}
/** An instance of `File` for stdin. */
export const stdin = new File(0);
/** An instance of `File` for stdout. */
export const stdout = new File(1);
/** An instance of `File` for stderr. */
export const stderr = new File(2);
export type OpenMode =
/** Read-only. Default. Starts at beginning of file. */
| "r"
/** Read-write. Start at beginning of file. */
| "r+"
/** Write-only. Opens and truncates existing file or creates new one for
* writing only.
*/
| "w"
/** Read-write. Opens and truncates existing file or creates new one for
* writing and reading.
*/
| "w+"
/** Write-only. Opens existing file or creates new one. Each write appends
* content to the end of file.
*/
| "a"
/** Read-write. Behaves like "a" and allows to read from file. */
| "a+"
/** Write-only. Exclusive create - creates new file only if one doesn't exist
* already.
*/
| "x"
/** Read-write. Behaves like `x` and allows to read from file. */
| "x+";
/** A factory function for creating instances of `File` associated with the
* supplied file name.
* @internal
*/
export function create(filename: string): Promise<File> {
return open(filename, "w+");
}

View File

@ -2,6 +2,8 @@
import { flatbuffers } from "flatbuffers";
import * as util from "./util";
/* eslint-disable @typescript-eslint/camelcase */
// Re-export some types.
export type Offset = flatbuffers.Offset;
export class ByteBuffer extends flatbuffers.ByteBuffer {}
@ -17,7 +19,7 @@ globalBuilder.inUse = false;
// We can do this because the "control" messages sent to the privileged
// side are guaranteed to be used during the call to libdeno.send().
export function createBuilder(): Builder {
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const gb = globalBuilder as any;
util.assert(!gb.inUse);

View File

@ -138,7 +138,6 @@ class FormDataBase {
}
}
// tslint:disable-next-line:variable-name
export class FormData extends DomIterableMixin<
string,
domTypes.FormDataEntryValue,

View File

@ -72,7 +72,7 @@ test(function formDataParamsSetSuccess() {
test(function formDataSetEmptyBlobSuccess() {
const formData = new FormData();
formData.set("a", new Blob([]), "blank.txt");
const file = formData.get("a");
formData.get("a");
/* TODO Fix this test.
assert(file instanceof File);
if (typeof file !== "string") {

View File

@ -56,7 +56,6 @@ window.clearInterval = timers.clearTimer;
window.console = new consoleTypes.Console(libdeno.print);
window.setTimeout = timers.setTimeout;
window.setInterval = timers.setInterval;
// tslint:disable-next-line:no-any
window.location = (undefined as unknown) as domTypes.Location;
// When creating the runtime type library, we use modifications to `window` to

View File

@ -8,8 +8,9 @@ import { requiredArguments } from "./util";
const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/;
const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isHeaders(value: any): value is domTypes.Headers {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return value instanceof Headers;
}
@ -30,13 +31,13 @@ class HeadersBase {
// The following name/value validations are copied from
// https://github.com/bitinn/node-fetch/blob/master/src/headers.js
// Copyright (c) 2016 David Frank. MIT License.
private _validateName(name: string) {
private _validateName(name: string): void {
if (invalidTokenRegex.test(name) || name === "") {
throw new TypeError(`${name} is not a legal HTTP header name`);
}
}
private _validateValue(value: string) {
private _validateValue(value: string): void {
if (invalidHeaderCharRegex.test(value)) {
throw new TypeError(`${value} is not a legal HTTP header value`);
}
@ -57,9 +58,9 @@ class HeadersBase {
// then throw a TypeError.
// ref: https://fetch.spec.whatwg.org/#concept-headers-fill
if (tuple.length !== 2) {
// tslint:disable:max-line-length
// prettier-ignore
throw new TypeError("Failed to construct 'Headers'; Each header pair must be an iterable [name, value] tuple");
throw new TypeError(
"Failed to construct 'Headers'; Each header pair must be an iterable [name, value] tuple"
);
}
const [name, value] = this._normalizeParams(tuple[0], tuple[1]);
@ -127,7 +128,6 @@ class HeadersBase {
}
// @internal
// tslint:disable-next-line:variable-name
export class Headers extends DomIterableMixin<
string,
string,

View File

@ -3,9 +3,7 @@ import { test, assert, assertEquals } from "./test_util.ts";
// Logic heavily copied from web-platform-tests, make
// sure pass mostly header basic test
/* tslint:disable-next-line:max-line-length */
// ref: https://github.com/web-platform-tests/wpt/blob/7c50c216081d6ea3c9afe553ee7b64534020a1b2/fetch/api/headers/headers-basic.html
/* tslint:disable:no-unused-expression */
test(function newHeaderTest() {
new Headers();
new Headers(undefined);
@ -75,7 +73,6 @@ test(function headerHasSuccess() {
const headers = new Headers(headerDict);
for (const name in headerDict) {
assert(headers.has(name), "headers has name " + name);
/* tslint:disable-next-line:max-line-length */
assert(
!headers.has("nameNotInHeaders"),
"headers do not have header: nameNotInHeaders"
@ -177,7 +174,6 @@ test(function headerTypesAvailable() {
assert(headers instanceof Headers);
});
// tslint:disable-next-line:max-line-length
// Modified from https://github.com/bitinn/node-fetch/blob/7d3293200a91ad52b5ca7962f9d6fd1c04983edb/test/test.js#L2001-L2014
// Copyright (c) 2016 David Frank. MIT License.
test(function headerIllegalReject() {

View File

@ -1,11 +1,13 @@
// This follows the WebIDL at: https://webassembly.github.io/spec/js-api/
// And follow on WebIDL at: https://webassembly.github.io/spec/web-api/
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any */
declare namespace WebAssembly {
type WebAssemblyInstantiatedSource = {
interface WebAssemblyInstantiatedSource {
module: Module;
instance: Instance;
};
}
/** Compiles a `WebAssembly.Module` from WebAssembly binary code. This
* function is useful if it is necessary to a compile a module before it can
@ -52,12 +54,15 @@ declare namespace WebAssembly {
type ImportExportKind = "function" | "table" | "memory" | "global";
type ModuleExportDescriptor = { name: string; kind: ImportExportKind };
type ModuleImportDescriptor = {
interface ModuleExportDescriptor {
name: string;
kind: ImportExportKind;
}
interface ModuleImportDescriptor {
module: string;
name: string;
kind: ImportExportKind;
};
}
class Module {
constructor(bufferSource: domTypes.BufferSource);
@ -87,10 +92,10 @@ declare namespace WebAssembly {
readonly exports: T;
}
type MemoryDescriptor = {
interface MemoryDescriptor {
initial: number;
maximum?: number;
};
}
class Memory {
constructor(descriptor: MemoryDescriptor);
@ -128,7 +133,10 @@ declare namespace WebAssembly {
set(index: number, value: (...args: any[]) => any): void;
}
type GlobalDescriptor = { value: string; mutable?: boolean };
interface GlobalDescriptor {
value: string;
mutable?: boolean;
}
/** Represents a global variable instance, accessible from both JavaScript and
* importable/exportable across one or more `WebAssembly.Module` instances.
@ -167,3 +175,5 @@ interface ImportMeta {
url: string;
main: boolean;
}
/* eslint-enable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any */

View File

@ -12,7 +12,8 @@ interface EvalErrorInfo {
// The actual thrown entity
// (might be an Error or anything else thrown by the user)
// If isNativeError is true, this is an Error
thrown: any; // tslint:disable-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
thrown: any;
}
interface Libdeno {
@ -29,11 +30,9 @@ interface Libdeno {
* Returns an array: [output, errInfo].
* If an error occurs, `output` becomes null and `errInfo` is non-null.
*/
evalContext(
code: string
): [any, EvalErrorInfo | null] /* tslint:disable-line:no-any */;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
evalContext(code: string): [any, EvalErrorInfo | null];
// tslint:disable-next-line:no-any
errorToJSON: (e: Error) => string;
}

View File

@ -4,11 +4,6 @@ import { notImplemented } from "./util";
import { Location } from "./dom_types";
import { window } from "./window";
export function setLocation(url: string): void {
window.location = new LocationImpl(url);
Object.freeze(window.location);
}
export class LocationImpl implements Location {
constructor(url: string) {
const u = new URL(url);
@ -40,13 +35,18 @@ export class LocationImpl implements Location {
port: string;
protocol: string;
search: string;
assign(url: string): void {
assign(_url: string): void {
throw notImplemented();
}
reload(): void {
throw notImplemented();
}
replace(url: string): void {
replace(_url: string): void {
throw notImplemented();
}
}
export function setLocation(url: string): void {
window.location = new LocationImpl(url);
Object.freeze(window.location);
}

View File

@ -1,5 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
// tslint:disable-next-line:no-reference
// eslint-disable-next-line @typescript-eslint/no-triple-slash-reference
/// <reference path="./plugins.d.ts" />
import "./globals";
@ -17,8 +18,7 @@ import * as deno from "./deno";
// TODO(kitsonk) remove with `--types` below
import libDts from "gen/lib/lib.deno_runtime.d.ts!string";
/* tslint:disable-next-line:no-default-export */
export default function denoMain() {
export default function denoMain(): void {
const startResMsg = os.start();
setVersions(startResMsg.denoVersion()!, startResMsg.v8Version()!);

View File

@ -10,32 +10,6 @@ export interface MakeTempDirOptions {
suffix?: string;
}
/** makeTempDirSync is the synchronous version of `makeTempDir`.
*
* const tempDirName0 = Deno.makeTempDirSync();
* const tempDirName1 = Deno.makeTempDirSync({ prefix: 'my_temp' });
*/
export function makeTempDirSync(options: MakeTempDirOptions = {}): string {
return res(dispatch.sendSync(...req(options)));
}
/** makeTempDir creates a new temporary directory in the directory `dir`, its
* name beginning with `prefix` and ending with `suffix`.
* It returns the full path to the newly created directory.
* If `dir` is unspecified, tempDir uses the default directory for temporary
* files. Multiple programs calling tempDir simultaneously will not choose the
* same directory. It is the caller's responsibility to remove the directory
* when no longer needed.
*
* const tempDirName0 = await Deno.makeTempDir();
* const tempDirName1 = await Deno.makeTempDir({ prefix: 'my_temp' });
*/
export async function makeTempDir(
options: MakeTempDirOptions = {}
): Promise<string> {
return res(await dispatch.sendAsync(...req(options)));
}
function req({
dir,
prefix,
@ -68,3 +42,29 @@ function res(baseRes: null | msg.Base): string {
assert(path != null);
return path!;
}
/** makeTempDirSync is the synchronous version of `makeTempDir`.
*
* const tempDirName0 = Deno.makeTempDirSync();
* const tempDirName1 = Deno.makeTempDirSync({ prefix: 'my_temp' });
*/
export function makeTempDirSync(options: MakeTempDirOptions = {}): string {
return res(dispatch.sendSync(...req(options)));
}
/** makeTempDir creates a new temporary directory in the directory `dir`, its
* name beginning with `prefix` and ending with `suffix`.
* It returns the full path to the newly created directory.
* If `dir` is unspecified, tempDir uses the default directory for temporary
* files. Multiple programs calling tempDir simultaneously will not choose the
* same directory. It is the caller's responsibility to remove the directory
* when no longer needed.
*
* const tempDirName0 = await Deno.makeTempDir();
* const tempDirName1 = await Deno.makeTempDir({ prefix: 'my_temp' });
*/
export async function makeTempDir(
options: MakeTempDirOptions = {}
): Promise<string> {
return res(await dispatch.sendAsync(...req(options)));
}

View File

@ -12,11 +12,6 @@ export interface Metrics {
bytesReceived: number;
}
/** Receive metrics from the privileged side of Deno. */
export function metrics(): Metrics {
return res(dispatch.sendSync(...req()));
}
function req(): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
msg.Metrics.startMetrics(builder);
@ -38,3 +33,8 @@ function res(baseRes: null | msg.Base): Metrics {
bytesReceived: res.bytesReceived().toFloat64()
};
}
/** Receive metrics from the privileged side of Deno. */
export function metrics(): Metrics {
return res(dispatch.sendSync(...req()));
}

View File

@ -1,9 +1,10 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { DomIterable } from "../dom_types";
import { window } from "../window";
import { requiredArguments } from "../util";
// tslint:disable:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Constructor<T = {}> = new (...args: any[]) => T;
/** Mixes in a DOM iterable methods into a base class, assumes that there is
@ -12,7 +13,6 @@ type Constructor<T = {}> = new (...args: any[]) => T;
* TODO Don't expose DomIterableMixin from "deno" namespace.
*/
export function DomIterableMixin<K, V, TBase extends Constructor>(
// tslint:disable-next-line:variable-name
Base: TBase,
dataSymbol: symbol
): TBase & Constructor<DomIterable<K, V>> {
@ -25,21 +25,23 @@ export function DomIterableMixin<K, V, TBase extends Constructor>(
// Symbol.iterator, and some have an Array, which yields V, in this case
// [K, V] too as they are arrays of tuples.
// tslint:disable-next-line:variable-name
const DomIterable = class extends Base {
*entries(): IterableIterator<[K, V]> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for (const entry of (this as any)[dataSymbol]) {
yield entry;
}
}
*keys(): IterableIterator<K> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for (const [key] of (this as any)[dataSymbol]) {
yield key;
}
}
*values(): IterableIterator<V> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for (const [, value] of (this as any)[dataSymbol]) {
yield value;
}
@ -47,7 +49,7 @@ export function DomIterableMixin<K, V, TBase extends Constructor>(
forEach(
callbackfn: (value: V, key: K, parent: this) => void,
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
thisArg?: any
): void {
requiredArguments(
@ -56,12 +58,14 @@ export function DomIterableMixin<K, V, TBase extends Constructor>(
1
);
callbackfn = callbackfn.bind(thisArg == null ? window : Object(thisArg));
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for (const [key, value] of (this as any)[dataSymbol]) {
callbackfn(value, key, this);
}
}
*[Symbol.iterator](): IterableIterator<[K, V]> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for (const entry of (this as any)[dataSymbol]) {
yield entry;
}
@ -76,4 +80,3 @@ export function DomIterableMixin<K, V, TBase extends Constructor>(
return DomIterable;
}
// tslint:enable:no-any

View File

@ -1,6 +1,7 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { test, assert, assertEquals } from "../test_util.ts";
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
function setup() {
const dataSymbol = Symbol("data symbol");
class Base {
@ -19,13 +20,12 @@ function setup() {
Base,
// This is using an internal API we don't want published as types, so having
// to cast to any to "trick" TypeScript
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
DomIterable: (Deno as any).DomIterableMixin(Base, dataSymbol)
};
}
test(function testDomIterable() {
// tslint:disable-next-line:variable-name
const { DomIterable, Base } = setup();
const fixture: Array<[string, number]> = [["foo", 1], ["bar", 2]];
@ -46,7 +46,7 @@ test(function testDomIterable() {
result = [];
const scope = {};
function callback(value, key, parent) {
function callback(value, key, parent): void {
assertEquals(parent, domIterable);
assert(key != null);
assert(value != null);
@ -60,14 +60,13 @@ test(function testDomIterable() {
});
test(function testDomIterableScope() {
// tslint:disable-next-line:variable-name
const { DomIterable } = setup();
const domIterable = new DomIterable([["foo", 1]]);
// tslint:disable-next-line:no-any
function checkScope(thisArg: any, expected: any) {
function callback() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function checkScope(thisArg: any, expected: any): void {
function callback(): void {
assertEquals(this, expected);
}
domIterable.forEach(callback, thisArg);

View File

@ -3,6 +3,21 @@ import * as msg from "gen/msg_generated";
import * as flatbuffers from "./flatbuffers";
import * as dispatch from "./dispatch";
function req(
path: string,
recursive: boolean,
mode: number
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const path_ = builder.createString(path);
msg.Mkdir.startMkdir(builder);
msg.Mkdir.addPath(builder, path_);
msg.Mkdir.addRecursive(builder, recursive);
msg.Mkdir.addMode(builder, mode);
const inner = msg.Mkdir.endMkdir(builder);
return [builder, msg.Any.Mkdir, inner];
}
/** Creates a new directory with the specified path synchronously.
* If `recursive` is set to true, nested directories will be created (also known
* as "mkdir -p").
@ -32,18 +47,3 @@ export async function mkdir(
): Promise<void> {
await dispatch.sendAsync(...req(path, recursive, mode));
}
function req(
path: string,
recursive: boolean,
mode: number
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const path_ = builder.createString(path);
msg.Mkdir.startMkdir(builder);
msg.Mkdir.addPath(builder, path_);
msg.Mkdir.addRecursive(builder, recursive);
msg.Mkdir.addMode(builder, mode);
const inner = msg.Mkdir.endMkdir(builder);
return [builder, msg.Any.Mkdir, inner];
}

108
js/net.ts
View File

@ -27,6 +27,58 @@ export interface Listener {
addr(): Addr;
}
enum ShutdownMode {
// See http://man7.org/linux/man-pages/man2/shutdown.2.html
// Corresponding to SHUT_RD, SHUT_WR, SHUT_RDWR
Read = 0,
Write,
ReadWrite // unused
}
function shutdown(rid: number, how: ShutdownMode): void {
const builder = flatbuffers.createBuilder();
msg.Shutdown.startShutdown(builder);
msg.Shutdown.addRid(builder, rid);
msg.Shutdown.addHow(builder, how);
const inner = msg.Shutdown.endShutdown(builder);
const baseRes = dispatch.sendSync(builder, msg.Any.Shutdown, inner);
assert(baseRes == null);
}
class ConnImpl implements Conn {
constructor(
readonly rid: number,
readonly remoteAddr: string,
readonly localAddr: string
) {}
write(p: Uint8Array): Promise<number> {
return write(this.rid, p);
}
read(p: Uint8Array): Promise<ReadResult> {
return read(this.rid, p);
}
close(): void {
close(this.rid);
}
/** closeRead shuts down (shutdown(2)) the reading side of the TCP connection.
* Most callers should just use close().
*/
closeRead(): void {
shutdown(this.rid, ShutdownMode.Read);
}
/** closeWrite shuts down (shutdown(2)) the writing side of the TCP
* connection. Most callers should just use close().
*/
closeWrite(): void {
shutdown(this.rid, ShutdownMode.Write);
}
}
class ListenerImpl implements Listener {
constructor(readonly rid: number) {}
@ -69,58 +121,6 @@ export interface Conn extends Reader, Writer, Closer {
closeWrite(): void;
}
class ConnImpl implements Conn {
constructor(
readonly rid: number,
readonly remoteAddr: string,
readonly localAddr: string
) {}
write(p: Uint8Array): Promise<number> {
return write(this.rid, p);
}
read(p: Uint8Array): Promise<ReadResult> {
return read(this.rid, p);
}
close(): void {
close(this.rid);
}
/** closeRead shuts down (shutdown(2)) the reading side of the TCP connection.
* Most callers should just use close().
*/
closeRead(): void {
shutdown(this.rid, ShutdownMode.Read);
}
/** closeWrite shuts down (shutdown(2)) the writing side of the TCP
* connection. Most callers should just use close().
*/
closeWrite(): void {
shutdown(this.rid, ShutdownMode.Write);
}
}
enum ShutdownMode {
// See http://man7.org/linux/man-pages/man2/shutdown.2.html
// Corresponding to SHUT_RD, SHUT_WR, SHUT_RDWR
Read = 0,
Write,
ReadWrite // unused
}
function shutdown(rid: number, how: ShutdownMode) {
const builder = flatbuffers.createBuilder();
msg.Shutdown.startShutdown(builder);
msg.Shutdown.addRid(builder, rid);
msg.Shutdown.addHow(builder, how);
const inner = msg.Shutdown.endShutdown(builder);
const baseRes = dispatch.sendSync(builder, msg.Any.Shutdown, inner);
assert(baseRes == null);
}
/** Listen announces on the local network address.
*
* The network must be `tcp`, `tcp4`, `tcp6`, `unix` or `unixpacket`.
@ -197,8 +197,8 @@ export async function dial(network: Network, address: string): Promise<Conn> {
/** **RESERVED** */
export async function connect(
network: Network,
address: string
_network: Network,
_address: string
): Promise<Conn> {
return notImplemented();
}

View File

@ -24,7 +24,7 @@ testPerm({ net: true }, async function netCloseWhileAccept() {
testPerm({ net: true }, async function netConcurrentAccept() {
const listener = Deno.listen("tcp", ":4502");
let acceptErrCount = 0;
const checkErr = e => {
const checkErr = (e): void => {
assertEquals(e.kind, Deno.ErrorKind.Other);
if (e.message === "Listener has been closed") {
assertEquals(acceptErrCount, 1);

View File

@ -97,6 +97,17 @@ export function fetchModuleMetaData(
};
}
function setEnv(key: string, value: string): void {
const builder = flatbuffers.createBuilder();
const _key = builder.createString(key);
const _value = builder.createString(value);
msg.SetEnv.startSetEnv(builder);
msg.SetEnv.addKey(builder, _key);
msg.SetEnv.addValue(builder, _value);
const inner = msg.SetEnv.endSetEnv(builder);
sendSync(builder, msg.Any.SetEnv, inner);
}
function createEnv(inner: msg.EnvironRes): { [index: string]: string } {
const env: { [index: string]: string } = {};
@ -113,17 +124,6 @@ function createEnv(inner: msg.EnvironRes): { [index: string]: string } {
});
}
function setEnv(key: string, value: string): void {
const builder = flatbuffers.createBuilder();
const _key = builder.createString(key);
const _value = builder.createString(value);
msg.SetEnv.startSetEnv(builder);
msg.SetEnv.addKey(builder, _key);
msg.SetEnv.addValue(builder, _value);
const inner = msg.SetEnv.endSetEnv(builder);
sendSync(builder, msg.Any.SetEnv, inner);
}
/** Returns a snapshot of the environment variables at invocation. Mutating a
* property in the object will set that variable in the environment for
* the process. The environment object will only accept `string`s

View File

@ -4,6 +4,7 @@ import { test, testPerm, assert, assertEquals } from "./test_util.ts";
testPerm({ env: true }, function envSuccess() {
const env = Deno.env();
assert(env !== null);
// eslint-disable-next-line @typescript-eslint/camelcase
env.test_var = "Hello World";
const newEnv = Deno.env();
assertEquals(env.test_var, newEnv.test_var);
@ -12,7 +13,7 @@ testPerm({ env: true }, function envSuccess() {
test(function envFailure() {
let caughtError = false;
try {
const env = Deno.env();
Deno.env();
} catch (err) {
caughtError = true;
assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);

View File

@ -5,7 +5,7 @@ import * as dispatch from "./dispatch";
import { assert } from "./util";
/** Permissions as granted by the caller */
export type Permissions = {
export interface Permissions {
read: boolean;
write: boolean;
net: boolean;
@ -13,10 +13,27 @@ export type Permissions = {
run: boolean;
// NOTE: Keep in sync with src/permissions.rs
};
}
export type Permission = keyof Permissions;
function getReq(): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
msg.Permissions.startPermissions(builder);
const inner = msg.Permissions.endPermissions(builder);
return [builder, msg.Any.Permissions, inner];
}
function createPermissions(inner: msg.PermissionsRes): Permissions {
return {
read: inner.read(),
write: inner.write(),
net: inner.net(),
env: inner.env(),
run: inner.run()
};
}
/** Inspect granted permissions for the current program.
*
* if (Deno.permissions().read) {
@ -33,6 +50,17 @@ export function permissions(): Permissions {
return createPermissions(res);
}
function revokeReq(
permission: string
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const permission_ = builder.createString(permission);
msg.PermissionRevoke.startPermissionRevoke(builder);
msg.PermissionRevoke.addPermission(builder, permission_);
const inner = msg.PermissionRevoke.endPermissionRevoke(builder);
return [builder, msg.Any.PermissionRevoke, inner];
}
/** Revoke a permission. When the permission was already revoked nothing changes
*
* if (Deno.permissions().read) {
@ -44,31 +72,3 @@ export function permissions(): Permissions {
export function revokePermission(permission: Permission): void {
dispatch.sendSync(...revokeReq(permission));
}
function createPermissions(inner: msg.PermissionsRes): Permissions {
return {
read: inner.read(),
write: inner.write(),
net: inner.net(),
env: inner.env(),
run: inner.run()
};
}
function getReq(): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
msg.Permissions.startPermissions(builder);
const inner = msg.Permissions.endPermissions(builder);
return [builder, msg.Any.Permissions, inner];
}
function revokeReq(
permission: string
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const permission_ = builder.createString(permission);
msg.PermissionRevoke.startPermissionRevoke(builder);
msg.PermissionRevoke.addPermission(builder, permission_);
const inner = msg.PermissionRevoke.endPermissionRevoke(builder);
return [builder, msg.Any.PermissionRevoke, inner];
}

View File

@ -22,7 +22,6 @@ import { assert, unreachable } from "./util";
export type ProcessStdio = "inherit" | "piped" | "null";
// TODO Maybe extend VSCode's 'CommandOptions'?
// tslint:disable-next-line:max-line-length
// See https://code.visualstudio.com/docs/editor/tasks-appendix#_schema-for-tasksjson
export interface RunOptions {
args: string[];
@ -33,6 +32,27 @@ export interface RunOptions {
stdin?: ProcessStdio;
}
async function runStatus(rid: number): Promise<ProcessStatus> {
const builder = flatbuffers.createBuilder();
msg.RunStatus.startRunStatus(builder);
msg.RunStatus.addRid(builder, rid);
const inner = msg.RunStatus.endRunStatus(builder);
const baseRes = await dispatch.sendAsync(builder, msg.Any.RunStatus, inner);
assert(baseRes != null);
assert(msg.Any.RunStatusRes === baseRes!.innerType());
const res = new msg.RunStatusRes();
assert(baseRes!.inner(res) != null);
if (res.gotSignal()) {
const signal = res.exitSignal();
return { signal, success: false };
} else {
const code = res.exitCode();
return { code, success: code === 0 };
}
}
export class Process {
readonly rid: number;
readonly pid: number;
@ -156,24 +176,3 @@ export function run(opt: RunOptions): Process {
return new Process(res);
}
async function runStatus(rid: number): Promise<ProcessStatus> {
const builder = flatbuffers.createBuilder();
msg.RunStatus.startRunStatus(builder);
msg.RunStatus.addRid(builder, rid);
const inner = msg.RunStatus.endRunStatus(builder);
const baseRes = await dispatch.sendAsync(builder, msg.Any.RunStatus, inner);
assert(baseRes != null);
assert(msg.Any.RunStatusRes === baseRes!.innerType());
const res = new msg.RunStatusRes();
assert(baseRes!.inner(res) != null);
if (res.gotSignal()) {
const signal = res.exitSignal();
return { signal, success: false };
} else {
const code = res.exitCode();
return { code, success: code === 0 };
}
}

View File

@ -5,23 +5,6 @@ import * as dispatch from "./dispatch";
import { FileInfo, FileInfoImpl } from "./file_info";
import { assert } from "./util";
/** Reads the directory given by path and returns a list of file info
* synchronously.
*
* const files = Deno.readDirSync("/");
*/
export function readDirSync(path: string): FileInfo[] {
return res(dispatch.sendSync(...req(path)));
}
/** Reads the directory given by path and returns a list of file info.
*
* const files = await Deno.readDir("/");
*/
export async function readDir(path: string): Promise<FileInfo[]> {
return res(await dispatch.sendAsync(...req(path)));
}
function req(path: string): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const path_ = builder.createString(path);
@ -42,3 +25,20 @@ function res(baseRes: null | msg.Base): FileInfo[] {
}
return fileInfos;
}
/** Reads the directory given by path and returns a list of file info
* synchronously.
*
* const files = Deno.readDirSync("/");
*/
export function readDirSync(path: string): FileInfo[] {
return res(dispatch.sendSync(...req(path)));
}
/** Reads the directory given by path and returns a list of file info.
*
* const files = await Deno.readDir("/");
*/
export async function readDir(path: string): Promise<FileInfo[]> {
return res(await dispatch.sendAsync(...req(path)));
}

View File

@ -3,7 +3,7 @@ import { testPerm, assert, assertEquals } from "./test_util.ts";
type FileInfo = Deno.FileInfo;
function assertSameContent(files: FileInfo[]) {
function assertSameContent(files: FileInfo[]): void {
let counter = 0;
for (const file of files) {
@ -30,7 +30,7 @@ testPerm({ read: true }, function readDirSyncSuccess() {
testPerm({ read: false }, function readDirSyncPerm() {
let caughtError = false;
try {
const files = Deno.readDirSync("tests/");
Deno.readDirSync("tests/");
} catch (e) {
caughtError = true;
assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);
@ -75,7 +75,7 @@ testPerm({ read: true }, async function readDirSuccess() {
testPerm({ read: false }, async function readDirPerm() {
let caughtError = false;
try {
const files = await Deno.readDir("tests/");
await Deno.readDir("tests/");
} catch (e) {
caughtError = true;
assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);

View File

@ -4,26 +4,6 @@ import * as flatbuffers from "./flatbuffers";
import { assert } from "./util";
import * as dispatch from "./dispatch";
/** Read the entire contents of a file synchronously.
*
* const decoder = new TextDecoder("utf-8");
* const data = Deno.readFileSync("hello.txt");
* console.log(decoder.decode(data));
*/
export function readFileSync(filename: string): Uint8Array {
return res(dispatch.sendSync(...req(filename)));
}
/** Read the entire contents of a file.
*
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello.txt");
* console.log(decoder.decode(data));
*/
export async function readFile(filename: string): Promise<Uint8Array> {
return res(await dispatch.sendAsync(...req(filename)));
}
function req(
filename: string
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
@ -44,3 +24,23 @@ function res(baseRes: null | msg.Base): Uint8Array {
assert(dataArray != null);
return new Uint8Array(dataArray!);
}
/** Read the entire contents of a file synchronously.
*
* const decoder = new TextDecoder("utf-8");
* const data = Deno.readFileSync("hello.txt");
* console.log(decoder.decode(data));
*/
export function readFileSync(filename: string): Uint8Array {
return res(dispatch.sendSync(...req(filename)));
}
/** Read the entire contents of a file.
*
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello.txt");
* console.log(decoder.decode(data));
*/
export async function readFile(filename: string): Promise<Uint8Array> {
return res(await dispatch.sendAsync(...req(filename)));
}

View File

@ -13,7 +13,7 @@ testPerm({ read: true }, function readFileSyncSuccess() {
testPerm({ read: false }, function readFileSyncPerm() {
let caughtError = false;
try {
const data = Deno.readFileSync("package.json");
Deno.readFileSync("package.json");
} catch (e) {
caughtError = true;
assertEquals(e.kind, Deno.ErrorKind.PermissionDenied);

View File

@ -4,22 +4,6 @@ import * as flatbuffers from "./flatbuffers";
import { assert } from "./util";
import * as dispatch from "./dispatch";
/** Returns the destination of the named symbolic link synchronously.
*
* const targetPath = Deno.readlinkSync("symlink/path");
*/
export function readlinkSync(name: string): string {
return res(dispatch.sendSync(...req(name)));
}
/** Returns the destination of the named symbolic link.
*
* const targetPath = await Deno.readlink("symlink/path");
*/
export async function readlink(name: string): Promise<string> {
return res(await dispatch.sendAsync(...req(name)));
}
function req(name: string): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const name_ = builder.createString(name);
@ -38,3 +22,19 @@ function res(baseRes: null | msg.Base): string {
assert(path !== null);
return path!;
}
/** Returns the destination of the named symbolic link synchronously.
*
* const targetPath = Deno.readlinkSync("symlink/path");
*/
export function readlinkSync(name: string): string {
return res(dispatch.sendSync(...req(name)));
}
/** Returns the destination of the named symbolic link.
*
* const targetPath = await Deno.readlink("symlink/path");
*/
export async function readlink(name: string): Promise<string> {
return res(await dispatch.sendAsync(...req(name)));
}

View File

@ -7,6 +7,19 @@ export interface RemoveOption {
recursive?: boolean;
}
function req(
path: string,
options: RemoveOption
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const path_ = builder.createString(path);
msg.Remove.startRemove(builder);
msg.Remove.addPath(builder, path_);
msg.Remove.addRecursive(builder, !!options.recursive);
const inner = msg.Remove.endRemove(builder);
return [builder, msg.Any.Remove, inner];
}
/** Removes the named file or directory synchronously. Would throw
* error if permission denied, not found, or directory not empty if `recursive`
* set to false.
@ -31,16 +44,3 @@ export async function remove(
): Promise<void> {
await dispatch.sendAsync(...req(path, options));
}
function req(
path: string,
options: RemoveOption
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const path_ = builder.createString(path);
msg.Remove.startRemove(builder);
msg.Remove.addPath(builder, path_);
msg.Remove.addRecursive(builder, !!options.recursive);
const inner = msg.Remove.endRemove(builder);
return [builder, msg.Any.Remove, inner];
}

View File

@ -3,6 +3,20 @@ import * as msg from "gen/msg_generated";
import * as flatbuffers from "./flatbuffers";
import * as dispatch from "./dispatch";
function req(
oldpath: string,
newpath: string
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const oldpath_ = builder.createString(oldpath);
const newpath_ = builder.createString(newpath);
msg.Rename.startRename(builder);
msg.Rename.addOldpath(builder, oldpath_);
msg.Rename.addNewpath(builder, newpath_);
const inner = msg.Rename.endRename(builder);
return [builder, msg.Any.Rename, inner];
}
/** Synchronously renames (moves) `oldpath` to `newpath`. If `newpath` already
* exists and is not a directory, `renameSync()` replaces it. OS-specific
* restrictions may apply when `oldpath` and `newpath` are in different
@ -23,17 +37,3 @@ export function renameSync(oldpath: string, newpath: string): void {
export async function rename(oldpath: string, newpath: string): Promise<void> {
await dispatch.sendAsync(...req(oldpath, newpath));
}
function req(
oldpath: string,
newpath: string
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const oldpath_ = builder.createString(oldpath);
const newpath_ = builder.createString(newpath);
msg.Rename.startRename(builder);
msg.Rename.addOldpath(builder, oldpath_);
msg.Rename.addNewpath(builder, newpath_);
const inner = msg.Rename.endRename(builder);
return [builder, msg.Any.Rename, inner];
}

View File

@ -68,6 +68,47 @@ export async function readline(rid: number, prompt: string): Promise<string> {
return line || "";
}
// Error messages that allow users to continue input
// instead of throwing an error to REPL
// ref: https://github.com/v8/v8/blob/master/src/message-template.h
// TODO(kevinkassimo): this list might not be comprehensive
const recoverableErrorMessages = [
"Unexpected end of input", // { or [ or (
"Missing initializer in const declaration", // const a
"Missing catch or finally after try", // try {}
"missing ) after argument list", // console.log(1
"Unterminated template literal" // `template
// TODO(kevinkassimo): need a parser to handling errors such as:
// "Missing } in template expression" // `${ or `${ a 123 }`
];
function isRecoverableError(e: Error): boolean {
return recoverableErrorMessages.includes(e.message);
}
// Evaluate code.
// Returns true if code is consumed (no error/irrecoverable error).
// Returns false if error is recoverable
function evaluate(code: string): boolean {
const [result, errInfo] = libdeno.evalContext(code);
if (!errInfo) {
console.log(result);
} else if (errInfo.isCompileError && isRecoverableError(errInfo.thrown)) {
// Recoverable compiler error
return false; // don't consume code.
} else {
if (errInfo.isNativeError) {
const formattedError = formatError(
libdeno.errorToJSON(errInfo.thrown as Error)
);
console.error(formattedError);
} else {
console.error("Thrown:", errInfo.thrown);
}
}
return true;
}
// @internal
export async function replLoop(): Promise<void> {
Object.defineProperties(window, replCommands);
@ -75,7 +116,7 @@ export async function replLoop(): Promise<void> {
const historyFile = "deno_history.txt";
const rid = startRepl(historyFile);
const quitRepl = (exitCode: number) => {
const quitRepl = (exitCode: number): void => {
// Special handling in case user calls deno.close(3).
try {
close(rid); // close signals Drop on REPL and saves history.
@ -129,44 +170,3 @@ export async function replLoop(): Promise<void> {
}
}
}
// Evaluate code.
// Returns true if code is consumed (no error/irrecoverable error).
// Returns false if error is recoverable
function evaluate(code: string): boolean {
const [result, errInfo] = libdeno.evalContext(code);
if (!errInfo) {
console.log(result);
} else if (errInfo.isCompileError && isRecoverableError(errInfo.thrown)) {
// Recoverable compiler error
return false; // don't consume code.
} else {
if (errInfo.isNativeError) {
const formattedError = formatError(
libdeno.errorToJSON(errInfo.thrown as Error)
);
console.error(formattedError);
} else {
console.error("Thrown:", errInfo.thrown);
}
}
return true;
}
// Error messages that allow users to continue input
// instead of throwing an error to REPL
// ref: https://github.com/v8/v8/blob/master/src/message-template.h
// TODO(kevinkassimo): this list might not be comprehensive
const recoverableErrorMessages = [
"Unexpected end of input", // { or [ or (
"Missing initializer in const declaration", // const a
"Missing catch or finally after try", // try {}
"missing ) after argument list", // console.log(1
"Unterminated template literal" // `template
// TODO(kevinkassimo): need a parser to handling errors such as:
// "Missing } in template expression" // `${ or `${ a 123 }`
];
function isRecoverableError(e: Error): boolean {
return recoverableErrorMessages.includes(e.message);
}

View File

@ -4,7 +4,9 @@ import * as flatbuffers from "./flatbuffers";
import { assert } from "./util";
import * as dispatch from "./dispatch";
export type ResourceMap = { [rid: number]: string };
export interface ResourceMap {
[rid: number]: string;
}
/** Returns a map of open _file like_ resource ids along with their string
* representation.
@ -19,7 +21,7 @@ export function resources(): ResourceMap {
const res = new msg.ResourcesRes();
assert(baseRes!.inner(res) !== null);
const resources = {} as ResourceMap;
const resources: ResourceMap = {};
for (let i = 0; i < res.resourcesLength(); i++) {
const item = res.resources(i)!;

View File

@ -5,6 +5,27 @@ import * as dispatch from "./dispatch";
import { assert } from "./util";
import { FileInfo, FileInfoImpl } from "./file_info";
function req(
filename: string,
lstat: boolean
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const filename_ = builder.createString(filename);
msg.Stat.startStat(builder);
msg.Stat.addFilename(builder, filename_);
msg.Stat.addLstat(builder, lstat);
const inner = msg.Stat.endStat(builder);
return [builder, msg.Any.Stat, inner];
}
function res(baseRes: null | msg.Base): FileInfo {
assert(baseRes != null);
assert(msg.Any.StatRes === baseRes!.innerType());
const res = new msg.StatRes();
assert(baseRes!.inner(res) != null);
return new FileInfoImpl(res);
}
/** Queries the file system for information on the path provided. If the given
* path is a symlink information about the symlink will be returned.
*
@ -45,24 +66,3 @@ export async function stat(filename: string): Promise<FileInfo> {
export function statSync(filename: string): FileInfo {
return res(dispatch.sendSync(...req(filename, false)));
}
function req(
filename: string,
lstat: boolean
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const filename_ = builder.createString(filename);
msg.Stat.startStat(builder);
msg.Stat.addFilename(builder, filename_);
msg.Stat.addLstat(builder, lstat);
const inner = msg.Stat.endStat(builder);
return [builder, msg.Any.Stat, inner];
}
function res(baseRes: null | msg.Base): FileInfo {
assert(baseRes != null);
assert(msg.Any.StatRes === baseRes!.innerType());
const res = new msg.StatRes();
assert(baseRes!.inner(res) != null);
return new FileInfoImpl(res);
}

View File

@ -4,6 +4,25 @@ import * as flatbuffers from "./flatbuffers";
import * as dispatch from "./dispatch";
import * as util from "./util";
function req(
oldname: string,
newname: string,
type?: string
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
// TODO Use type for Windows.
if (type) {
return util.notImplemented();
}
const builder = flatbuffers.createBuilder();
const oldname_ = builder.createString(oldname);
const newname_ = builder.createString(newname);
msg.Symlink.startSymlink(builder);
msg.Symlink.addOldname(builder, oldname_);
msg.Symlink.addNewname(builder, newname_);
const inner = msg.Symlink.endSymlink(builder);
return [builder, msg.Any.Symlink, inner];
}
/** Synchronously creates `newname` as a symbolic link to `oldname`. The type
* argument can be set to `dir` or `file` and is only available on Windows
* (ignored on other platforms).
@ -31,22 +50,3 @@ export async function symlink(
): Promise<void> {
await dispatch.sendAsync(...req(oldname, newname, type));
}
function req(
oldname: string,
newname: string,
type?: string
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
// TODO Use type for Windows.
if (type) {
return util.notImplemented();
}
const builder = flatbuffers.createBuilder();
const oldname_ = builder.createString(oldname);
const newname_ = builder.createString(newname);
msg.Symlink.startSymlink(builder);
msg.Symlink.addOldname(builder, oldname_);
msg.Symlink.addNewname(builder, newname_);
const inner = msg.Symlink.endSymlink(builder);
return [builder, msg.Any.Symlink, inner];
}

View File

@ -52,12 +52,15 @@ function permFromString(s: string): DenoPermissions {
};
}
export function testPerm(perms: DenoPermissions, fn: testing.TestFunction) {
export function testPerm(
perms: DenoPermissions,
fn: testing.TestFunction
): void {
const name = `${fn.name}_${permToString(perms)}`;
testing.test({ fn, name });
}
export function test(fn: testing.TestFunction) {
export function test(fn: testing.TestFunction): void {
testPerm(
{ read: false, write: false, net: false, env: false, run: false },
fn

View File

@ -27,124 +27,10 @@ import * as base64 from "base64-js";
import * as domTypes from "./dom_types";
import { DenoError, ErrorKind } from "./errors";
/** Decodes a string of data which has been encoded using base-64. */
export function atob(s: string): string {
const rem = s.length % 4;
// base64-js requires length exactly times of 4
if (rem > 0) {
s = s.padEnd(s.length + (4 - rem), "=");
}
let byteArray;
try {
byteArray = base64.toByteArray(s);
} catch (_) {
throw new DenoError(
ErrorKind.InvalidInput,
"The string to be decoded is not correctly encoded"
);
}
let result = "";
for (let i = 0; i < byteArray.length; i++) {
result += String.fromCharCode(byteArray[i]);
}
return result;
}
/** Creates a base-64 ASCII string from the input string. */
export function btoa(s: string): string {
const byteArray = [];
for (let i = 0; i < s.length; i++) {
const charCode = s[i].charCodeAt(0);
if (charCode > 0xff) {
throw new DenoError(
ErrorKind.InvalidInput,
"The string to be encoded contains characters " +
"outside of the Latin1 range."
);
}
byteArray.push(charCode);
}
const result = base64.fromByteArray(Uint8Array.from(byteArray));
return result;
}
interface DecoderOptions {
fatal?: boolean;
}
interface Decoder {
handler(stream: Stream, byte: number): number | null;
}
interface Encoder {
handler(codePoint: number): number | number[];
}
const CONTINUE = null;
const END_OF_STREAM = -1;
const FINISHED = -1;
// The encodingMap is a hash of labels that are indexed by the conical
// encoding.
const encodingMap: { [key: string]: string[] } = {
"windows-1252": [
"ansi_x3.4-1968",
"ascii",
"cp1252",
"cp819",
"csisolatin1",
"ibm819",
"iso-8859-1",
"iso-ir-100",
"iso8859-1",
"iso88591",
"iso_8859-1",
"iso_8859-1:1987",
"l1",
"latin1",
"us-ascii",
"windows-1252",
"x-cp1252"
],
"utf-8": ["unicode-1-1-utf-8", "utf-8", "utf8"]
};
// We convert these into a Map where every label resolves to its canonical
// encoding type.
const encodings = new Map<string, string>();
for (const key of Object.keys(encodingMap)) {
const labels = encodingMap[key];
for (const label of labels) {
encodings.set(label, key);
}
}
// A map of functions that return new instances of a decoder indexed by the
// encoding type.
const decoders = new Map<string, (options: DecoderOptions) => Decoder>();
decoders.set("utf-8", (options: DecoderOptions) => {
return new UTF8Decoder(options);
});
// Single byte decoders are an array of code point lookups
const encodingIndexes = new Map<string, number[]>();
// tslint:disable:max-line-length
// prettier-ignore
encodingIndexes.set("windows-1252", [8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]);
// tslint:enable
for (const [key, index] of encodingIndexes) {
decoders.set(key, (options: DecoderOptions) => {
return new SingleByteDecoder(index, options);
});
}
function codePointsToString(codePoints: number[]): string {
let s = "";
for (const cp of codePoints) {
s += String.fromCodePoint(cp);
}
return s;
}
function decoderError(fatal: boolean): number | never {
if (fatal) {
throw new TypeError("Decoder error.");
@ -152,11 +38,11 @@ function decoderError(fatal: boolean): number | never {
return 0xfffd; // default code point
}
function inRange(a: number, min: number, max: number) {
function inRange(a: number, min: number, max: number): boolean {
return min <= a && a <= max;
}
function isASCIIByte(a: number) {
function isASCIIByte(a: number): boolean {
return inRange(a, 0x00, 0x7f);
}
@ -168,67 +54,6 @@ function stringToCodePoints(input: string): number[] {
return u;
}
class Stream {
private _tokens: number[];
constructor(tokens: number[] | Uint8Array) {
this._tokens = [].slice.call(tokens);
this._tokens.reverse();
}
endOfStream(): boolean {
return !this._tokens.length;
}
read(): number {
return !this._tokens.length ? END_OF_STREAM : this._tokens.pop()!;
}
prepend(token: number | number[]): void {
if (Array.isArray(token)) {
while (token.length) {
this._tokens.push(token.pop()!);
}
} else {
this._tokens.push(token);
}
}
push(token: number | number[]): void {
if (Array.isArray(token)) {
while (token.length) {
this._tokens.unshift(token.shift()!);
}
} else {
this._tokens.unshift(token);
}
}
}
class SingleByteDecoder implements Decoder {
private _index: number[];
private _fatal: boolean;
constructor(index: number[], options: DecoderOptions) {
this._fatal = options.fatal || false;
this._index = index;
}
handler(stream: Stream, byte: number): number {
if (byte === END_OF_STREAM) {
return FINISHED;
}
if (isASCIIByte(byte)) {
return byte;
}
const codePoint = this._index[byte - 0x80];
if (codePoint == null) {
return decoderError(this._fatal);
}
return codePoint;
}
}
class UTF8Decoder implements Decoder {
private _codePoint = 0;
private _bytesSeen = 0;
@ -349,6 +174,179 @@ class UTF8Encoder implements Encoder {
}
}
/** Decodes a string of data which has been encoded using base-64. */
export function atob(s: string): string {
const rem = s.length % 4;
// base64-js requires length exactly times of 4
if (rem > 0) {
s = s.padEnd(s.length + (4 - rem), "=");
}
let byteArray;
try {
byteArray = base64.toByteArray(s);
} catch (_) {
throw new DenoError(
ErrorKind.InvalidInput,
"The string to be decoded is not correctly encoded"
);
}
let result = "";
for (let i = 0; i < byteArray.length; i++) {
result += String.fromCharCode(byteArray[i]);
}
return result;
}
/** Creates a base-64 ASCII string from the input string. */
export function btoa(s: string): string {
const byteArray = [];
for (let i = 0; i < s.length; i++) {
const charCode = s[i].charCodeAt(0);
if (charCode > 0xff) {
throw new DenoError(
ErrorKind.InvalidInput,
"The string to be encoded contains characters " +
"outside of the Latin1 range."
);
}
byteArray.push(charCode);
}
const result = base64.fromByteArray(Uint8Array.from(byteArray));
return result;
}
interface DecoderOptions {
fatal?: boolean;
}
interface Decoder {
handler(stream: Stream, byte: number): number | null;
}
interface Encoder {
handler(codePoint: number): number | number[];
}
class SingleByteDecoder implements Decoder {
private _index: number[];
private _fatal: boolean;
constructor(index: number[], options: DecoderOptions) {
this._fatal = options.fatal || false;
this._index = index;
}
handler(stream: Stream, byte: number): number {
if (byte === END_OF_STREAM) {
return FINISHED;
}
if (isASCIIByte(byte)) {
return byte;
}
const codePoint = this._index[byte - 0x80];
if (codePoint == null) {
return decoderError(this._fatal);
}
return codePoint;
}
}
// The encodingMap is a hash of labels that are indexed by the conical
// encoding.
const encodingMap: { [key: string]: string[] } = {
"windows-1252": [
"ansi_x3.4-1968",
"ascii",
"cp1252",
"cp819",
"csisolatin1",
"ibm819",
"iso-8859-1",
"iso-ir-100",
"iso8859-1",
"iso88591",
"iso_8859-1",
"iso_8859-1:1987",
"l1",
"latin1",
"us-ascii",
"windows-1252",
"x-cp1252"
],
"utf-8": ["unicode-1-1-utf-8", "utf-8", "utf8"]
};
// We convert these into a Map where every label resolves to its canonical
// encoding type.
const encodings = new Map<string, string>();
for (const key of Object.keys(encodingMap)) {
const labels = encodingMap[key];
for (const label of labels) {
encodings.set(label, key);
}
}
// A map of functions that return new instances of a decoder indexed by the
// encoding type.
const decoders = new Map<string, (options: DecoderOptions) => Decoder>();
decoders.set("utf-8", (options: DecoderOptions) => {
return new UTF8Decoder(options);
});
// Single byte decoders are an array of code point lookups
const encodingIndexes = new Map<string, number[]>();
// prettier-ignore
encodingIndexes.set("windows-1252", [8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]);
for (const [key, index] of encodingIndexes) {
decoders.set(key, (options: DecoderOptions) => {
return new SingleByteDecoder(index, options);
});
}
function codePointsToString(codePoints: number[]): string {
let s = "";
for (const cp of codePoints) {
s += String.fromCodePoint(cp);
}
return s;
}
class Stream {
private _tokens: number[];
constructor(tokens: number[] | Uint8Array) {
this._tokens = [].slice.call(tokens);
this._tokens.reverse();
}
endOfStream(): boolean {
return !this._tokens.length;
}
read(): number {
return !this._tokens.length ? END_OF_STREAM : this._tokens.pop()!;
}
prepend(token: number | number[]): void {
if (Array.isArray(token)) {
while (token.length) {
this._tokens.push(token.pop()!);
}
} else {
this._tokens.push(token);
}
}
push(token: number | number[]): void {
if (Array.isArray(token)) {
while (token.length) {
this._tokens.unshift(token.shift()!);
}
} else {
this._tokens.unshift(token);
}
}
}
export interface TextDecodeOptions {
stream?: false;
}

View File

@ -46,7 +46,7 @@ test(function textDecoderASCII() {
test(function textDecoderErrorEncoding() {
let didThrow = false;
try {
const decoder = new TextDecoder("foo");
new TextDecoder("foo");
} catch (e) {
didThrow = true;
assertEquals(e.message, "The encoding label provided ('foo') is invalid.");

View File

@ -4,10 +4,6 @@ import * as msg from "gen/msg_generated";
import * as flatbuffers from "./flatbuffers";
import { sendSync, setFireTimersCallback } from "./dispatch";
// Tell the dispatcher which function it should call to fire timers that are
// due. This is done using a callback because circular imports are disallowed.
setFireTimersCallback(fireTimers);
interface Timer {
id: number;
callback: () => void;
@ -34,14 +30,14 @@ let nextTimerId = 1;
const idMap = new Map<number, Timer>();
const dueMap: { [due: number]: Timer[] } = Object.create(null);
function getTime() {
function getTime(): number {
// TODO: use a monotonic clock.
const now = Date.now() - EPOCH;
assert(now >= 0 && now < APOCALYPSE);
return now;
}
function setGlobalTimeout(due: number | null, now: number) {
function setGlobalTimeout(due: number | null, now: number): void {
// Since JS and Rust don't use the same clock, pass the time to rust as a
// relative time value. On the Rust side we'll turn that into an absolute
// value again.
@ -65,7 +61,7 @@ function setGlobalTimeout(due: number | null, now: number) {
globalTimeoutDue = due;
}
function schedule(timer: Timer, now: number) {
function schedule(timer: Timer, now: number): void {
assert(!timer.scheduled);
assert(now <= timer.due);
// Find or create the list of timers that will fire at point-in-time `due`.
@ -83,7 +79,7 @@ function schedule(timer: Timer, now: number) {
}
}
function unschedule(timer: Timer) {
function unschedule(timer: Timer): void {
if (!timer.scheduled) {
return;
}
@ -112,7 +108,7 @@ function unschedule(timer: Timer) {
}
}
function fire(timer: Timer) {
function fire(timer: Timer): void {
// If the timer isn't found in the ID map, that means it has been cancelled
// between the timer firing and the promise callback (this function).
if (!idMap.has(timer.id)) {
@ -135,7 +131,7 @@ function fire(timer: Timer) {
callback();
}
function fireTimers() {
function fireTimers(): void {
const now = getTime();
// Bail out if we're not expecting the global timer to fire (yet).
if (globalTimeoutDue === null || now < globalTimeoutDue) {
@ -171,7 +167,7 @@ function fireTimers() {
setGlobalTimeout(nextTimerDue, now);
}
export type Args = any[]; // tslint:disable-line:no-any
export type Args = unknown[];
function setTimer(
cb: (...args: Args) => void,
@ -241,3 +237,7 @@ export function clearTimer(id: number): void {
unschedule(timer);
idMap.delete(timer.id);
}
// Tell the dispatcher which function it should call to fire timers that are
// due. This is done using a callback because circular imports are disallowed.
setFireTimersCallback(fireTimers);

View File

@ -1,7 +1,12 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { test, assertEquals } from "./test_util.ts";
function deferred() {
function deferred(): {
promise: Promise<{}>;
resolve: (value?: {} | PromiseLike<{}>) => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
reject: (reason?: any) => void;
} {
let resolve;
let reject;
const promise = new Promise((res, rej) => {
@ -15,7 +20,7 @@ function deferred() {
};
}
function waitForMs(ms) {
async function waitForMs(ms): Promise<number> {
return new Promise(resolve => setTimeout(resolve, ms));
}
@ -62,6 +67,10 @@ test(async function timeoutCancelSuccess() {
});
test(async function timeoutCancelMultiple() {
function uncalled(): never {
throw new Error("This function should not be called.");
}
// Set timers and cancel them in the same order.
const t1 = setTimeout(uncalled, 10);
const t2 = setTimeout(uncalled, 10);
@ -80,10 +89,6 @@ test(async function timeoutCancelMultiple() {
// Sleep until we're certain that the cancelled timers aren't gonna fire.
await waitForMs(50);
function uncalled() {
throw new Error("This function should not be called.");
}
});
test(async function timeoutCancelInvalidSilentFail() {
@ -138,15 +143,15 @@ test(async function intervalCancelSuccess() {
test(async function intervalOrdering() {
const timers = [];
let timeouts = 0;
for (let i = 0; i < 10; i++) {
timers[i] = setTimeout(onTimeout, 20);
}
function onTimeout() {
function onTimeout(): void {
++timeouts;
for (let i = 1; i < timers.length; i++) {
clearTimeout(timers[i]);
}
}
for (let i = 0; i < 10; i++) {
timers[i] = setTimeout(onTimeout, 20);
}
await waitForMs(100);
assertEquals(timeouts, 1);
});

View File

@ -3,6 +3,20 @@ import * as msg from "gen/msg_generated";
import * as flatbuffers from "./flatbuffers";
import * as dispatch from "./dispatch";
function req(
name: string,
len?: number
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const name_ = builder.createString(name);
len = len && len > 0 ? Math.floor(len) : 0;
msg.Truncate.startTruncate(builder);
msg.Truncate.addName(builder, name_);
msg.Truncate.addLen(builder, len);
const inner = msg.Truncate.endTruncate(builder);
return [builder, msg.Any.Truncate, inner];
}
/** Truncates or extends the specified file synchronously, updating the size of
* this file to become size.
*
@ -21,17 +35,3 @@ export function truncateSync(name: string, len?: number): void {
export async function truncate(name: string, len?: number): Promise<void> {
await dispatch.sendAsync(...req(name, len));
}
function req(
name: string,
len?: number
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const name_ = builder.createString(name);
len = len && len > 0 ? Math.floor(len) : 0;
msg.Truncate.startTruncate(builder);
msg.Truncate.addName(builder, name_);
msg.Truncate.addLen(builder, len);
const inner = msg.Truncate.endTruncate(builder);
return [builder, msg.Any.Truncate, inner];
}

View File

@ -67,17 +67,16 @@ export class URL {
private _parts: URLParts;
private _searchParams!: urlSearchParams.URLSearchParams;
private _updateSearchParams() {
private _updateSearchParams(): void {
const searchParams = new urlSearchParams.URLSearchParams(this.search);
for (const methodName of searchParamsMethods) {
// tslint:disable:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const method: (...args: any[]) => any = searchParams[methodName];
searchParams[methodName] = (...args: any[]) => {
searchParams[methodName] = (...args: unknown[]) => {
method.apply(searchParams, args);
this.search = searchParams.toString();
};
// tslint:enable
}
this._searchParams = searchParams;
}

View File

@ -175,9 +175,9 @@ export class URLSearchParams {
*/
forEach(
callbackfn: (value: string, key: string, parent: URLSearchParams) => void,
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
thisArg?: any
) {
): void {
requiredArguments("URLSearchParams.forEach", arguments.length, 1);
if (typeof thisArg !== "undefined") {

View File

@ -16,15 +16,14 @@ export function setLogDebug(debug: boolean, source?: string): void {
* Enable with the `--log-debug` or `-D` command line flag.
* @internal
*/
// tslint:disable-next-line:no-any
export function log(...args: any[]): void {
export function log(...args: unknown[]): void {
if (logDebug) {
console.log(`DEBUG ${logSource} -`, ...args);
}
}
// @internal
export function assert(cond: boolean, msg = "assert") {
export function assert(cond: boolean, msg = "assert"): void {
if (!cond) {
throw Error(msg);
}
@ -62,7 +61,7 @@ export function arrayToStr(ui8: Uint8Array): string {
export interface ResolvableMethods<T> {
resolve: (value?: T | PromiseLike<T>) => void;
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
reject: (reason?: any) => void;
}
@ -107,7 +106,6 @@ export function containsOnlyASCII(str: string): boolean {
return /^[\x00-\x7F]*$/.test(str);
}
// tslint:disable-next-line:variable-name
const TypedArrayConstructor = Object.getPrototypeOf(Uint8Array);
export function isTypedArray(x: unknown): x is TypedArray {
return x instanceof TypedArrayConstructor;

View File

@ -50,7 +50,7 @@ export function workerClose(): void {
isClosing = true;
}
export async function workerMain() {
export async function workerMain(): Promise<void> {
log("workerMain");
while (!isClosing) {

View File

@ -3,6 +3,34 @@ import * as msg from "gen/msg_generated";
import * as flatbuffers from "./flatbuffers";
import * as dispatch from "./dispatch";
function req(
filename: string,
data: Uint8Array,
options: WriteFileOptions
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset, Uint8Array] {
const builder = flatbuffers.createBuilder();
const filename_ = builder.createString(filename);
msg.WriteFile.startWriteFile(builder);
msg.WriteFile.addFilename(builder, filename_);
// Perm is not updated by default
if (options.perm !== undefined && options.perm !== null) {
msg.WriteFile.addUpdatePerm(builder, true);
msg.WriteFile.addPerm(builder, options.perm!);
} else {
msg.WriteFile.addUpdatePerm(builder, false);
msg.WriteFile.addPerm(builder, 0o666);
}
// Create is turned on by default
if (options.create !== undefined) {
msg.WriteFile.addIsCreate(builder, !!options.create);
} else {
msg.WriteFile.addIsCreate(builder, true);
}
msg.WriteFile.addIsAppend(builder, !!options.append);
const inner = msg.WriteFile.endWriteFile(builder);
return [builder, msg.Any.WriteFile, inner, data];
}
/** Options for writing to a file.
* `perm` would change the file's permission if set.
* `create` decides if the file should be created if not exists (default: true)
@ -41,31 +69,3 @@ export async function writeFile(
): Promise<void> {
await dispatch.sendAsync(...req(filename, data, options));
}
function req(
filename: string,
data: Uint8Array,
options: WriteFileOptions
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset, Uint8Array] {
const builder = flatbuffers.createBuilder();
const filename_ = builder.createString(filename);
msg.WriteFile.startWriteFile(builder);
msg.WriteFile.addFilename(builder, filename_);
// Perm is not updated by default
if (options.perm !== undefined && options.perm !== null) {
msg.WriteFile.addUpdatePerm(builder, true);
msg.WriteFile.addPerm(builder, options.perm!);
} else {
msg.WriteFile.addUpdatePerm(builder, false);
msg.WriteFile.addPerm(builder, 0o666);
}
// Create is turned on by default
if (options.create !== undefined) {
msg.WriteFile.addIsCreate(builder, !!options.create);
} else {
msg.WriteFile.addIsCreate(builder, true);
}
msg.WriteFile.addIsAppend(builder, !!options.append);
const inner = msg.WriteFile.endWriteFile(builder);
return [builder, msg.Any.WriteFile, inner, data];
}

View File

@ -4,7 +4,11 @@
"@types/base64-js": "1.2.5",
"@types/flatbuffers": "1.9.1",
"@types/prettier": "1.16.1",
"@typescript-eslint/eslint-plugin": "1.4.2",
"@typescript-eslint/parser": "1.4.2",
"base64-js": "1.3.0",
"eslint": "5.15.1",
"eslint-config-prettier": "4.1.0",
"flatbuffers": "1.9.0",
"magic-string": "0.25.2",
"prettier": "1.16.4",
@ -20,9 +24,6 @@
"rollup-pluginutils": "2.4.1",
"ts-morph": "1.3.0",
"ts-node": "8.0.2",
"tslint": "^5.10.0",
"tslint-eslint-rules": "^5.3.1",
"tslint-no-circular-imports": "^0.5.0",
"typescript": "3.2.2"
}
}

View File

@ -1,6 +1,6 @@
// Check that we can use the async keyword.
async function main() {
await new Promise((resolve, reject) => {
async function main(): Promise<void> {
await new Promise(resolve => {
console.log("2");
setTimeout(resolve, 100);
});

View File

@ -1,5 +1,4 @@
// http -> https redirect would happen:
// tslint:disable-next-line:max-line-length
import { printHello } from "http://gist.githubusercontent.com/ry/f12b2aa3409e6b52645bc346a9e22929/raw/79318f239f51d764384a8bded8d7c6a833610dde/print_hello.ts";
printHello();

View File

@ -1,7 +1,7 @@
async function fn() {
async function fn(): Promise<never> {
throw new Error("message");
}
async function call() {
async function call(): Promise<void> {
try {
console.log("before await fn()");
await fn();

View File

@ -2,7 +2,6 @@
// based on the URL containing `.t#.` strings, which exercises the different
// mapping of media types end to end.
// tslint:disable:max-line-length
import { loaded as loadedTs1 } from "http://localhost:4545/tests/subdir/mt_text_typescript.t1.ts";
import { loaded as loadedTs2 } from "http://localhost:4545/tests/subdir/mt_video_vdn.t2.ts";
import { loaded as loadedTs3 } from "http://localhost:4545/tests/subdir/mt_video_mp2t.t3.ts";

View File

@ -1,5 +1,5 @@
console.log("hello");
const foo = async () => {
const foo = async (): Promise<never> => {
console.log("before error");
throw Error("error");
};

View File

@ -1,6 +1,6 @@
const { stdout, open, copy, args } = Deno;
async function main() {
async function main(): Promise<void> {
for (let i = 1; i < args.length; i++) {
const filename = args[i];
const file = await open(filename);

View File

@ -1,8 +1,8 @@
function foo() {
function foo(): never {
throw Error("bad");
}
function bar() {
function bar(): void {
foo();
}

View File

@ -1,6 +1,6 @@
import { throwsError } from "./subdir/mod1.ts";
function foo() {
function foo(): void {
throwsError();
}

View File

@ -1 +1,2 @@
// eslint-disable-next-line
import * as badModule from "bad-module.ts";

View File

@ -1,3 +1,4 @@
(async () => {
// eslint-disable-next-line
const badModule = await import("bad-module.ts");
})();

View File

@ -2,5 +2,5 @@
consol.log("hello world!");
// the following error should be ignored and not output to the console
// @ts-ignore
// eslint-disable-next-line
const foo = new Foo();

View File

@ -2,7 +2,7 @@
import { assert } from "../js/deps/https/deno.land/std/testing/asserts.ts";
// TODO Top level await https://github.com/denoland/deno/issues/471
async function main() {
async function main(): Promise<void> {
const response = await fetch("http://localhost:4545/package.json");
const json = await response.json();
const deps = Object.keys(json.devDependencies);

View File

@ -1,6 +1,5 @@
// TODO Use https://localhost:4555/ but we need more infrastructure to
// support verifying self-signed certificates.
// tslint:disable-next-line:max-line-length
import { printHello } from "https://gist.githubusercontent.com/ry/f12b2aa3409e6b52645bc346a9e22929/raw/79318f239f51d764384a8bded8d7c6a833610dde/print_hello.ts";
printHello();

@ -1 +1 @@
Subproject commit 1ba775b7b8e555fdba7753ef91ac064b597dcbaf
Subproject commit 1d46f6634d7feb9889cf69c14e80803deaeaa68d

View File

@ -10,8 +10,8 @@ enable_ansi_colors()
third_party_path = os.path.join(root_path, "third_party")
cpplint = os.path.join(third_party_path, "cpplint", "cpplint.py")
tslint = os.path.join(third_party_path, "node_modules", "tslint", "bin",
"tslint")
eslint = os.path.join(third_party_path, "node_modules", "eslint", "bin",
"eslint")
os.chdir(root_path)
run([
@ -19,10 +19,9 @@ run([
"--repository=libdeno", "--extensions=cc,h", "--recursive", "libdeno"
])
run(["node", tslint, "-p", ".", "--exclude", "**/gen/**/*.ts"])
run([
"node", tslint, "./js/**/*_test.ts", "./tests/**/*.ts", "./core/*.js",
"--exclude", "**/gen/**/*.ts", "--project", "tsconfig.json"
"node", eslint, "./js/**/*.{ts,js}", "./core/**/*.{ts,js}",
"./tests/**/*.{ts,js}"
])
run([sys.executable, "third_party/depot_tools/pylint.py"] +

View File

@ -70,7 +70,6 @@ const { ModuleKind, ModuleResolutionKind, ScriptTarget } = ts;
/**
* A preamble which is appended to the start of the library.
*/
// tslint:disable-next-line:max-line-length
const libPreamble = `// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
/// <reference no-default-lib="true" />

View File

@ -12,7 +12,6 @@ let debug = false;
let silent = false;
process.argv.forEach((arg, i, argv) => {
// tslint:disable-next-line:switch-default
switch (arg) {
case "--basePath":
basePath = path.resolve(argv[i + 1]);

View File

@ -2,7 +2,6 @@ import * as moduleC from "./moduleC";
import * as moduleD from "./moduleD";
import * as moduleE from "./moduleE";
// tslint:disable-next-line:no-any
const foobarbaz: any = {};
foobarbaz.bar = new moduleC.Bar();
foobarbaz.qat = moduleC.qat;

View File

@ -1,66 +0,0 @@
{
"rules": {
"array-type": [true, "array-simple"],
"arrow-return-shorthand": true,
"ban": [
true,
["fit"],
["fdescribe"],
["xit"],
["xdescribe"],
["fitAsync"],
["xitAsync"],
["fitFakeAsync"],
["xitFakeAsync"]
],
"ban-types": [
true,
["Object", "Use {} instead."],
["String", "Use 'string' instead."],
["Number", "Use 'number' instead."],
["Boolean", "Use 'boolean' instead."]
],
"class-name": true,
"curly": true,
"interface-name": [true, "never-prefix"],
"jsdoc-format": true,
"forin": false,
"label-position": true,
"max-line-length": [true, 80],
"new-parens": true,
"no-angle-bracket-type-assertion": true,
"no-any": true,
"no-construct": true,
"no-consecutive-blank-lines": true,
"no-debugger": true,
"no-default-export": true,
"no-inferrable-types": true,
"no-reference": true,
"no-require-imports": true,
"no-string-throw": true,
"no-unused-expression": true,
"no-var-keyword": true,
"object-literal-shorthand": true,
"only-arrow-functions": [
true,
"allow-declarations",
"allow-named-functions"
],
"prefer-const": true,
"quotemark": [true, "double"],
"radix": true,
"restrict-plus-operands": true,
"semicolon": [true, "always", "ignore-bound-class-methods"],
"switch-default": true,
"triple-equals": [true, "allow-null-check"],
"use-isnan": true,
"variable-name": [
true,
"check-format",
"ban-keywords",
"allow-leading-underscore",
"allow-trailing-underscore"
]
},
"extends": ["tslint-no-circular-imports"]
}