mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
Improve globals for runtime type library
This commit is contained in:
parent
c4bddc4651
commit
64f0dfd50e
5 changed files with 53 additions and 72 deletions
|
@ -1,19 +1,19 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
import * as blob from "./blob";
|
import * as blob from "./blob";
|
||||||
import * as console from "./console";
|
import * as console_ from "./console";
|
||||||
import * as fetch_ from "./fetch";
|
import * as fetch_ from "./fetch";
|
||||||
import { globalEval } from "./global_eval";
|
import { globalEval } from "./global_eval";
|
||||||
import { libdeno } from "./libdeno";
|
import { libdeno } from "./libdeno";
|
||||||
import * as textEncoding from "./text_encoding";
|
import * as textEncoding from "./text_encoding";
|
||||||
import * as timers from "./timers";
|
import * as timers from "./timers";
|
||||||
import * as urlsearchparams from "./url_search_params";
|
import * as urlSearchParams from "./url_search_params";
|
||||||
|
|
||||||
// During the build process, augmentations to the variable `window` in this
|
// During the build process, augmentations to the variable `window` in this
|
||||||
// file are tracked and created as part of default library that is built into
|
// file are tracked and created as part of default library that is built into
|
||||||
// deno, we only need to declare the enough to compile deno.
|
// deno, we only need to declare the enough to compile deno.
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
const console: console.Console;
|
const console: console_.Console;
|
||||||
const setTimeout: typeof timers.setTimeout;
|
const setTimeout: typeof timers.setTimeout;
|
||||||
// tslint:disable-next-line:variable-name
|
// tslint:disable-next-line:variable-name
|
||||||
const TextEncoder: typeof textEncoding.TextEncoder;
|
const TextEncoder: typeof textEncoding.TextEncoder;
|
||||||
|
@ -28,13 +28,13 @@ window.setInterval = timers.setInterval;
|
||||||
window.clearTimeout = timers.clearTimer;
|
window.clearTimeout = timers.clearTimer;
|
||||||
window.clearInterval = timers.clearTimer;
|
window.clearInterval = timers.clearTimer;
|
||||||
|
|
||||||
window.console = new console.Console(libdeno.print);
|
window.console = new console_.Console(libdeno.print);
|
||||||
window.TextEncoder = textEncoding.TextEncoder;
|
window.TextEncoder = textEncoding.TextEncoder;
|
||||||
window.TextDecoder = textEncoding.TextDecoder;
|
window.TextDecoder = textEncoding.TextDecoder;
|
||||||
window.atob = textEncoding.atob;
|
window.atob = textEncoding.atob;
|
||||||
window.btoa = textEncoding.btoa;
|
window.btoa = textEncoding.btoa;
|
||||||
|
|
||||||
window.URLSearchParams = urlsearchparams.URLSearchParams;
|
window.URLSearchParams = urlSearchParams.URLSearchParams;
|
||||||
|
|
||||||
window.fetch = fetch_.fetch;
|
window.fetch = fetch_.fetch;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
[WILDCARD]~~~~~~[0m
|
[WILDCARD]~~~~~~[0m
|
||||||
|
|
||||||
[96m$asset$/lib.deno_runtime.d.ts[WILDCARD]
|
[96m$asset$/lib.deno_runtime.d.ts[WILDCARD]
|
||||||
[WILDCARD]const console: console.Console;
|
[WILDCARD]declare const console: console_.Console;
|
||||||
[WILDCARD]~~~~~~~[0m
|
[WILDCARD]~~~~~~~[0m
|
||||||
[WILDCARD]'console' is declared here.
|
[WILDCARD]'console' is declared here.
|
||||||
|
|
||||||
|
|
|
@ -47,12 +47,14 @@ export function addVariableDeclaration(
|
||||||
node: StatementedNode,
|
node: StatementedNode,
|
||||||
name: string,
|
name: string,
|
||||||
type: string,
|
type: string,
|
||||||
|
hasDeclareKeyword?: boolean,
|
||||||
jsdocs?: JSDoc[]
|
jsdocs?: JSDoc[]
|
||||||
): VariableStatement {
|
): VariableStatement {
|
||||||
return node.addVariableStatement({
|
return node.addVariableStatement({
|
||||||
declarationKind: VariableDeclarationKind.Const,
|
declarationKind: VariableDeclarationKind.Const,
|
||||||
declarations: [{ name, type }],
|
declarations: [{ name, type }],
|
||||||
docs: jsdocs && jsdocs.map(jsdoc => jsdoc.getText())
|
docs: jsdocs && jsdocs.map(jsdoc => jsdoc.getText()),
|
||||||
|
hasDeclareKeyword
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,8 +283,17 @@ export function namespaceSourceFile(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO need to properly unwrap this
|
||||||
const globalNamespace = sourceFile.getNamespace("global");
|
const globalNamespace = sourceFile.getNamespace("global");
|
||||||
const globalNamespaceText = globalNamespace && globalNamespace.print();
|
let globalNamespaceText = "";
|
||||||
|
if (globalNamespace) {
|
||||||
|
const structure = globalNamespace.getStructure();
|
||||||
|
if (structure.bodyText && typeof structure.bodyText === "string") {
|
||||||
|
globalNamespaceText = structure.bodyText;
|
||||||
|
} else {
|
||||||
|
throw new TypeError("Unexpected global declaration structure.");
|
||||||
|
}
|
||||||
|
}
|
||||||
if (globalNamespace) {
|
if (globalNamespace) {
|
||||||
globalNamespace.remove();
|
globalNamespace.remove();
|
||||||
}
|
}
|
||||||
|
@ -319,7 +330,8 @@ export function namespaceSourceFile(
|
||||||
|
|
||||||
return `${output}
|
return `${output}
|
||||||
${globalNamespaceText || ""}
|
${globalNamespaceText || ""}
|
||||||
namespace ${namespace} {
|
|
||||||
|
declare namespace ${namespace} {
|
||||||
${debug ? getSourceComment(sourceFile, rootPath) : ""}
|
${debug ? getSourceComment(sourceFile, rootPath) : ""}
|
||||||
${sourceFile.getText()}
|
${sourceFile.getText()}
|
||||||
}`;
|
}`;
|
||||||
|
|
|
@ -123,54 +123,36 @@ export function flatten({
|
||||||
namespace.addStatements(statements);
|
namespace.addStatements(statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MergeOptions {
|
interface MergeGlobalOptions {
|
||||||
basePath: string;
|
basePath: string;
|
||||||
declarationProject: Project;
|
|
||||||
debug?: boolean;
|
debug?: boolean;
|
||||||
globalVarName: string;
|
declarationProject: Project;
|
||||||
filePath: string;
|
filePath: string;
|
||||||
|
globalVarName: string;
|
||||||
inputProject: Project;
|
inputProject: Project;
|
||||||
interfaceName: string;
|
interfaceName: string;
|
||||||
namespaceName: string;
|
|
||||||
targetSourceFile: SourceFile;
|
targetSourceFile: SourceFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Take a module and merge into into a single namespace */
|
/** Take a module and merge it into the global scope */
|
||||||
export function merge({
|
export function mergeGlobal({
|
||||||
basePath,
|
basePath,
|
||||||
declarationProject,
|
|
||||||
debug,
|
debug,
|
||||||
globalVarName,
|
declarationProject,
|
||||||
filePath,
|
filePath,
|
||||||
|
globalVarName,
|
||||||
inputProject,
|
inputProject,
|
||||||
interfaceName,
|
interfaceName,
|
||||||
namespaceName,
|
|
||||||
targetSourceFile
|
targetSourceFile
|
||||||
}: MergeOptions) {
|
}: MergeGlobalOptions): void {
|
||||||
// We have to build the module/namespace in small pieces which will reflect
|
// Add the global object interface
|
||||||
// how the global runtime environment will be for Deno
|
const interfaceDeclaration = targetSourceFile.addInterface({
|
||||||
|
name: interfaceName,
|
||||||
// We need to add a module named `"globals"` which will contain all the global
|
hasDeclareKeyword: true
|
||||||
// runtime context
|
|
||||||
const mergedModule = targetSourceFile.addNamespace({
|
|
||||||
name: namespaceName,
|
|
||||||
hasDeclareKeyword: true,
|
|
||||||
declarationKind: NamespaceDeclarationKind.Module
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add the global Window interface
|
|
||||||
const interfaceDeclaration = mergedModule.addInterface({
|
|
||||||
name: interfaceName
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add the global scope augmentation module of the "globals" module
|
|
||||||
const mergedGlobalNamespace = mergedModule.addNamespace({
|
|
||||||
name: "global",
|
|
||||||
declarationKind: NamespaceDeclarationKind.Global
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Declare the global variable
|
// Declare the global variable
|
||||||
addVariableDeclaration(mergedGlobalNamespace, globalVarName, interfaceName);
|
addVariableDeclaration(targetSourceFile, globalVarName, interfaceName, true);
|
||||||
|
|
||||||
// Add self reference to the global variable
|
// Add self reference to the global variable
|
||||||
addInterfaceProperty(interfaceDeclaration, globalVarName, interfaceName);
|
addInterfaceProperty(interfaceDeclaration, globalVarName, interfaceName);
|
||||||
|
@ -201,9 +183,9 @@ export function merge({
|
||||||
TypeGuards.isPropertyAccessExpression(leftExpression) &&
|
TypeGuards.isPropertyAccessExpression(leftExpression) &&
|
||||||
leftExpression.getExpression().getText() === globalVarName
|
leftExpression.getExpression().getText() === globalVarName
|
||||||
) {
|
) {
|
||||||
const windowProperty = leftExpression.getName();
|
const globalVarProperty = leftExpression.getName();
|
||||||
if (windowProperty !== globalVarName) {
|
if (globalVarProperty !== globalVarName) {
|
||||||
globalVariables.set(windowProperty, {
|
globalVariables.set(globalVarProperty, {
|
||||||
type: firstChild.getType(),
|
type: firstChild.getType(),
|
||||||
node
|
node
|
||||||
});
|
});
|
||||||
|
@ -228,7 +210,7 @@ export function merge({
|
||||||
dependentSourceFiles.add(valueDeclaration.getSourceFile());
|
dependentSourceFiles.add(valueDeclaration.getSourceFile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addVariableDeclaration(mergedGlobalNamespace, property, type);
|
addVariableDeclaration(targetSourceFile, property, type, true);
|
||||||
addInterfaceProperty(interfaceDeclaration, property, type);
|
addInterfaceProperty(interfaceDeclaration, property, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +237,7 @@ export function merge({
|
||||||
const dtsSourceFile = declarationProject.getSourceFileOrThrow(
|
const dtsSourceFile = declarationProject.getSourceFileOrThrow(
|
||||||
dtsFilePath
|
dtsFilePath
|
||||||
);
|
);
|
||||||
mergedModule.addStatements(
|
targetSourceFile.addStatements(
|
||||||
namespaceSourceFile(dtsSourceFile, {
|
namespaceSourceFile(dtsSourceFile, {
|
||||||
debug,
|
debug,
|
||||||
namespace: declaration.getNamespaceImportOrThrow().getText(),
|
namespace: declaration.getNamespaceImportOrThrow().getText(),
|
||||||
|
@ -267,7 +249,7 @@ export function merge({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
addSourceComment(mergedModule, sourceFile, basePath);
|
addSourceComment(targetSourceFile, sourceFile, basePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,20 +395,19 @@ export function main({
|
||||||
console.log(`Created module "deno".`);
|
console.log(`Created module "deno".`);
|
||||||
}
|
}
|
||||||
|
|
||||||
merge({
|
mergeGlobal({
|
||||||
basePath,
|
basePath,
|
||||||
declarationProject,
|
|
||||||
debug,
|
debug,
|
||||||
globalVarName: "window",
|
declarationProject,
|
||||||
filePath: `${basePath}/js/globals.ts`,
|
filePath: `${basePath}/js/globals.ts`,
|
||||||
|
globalVarName: "window",
|
||||||
inputProject,
|
inputProject,
|
||||||
interfaceName: "Window",
|
interfaceName: "Window",
|
||||||
namespaceName: `"globals"`,
|
|
||||||
targetSourceFile: libDTs
|
targetSourceFile: libDTs
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
console.log(`Created module "globals".`);
|
console.log(`Merged "globals" into global scope.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the preamble
|
// Add the preamble
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import { Project, ts } from "ts-simple-ast";
|
import { Project, ts } from "ts-simple-ast";
|
||||||
import { assert, assertEqual, test } from "../../js/testing/testing";
|
import { assert, assertEqual, test } from "../../js/testing/testing";
|
||||||
import { flatten, merge } from "./build_library";
|
import { flatten, mergeGlobal } from "./build_library";
|
||||||
import { loadDtsFiles } from "./ast_util";
|
import { loadDtsFiles } from "./ast_util";
|
||||||
|
|
||||||
const { ModuleKind, ModuleResolutionKind, ScriptTarget } = ts;
|
const { ModuleKind, ModuleResolutionKind, ScriptTarget } = ts;
|
||||||
|
@ -116,7 +116,7 @@ test(function buildLibraryMerge() {
|
||||||
outputSourceFile: targetSourceFile
|
outputSourceFile: targetSourceFile
|
||||||
} = setupFixtures();
|
} = setupFixtures();
|
||||||
|
|
||||||
merge({
|
mergeGlobal({
|
||||||
basePath,
|
basePath,
|
||||||
declarationProject,
|
declarationProject,
|
||||||
debug,
|
debug,
|
||||||
|
@ -124,31 +124,19 @@ test(function buildLibraryMerge() {
|
||||||
filePath: `${buildPath}/globals.ts`,
|
filePath: `${buildPath}/globals.ts`,
|
||||||
inputProject,
|
inputProject,
|
||||||
interfaceName: "FooBar",
|
interfaceName: "FooBar",
|
||||||
namespaceName: `"bazqat"`,
|
|
||||||
targetSourceFile
|
targetSourceFile
|
||||||
});
|
});
|
||||||
|
|
||||||
assert(targetSourceFile.getNamespace(`"bazqat"`) != null);
|
assert(targetSourceFile.getNamespace("moduleC") != null);
|
||||||
assertEqual(targetSourceFile.getNamespaces().length, 1);
|
assertEqual(targetSourceFile.getNamespaces().length, 1);
|
||||||
const namespaceBazqat = targetSourceFile.getNamespaceOrThrow(`"bazqat"`);
|
assert(targetSourceFile.getInterface("FooBar") != null);
|
||||||
assert(namespaceBazqat.getNamespace("global") != null);
|
assertEqual(targetSourceFile.getInterfaces().length, 1);
|
||||||
assert(namespaceBazqat.getNamespace("moduleC") != null);
|
const variableDeclarations = targetSourceFile.getVariableDeclarations();
|
||||||
assertEqual(namespaceBazqat.getNamespaces().length, 2);
|
assertEqual(variableDeclarations[0].getType().getText(), `FooBar`);
|
||||||
assert(namespaceBazqat.getInterface("FooBar") != null);
|
assertEqual(variableDeclarations[1].getType().getText(), `moduleC.Bar`);
|
||||||
assertEqual(namespaceBazqat.getInterfaces().length, 1);
|
|
||||||
const globalNamespace = namespaceBazqat.getNamespaceOrThrow("global");
|
|
||||||
const variableDeclarations = globalNamespace.getVariableDeclarations();
|
|
||||||
assertEqual(
|
|
||||||
variableDeclarations[0].getType().getText(),
|
|
||||||
`import("bazqat").FooBar`
|
|
||||||
);
|
|
||||||
assertEqual(
|
|
||||||
variableDeclarations[1].getType().getText(),
|
|
||||||
`import("bazqat").moduleC.Bar`
|
|
||||||
);
|
|
||||||
assertEqual(
|
assertEqual(
|
||||||
variableDeclarations[2].getType().getText(),
|
variableDeclarations[2].getType().getText(),
|
||||||
`typeof import("bazqat").moduleC.qat`
|
`typeof moduleC.qat`
|
||||||
);
|
);
|
||||||
assertEqual(variableDeclarations.length, 3);
|
assertEqual(variableDeclarations.length, 3);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue