0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 17:34:47 -05:00

Add JSDoc to deno_typescript (#2890)

This commit is contained in:
Kitson Kelly 2019-09-10 14:54:32 +10:00 committed by Ryan Dahl
parent 46cbc6e0e9
commit 3779667646
4 changed files with 150 additions and 92 deletions

View file

@ -1,20 +1,34 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
// A very very basic AMD preamble to support the output of TypeScript outFile // A very very basic AMD preamble to support the output of TypeScript outFile
// bundles. // bundles.
let require, define;
/**
* @type {(name: string) => any}
*/
let require;
/**
* @type {(name: string, deps: ReadonlyArray<string>, factory: (...deps: any[]) => void) => void}
*/
let define;
(function() { (function() {
/**
* @type {Map<string, { name: string, exports: any }>}
*/
const modules = new Map(); const modules = new Map();
function println(first, ...s) { /**
Deno.core.print(first + " " + s.map(JSON.stringify).join(" ") + "\n"); * @param {string} name
} */
function createOrLoadModule(name) { function createOrLoadModule(name) {
if (!modules.has(name)) { let m = modules.get(name);
const m = { name, exports: {} }; if (!m) {
m = { name, exports: {} };
modules.set(name, m); modules.set(name, m);
} }
return modules.get(name); return m;
} }
require = name => { require = name => {

View file

@ -1,8 +1,16 @@
// Because we're bootstrapping the TS compiler without dependencies on Node, // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
// this is written in JS.
// Because we're bootstrapping the TypeScript compiler without dependencies on
// Node, this is written in JavaScript, but leverages JSDoc that can be
// understood by the TypeScript language service, so it allows type safety
// checking in VSCode.
const ASSETS = "$asset$"; const ASSETS = "$asset$";
/**
* @param {string} configText
* @param {Array<string>} rootNames
*/
function main(configText, rootNames) { function main(configText, rootNames) {
println(`>>> ts version ${ts.version}`); println(`>>> ts version ${ts.version}`);
println(`>>> rootNames ${rootNames}`); println(`>>> rootNames ${rootNames}`);
@ -34,37 +42,57 @@ function main(configText, rootNames) {
dispatch("setEmitResult", emitResult); dispatch("setEmitResult", emitResult);
} }
/**
* @param {...string} s
*/
function println(...s) { function println(...s) {
Deno.core.print(s.join(" ") + "\n"); Deno.core.print(s.join(" ") + "\n");
} }
/**
* @returns {never}
*/
function unreachable() { function unreachable() {
throw Error("unreachable"); throw Error("unreachable");
} }
/**
* @param {unknown} cond
*/
function assert(cond) { function assert(cond) {
if (!cond) { if (!cond) {
throw Error("assert"); throw Error("assert");
} }
} }
// decode(Uint8Array): string /**
* @param {Uint8Array | null} ui8
*/
function decodeAscii(ui8) { function decodeAscii(ui8) {
let out = ""; let out = "";
if (!ui8) {
return out;
}
for (let i = 0; i < ui8.length; i++) { for (let i = 0; i < ui8.length; i++) {
out += String.fromCharCode(ui8[i]); out += String.fromCharCode(ui8[i]);
} }
return out; return out;
} }
/**
* @param {string} str
*/
function encode(str) { function encode(str) {
const charCodes = str.split("").map(c => c.charCodeAt(0)); const charCodes = str.split("").map(c => c.charCodeAt(0));
const ui8 = new Uint8Array(charCodes); const ui8 = new Uint8Array(charCodes);
return ui8; return ui8;
} }
// Warning! The op_id values below are shared between this code and //
// the Rust side. Update with care! /** **Warning!** The op_id values below are shared between this code and the
* Rust side. Update with care!
* @type {Record<string, number>}
*/
const ops = { const ops = {
readFile: 49, readFile: 49,
exit: 50, exit: 50,
@ -73,53 +101,56 @@ const ops = {
setEmitResult: 53 setEmitResult: 53
}; };
// interface CompilerHost extends ModuleResolutionHost { /**
* @implements {ts.CompilerHost}
*/
class Host { class Host {
// fileExists(fileName: string): boolean; /**
* @param {string} fileName
*/
fileExists(fileName) { fileExists(fileName) {
return true; return true;
} }
// readFile(fileName: string): string | undefined; /**
readFile() { * @param {string} fileName
*/
readFile(fileName) {
unreachable(); unreachable();
return undefined;
} }
// trace?(s: string): void;
// directoryExists?(directoryName: string): boolean;
// realpath?(path: string): string;
// getCurrentDirectory?(): string;
// getDirectories?(path: string): string[];
// useCaseSensitiveFileNames(): boolean;
useCaseSensitiveFileNames() { useCaseSensitiveFileNames() {
return false; return false;
} }
// getDefaultLibFileName(options: CompilerOptions): string; /**
getDefaultLibFileName(options) { * @param {ts.CompilerOptions} _options
*/
getDefaultLibFileName(_options) {
return "lib.deno_core.d.ts"; return "lib.deno_core.d.ts";
} }
// getDefaultLibLocation?(): string;
getDefaultLibLocation() { getDefaultLibLocation() {
return ASSETS; return ASSETS;
} }
// getCurrentDirectory(): string;
getCurrentDirectory() { getCurrentDirectory() {
return "."; return ".";
} }
// getCanonicalFileName(fileName: string): string /**
getCanonicalFileName(fileName) { * @param {string} fileName
unreachable(); * @param {ts.ScriptTarget} languageVersion
} * @param {(message: string) => void} _onError
* @param {boolean} shouldCreateNewSourceFile
// getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: */
// (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile getSourceFile(
// | undefined; fileName,
getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) { languageVersion,
_onError,
shouldCreateNewSourceFile
) {
assert(!shouldCreateNewSourceFile); // We haven't yet encountered this. assert(!shouldCreateNewSourceFile); // We haven't yet encountered this.
// This hacks around the fact that TypeScript tries to magically guess the // This hacks around the fact that TypeScript tries to magically guess the
@ -148,27 +179,34 @@ class Host {
return sourceFile; return sourceFile;
} }
/* /**
writeFile( * @param {string} fileName
fileName: string, * @param {string} data
data: string, * @param {boolean} _writeByteOrderMark
writeByteOrderMark: boolean, * @param {((message: string) => void)?} _onError
onError?: (message: string) => void, * @param {ReadonlyArray<ts.SourceFile>?} sourceFiles
sourceFiles?: ReadonlyArray<ts.SourceFile> */
): void
*/
writeFile( writeFile(
fileName, fileName,
data, data,
writeByteOrderMark, _writeByteOrderMark,
onError = null, _onError = null,
sourceFiles = null sourceFiles = null
) { ) {
if (sourceFiles == null) {
return;
}
const moduleName = sourceFiles[sourceFiles.length - 1].moduleName; const moduleName = sourceFiles[sourceFiles.length - 1].moduleName;
return dispatch("writeFile", { fileName, moduleName, data }); return dispatch("writeFile", { fileName, moduleName, data });
} }
// getSourceFileByPath?(fileName: string, path: Path, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined; /**
* @param {string} fileName
* @param {ts.Path} path
* @param {ts.ScriptTarget} languageVersion
* @param {*} onError
* @param {boolean} shouldCreateNewSourceFile
*/
getSourceFileByPath( getSourceFileByPath(
fileName, fileName,
path, path,
@ -177,35 +215,27 @@ class Host {
shouldCreateNewSourceFile shouldCreateNewSourceFile
) { ) {
unreachable(); unreachable();
return undefined;
} }
// getCancellationToken?(): CancellationToken; /**
getCancellationToken() { * @param {string} fileName
unreachable(); */
}
// getCanonicalFileName(fileName: string): string;
getCanonicalFileName(fileName) { getCanonicalFileName(fileName) {
return fileName; return fileName;
} }
// getNewLine(): string
getNewLine() { getNewLine() {
return "\n"; return "\n";
} }
// readDirectory?(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): string[]; /**
readDirectory() { * @param {string[]} moduleNames
unreachable(); * @param {string} containingFile
} * @return {Array<ts.ResolvedModule | undefined>}
*/
// resolveModuleNames?(
// moduleNames: string[],
// containingFile: string,
// reusedNames?: string[],
// redirectedReference?: ResolvedProjectReference
// ): (ResolvedModule | undefined)[];
resolveModuleNames(moduleNames, containingFile) { resolveModuleNames(moduleNames, containingFile) {
/** @type {string[]} */
const resolvedNames = dispatch("resolveModuleNames", { const resolvedNames = dispatch("resolveModuleNames", {
moduleNames, moduleNames,
containingFile containingFile
@ -216,37 +246,18 @@ class Host {
}); });
return r; return r;
} }
// resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[];
/*
resolveTypeReferenceDirectives() {
unreachable();
}
*/
// getEnvironmentVariable?(name: string): string | undefined;
getEnvironmentVariable() {
unreachable();
}
// createHash?(data: string): string;
createHash() {
unreachable();
}
// getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined;
getParsedCommandLine() {
unreachable();
}
} }
/**
* @param {string} configurationText
*/
function configure(configurationText) { function configure(configurationText) {
const { config, error } = ts.parseConfigFileTextToJson( const { config, error } = ts.parseConfigFileTextToJson(
"tsconfig.json", "tsconfig.json",
configurationText configurationText
); );
if (error) { if (error) {
return { diagnostics: [error] }; return { options: {}, diagnostics: [error] };
} }
const { options, errors } = ts.convertCompilerOptionsFromJson( const { options, errors } = ts.convertCompilerOptionsFromJson(
config.compilerOptions, config.compilerOptions,
@ -258,6 +269,10 @@ function configure(configurationText) {
}; };
} }
/**
* @param {string} opName
* @param {Record<string,any>} obj
*/
function dispatch(opName, obj) { function dispatch(opName, obj) {
const s = JSON.stringify(obj); const s = JSON.stringify(obj);
const msg = encode(s); const msg = encode(s);
@ -270,14 +285,21 @@ function dispatch(opName, obj) {
return res["ok"]; return res["ok"];
} }
/**
* @param {number} code
*/
function exit(code) { function exit(code) {
dispatch("exit", { code }); dispatch("exit", { code });
unreachable(); return unreachable();
} }
// Maximum number of diagnostics to display. // Maximum number of diagnostics to display.
const MAX_ERRORS = 5; const MAX_ERRORS = 5;
/**
* @param {ts.CompilerHost} host
* @param {ReadonlyArray<ts.Diagnostic> | undefined} diagnostics
*/
function handleDiagnostics(host, diagnostics) { function handleDiagnostics(host, diagnostics) {
if (diagnostics && diagnostics.length) { if (diagnostics && diagnostics.length) {
let rest = 0; let rest = 0;
@ -294,7 +316,10 @@ function handleDiagnostics(host, diagnostics) {
} }
} }
/** Returns the TypeScript Extension enum for a given media type. */ /** Returns the TypeScript Extension enum for a given media type.
* @param {string} fileName
* @returns {ts.Extension}
*/
function getExtension(fileName) { function getExtension(fileName) {
if (fileName.endsWith(".d.ts")) { if (fileName.endsWith(".d.ts")) {
return ts.Extension.Dts; return ts.Extension.Dts;

13
deno_typescript/globals.d.ts vendored Normal file
View file

@ -0,0 +1,13 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
// This scopes the `ts` namespace globally, which is where it exists at runtime
// when building Deno, but the `typescript/lib/typescript.d.ts` is defined as a
// module
import * as _ts from "typescript";
declare global {
namespace ts {
export = _ts;
}
}

View file

@ -0,0 +1,6 @@
{
"compilerOptions": {
"strict": true,
"target": "esnext"
}
}