Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e9c3ee5edf |
+60
-68
@@ -18,17 +18,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
import { File, FileTransform } from "async-build";
|
||||
import { FileTransform } from "async-build";
|
||||
|
||||
import * as AST from "./typescript/ast";
|
||||
import { Compiler } from "./typescript/compiler";
|
||||
import { walk } from "./typescript/walker";
|
||||
|
||||
function flatten<T>(arr: T[][]): T[] {
|
||||
var result: T[] = [];
|
||||
let result: T[] = [];
|
||||
|
||||
for (const a of arr) {
|
||||
result = result.concat(a);
|
||||
@@ -37,7 +34,7 @@ function flatten<T>(arr: T[][]): T[] {
|
||||
return result;
|
||||
}
|
||||
|
||||
var sorter = (() => {
|
||||
const sorter = (() => {
|
||||
function visibilitySorter(value1: { isPrivate?: boolean; isProtected?: boolean; }, value2: { isPrivate?: boolean; isProtected?: boolean; }) {
|
||||
if (value1.isPrivate === value2.isPrivate && value1.isProtected === value2.isProtected) {
|
||||
return 0;
|
||||
@@ -62,10 +59,10 @@ var sorter = (() => {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var types = [AST.Property, AST.Function, AST.Interface, AST.Class, AST.Enum];
|
||||
const types = [AST.Property, AST.Function, AST.Interface, AST.Class, AST.Enum];
|
||||
function typeSorter(value1: AST.ModuleMember | AST.NamespaceMember, value2: AST.ModuleMember | AST.NamespaceMember) {
|
||||
var type1Index = -1;
|
||||
var type2Index = -1;
|
||||
let type1Index = -1;
|
||||
let type2Index = -1;
|
||||
|
||||
types.every((type, index) => {
|
||||
if (value1 instanceof type) {
|
||||
@@ -84,11 +81,11 @@ var sorter = (() => {
|
||||
return value1.name.localeCompare(value2.name);
|
||||
}
|
||||
|
||||
var sorters: ((value1: AST.ModuleMember, value2: AST.ModuleMember) => number)[] = [visibilitySorter, typeSorter, nameSorter];
|
||||
const sorters: ((value1: AST.ModuleMember, value2: AST.ModuleMember) => number)[] = [visibilitySorter, typeSorter, nameSorter];
|
||||
|
||||
return (value1: AST.ModuleMember, value2: AST.ModuleMember) => {
|
||||
for (var i = 0; i < sorters.length; i++) {
|
||||
var result = sorters[i](value1, value2);
|
||||
for (const sorter of sorters) {
|
||||
const result = sorter(value1, value2);
|
||||
|
||||
if (result !== 0) {
|
||||
return result;
|
||||
@@ -110,10 +107,10 @@ function sanitize(str: string) {
|
||||
function toVariableName(item: { name: string }) {
|
||||
// TODO: Handle non-letters (are both their toLowerCase() and toUpperCase())
|
||||
|
||||
var name = item.name;
|
||||
var result = "";
|
||||
const name = item.name;
|
||||
let result = "";
|
||||
|
||||
for (var i = 0; i < name.length; i++) {
|
||||
for (let i = 0; i < name.length; i++) {
|
||||
if (name[i] === name[i].toLowerCase()) {
|
||||
// This is lower case. Write it as lower case.
|
||||
result += name[i];
|
||||
@@ -168,15 +165,15 @@ function toUsageName(item: AST.Class | AST.Interface | AST.Function | AST.Proper
|
||||
}
|
||||
|
||||
if (item.parent instanceof AST.Namespace) {
|
||||
if ((<AST.Class | AST.Interface | AST.Function | AST.Enum>item).isPrivate) {
|
||||
if ((item as AST.CanBePrivate).isPrivate) {
|
||||
return item.name;
|
||||
}
|
||||
|
||||
return item.fullName;
|
||||
}
|
||||
|
||||
if ((<AST.Function>item).isStatic) {
|
||||
return toUsageName(<AST.Class | AST.Interface>item.parent) + '.' + item.name;
|
||||
if ((item as AST.CanBeStatic).isStatic) {
|
||||
return toUsageName(item.parent as AST.Class | AST.Interface) + '.' + item.name;
|
||||
}
|
||||
|
||||
return toVariableName(item.parent) + '.' + item.name;
|
||||
@@ -187,13 +184,12 @@ function toId(item: { fullName?: string; name: string; }): string {
|
||||
}
|
||||
|
||||
function toLink(item: AST.ModuleMember | AST.EnumMember | AST.TypeReference): string {
|
||||
var result = `<a href="#${ toId(item) }">${ sanitize(item.name) }`;
|
||||
let result = `<a href="#${ toId(item) }">${ sanitize(item.name) }`;
|
||||
|
||||
var itemWithGenerics = <AST.HasGenerics>item;
|
||||
if (itemWithGenerics.generics !== undefined && itemWithGenerics.generics.length > 0) {
|
||||
var generics = <(string | AST.TypeReference | AST.IntrinsicTypeReference)[]>itemWithGenerics.generics;
|
||||
if (AST.hasGenerics(item) && item.generics.length > 0) {
|
||||
const generics = item.generics as (string | AST.TypeReference | AST.IntrinsicTypeReference)[];
|
||||
result += sanitize(`.<${ generics.map(generic =>
|
||||
(generic instanceof AST.TypeReference || generic instanceof AST.IntrinsicTypeReference) ? generic.name : <string>generic
|
||||
(generic instanceof AST.TypeReference || generic instanceof AST.IntrinsicTypeReference) ? generic.name : generic
|
||||
).join(', ') }>`);
|
||||
}
|
||||
|
||||
@@ -203,9 +199,9 @@ function toLink(item: AST.ModuleMember | AST.EnumMember | AST.TypeReference): st
|
||||
}
|
||||
|
||||
function writeDescription(text: string): string {
|
||||
var result = sanitize(text).replace(/\{@link ([^} ]+)\}/g, (substring, linkTarget) => `<a href="#${ linkTarget }">${ linkTarget }</a>`);
|
||||
let result = sanitize(text).replace(/\{@link ([^} ]+)\}/g, (substring, linkTarget) => `<a href="#${ linkTarget }">${ linkTarget }</a>`);
|
||||
|
||||
var inCodeBlock = false;
|
||||
let inCodeBlock = false;
|
||||
result = result.split("\n").map(line => {
|
||||
if (line.substr(0, " ".length) === " ") {
|
||||
line = line.substr(" ".length);
|
||||
@@ -288,7 +284,7 @@ function functionToHtml(func: AST.Function): string[] {
|
||||
}
|
||||
|
||||
function interfaceToHtml(interfase: AST.Interface): string[] {
|
||||
var members: AST.InterfaceMember[] = [];
|
||||
const members: AST.InterfaceMember[] = [];
|
||||
Object.keys(interfase.members).forEach(memberName => members.push(interfase.members[memberName]));
|
||||
|
||||
members.sort(sorter);
|
||||
@@ -310,7 +306,7 @@ function interfaceToHtml(interfase: AST.Interface): string[] {
|
||||
return functionToHtml(member).map(indenter(2));
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unrecognized member type: ${ (<any>member.constructor).name }`);
|
||||
throw new Error(`Unrecognized member type: ${ (member as any).constructor.name }`);
|
||||
}
|
||||
}))).concat([
|
||||
' </dd>',
|
||||
@@ -320,7 +316,7 @@ function interfaceToHtml(interfase: AST.Interface): string[] {
|
||||
}
|
||||
|
||||
function classToHtml(clazz: AST.Class): string[] {
|
||||
var members: AST.InterfaceMember[] = [];
|
||||
const members: AST.InterfaceMember[] = [];
|
||||
Object.keys(clazz.members).forEach(memberName => members.push(clazz.members[memberName]));
|
||||
|
||||
members.sort(sorter);
|
||||
@@ -330,7 +326,7 @@ function classToHtml(clazz: AST.Class): string[] {
|
||||
clazz.isAbstract ? ' abstract' : ''}${
|
||||
clazz.isPrivate ? ' private' : ''}">`,
|
||||
` <dt class="name">class ${ toLink(clazz) }${
|
||||
(clazz.baseType !== null) ? ` extends ${ (clazz.baseType instanceof AST.TypeReference) ? toLink(<AST.TypeReference>clazz.baseType) : clazz.baseType.name }` : '' }${
|
||||
(clazz.baseType !== null) ? ` extends ${ (clazz.baseType instanceof AST.TypeReference) ? toLink(clazz.baseType) : clazz.baseType.name }` : '' }${
|
||||
(clazz.interfaces.length > 0) ? ` implements ${ clazz.interfaces.map(interfase => interfase instanceof AST.TypeReference ? toLink(interfase) : interfase.name).join(', ') }` : ''}</dt>`,
|
||||
' <dd class="description">',
|
||||
` ${ writeDescription(clazz.description) }`,
|
||||
@@ -350,7 +346,7 @@ function classToHtml(clazz: AST.Class): string[] {
|
||||
return functionToHtml(member).map(indenter(2));
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unrecognized member type: ${ (<any>member.constructor).name }`);
|
||||
throw new Error(`Unrecognized member type: ${ (member as any).constructor.name }`);
|
||||
}
|
||||
}))).concat([
|
||||
' </dd>',
|
||||
@@ -406,30 +402,26 @@ function propertyToHtml(property: AST.Property): string[] {
|
||||
}
|
||||
|
||||
export function build(outputFilePath: string, root: string, rootNamespaceName: string): FileTransform {
|
||||
var compiler = new Compiler();
|
||||
|
||||
return new FileTransform(function (file: File): void {
|
||||
var self: FileTransform = this;
|
||||
const compiler = new Compiler();
|
||||
|
||||
return new FileTransform(function (file): void {
|
||||
// Compile
|
||||
compiler.compile(file);
|
||||
|
||||
// Walk
|
||||
var walkResult = walk(compiler, root, rootNamespaceName);
|
||||
var namespaces = walkResult.namespaces;
|
||||
var modules = walkResult.modules;
|
||||
const walkResult = walk(compiler, root, rootNamespaceName);
|
||||
const namespaces = walkResult.namespaces;
|
||||
const modules = walkResult.modules;
|
||||
|
||||
// Make HTML
|
||||
|
||||
var namespaceNames = Object.keys(namespaces)
|
||||
const namespaceNames = Object.keys(namespaces)
|
||||
.filter(namespaceName => namespaceName.substr(0, rootNamespaceName.length) === rootNamespaceName)
|
||||
.sort((ns1, ns2) => ns1.localeCompare(ns2));
|
||||
|
||||
var moduleNames = Object.keys(modules).sort((ns1, ns2) => ns1.localeCompare(ns2));
|
||||
const moduleNames = Object.keys(modules).sort((ns1, ns2) => ns1.localeCompare(ns2)).filter(moduleName => Object.keys(modules[moduleName].members).length > 0);
|
||||
|
||||
moduleNames = moduleNames.filter(moduleName => Object.keys(modules[moduleName].members).length > 0);
|
||||
|
||||
self.push({
|
||||
this.push({
|
||||
path: outputFilePath,
|
||||
contents: Buffer.concat([new Buffer(
|
||||
`<?xml version="1.0" encoding="utf-8" ?>
|
||||
@@ -589,9 +581,9 @@ export function build(outputFilePath: string, root: string, rootNamespaceName: s
|
||||
<label><input type="checkbox" id="show-private" />Show private</label>
|
||||
`
|
||||
)].concat(namespaceNames.map(namespaceName => {
|
||||
var namespace = namespaces[namespaceName];
|
||||
const namespace = namespaces[namespaceName];
|
||||
|
||||
var namespaceMembers: AST.NamespaceMember[] = [];
|
||||
const namespaceMembers: AST.NamespaceMember[] = [];
|
||||
for (const memberName of Object.keys(namespace.members)) {
|
||||
namespaceMembers.push(namespace.members[memberName]);
|
||||
}
|
||||
@@ -613,13 +605,13 @@ export function build(outputFilePath: string, root: string, rootNamespaceName: s
|
||||
`
|
||||
)]));
|
||||
})).concat(moduleNames.map(moduleName => {
|
||||
var module = modules[moduleName];
|
||||
const module = modules[moduleName];
|
||||
|
||||
var moduleMembers: AST.ModuleMemberWithoutReference[] = [];
|
||||
const moduleMembers: AST.ModuleMemberWithoutReference[] = [];
|
||||
for (const memberName of Object.keys(module.members)) {
|
||||
var member = module.members[memberName];
|
||||
if ((<AST.HasParent><any>member).parent === module) {
|
||||
moduleMembers.push(<AST.ModuleMemberWithoutReference>member);
|
||||
const member = module.members[memberName];
|
||||
if ((member as AST.HasParent).parent === module) {
|
||||
moduleMembers.push(member as AST.ModuleMemberWithoutReference);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,22 +641,22 @@ export function build(outputFilePath: string, root: string, rootNamespaceName: s
|
||||
<div class="content">
|
||||
`
|
||||
)]).concat(flatten(namespaceNames.map(namespaceName => {
|
||||
var namespace = namespaces[namespaceName];
|
||||
const namespace = namespaces[namespaceName];
|
||||
|
||||
var namespaceMembers: AST.NamespaceMember[] = [];
|
||||
const namespaceMembers: AST.NamespaceMember[] = [];
|
||||
for (const memberName of Object.keys(namespace.members)) {
|
||||
namespaceMembers.push(namespace.members[memberName]);
|
||||
}
|
||||
|
||||
namespaceMembers.sort(sorter);
|
||||
|
||||
var properties = <AST.Property[]>namespaceMembers.filter(member => member instanceof AST.Property);
|
||||
var functions = <AST.Function[]>namespaceMembers.filter(member => member instanceof AST.Function);
|
||||
var interfaces = <AST.Interface[]>namespaceMembers.filter(member => member instanceof AST.Interface);
|
||||
var classes = <AST.Class[]>namespaceMembers.filter(member => member instanceof AST.Class);
|
||||
var enums = <AST.Enum[]>namespaceMembers.filter(member => member instanceof AST.Enum);
|
||||
const properties = namespaceMembers.filter(member => member instanceof AST.Property) as AST.Property[];
|
||||
const functions = namespaceMembers.filter(member => member instanceof AST.Function) as AST.Function[];
|
||||
const interfaces = namespaceMembers.filter(member => member instanceof AST.Interface) as AST.Interface[];
|
||||
const classes = namespaceMembers.filter(member => member instanceof AST.Class) as AST.Class[];
|
||||
const enums = namespaceMembers.filter(member => member instanceof AST.Enum) as AST.Enum[];
|
||||
|
||||
var result = [new Buffer(
|
||||
const result = [new Buffer(
|
||||
` <section class="namespace">
|
||||
<h1 id="${ sanitize(namespaceName) }">Namespace ${ sanitize(namespaceName) }</h1>
|
||||
`
|
||||
@@ -762,13 +754,13 @@ export function build(outputFilePath: string, root: string, rootNamespaceName: s
|
||||
|
||||
return result;
|
||||
}))).concat(flatten(moduleNames.map(moduleName => {
|
||||
var module = modules[moduleName];
|
||||
const module = modules[moduleName];
|
||||
|
||||
var moduleMembers: AST.ModuleMember[] = [];
|
||||
const moduleMembers: AST.ModuleMember[] = [];
|
||||
for (const memberName of Object.keys(module.members)) {
|
||||
var member = module.members[memberName];
|
||||
if ((<AST.HasParent><any>member).parent === module) {
|
||||
moduleMembers.push(<AST.ModuleMember>member);
|
||||
const member = module.members[memberName];
|
||||
if ((member as AST.HasParent).parent === module) {
|
||||
moduleMembers.push(member);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -778,13 +770,13 @@ export function build(outputFilePath: string, root: string, rootNamespaceName: s
|
||||
|
||||
moduleMembers.sort(sorter);
|
||||
|
||||
var properties = <AST.Property[]>moduleMembers.filter(member => member instanceof AST.Property);
|
||||
var functions = <AST.Function[]>moduleMembers.filter(member => member instanceof AST.Function);
|
||||
var interfaces = <AST.Interface[]>moduleMembers.filter(member => member instanceof AST.Interface);
|
||||
var classes = <AST.Class[]>moduleMembers.filter(member => member instanceof AST.Class);
|
||||
var enums = <AST.Enum[]>moduleMembers.filter(member => member instanceof AST.Enum);
|
||||
const properties = moduleMembers.filter(member => member instanceof AST.Property) as AST.Property[];
|
||||
const functions = moduleMembers.filter(member => member instanceof AST.Function) as AST.Function[];
|
||||
const interfaces = moduleMembers.filter(member => member instanceof AST.Interface) as AST.Interface[];
|
||||
const classes = moduleMembers.filter(member => member instanceof AST.Class) as AST.Class[];
|
||||
const enums = moduleMembers.filter(member => member instanceof AST.Enum) as AST.Enum[];
|
||||
|
||||
var result = [new Buffer(
|
||||
const result = [new Buffer(
|
||||
` <section class="module">
|
||||
<h1 id="${ sanitize(moduleName) }">Module ${ sanitize(moduleName) }</h1>
|
||||
`
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": false,
|
||||
"strictNullChecks": false,
|
||||
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "classic",
|
||||
"noImplicitUseStrict": false
|
||||
},
|
||||
|
||||
"files": [
|
||||
"./typescript/index.ts",
|
||||
"./doc.ts",
|
||||
"./node.d.ts",
|
||||
"./typescript/typescript.d.ts",
|
||||
"../node_modules/async-build/typings.d.ts"
|
||||
]
|
||||
}
|
||||
+12
-2
@@ -18,7 +18,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as ts from "typescript";
|
||||
import ts = require("typescript");
|
||||
|
||||
export class HasParent {
|
||||
public parent: HasParent = null;
|
||||
@@ -30,7 +30,7 @@ export class HasParent {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
var parent = this.parent;
|
||||
const parent = this.parent;
|
||||
if (parent instanceof Namespace) {
|
||||
return parent.getMemberFullName(this);
|
||||
}
|
||||
@@ -188,7 +188,17 @@ export class UnresolvedType {
|
||||
}
|
||||
|
||||
export type HasStringGenerics = Class | Interface | Function;
|
||||
|
||||
export function hasStringGenerics(item: NamespaceMember): item is HasStringGenerics {
|
||||
return (item as HasGenerics).generics !== undefined;
|
||||
}
|
||||
|
||||
export type HasGenerics = HasStringGenerics | TypeReference;
|
||||
|
||||
export function hasGenerics(item: ModuleMember | EnumMember | TypeReference): item is HasGenerics {
|
||||
return (item as HasGenerics).generics !== undefined;
|
||||
}
|
||||
|
||||
export type CanBePrivate = Class | Interface | Function | Getter | Setter | Enum | Reference;
|
||||
export type CanBeProtected = Function;
|
||||
export type CanBeStatic = Function;
|
||||
|
||||
+57
-178
@@ -18,33 +18,52 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as ts from "typescript";
|
||||
import path = require("path");
|
||||
import ts = require("typescript");
|
||||
|
||||
import { File, FileTransform, FileWatcher } from "async-build";
|
||||
import { File, FileTransform } from "async-build";
|
||||
|
||||
import * as AST from "./ast";
|
||||
import { walk } from "./walker";
|
||||
|
||||
export interface StreamingCompilerHost extends ts.CompilerHost, ts.ParseConfigHost {
|
||||
export interface StreamingCompilerHost extends ts.CompilerHost {
|
||||
setOutputStream(outputStream: FileTransform): void;
|
||||
}
|
||||
|
||||
function createCompilerHost(options: ts.CompilerOptions): StreamingCompilerHost {
|
||||
const host = ts.createCompilerHost(options) as StreamingCompilerHost;
|
||||
|
||||
let _outputStream: FileTransform = null;
|
||||
host.setOutputStream = outputStream => _outputStream = outputStream;
|
||||
|
||||
host.writeFile = (fileName, data, writeByteOrderMark, onError?, sourceFiles?): void => {
|
||||
_outputStream.push({
|
||||
path: fileName,
|
||||
contents: new Buffer(data)
|
||||
});
|
||||
};
|
||||
|
||||
host.useCaseSensitiveFileNames = () => true;
|
||||
|
||||
host.getNewLine = () => "\n";
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
export class Compiler {
|
||||
private _projectRoot: string = null;
|
||||
private _host: StreamingCompilerHost;
|
||||
private _program: ts.Program = null;
|
||||
|
||||
constructor(private _host: StreamingCompilerHost = new CompilerHost()) { }
|
||||
|
||||
compile(projectConfigFile: File) {
|
||||
this._projectRoot = path.dirname(projectConfigFile.path);
|
||||
|
||||
var projectConfig = ts.parseJsonConfigFileContent(JSON.parse(projectConfigFile.contents.toString()), this._host, this._projectRoot);
|
||||
const projectConfig = ts.parseJsonConfigFileContent(JSON.parse(projectConfigFile.contents.toString()), ts.sys, this._projectRoot);
|
||||
|
||||
this._host = createCompilerHost(projectConfig.options);
|
||||
this._program = ts.createProgram(projectConfig.fileNames, projectConfig.options, this._host);
|
||||
|
||||
var syntacticDiagnostics = this._program.getSyntacticDiagnostics();
|
||||
const syntacticDiagnostics = this._program.getSyntacticDiagnostics();
|
||||
if (syntacticDiagnostics.length > 0) {
|
||||
this._reportDiagnostics(syntacticDiagnostics);
|
||||
throw new Error("There were one or more syntactic diagnostics.");
|
||||
@@ -56,13 +75,13 @@ export class Compiler {
|
||||
throw new Error("There were one or more options diagnostics.");
|
||||
}
|
||||
|
||||
var globalDiagnostics = this._program.getGlobalDiagnostics();
|
||||
const globalDiagnostics = this._program.getGlobalDiagnostics();
|
||||
if (globalDiagnostics.length > 0) {
|
||||
this._reportDiagnostics(globalDiagnostics);
|
||||
throw new Error("There were one or more global diagnostics.");
|
||||
}
|
||||
|
||||
var semanticDiagnostics = this._program.getSemanticDiagnostics();
|
||||
const semanticDiagnostics = this._program.getSemanticDiagnostics();
|
||||
if (semanticDiagnostics.length > 0) {
|
||||
this._reportDiagnostics(semanticDiagnostics);
|
||||
throw new Error("There were one or more semantic diagnostics.");
|
||||
@@ -72,7 +91,7 @@ export class Compiler {
|
||||
writeFiles(outputStream: FileTransform) {
|
||||
this._host.setOutputStream(outputStream);
|
||||
|
||||
var emitDiagnostics = this._program.emit().diagnostics;
|
||||
const emitDiagnostics = this._program.emit().diagnostics;
|
||||
if (emitDiagnostics.length > 0) {
|
||||
this._reportDiagnostics(emitDiagnostics);
|
||||
throw new Error("There were one or more emit diagnostics.");
|
||||
@@ -93,10 +112,10 @@ export class Compiler {
|
||||
|
||||
private _reportDiagnostics(diagnostics: ts.Diagnostic[]) {
|
||||
for (const diagnostic of diagnostics) {
|
||||
var message = "";
|
||||
let message = "";
|
||||
|
||||
if (diagnostic.file) {
|
||||
var location = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
||||
const location = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
||||
message = `${ diagnostic.file.fileName }(${ location.line + 1 },${ location.character }): `;
|
||||
}
|
||||
|
||||
@@ -110,168 +129,23 @@ export class Compiler {
|
||||
};
|
||||
}
|
||||
|
||||
const typeScriptModulePath = path.dirname(require.resolve("typescript"));
|
||||
|
||||
class CompilerHost implements StreamingCompilerHost {
|
||||
protected _sourceFiles = Object.create(null);
|
||||
|
||||
private _outputStream: FileTransform = null;
|
||||
|
||||
setOutputStream(outputStream: FileTransform): void {
|
||||
this._outputStream = outputStream;
|
||||
}
|
||||
|
||||
// ts.ModuleResolutionHost members
|
||||
|
||||
fileExists(fileName: string): boolean {
|
||||
return fs.existsSync(fileName);
|
||||
}
|
||||
|
||||
readFile(fileName: string): string {
|
||||
if (!this.fileExists(fileName)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return fs.readFileSync(fileName, { encoding: "utf8" });
|
||||
}
|
||||
|
||||
// ts.CompilerHost members
|
||||
|
||||
getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError: (message: string) => void): ts.SourceFile {
|
||||
if (fileName in this._sourceFiles) {
|
||||
return this._sourceFiles[fileName];
|
||||
}
|
||||
|
||||
try {
|
||||
var text = fs.readFileSync(fileName, { encoding: "utf8" });
|
||||
var result = ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5);
|
||||
this._sourceFiles[fileName] = result;
|
||||
}
|
||||
catch (ex) {
|
||||
if (onError) {
|
||||
onError(ex.message);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
getDefaultLibFileName(): string {
|
||||
return path.join(typeScriptModulePath, "lib.dom.d.ts");
|
||||
}
|
||||
|
||||
writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError: (message?: string) => void): void {
|
||||
this._outputStream.push({
|
||||
path: fileName,
|
||||
contents: new Buffer(data)
|
||||
});
|
||||
}
|
||||
|
||||
getCurrentDirectory(): string {
|
||||
return path.resolve(".");
|
||||
}
|
||||
|
||||
getCanonicalFileName(fileName: string): string {
|
||||
return ts.normalizeSlashes(path.resolve(fileName));
|
||||
}
|
||||
|
||||
useCaseSensitiveFileNames(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
getNewLine(): string {
|
||||
return "\n";
|
||||
}
|
||||
|
||||
// ts.ParseConfigHost members
|
||||
|
||||
readDirectory(rootDir: string, extension: string, exclude: string[]): string[] {
|
||||
return ts.sys.readDirectory(rootDir, extension, exclude).map(fileName => this.getCanonicalFileName(fileName));
|
||||
}
|
||||
}
|
||||
|
||||
class WatchCompilerHost extends CompilerHost {
|
||||
private _fileWatcher = new FileWatcher(fileNames => this._onFilesChanged(fileNames));
|
||||
|
||||
private _filesChangedSinceLast: string[] = [];
|
||||
|
||||
constructor(private _onChangeCallback: () => void) {
|
||||
super();
|
||||
}
|
||||
|
||||
getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError: (message: string) => void): ts.SourceFile {
|
||||
var result = super.getSourceFile(fileName, languageVersion, onError);
|
||||
if (result !== undefined) {
|
||||
this._fileWatcher.watchFile(fileName);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
private _onFilesChanged(fileNames: string[]) {
|
||||
for (const fileName of fileNames) {
|
||||
delete this._sourceFiles[fileName];
|
||||
}
|
||||
|
||||
this._onChangeCallback();
|
||||
}
|
||||
}
|
||||
|
||||
export function build(root: string, rootNamespaceName: string): FileTransform {
|
||||
var compiler = new Compiler();
|
||||
|
||||
return new FileTransform(function (projectConfigFile: File): void {
|
||||
var self: FileTransform = this;
|
||||
const compiler = new Compiler();
|
||||
|
||||
return new FileTransform(function (projectConfigFile): void {
|
||||
console.log("Compiling " + projectConfigFile.path + "...");
|
||||
|
||||
compiler.compile(projectConfigFile);
|
||||
|
||||
var walkResult = walk(compiler, root, rootNamespaceName);
|
||||
const walkResult = walk(compiler, root, rootNamespaceName);
|
||||
addJSDocComments(walkResult.modules);
|
||||
|
||||
compiler.writeFiles(self);
|
||||
compiler.writeFiles(this);
|
||||
|
||||
console.log("Compile succeeded.");
|
||||
});
|
||||
}
|
||||
|
||||
export function watch(root: string, rootNamespaceName: string): FileTransform {
|
||||
return new FileTransform(function (projectConfigFile: File): void {
|
||||
var self: FileTransform = this;
|
||||
|
||||
function compile() {
|
||||
console.log("Compiling " + projectConfigFile.path + "...");
|
||||
|
||||
compiler.compile(projectConfigFile);
|
||||
|
||||
compiler.writeFiles(self);
|
||||
|
||||
console.log("Compile succeeded.");
|
||||
|
||||
self.push({
|
||||
path: "END",
|
||||
contents: ""
|
||||
});
|
||||
};
|
||||
|
||||
var compilerHost = new WatchCompilerHost(() => {
|
||||
try {
|
||||
compile();
|
||||
}
|
||||
catch (ex) {
|
||||
console.error("Compile failed." + ex.stack);
|
||||
}
|
||||
});
|
||||
|
||||
var compiler = new Compiler(compilerHost);
|
||||
|
||||
compile();
|
||||
|
||||
console.log("Listening for changes...");
|
||||
}, callback => { });
|
||||
}
|
||||
|
||||
function addJSDocComments(modules: { [name: string]: AST.Module }): void {
|
||||
function visitor(current: AST.Module | AST.ModuleMember | AST.InterfaceMember) {
|
||||
if (current instanceof AST.Module) {
|
||||
@@ -282,18 +156,18 @@ function addJSDocComments(modules: { [name: string]: AST.Module }): void {
|
||||
return;
|
||||
}
|
||||
|
||||
var newComments: string[] = [];
|
||||
const newComments: string[] = [];
|
||||
|
||||
if (current instanceof AST.Class) {
|
||||
newComments.push("@constructor");
|
||||
|
||||
if (current.baseType !== null) {
|
||||
var baseType = current.baseType;
|
||||
const baseType = current.baseType;
|
||||
newComments.push(
|
||||
"@extends {" +
|
||||
baseType.fullName + (
|
||||
(baseType instanceof AST.TypeReference && baseType.generics.length) > 0 ?
|
||||
(".<" + (<AST.TypeReference>baseType).generics.map(generic => generic.fullName).join(", ") + ">") :
|
||||
(".<" + (baseType as AST.TypeReference).generics.map(generic => generic.fullName).join(", ") + ">") :
|
||||
""
|
||||
) +
|
||||
"}"
|
||||
@@ -323,37 +197,37 @@ function addJSDocComments(modules: { [name: string]: AST.Module }): void {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((<AST.HasParent><any>current).parent instanceof AST.Namespace) {
|
||||
newComments.push("@memberOf " + (<AST.HasParent><any>current).parent.fullName);
|
||||
if (current.parent instanceof AST.Namespace) {
|
||||
newComments.push("@memberOf " + current.parent.fullName);
|
||||
}
|
||||
|
||||
if ((<AST.HasStringGenerics>current).generics !== undefined && (<AST.HasStringGenerics>current).generics.length > 0) {
|
||||
newComments.push("@template " + (<AST.HasStringGenerics>current).generics.join(", "));
|
||||
if (AST.hasStringGenerics(current) && current.generics.length > 0) {
|
||||
newComments.push("@template " + current.generics.join(", "));
|
||||
}
|
||||
|
||||
if ((<AST.CanBePrivate><any>current).isPrivate) {
|
||||
if ((current as AST.CanBePrivate).isPrivate) {
|
||||
newComments.push("@private");
|
||||
}
|
||||
|
||||
if ((<AST.CanBeProtected>current).isProtected) {
|
||||
if ((current as AST.CanBeProtected).isProtected) {
|
||||
newComments.push("@protected");
|
||||
}
|
||||
|
||||
if ((<AST.CanBeStatic>current).isStatic) {
|
||||
if ((current as AST.CanBeStatic).isStatic) {
|
||||
newComments.push("@static");
|
||||
}
|
||||
|
||||
if (newComments.length > 0) {
|
||||
if (current instanceof AST.Property) {
|
||||
var nodes: ts.Node[] = [];
|
||||
const nodes: ts.Node[] = [];
|
||||
if (current.getter !== null) { nodes.push(current.getter.astNode); }
|
||||
if (current.setter !== null && nodes[0] !== current.setter.astNode) { nodes.push(current.setter.astNode); }
|
||||
for (const node of nodes) {
|
||||
(<any>node)["typescript-new-comment"] = newComments;
|
||||
(node as any)["typescript-new-comment"] = newComments;
|
||||
}
|
||||
}
|
||||
else {
|
||||
(<any>(<AST.Class | AST.Interface | AST.Function | AST.Enum>current).astNode)["typescript-new-comment"] = newComments;
|
||||
(current.astNode as any)["typescript-new-comment"] = newComments;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,6 +237,7 @@ function addJSDocComments(modules: { [name: string]: AST.Module }): void {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
class FakeSourceFile {
|
||||
public text: string;
|
||||
public lineMap: number[];
|
||||
@@ -403,8 +278,11 @@ class FakeSourceFile {
|
||||
}
|
||||
|
||||
var fakeSourceFiles: { [name: string]: FakeSourceFile } = Object.create(null);
|
||||
*/
|
||||
|
||||
export const oldGetLeadingCommentRangesOfNodeFromText: typeof ts.getLeadingCommentRangesOfNodeFromText = ts.getLeadingCommentRangesOfNodeFromText.bind(ts);
|
||||
|
||||
/*
|
||||
ts.getLeadingCommentRangesOfNodeFromText = (node: ts.Node, text: string) => {
|
||||
const originalComments = oldGetLeadingCommentRangesOfNodeFromText(node, text);
|
||||
|
||||
@@ -422,12 +300,13 @@ ts.getLeadingCommentRangesOfNodeFromText = (node: ts.Node, text: string) => {
|
||||
};
|
||||
|
||||
var oldWriteCommentRange: typeof ts.writeCommentRange = ts.writeCommentRange.bind(ts);
|
||||
ts.writeCommentRange = (text: string, lineMap: number[], writer: ts.EmitTextWriter, comment: ts.CommentRange, newLine: string) => {
|
||||
ts.writeCommentRange = (text: string, lineMap: number[], writer: ts.EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => {
|
||||
if ((<{ sourceFile: ts.SourceFile }><any>comment).sourceFile) {
|
||||
const currentSourceFile = (<{ sourceFile: ts.SourceFile }><any>comment).sourceFile;
|
||||
text = currentSourceFile.text;
|
||||
lineMap = currentSourceFile.lineMap;
|
||||
}
|
||||
|
||||
return oldWriteCommentRange(text, lineMap, writer, comment, newLine);
|
||||
return oldWriteCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
|
||||
};
|
||||
*/
|
||||
|
||||
Vendored
+14
-13
@@ -1,22 +1,23 @@
|
||||
declare namespace ts {
|
||||
export interface EmitTextWriter { }
|
||||
interface EmitTextWriter { }
|
||||
|
||||
export interface IntrinsicType extends Type {
|
||||
interface IntrinsicType extends Type {
|
||||
intrinsicName: string;
|
||||
}
|
||||
|
||||
export interface SourceFile {
|
||||
interface SourceFile {
|
||||
lineMap: number[];
|
||||
}
|
||||
|
||||
export function forEachValue<T, U>(map: Map<T>, callback: (value: T) => U): U;
|
||||
export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration): ExpressionWithTypeArguments;
|
||||
export function getClassImplementsHeritageClauseElements(node: ClassDeclaration): NodeArray<ExpressionWithTypeArguments>;
|
||||
export function getInterfaceBaseTypeNodes(node: InterfaceDeclaration): NodeArray<ExpressionWithTypeArguments>;
|
||||
export function getLeadingCommentRangesOfNodeFromText(node: Node, text: string): CommentRange[];
|
||||
export function getLineStarts(sourceFile: SourceFile): number[];
|
||||
export function getSourceFileOfNode(node: Node): SourceFile;
|
||||
export function getTextOfNode(node: Node, includeTrivia?: boolean): string;
|
||||
export function normalizeSlashes(path: string): string;
|
||||
export function writeCommentRange(text: string, lineMap: number[], writer: EmitTextWriter, comment: CommentRange, newLine: string): void;
|
||||
function forEachProperty<T, U>(map: Map<T>, callback: (value: T, key: string) => U): U;
|
||||
function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration): ExpressionWithTypeArguments;
|
||||
function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration): ExpressionWithTypeArguments[];
|
||||
function getInterfaceBaseTypeNodes(node: InterfaceDeclaration): ExpressionWithTypeArguments[];
|
||||
function getLeadingCommentRangesOfNodeFromText(node: Node, text: string): CommentRange[];
|
||||
function getLineStarts(sourceFile: SourceFile): number[];
|
||||
function getSourceFileOfNode(node: Node): SourceFile;
|
||||
function getTextOfNode(node: Node, includeTrivia?: boolean): string;
|
||||
function normalizeSlashes(path: string): string;
|
||||
function writeCommentRange(text: string, lineMap: number[], writer: EmitTextWriter, comment: CommentRange, newLine: string): void;
|
||||
function hasModifier(node: Node, flags: ModifierFlags): boolean;
|
||||
}
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { build, watch } from "./compiler";
|
||||
export { build } from "./compiler";
|
||||
|
||||
+175
-166
@@ -18,8 +18,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as path from "path";
|
||||
import * as ts from "typescript";
|
||||
import path = require("path");
|
||||
import ts = require("typescript");
|
||||
|
||||
import { Compiler, oldGetLeadingCommentRangesOfNodeFromText } from "./compiler";
|
||||
|
||||
@@ -68,13 +68,13 @@ class Walker {
|
||||
}
|
||||
|
||||
walk(sourceFile: ts.SourceFile): void {
|
||||
var moduleName = this._moduleNameFromFileName(sourceFile.fileName);
|
||||
const moduleName = this._moduleNameFromFileName(sourceFile.fileName);
|
||||
|
||||
if (!(moduleName in this.modules)) {
|
||||
this.modules[moduleName] = new AST.Module(moduleName);
|
||||
}
|
||||
|
||||
var module = this._scope.enter(this.modules[moduleName]);
|
||||
const module = this._scope.enter(this.modules[moduleName]);
|
||||
this._currentSourceFile = sourceFile;
|
||||
|
||||
for (const statement of sourceFile.statements) {
|
||||
@@ -87,31 +87,31 @@ class Walker {
|
||||
private _walk(node: ts.Node, parent: AST.Module): void {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.VariableStatement:
|
||||
this._visitVariableStatement(<ts.VariableStatement>node, parent);
|
||||
this._visitVariableStatement(node as ts.VariableStatement, parent);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.FunctionDeclaration:
|
||||
this._visitFunctionDeclaration(<ts.FunctionDeclaration>node, parent);
|
||||
this._visitFunctionDeclaration(node as ts.FunctionDeclaration, parent);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.ClassDeclaration:
|
||||
this._visitClassDeclaration(<ts.ClassDeclaration>node, parent);
|
||||
this._visitClassDeclaration(node as ts.ClassDeclaration, parent);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.InterfaceDeclaration:
|
||||
this._visitInterfaceDeclaration(<ts.InterfaceDeclaration>node, parent);
|
||||
this._visitInterfaceDeclaration(node as ts.InterfaceDeclaration, parent);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.EnumDeclaration:
|
||||
this._visitEnumDeclaration(<ts.EnumDeclaration>node, parent);
|
||||
this._visitEnumDeclaration(node as ts.EnumDeclaration, parent);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.ImportDeclaration:
|
||||
this._visitImportDeclaration(<ts.ImportDeclaration>node, parent);
|
||||
this._visitImportDeclaration(node as ts.ImportDeclaration, parent);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.ExportDeclaration:
|
||||
this._visitExportDeclaration(<ts.ExportDeclaration>node, parent);
|
||||
this._visitExportDeclaration(node as ts.ExportDeclaration, parent);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.ExpressionStatement:
|
||||
@@ -121,7 +121,7 @@ class Walker {
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error(node.kind, (<any>ts).SyntaxKind[node.kind], node);
|
||||
console.error(node.kind, ts.SyntaxKind[node.kind], node);
|
||||
throw new Error("Unrecognized node.");
|
||||
}
|
||||
}
|
||||
@@ -130,20 +130,20 @@ class Walker {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.PropertySignature:
|
||||
case ts.SyntaxKind.PropertyDeclaration:
|
||||
this._visitProperty(<ts.PropertyDeclaration>node, clazz);
|
||||
this._visitProperty(node as ts.PropertyDeclaration, clazz);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.MethodSignature:
|
||||
case ts.SyntaxKind.MethodDeclaration:
|
||||
this._visitMethod(<ts.MethodDeclaration>node, clazz);
|
||||
this._visitMethod(node as ts.MethodDeclaration, clazz);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.GetAccessor:
|
||||
this._visitGetAccessor(<ts.AccessorDeclaration>node, clazz);
|
||||
this._visitGetAccessor(node as ts.AccessorDeclaration, clazz);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.SetAccessor:
|
||||
this._visitSetAccessor(<ts.AccessorDeclaration>node, clazz);
|
||||
this._visitSetAccessor(node as ts.AccessorDeclaration, clazz);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.TypeParameter:
|
||||
@@ -152,7 +152,7 @@ class Walker {
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error(node.kind, (<any>ts).SyntaxKind[node.kind], node);
|
||||
console.error(node.kind, ts.SyntaxKind[node.kind], node);
|
||||
throw new Error("Unrecognized node.");
|
||||
}
|
||||
}
|
||||
@@ -161,12 +161,12 @@ class Walker {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.PropertySignature:
|
||||
case ts.SyntaxKind.PropertyDeclaration:
|
||||
this._visitProperty(<ts.PropertyDeclaration>node, interfase);
|
||||
this._visitProperty(node as ts.PropertyDeclaration, interfase);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.MethodSignature:
|
||||
case ts.SyntaxKind.MethodDeclaration:
|
||||
this._visitMethod(<ts.MethodDeclaration>node, interfase);
|
||||
this._visitMethod(node as ts.MethodDeclaration, interfase);
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.TypeParameter:
|
||||
@@ -176,24 +176,24 @@ class Walker {
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error(node.kind, (<any>ts).SyntaxKind[node.kind], node);
|
||||
console.error(node.kind, ts.SyntaxKind[node.kind], node);
|
||||
throw new Error("Unrecognized node.");
|
||||
}
|
||||
}
|
||||
|
||||
private _visitProperty(node: ts.PropertyDeclaration, parent: AST.Class | AST.Interface) {
|
||||
if ((node.flags & ts.NodeFlags.Private) === ts.NodeFlags.Private) {
|
||||
if (ts.hasModifier(node, ts.ModifierFlags.Private)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
|
||||
if (jsDoc.typeAnnotation === null) {
|
||||
this._notifyIncorrectJsDoc(`Field ${ ts.getTextOfNode(node.name) } has no @type annotation.`);
|
||||
jsDoc.typeAnnotation = "*";
|
||||
}
|
||||
|
||||
var property = this._scope.enter(new AST.Property(ts.getTextOfNode(node.name)));
|
||||
const property = this._scope.enter(new AST.Property(ts.getTextOfNode(node.name)));
|
||||
parent.members[property.name] = property;
|
||||
property.getter = new AST.Getter(node, jsDoc.description, jsDoc.typeAnnotation, false);
|
||||
property.setter = new AST.Setter(node, jsDoc.description, jsDoc.typeAnnotation, false);
|
||||
@@ -201,9 +201,9 @@ class Walker {
|
||||
}
|
||||
|
||||
private _visitMethod(node: ts.MethodDeclaration, parent: AST.Class | AST.Interface) {
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
|
||||
var parameters = this._connectParameters(node.parameters, jsDoc.parameters,
|
||||
const parameters = this._connectParameters(node.parameters, jsDoc.parameters,
|
||||
parameterName => `Could not find @param annotation for ${ parameterName } on method ${ ts.getTextOfNode(node.name) }`
|
||||
);
|
||||
|
||||
@@ -212,25 +212,25 @@ class Walker {
|
||||
jsDoc.returnType = new AST.ReturnType("", "*");
|
||||
}
|
||||
|
||||
var isPrivate = (node.flags & ts.NodeFlags.Private) === ts.NodeFlags.Private;
|
||||
var isProtected = (node.flags & ts.NodeFlags.Protected) === ts.NodeFlags.Protected;
|
||||
var isStatic = (node.flags & ts.NodeFlags.Static) === ts.NodeFlags.Static;
|
||||
const isPrivate = ts.hasModifier(node, ts.ModifierFlags.Private);
|
||||
const isProtected = ts.hasModifier(node, ts.ModifierFlags.Protected);
|
||||
const isStatic = ts.hasModifier(node, ts.ModifierFlags.Static);
|
||||
|
||||
var generics = this._getGenericsOfSignatureDeclaration(node);
|
||||
const generics = this._getGenericsOfSignatureDeclaration(node);
|
||||
|
||||
var method = this._scope.enter(new AST.Function(ts.getTextOfNode(node.name), node, jsDoc.description, generics, parameters, jsDoc.returnType, jsDoc.isAbstract, isPrivate, isProtected, isStatic));
|
||||
const method = this._scope.enter(new AST.Function(ts.getTextOfNode(node.name), node, jsDoc.description, generics, parameters, jsDoc.returnType, jsDoc.isAbstract, isPrivate, isProtected, isStatic));
|
||||
parent.members[method.name] = method;
|
||||
this._scope.leave();
|
||||
}
|
||||
|
||||
private _visitGetAccessor(node: ts.AccessorDeclaration, clazz: AST.Class): void {
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
|
||||
var name = ts.getTextOfNode(node.name);
|
||||
const name = ts.getTextOfNode(node.name);
|
||||
|
||||
var isPrivate = (node.flags & ts.NodeFlags.Private) === ts.NodeFlags.Private;
|
||||
const isPrivate = ts.hasModifier(node, ts.ModifierFlags.Private);
|
||||
|
||||
var property = <AST.Property>clazz.members[name];
|
||||
let property = clazz.members[name] as AST.Property;
|
||||
if (property === undefined) {
|
||||
this._scope.enter(property = new AST.Property(name));
|
||||
|
||||
@@ -247,13 +247,13 @@ class Walker {
|
||||
}
|
||||
|
||||
private _visitSetAccessor(node: ts.AccessorDeclaration, clazz: AST.Class): void {
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
|
||||
var name = ts.getTextOfNode(node.name);
|
||||
const name = ts.getTextOfNode(node.name);
|
||||
|
||||
var isPrivate = (node.flags & ts.NodeFlags.Private) === ts.NodeFlags.Private;
|
||||
const isPrivate = ts.hasModifier(node, ts.ModifierFlags.Private);
|
||||
|
||||
var property = <AST.Property>clazz.members[name];
|
||||
let property = clazz.members[name] as AST.Property;
|
||||
if (property === undefined) {
|
||||
this._scope.enter(property = new AST.Property(name));
|
||||
|
||||
@@ -274,17 +274,17 @@ class Walker {
|
||||
return;
|
||||
}
|
||||
|
||||
var declaration = node.declarationList.declarations[0];
|
||||
if ((declaration.flags & ts.NodeFlags.Ambient) === ts.NodeFlags.Ambient) {
|
||||
const declaration = node.declarationList.declarations[0];
|
||||
if (ts.hasModifier(declaration, ts.ModifierFlags.Ambient)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
if (jsDoc.typeAnnotation === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var property = this._scope.enter(new AST.Property(ts.getTextOfNode(declaration.name)));
|
||||
const property = this._scope.enter(new AST.Property(ts.getTextOfNode(declaration.name)));
|
||||
property.getter = new AST.Getter(node, jsDoc.description, jsDoc.typeAnnotation, false);
|
||||
|
||||
parent.members[property.name] = property;
|
||||
@@ -293,13 +293,13 @@ class Walker {
|
||||
}
|
||||
|
||||
private _visitFunctionDeclaration(node: ts.FunctionDeclaration, parent: AST.Module): void {
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
|
||||
var isPrivate = (node.flags & ts.NodeFlags.Export) !== ts.NodeFlags.Export;
|
||||
const isPrivate = !ts.hasModifier(node, ts.ModifierFlags.Export);
|
||||
|
||||
var generics = this._getGenericsOfSignatureDeclaration(node);
|
||||
const generics = this._getGenericsOfSignatureDeclaration(node);
|
||||
|
||||
var parameters = this._connectParameters(node.parameters, jsDoc.parameters,
|
||||
const parameters = this._connectParameters(node.parameters, jsDoc.parameters,
|
||||
parameterName => `Could not find @param annotation for ${ parameterName } on function ${ node.name.text }`
|
||||
);
|
||||
|
||||
@@ -312,7 +312,7 @@ class Walker {
|
||||
jsDoc.returnType = new AST.ReturnType("", "*");
|
||||
}
|
||||
|
||||
var freeFunction = this._scope.enter(new AST.Function(node.name.text, node, jsDoc.description, generics, parameters, jsDoc.returnType, jsDoc.isAbstract, isPrivate, false, false));
|
||||
const freeFunction = this._scope.enter(new AST.Function(node.name.text, node, jsDoc.description, generics, parameters, jsDoc.returnType, jsDoc.isAbstract, isPrivate, false, false));
|
||||
|
||||
parent.members[freeFunction.name] = freeFunction;
|
||||
|
||||
@@ -320,32 +320,32 @@ class Walker {
|
||||
}
|
||||
|
||||
private _visitClassDeclaration(node: ts.ClassDeclaration, parent: AST.Module): void {
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
|
||||
var baseTypeHeritageClauseElement = ts.getClassExtendsHeritageClauseElement(node) || null;
|
||||
var baseType: AST.UnresolvedType = null;
|
||||
const type = this._typeChecker.getTypeAtLocation(node) as ts.InterfaceType;
|
||||
|
||||
const generics = this._getGenericsOfInterfaceType(type);
|
||||
|
||||
const baseTypeHeritageClauseElement = ts.getClassExtendsHeritageClauseElement(node) || null;
|
||||
let baseType: AST.UnresolvedType = null;
|
||||
if (baseTypeHeritageClauseElement !== null) {
|
||||
baseType = new AST.UnresolvedType(
|
||||
this._typeChecker.getTypeAtLocation(baseTypeHeritageClauseElement).symbol,
|
||||
this._getGenericsOfTypeReferenceNode(baseTypeHeritageClauseElement)
|
||||
this._getGenericsOfTypeReferenceNode(baseTypeHeritageClauseElement, generics)
|
||||
);
|
||||
}
|
||||
|
||||
var interfaces = (ts.getClassImplementsHeritageClauseElements(node) || []).map(type => new AST.UnresolvedType(
|
||||
const interfaces = (ts.getClassImplementsHeritageClauseElements(node) || []).map(type => new AST.UnresolvedType(
|
||||
this._typeChecker.getTypeAtLocation(type).symbol,
|
||||
this._getGenericsOfTypeReferenceNode(type)
|
||||
this._getGenericsOfTypeReferenceNode(type, generics)
|
||||
));
|
||||
|
||||
var isPrivate = (node.flags & ts.NodeFlags.Export) !== ts.NodeFlags.Export;
|
||||
const isPrivate = !ts.hasModifier(node, ts.ModifierFlags.Export);
|
||||
|
||||
var type = <ts.InterfaceType>this._typeChecker.getTypeAtLocation(node);
|
||||
|
||||
var generics = this._getGenericsOfInterfaceType(type);
|
||||
|
||||
var parameters: AST.Parameter[] = [];
|
||||
let parameters: AST.Parameter[] = [];
|
||||
|
||||
if (type.symbol.members["__constructor"] !== undefined) {
|
||||
parameters = this._connectParameters((<ts.ConstructorDeclaration>type.symbol.members["__constructor"].declarations[0]).parameters, jsDoc.parameters,
|
||||
parameters = this._connectParameters((type.symbol.members["__constructor"].declarations[0] as ts.ConstructorDeclaration).parameters, jsDoc.parameters,
|
||||
parameterName => `Could not find @param annotation for ${ parameterName } on constructor in class ${ node.name.text }`
|
||||
);
|
||||
}
|
||||
@@ -353,11 +353,11 @@ class Walker {
|
||||
this._notifyIncorrectJsDoc("There are @param annotations on this class but it has no constructors.");
|
||||
}
|
||||
|
||||
var clazz = this._scope.enter(new AST.Class(node.name.text, node, jsDoc.description, generics, parameters, baseType, interfaces, jsDoc.isAbstract, isPrivate));
|
||||
const clazz = this._scope.enter(new AST.Class(node.name.text, node, jsDoc.description, generics, parameters, baseType, interfaces, jsDoc.isAbstract, isPrivate));
|
||||
|
||||
parent.members[clazz.name] = clazz;
|
||||
|
||||
ts.forEachValue(type.symbol.exports, symbol => {
|
||||
ts.forEachProperty(type.symbol.exports, symbol => {
|
||||
if (symbol.name === "prototype") {
|
||||
return;
|
||||
}
|
||||
@@ -367,7 +367,7 @@ class Walker {
|
||||
}
|
||||
});
|
||||
|
||||
ts.forEachValue(type.symbol.members, symbol => {
|
||||
ts.forEachProperty(type.symbol.members, symbol => {
|
||||
for (const declaration of symbol.declarations) {
|
||||
this._walkClassMember(declaration, clazz);
|
||||
}
|
||||
@@ -377,28 +377,28 @@ class Walker {
|
||||
}
|
||||
|
||||
private _visitInterfaceDeclaration(node: ts.InterfaceDeclaration, parent: AST.Module): void {
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
|
||||
var baseTypes = (ts.getInterfaceBaseTypeNodes(node) || []).map(type => new AST.UnresolvedType(
|
||||
const type = this._typeChecker.getTypeAtLocation(node) as ts.InterfaceType;
|
||||
|
||||
const generics = this._getGenericsOfInterfaceType(type);
|
||||
|
||||
const baseTypes = (ts.getInterfaceBaseTypeNodes(node) || []).map(type => new AST.UnresolvedType(
|
||||
this._typeChecker.getTypeAtLocation(type).symbol,
|
||||
this._getGenericsOfTypeReferenceNode(type)
|
||||
this._getGenericsOfTypeReferenceNode(type, generics)
|
||||
));
|
||||
|
||||
var existingInterfaceType = parent.members[node.name.text];
|
||||
const existingInterfaceType = parent.members[node.name.text];
|
||||
if (existingInterfaceType !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var isPrivate = (node.flags & ts.NodeFlags.Export) !== ts.NodeFlags.Export;
|
||||
const isPrivate = !ts.hasModifier(node, ts.ModifierFlags.Export);
|
||||
|
||||
var type = <ts.InterfaceType>this._typeChecker.getTypeAtLocation(node);
|
||||
|
||||
var generics = this._getGenericsOfInterfaceType(type);
|
||||
|
||||
var interfase = this._scope.enter(new AST.Interface(node.name.text, node, jsDoc.description, generics, baseTypes, isPrivate));
|
||||
const interfase = this._scope.enter(new AST.Interface(node.name.text, node, jsDoc.description, generics, baseTypes, isPrivate));
|
||||
parent.members[interfase.name] = interfase;
|
||||
|
||||
ts.forEachValue(type.symbol.members, symbol => {
|
||||
ts.forEachProperty(type.symbol.members, symbol => {
|
||||
for (const declaration of symbol.declarations) {
|
||||
this._walkInterfaceMember(declaration, interfase);
|
||||
}
|
||||
@@ -408,33 +408,33 @@ class Walker {
|
||||
}
|
||||
|
||||
private _visitEnumDeclaration(node: ts.EnumDeclaration, parent: AST.Module): void {
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
|
||||
var existingEnumType = parent.members[node.name.text];
|
||||
const existingEnumType = parent.members[node.name.text];
|
||||
if (existingEnumType !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var isPrivate = (node.flags & ts.NodeFlags.Export) !== ts.NodeFlags.Export;
|
||||
const isPrivate = !ts.hasModifier(node, ts.ModifierFlags.Export);
|
||||
|
||||
var type = this._typeChecker.getTypeAtLocation(node);
|
||||
const type = this._typeChecker.getTypeAtLocation(node);
|
||||
|
||||
var enumType = this._scope.enter(new AST.Enum(node.name.text, node, jsDoc.description, isPrivate));
|
||||
const enumType = this._scope.enter(new AST.Enum(node.name.text, node, jsDoc.description, isPrivate));
|
||||
parent.members[enumType.name] = enumType;
|
||||
|
||||
ts.forEachValue(type.symbol.exports, symbol => {
|
||||
this._visitEnumMember(<ts.EnumMember>symbol.declarations[0], enumType);
|
||||
ts.forEachProperty(type.symbol.exports, symbol => {
|
||||
this._visitEnumMember(symbol.declarations[0] as ts.EnumMember, enumType);
|
||||
});
|
||||
|
||||
this._scope.leave();
|
||||
}
|
||||
|
||||
private _visitEnumMember(node: ts.EnumMember, parent: AST.Enum): void {
|
||||
var jsDoc = this._parseJSDoc(node);
|
||||
const jsDoc = this._parseJSDoc(node);
|
||||
|
||||
var value = (node.initializer === undefined) ? null : parseInt((<ts.LiteralExpression>node.initializer).text);
|
||||
const value = (node.initializer === undefined) ? null : parseInt((node.initializer as ts.LiteralExpression).text);
|
||||
|
||||
var enumMember = this._scope.enter(new AST.EnumMember(ts.getTextOfNode(node.name), (jsDoc === null) ? "" : jsDoc.description, value));
|
||||
const enumMember = this._scope.enter(new AST.EnumMember(ts.getTextOfNode(node.name), (jsDoc === null) ? "" : jsDoc.description, value));
|
||||
|
||||
parent.members.push(enumMember);
|
||||
|
||||
@@ -451,16 +451,16 @@ class Walker {
|
||||
throw new Error("Default import is not supported.");
|
||||
}
|
||||
|
||||
var moduleName = this._resolve((<ts.LiteralExpression>node.moduleSpecifier).text, parent);
|
||||
const moduleName = this._resolve((node.moduleSpecifier as ts.LiteralExpression).text, parent);
|
||||
|
||||
if ((<ts.NamespaceImport>node.importClause.namedBindings).name !== undefined) {
|
||||
if ((node.importClause.namedBindings as ts.NamespaceImport).name !== undefined) {
|
||||
// import * as foo from "baz";
|
||||
parent.members[(<ts.NamespaceImport>node.importClause.namedBindings).name.text] = new AST.Reference(moduleName, "*", true);
|
||||
parent.members[(node.importClause.namedBindings as ts.NamespaceImport).name.text] = new AST.Reference(moduleName, "*", true);
|
||||
}
|
||||
else if ((<ts.NamedImports>node.importClause.namedBindings).elements !== undefined) {
|
||||
else if ((node.importClause.namedBindings as ts.NamedImports).elements !== undefined) {
|
||||
// import { foo, bar } from "baz";
|
||||
for (const element of (<ts.NamedImports>node.importClause.namedBindings).elements) {
|
||||
var importedName = element.propertyName && element.propertyName.text || element.name.text;
|
||||
for (const element of (node.importClause.namedBindings as ts.NamedImports).elements) {
|
||||
const importedName = element.propertyName && element.propertyName.text || element.name.text;
|
||||
parent.members[element.name.text] = new AST.Reference(moduleName, importedName, true);
|
||||
}
|
||||
}
|
||||
@@ -472,22 +472,22 @@ class Walker {
|
||||
private _visitExportDeclaration(node: ts.ExportDeclaration, parent: AST.Module): void {
|
||||
if (node.moduleSpecifier !== undefined) {
|
||||
// export { foo } from "bar";
|
||||
var moduleName = this._resolve((<ts.LiteralExpression>node.moduleSpecifier).text, parent);
|
||||
const moduleName = this._resolve((node.moduleSpecifier as ts.LiteralExpression).text, parent);
|
||||
for (const element of node.exportClause.elements) {
|
||||
var importedName = element.propertyName && element.propertyName.text || element.name.text;
|
||||
const importedName = element.propertyName && element.propertyName.text || element.name.text;
|
||||
parent.members[element.name.text] = new AST.Reference(moduleName, importedName, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export { foo };
|
||||
for (const element of node.exportClause.elements) {
|
||||
(<AST.CanBePrivate><any>parent.members[element.name.text]).isPrivate = false;
|
||||
(parent.members[element.name.text] as AST.CanBePrivate).isPrivate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _resolve(relativeModuleName: string, currentModule: AST.Module): string {
|
||||
var result = ts.normalizeSlashes(path.join(currentModule.name, `../${ relativeModuleName }`));
|
||||
let result = ts.normalizeSlashes(path.join(currentModule.name, `../${ relativeModuleName }`));
|
||||
|
||||
if (result[0] !== ".") {
|
||||
result = `./${ result }`;
|
||||
@@ -497,7 +497,7 @@ class Walker {
|
||||
}
|
||||
|
||||
private _parseJSDoc(node: ts.Node): JSDoc {
|
||||
var comments = oldGetLeadingCommentRangesOfNodeFromText(node, this._currentSourceFile.text);
|
||||
let comments = oldGetLeadingCommentRangesOfNodeFromText(node, this._currentSourceFile.text);
|
||||
|
||||
if (comments === undefined) {
|
||||
comments = [];
|
||||
@@ -507,41 +507,41 @@ class Walker {
|
||||
comments = [comments[comments.length - 1]];
|
||||
}
|
||||
|
||||
var comment =
|
||||
const comment =
|
||||
(comments.length === 0) ?
|
||||
"" :
|
||||
this._currentSourceFile.text.substring(comments[0].pos, comments[0].end);
|
||||
|
||||
var commentStartIndex = comment.indexOf("/**");
|
||||
var commentEndIndex = comment.lastIndexOf("*/");
|
||||
const commentStartIndex = comment.indexOf("/**");
|
||||
const commentEndIndex = comment.lastIndexOf("*/");
|
||||
|
||||
var lines =
|
||||
const lines =
|
||||
(commentStartIndex === -1 || commentEndIndex === -1) ?
|
||||
[] :
|
||||
comment.substring(commentStartIndex + 2, commentEndIndex).split("\n").map(line => {
|
||||
var match = line.match(/^[ \t]*\* (.*)/);
|
||||
const match = line.match(/^[ \t]*\* (.*)/);
|
||||
if (match === null) {
|
||||
return "";
|
||||
}
|
||||
return match[1];
|
||||
});
|
||||
|
||||
var rootDescription = "";
|
||||
let rootDescription = "";
|
||||
|
||||
var parameters: { [name: string]: AST.Parameter } = Object.create(null);
|
||||
const parameters: { [name: string]: AST.Parameter } = Object.create(null);
|
||||
|
||||
var typeAnnotation: string = null;
|
||||
let typeAnnotation: string = null;
|
||||
|
||||
var returnType: AST.ReturnType = null;
|
||||
let returnType: AST.ReturnType = null;
|
||||
|
||||
var isAbstract = false;
|
||||
let isAbstract = false;
|
||||
|
||||
var lastRead: { description: string } = null;
|
||||
let lastRead: { description: string } = null;
|
||||
|
||||
for (const line of lines) {
|
||||
var firstWordMatch = line.match(/^\s*(\S+)(\s*)/);
|
||||
var firstWord = (firstWordMatch !== null) ? firstWordMatch[1] : "";
|
||||
var remainingLine = (firstWordMatch !== null) ? line.substring(firstWordMatch[0].length) : "";
|
||||
const firstWordMatch = line.match(/^\s*(\S+)(\s*)/);
|
||||
const firstWord = (firstWordMatch !== null) ? firstWordMatch[1] : "";
|
||||
let remainingLine = (firstWordMatch !== null) ? line.substring(firstWordMatch[0].length) : "";
|
||||
|
||||
if (firstWord[0] === "@") {
|
||||
lastRead = null;
|
||||
@@ -552,30 +552,33 @@ class Walker {
|
||||
isAbstract = true;
|
||||
break;
|
||||
|
||||
case "@param":
|
||||
var type: string;
|
||||
case "@param": {
|
||||
let type: string;
|
||||
[type, remainingLine] = this._readType(remainingLine);
|
||||
|
||||
var [, name, description] = remainingLine.match(/(\S+)\s*(.*)/);
|
||||
const [, name, description] = remainingLine.match(/(\S+)\s*(.*)/);
|
||||
|
||||
var subParameterMatch = name.match(/^(?:(.+)\.([^\.]+))|(?:(.+)\[("[^\[\]"]+")\])$/);
|
||||
const subParameterMatch = name.match(/^(?:(.+)\.([^\.]+))|(?:(.+)\[("[^\[\]"]+")\])$/);
|
||||
if (subParameterMatch === null) {
|
||||
parameters[name] = lastRead = new AST.Parameter(name, description, type);
|
||||
}
|
||||
else {
|
||||
var parentName = subParameterMatch[1] || subParameterMatch[3];
|
||||
var childName = subParameterMatch[2] || subParameterMatch[4];
|
||||
var parentParameter = parameters[parentName];
|
||||
const parentName = subParameterMatch[1] || subParameterMatch[3];
|
||||
const childName = subParameterMatch[2] || subParameterMatch[4];
|
||||
const parentParameter = parameters[parentName];
|
||||
parentParameter.subParameters.push(lastRead = new AST.Parameter(childName, description, type));
|
||||
}
|
||||
break;
|
||||
|
||||
case "@return":
|
||||
var [type, description] = this._readType(remainingLine);
|
||||
break;
|
||||
}
|
||||
|
||||
case "@return": {
|
||||
const [type, description] = this._readType(remainingLine);
|
||||
|
||||
returnType = lastRead = new AST.ReturnType(description, type);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "@type":
|
||||
[typeAnnotation] = this._readType(remainingLine);
|
||||
@@ -606,9 +609,9 @@ class Walker {
|
||||
return ["*", remainingLine];
|
||||
}
|
||||
|
||||
var index = -1;
|
||||
var numberOfUnterminatedBraces = 0;
|
||||
for (var i = 0; i < remainingLine.length; i++) {
|
||||
let index = -1;
|
||||
let numberOfUnterminatedBraces = 0;
|
||||
for (let i = 0; i < remainingLine.length; i++) {
|
||||
if (remainingLine[i] === "{") {
|
||||
numberOfUnterminatedBraces++;
|
||||
}
|
||||
@@ -626,7 +629,7 @@ class Walker {
|
||||
throw new Error("Unterminated type specifier.");
|
||||
}
|
||||
|
||||
var type = remainingLine.substr(1, index - 1);
|
||||
const type = remainingLine.substr(1, index - 1);
|
||||
remainingLine = remainingLine.substr(index + 1).replace(/^\s+/, "");
|
||||
|
||||
return [type, remainingLine];
|
||||
@@ -640,16 +643,24 @@ class Walker {
|
||||
return signatureDeclaration.typeParameters.map(typeParameter => typeParameter.name.text);
|
||||
}
|
||||
|
||||
private _getGenericsOfTypeReferenceNode(typeReferenceNode: ts.ExpressionWithTypeArguments): (AST.UnresolvedType | AST.IntrinsicTypeReference)[] {
|
||||
private _getGenericsOfTypeReferenceNode(typeReferenceNode: ts.ExpressionWithTypeArguments, intrinsicGenerics: string[]): (AST.UnresolvedType | AST.IntrinsicTypeReference)[] {
|
||||
if (typeReferenceNode.typeArguments === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var typeReference = <ts.TypeReference>this._typeChecker.getTypeAtLocation(typeReferenceNode);
|
||||
const typeReference = this._typeChecker.getTypeAtLocation(typeReferenceNode) as ts.TypeReference;
|
||||
|
||||
return typeReference.typeArguments.map(typeArgument => {
|
||||
if ((<ts.IntrinsicType>typeArgument).intrinsicName !== undefined) {
|
||||
return new AST.IntrinsicTypeReference((<ts.IntrinsicType>typeArgument).intrinsicName);
|
||||
if ((typeArgument as ts.IntrinsicType).intrinsicName !== undefined) {
|
||||
return new AST.IntrinsicTypeReference((typeArgument as ts.IntrinsicType).intrinsicName);
|
||||
}
|
||||
|
||||
if (typeArgument.flags & ts.TypeFlags.TypeParameter) {
|
||||
if (intrinsicGenerics.indexOf(typeArgument.symbol.name) !== -1) {
|
||||
return new AST.IntrinsicTypeReference(typeArgument.symbol.name);
|
||||
}
|
||||
|
||||
throw new Error(`Unbound type parameter ${ typeArgument.symbol.name }`);
|
||||
}
|
||||
|
||||
return new AST.UnresolvedType(typeArgument.symbol, []);
|
||||
@@ -668,12 +679,12 @@ class Walker {
|
||||
|
||||
private _connectParameters(astParameters: ts.ParameterDeclaration[], jsDocParameters: { [name: string]: AST.Parameter }, onMissingMessageCallback: (parameterName: string) => string) {
|
||||
return astParameters.map(parameter => {
|
||||
var parameterName = (<ts.Identifier>parameter.name).text;
|
||||
let parameterName = (parameter.name as ts.Identifier).text;
|
||||
if (parameterName[0] === "_") {
|
||||
parameterName = parameterName.substr(1);
|
||||
}
|
||||
|
||||
var jsDocParameter = jsDocParameters[parameterName];
|
||||
let jsDocParameter = jsDocParameters[parameterName];
|
||||
|
||||
if (jsDocParameter === undefined) {
|
||||
this._notifyIncorrectJsDoc(onMissingMessageCallback.call(this, parameterName));
|
||||
@@ -685,8 +696,8 @@ class Walker {
|
||||
}
|
||||
|
||||
private _notifyIncorrectJsDoc(message: string): void {
|
||||
var fileName = path.basename(this._currentSourceFile.fileName);
|
||||
if (fileName === "lib.core.d.ts" || fileName === "lib.dom.d.ts") {
|
||||
const fileName = path.basename(this._currentSourceFile.fileName);
|
||||
if (fileName === "lib.es5.d.ts" || fileName === "lib.dom.d.ts") {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -695,17 +706,17 @@ class Walker {
|
||||
|
||||
link(rootNamespaceName: string): void {
|
||||
for (const moduleName of Object.keys(this.modules)) {
|
||||
var module = this.modules[moduleName];
|
||||
const module = this.modules[moduleName];
|
||||
|
||||
for (const memberName of Object.keys(module.members)) {
|
||||
var member = module.members[memberName];
|
||||
const member = module.members[memberName];
|
||||
|
||||
if (member instanceof AST.Class) {
|
||||
if (member.unresolvedBaseType instanceof AST.UnresolvedType) {
|
||||
member.baseType = this._resolveTypeReference(<AST.UnresolvedType>member.unresolvedBaseType);
|
||||
member.baseType = this._resolveTypeReference(member.unresolvedBaseType);
|
||||
}
|
||||
else {
|
||||
member.baseType = <AST.TypeReference | AST.IntrinsicTypeReference>member.unresolvedBaseType;
|
||||
member.baseType = member.unresolvedBaseType;
|
||||
}
|
||||
|
||||
member.interfaces = member.unresolvedInterfaces.map(interfase => {
|
||||
@@ -713,7 +724,7 @@ class Walker {
|
||||
return this._resolveTypeReference(interfase);
|
||||
}
|
||||
|
||||
return <AST.TypeReference | AST.IntrinsicTypeReference>interfase;
|
||||
return interfase;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -723,12 +734,12 @@ class Walker {
|
||||
return this._resolveTypeReference(baseType);
|
||||
}
|
||||
|
||||
return <AST.TypeReference | AST.IntrinsicTypeReference>baseType;
|
||||
return baseType;
|
||||
});
|
||||
}
|
||||
|
||||
else if (member instanceof AST.Enum) {
|
||||
var value = 0;
|
||||
let value = 0;
|
||||
for (const enumMember of member.members) {
|
||||
if (enumMember.value === null) {
|
||||
enumMember.value = value;
|
||||
@@ -750,17 +761,17 @@ class Walker {
|
||||
|
||||
private _moduleToNamespace(module: AST.Module): void {
|
||||
for (const memberName of Object.keys(module.members)) {
|
||||
var member = module.members[memberName];
|
||||
let member = module.members[memberName];
|
||||
|
||||
if (member instanceof AST.Reference) {
|
||||
if ((<AST.Reference>member).isPrivate) {
|
||||
if (member.isPrivate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (member.name === "*") {
|
||||
var newNamespace = this._scope.enter(new AST.Namespace(memberName));
|
||||
const newNamespace = this._scope.enter(new AST.Namespace(memberName));
|
||||
|
||||
var existingNamespace = this.namespaces[newNamespace.fullName];
|
||||
const existingNamespace = this.namespaces[newNamespace.fullName];
|
||||
if (existingNamespace !== undefined) {
|
||||
this._scope.leave();
|
||||
this._scope.enter(existingNamespace);
|
||||
@@ -769,10 +780,10 @@ class Walker {
|
||||
this.namespaces[newNamespace.fullName] = newNamespace;
|
||||
}
|
||||
|
||||
var referencedModuleName = (<AST.Reference>member).moduleName;
|
||||
var referencedModule = this.modules[referencedModuleName];
|
||||
let referencedModuleName = member.moduleName;
|
||||
let referencedModule = this.modules[referencedModuleName];
|
||||
if (referencedModule === undefined && ((referencedModuleName + "/index") in this.modules)) {
|
||||
(<AST.Reference>member).moduleName = referencedModuleName = referencedModuleName + "/index";
|
||||
member.moduleName = referencedModuleName = referencedModuleName + "/index";
|
||||
referencedModule = this.modules[referencedModuleName];
|
||||
}
|
||||
this._moduleToNamespace(referencedModule);
|
||||
@@ -781,56 +792,56 @@ class Walker {
|
||||
}
|
||||
else {
|
||||
while (member instanceof AST.Reference) {
|
||||
member = this.modules[(<AST.Reference>member).moduleName].members[member.name];
|
||||
member = this.modules[member.moduleName].members[member.name];
|
||||
}
|
||||
|
||||
this._scope.enter(<AST.NamespaceMember><any>member);
|
||||
this._scope.enter(member);
|
||||
this._scope.leave();
|
||||
(<AST.Namespace>this._scope.current).members[member.name] = <AST.NamespaceMember>member;
|
||||
(this._scope.current as AST.Namespace).members[member.name] = member;
|
||||
}
|
||||
}
|
||||
else if (!(<AST.CanBePrivate><any>member).isPrivate) {
|
||||
this._scope.enter(<AST.NamespaceMember>member);
|
||||
else if (!(member as AST.CanBePrivate).isPrivate) {
|
||||
this._scope.enter(member);
|
||||
this._scope.leave();
|
||||
(<AST.Namespace>this._scope.current).members[member.name] = <AST.NamespaceMember>member;
|
||||
(this._scope.current as AST.Namespace).members[member.name] = member;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _resolveTypeReference(unresolvedType: AST.UnresolvedType): AST.TypeReference {
|
||||
var node: ts.Node = unresolvedType.symbol.declarations[0];
|
||||
let node: ts.Node = unresolvedType.symbol.declarations[0];
|
||||
while (node.kind !== ts.SyntaxKind.SourceFile) {
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
var sourceFile = <ts.SourceFile>node;
|
||||
const sourceFile = node as ts.SourceFile;
|
||||
|
||||
var moduleName = this._moduleNameFromFileName(sourceFile.fileName);
|
||||
var module = this.modules[moduleName];
|
||||
const moduleName = this._moduleNameFromFileName(sourceFile.fileName);
|
||||
const module = this.modules[moduleName];
|
||||
|
||||
var result = module.members[unresolvedType.symbol.name];
|
||||
let result = module.members[unresolvedType.symbol.name];
|
||||
|
||||
if (result === undefined) {
|
||||
throw new Error(`Type ${ unresolvedType.symbol.name } could not be resolved.`);
|
||||
}
|
||||
|
||||
while (result instanceof AST.Reference) {
|
||||
result = this.modules[(<AST.Reference>result).moduleName].members[result.name];
|
||||
result = this.modules[result.moduleName].members[result.name];
|
||||
}
|
||||
|
||||
var resultGenerics = unresolvedType.generics.map(generic => {
|
||||
const resultGenerics = unresolvedType.generics.map(generic => {
|
||||
if (generic instanceof AST.UnresolvedType) {
|
||||
return this._resolveTypeReference(generic);
|
||||
}
|
||||
|
||||
return <AST.IntrinsicTypeReference>generic;
|
||||
return generic;
|
||||
});
|
||||
|
||||
return new AST.TypeReference(<AST.NamespaceMember><any>result, resultGenerics);
|
||||
return new AST.TypeReference(result, resultGenerics);
|
||||
}
|
||||
|
||||
private _moduleNameFromFileName(fileName: string): string {
|
||||
var result = ts.normalizeSlashes(path.relative(this._compiler.projectRoot, fileName));
|
||||
let result = ts.normalizeSlashes(path.relative(this._compiler.projectRoot, fileName));
|
||||
|
||||
result = result.substr(0, result.length - ".ts".length);
|
||||
|
||||
@@ -843,16 +854,14 @@ class Walker {
|
||||
}
|
||||
|
||||
export function walk(compiler: Compiler, root: string, rootNamespaceName: string) {
|
||||
var sourceFiles = compiler.sourceFiles;
|
||||
var rootFileName = ts.normalizeSlashes(path.resolve(root));
|
||||
var rootSourceFile = sourceFiles.filter(sourceFile => sourceFile.fileName === rootFileName)[0];
|
||||
const sourceFiles = compiler.sourceFiles;
|
||||
|
||||
var walker = new Walker(compiler);
|
||||
const walker = new Walker(compiler);
|
||||
|
||||
// Walk
|
||||
for (const sourceFile of sourceFiles) {
|
||||
if (
|
||||
path.basename(sourceFile.fileName) === "lib.core.d.ts" ||
|
||||
path.basename(sourceFile.fileName) === "lib.es5.d.ts" ||
|
||||
path.basename(sourceFile.fileName) === "lib.dom.d.ts" ||
|
||||
sourceFile.fileName.substr(-"references.d.ts".length) === "references.d.ts"
|
||||
) {
|
||||
|
||||
+4
-4
@@ -17,7 +17,7 @@
|
||||
"main": "lib/libjass.js",
|
||||
"scripts": {
|
||||
"prepublish": "node ./build.js clean default",
|
||||
"build": "tsc ./build/typescript/index.ts ./build/doc.ts ./build/node.d.ts ./build/typescript/typescript.d.ts ./node_modules/async-build/typings.d.ts -m commonjs -t es5 -noImplicitAny --moduleResolution classic",
|
||||
"build": "tsc -p ./build/tsconfig.json",
|
||||
"test": "node ./build.js test",
|
||||
"test-lib": "intern-client config=tests/intern reporters=Pretty",
|
||||
"test-minified": "intern-client config=tests/intern reporters=Pretty minified=true",
|
||||
@@ -26,12 +26,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"async": "1.x >=1.4",
|
||||
"async-build": "0.3.0",
|
||||
"async-build": "0.3.1",
|
||||
"intern": "3.x >=3.2.0",
|
||||
"npm": "3.x",
|
||||
"pngjs": "2.3.1",
|
||||
"pngjs": "3.x",
|
||||
"sax": "1.x",
|
||||
"typescript": "1.8.10",
|
||||
"typescript": "next",
|
||||
"uglify-js": "2.x >=2.4.24"
|
||||
},
|
||||
"private": true
|
||||
|
||||
+8
-8
@@ -67,27 +67,27 @@ export { version } from "./version";
|
||||
export function configure(newConfig: {
|
||||
debugMode?: boolean,
|
||||
verboseMode?: boolean,
|
||||
Set?: typeof set.Set,
|
||||
Map?: typeof map.Map,
|
||||
Promise?: typeof promise.Promise,
|
||||
Set?: typeof set.Set | null,
|
||||
Map?: typeof map.Map | null,
|
||||
Promise?: typeof promise.Promise | null,
|
||||
}): void {
|
||||
if ("debugMode" in newConfig) {
|
||||
if (typeof newConfig.debugMode === "boolean") {
|
||||
settings.setDebugMode(newConfig.debugMode);
|
||||
}
|
||||
|
||||
if ("verboseMode" in newConfig) {
|
||||
if (typeof newConfig.verboseMode === "boolean") {
|
||||
settings.setVerboseMode(newConfig.verboseMode);
|
||||
}
|
||||
|
||||
if ("Set" in newConfig) {
|
||||
if (typeof newConfig.Set === "function" || newConfig.Set === null) {
|
||||
set.setImplementation(newConfig.Set);
|
||||
}
|
||||
|
||||
if ("Map" in newConfig) {
|
||||
if (typeof newConfig.Map === "function" || newConfig.Map === null) {
|
||||
map.setImplementation(newConfig.Map);
|
||||
}
|
||||
|
||||
if ("Promise" in newConfig) {
|
||||
if (typeof newConfig.Promise === "function" || newConfig.Promise === null) {
|
||||
promise.setImplementation(newConfig.Promise);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ import { Map } from "../utility/map";
|
||||
* @param {string} line
|
||||
* @return {Property}
|
||||
*/
|
||||
export function parseLineIntoProperty(line: string): Property {
|
||||
export function parseLineIntoProperty(line: string): Property | null {
|
||||
const colonPos = line.indexOf(":");
|
||||
if (colonPos === -1) {
|
||||
return null;
|
||||
@@ -47,7 +47,7 @@ export function parseLineIntoProperty(line: string): Property {
|
||||
* @param {!Array.<string>} formatSpecifier
|
||||
* @return {TypedTemplate}
|
||||
*/
|
||||
export function parseLineIntoTypedTemplate(line: string, formatSpecifier: string[]): TypedTemplate {
|
||||
export function parseLineIntoTypedTemplate(line: string, formatSpecifier: string[]): TypedTemplate | null {
|
||||
const property = parseLineIntoProperty(line);
|
||||
if (property === null) {
|
||||
return null;
|
||||
|
||||
+92
-93
@@ -71,7 +71,7 @@ class ParserRun {
|
||||
/**
|
||||
* @type {ParseNode}
|
||||
*/
|
||||
get result(): ParseNode {
|
||||
get result(): ParseNode | null {
|
||||
return this._result;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_enclosedTags(parent: ParseNode): ParseNode {
|
||||
parse_enclosedTags(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
current.value = [];
|
||||
@@ -135,7 +135,7 @@ class ParserRun {
|
||||
}
|
||||
|
||||
for (let next = this._peek(); this._haveMore() && next !== "}"; next = this._peek()) {
|
||||
let childNode: ParseNode = null;
|
||||
let childNode: ParseNode | null = null;
|
||||
|
||||
if (this.read(current, "\\") !== null) {
|
||||
childNode =
|
||||
@@ -237,7 +237,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_newline(parent: ParseNode): ParseNode {
|
||||
parse_newline(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "\\N") === null) {
|
||||
@@ -254,7 +254,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_hardspace(parent: ParseNode): ParseNode {
|
||||
parse_hardspace(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "\\h") === null) {
|
||||
@@ -301,7 +301,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_a(parent: ParseNode): ParseNode {
|
||||
parse_tag_a(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "a") === null) {
|
||||
@@ -339,8 +339,8 @@ class ParserRun {
|
||||
|
||||
const valueNode = new ParseNode(current, next);
|
||||
|
||||
let value: number;
|
||||
switch (valueNode.value) {
|
||||
let value: number = -1;
|
||||
switch ((valueNode.value)) {
|
||||
case "1":
|
||||
value = 1;
|
||||
break;
|
||||
@@ -387,7 +387,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_alpha(parent: ParseNode): ParseNode {
|
||||
parse_tag_alpha(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -395,7 +395,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_an(parent: ParseNode): ParseNode {
|
||||
parse_tag_an(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "an") === null) {
|
||||
@@ -421,7 +421,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_b(parent: ParseNode): ParseNode {
|
||||
parse_tag_b(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "b") === null) {
|
||||
@@ -429,7 +429,7 @@ class ParserRun {
|
||||
return null;
|
||||
}
|
||||
|
||||
let valueNode: ParseNode = null;
|
||||
let valueNode: ParseNode | null = null;
|
||||
|
||||
let next = this._peek();
|
||||
|
||||
@@ -459,7 +459,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_be(parent: ParseNode): ParseNode {
|
||||
parse_tag_be(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_blur(parent: ParseNode): ParseNode {
|
||||
parse_tag_blur(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -475,7 +475,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_bord(parent: ParseNode): ParseNode {
|
||||
parse_tag_bord(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_c(parent: ParseNode): ParseNode {
|
||||
parse_tag_c(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -491,7 +491,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_clip(parent: ParseNode): ParseNode {
|
||||
parse_tag_clip(parent: ParseNode): ParseNode | null {
|
||||
return this._parse_tag_clip_or_iclip("clip", parent);
|
||||
}
|
||||
|
||||
@@ -499,7 +499,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fad(parent: ParseNode): ParseNode {
|
||||
parse_tag_fad(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "fad") === null) {
|
||||
@@ -543,7 +543,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fade(parent: ParseNode): ParseNode {
|
||||
parse_tag_fade(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "fade") === null) {
|
||||
@@ -646,7 +646,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fax(parent: ParseNode): ParseNode {
|
||||
parse_tag_fax(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -654,7 +654,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fay(parent: ParseNode): ParseNode {
|
||||
parse_tag_fay(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -662,7 +662,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fn(parent: ParseNode): ParseNode {
|
||||
parse_tag_fn(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "fn") === null) {
|
||||
@@ -690,7 +690,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fr(parent: ParseNode): ParseNode {
|
||||
parse_tag_fr(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -698,7 +698,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_frx(parent: ParseNode): ParseNode {
|
||||
parse_tag_frx(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -706,7 +706,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fry(parent: ParseNode): ParseNode {
|
||||
parse_tag_fry(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -714,7 +714,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_frz(parent: ParseNode): ParseNode {
|
||||
parse_tag_frz(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -722,7 +722,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fs(parent: ParseNode): ParseNode {
|
||||
parse_tag_fs(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -730,7 +730,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fsplus(parent: ParseNode): ParseNode {
|
||||
parse_tag_fsplus(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "fs+") === null) {
|
||||
@@ -754,7 +754,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fsminus(parent: ParseNode): ParseNode {
|
||||
parse_tag_fsminus(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "fs-") === null) {
|
||||
@@ -778,7 +778,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fscx(parent: ParseNode): ParseNode {
|
||||
parse_tag_fscx(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "fscx") === null) {
|
||||
@@ -802,7 +802,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fscy(parent: ParseNode): ParseNode {
|
||||
parse_tag_fscy(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "fscy") === null) {
|
||||
@@ -826,7 +826,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_fsp(parent: ParseNode): ParseNode {
|
||||
parse_tag_fsp(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -834,7 +834,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_i(parent: ParseNode): ParseNode {
|
||||
parse_tag_i(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -842,7 +842,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_iclip(parent: ParseNode): ParseNode {
|
||||
parse_tag_iclip(parent: ParseNode): ParseNode | null {
|
||||
return this._parse_tag_clip_or_iclip("iclip", parent);
|
||||
}
|
||||
|
||||
@@ -850,7 +850,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_k(parent: ParseNode): ParseNode {
|
||||
parse_tag_k(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "k") === null) {
|
||||
@@ -874,7 +874,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_K(parent: ParseNode): ParseNode {
|
||||
parse_tag_K(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "K") === null) {
|
||||
@@ -898,7 +898,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_kf(parent: ParseNode): ParseNode {
|
||||
parse_tag_kf(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "kf") === null) {
|
||||
@@ -922,7 +922,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_ko(parent: ParseNode): ParseNode {
|
||||
parse_tag_ko(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "ko") === null) {
|
||||
@@ -946,7 +946,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_move(parent: ParseNode): ParseNode {
|
||||
parse_tag_move(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "move") === null) {
|
||||
@@ -998,8 +998,8 @@ class ParserRun {
|
||||
return null;
|
||||
}
|
||||
|
||||
let t1Node: ParseNode = null;
|
||||
let t2Node: ParseNode = null;
|
||||
let t1Node: ParseNode | null = null;
|
||||
let t2Node: ParseNode | null = null;
|
||||
|
||||
if (this.read(current, ",") !== null) {
|
||||
t1Node = this.parse_decimal(current);
|
||||
@@ -1037,7 +1037,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_org(parent: ParseNode): ParseNode {
|
||||
parse_tag_org(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "org") === null) {
|
||||
@@ -1081,7 +1081,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_p(parent: ParseNode): ParseNode {
|
||||
parse_tag_p(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1089,7 +1089,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_pbo(parent: ParseNode): ParseNode {
|
||||
parse_tag_pbo(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1097,7 +1097,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_pos(parent: ParseNode): ParseNode {
|
||||
parse_tag_pos(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "pos") === null) {
|
||||
@@ -1141,7 +1141,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_q(parent: ParseNode): ParseNode {
|
||||
parse_tag_q(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "q") === null) {
|
||||
@@ -1167,7 +1167,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_r(parent: ParseNode): ParseNode {
|
||||
parse_tag_r(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "r") === null) {
|
||||
@@ -1195,7 +1195,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_s(parent: ParseNode): ParseNode {
|
||||
parse_tag_s(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1203,7 +1203,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_shad(parent: ParseNode): ParseNode {
|
||||
parse_tag_shad(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1211,7 +1211,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_t(parent: ParseNode): ParseNode {
|
||||
parse_tag_t(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, "t") === null) {
|
||||
@@ -1224,9 +1224,9 @@ class ParserRun {
|
||||
return null;
|
||||
}
|
||||
|
||||
let startNode: ParseNode = null;
|
||||
let endNode: ParseNode = null;
|
||||
let accelNode: ParseNode = null;
|
||||
let startNode: ParseNode | null = null;
|
||||
let endNode: ParseNode | null = null;
|
||||
let accelNode: ParseNode | null = null;
|
||||
|
||||
const firstNode = this.parse_decimal(current);
|
||||
if (firstNode !== null) {
|
||||
@@ -1268,7 +1268,7 @@ class ParserRun {
|
||||
const transformTags: parts.Part[] = [];
|
||||
|
||||
for (let next = this._peek(); this._haveMore() && next !== ")" && next !== "}"; next = this._peek()) {
|
||||
let childNode: ParseNode = null;
|
||||
let childNode: ParseNode | null = null;
|
||||
|
||||
if (this.read(current, "\\") !== null) {
|
||||
childNode =
|
||||
@@ -1354,7 +1354,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_u(parent: ParseNode): ParseNode {
|
||||
parse_tag_u(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1362,7 +1362,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_xbord(parent: ParseNode): ParseNode {
|
||||
parse_tag_xbord(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1370,7 +1370,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_xshad(parent: ParseNode): ParseNode {
|
||||
parse_tag_xshad(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1378,7 +1378,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_ybord(parent: ParseNode): ParseNode {
|
||||
parse_tag_ybord(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1386,7 +1386,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_yshad(parent: ParseNode): ParseNode {
|
||||
parse_tag_yshad(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1394,7 +1394,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_1a(parent: ParseNode): ParseNode {
|
||||
parse_tag_1a(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1402,7 +1402,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_1c(parent: ParseNode): ParseNode {
|
||||
parse_tag_1c(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1410,7 +1410,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_2a(parent: ParseNode): ParseNode {
|
||||
parse_tag_2a(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1418,7 +1418,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_2c(parent: ParseNode): ParseNode {
|
||||
parse_tag_2c(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1426,7 +1426,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_3a(parent: ParseNode): ParseNode {
|
||||
parse_tag_3a(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1434,7 +1434,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_3c(parent: ParseNode): ParseNode {
|
||||
parse_tag_3c(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1442,7 +1442,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_4a(parent: ParseNode): ParseNode {
|
||||
parse_tag_4a(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1450,7 +1450,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_tag_4c(parent: ParseNode): ParseNode {
|
||||
parse_tag_4c(parent: ParseNode): ParseNode | null {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
@@ -1461,7 +1461,7 @@ class ParserRun {
|
||||
parse_drawingInstructions(parent: ParseNode): ParseNode {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
let currentType: string = null;
|
||||
let currentType: string | null = null;
|
||||
const numberParts: ParseNode[] = [];
|
||||
|
||||
current.value = [];
|
||||
@@ -1518,7 +1518,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_decimalInt32(parent: ParseNode): ParseNode {
|
||||
parse_decimalInt32(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
const isNegative = this.read(current, "-") !== null;
|
||||
@@ -1550,7 +1550,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_hexInt32(parent: ParseNode): ParseNode {
|
||||
parse_hexInt32(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
const isNegative = this.read(current, "-") !== null;
|
||||
@@ -1590,7 +1590,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_decimalOrHexInt32(parent: ParseNode): ParseNode {
|
||||
parse_decimalOrHexInt32(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
const valueNode =
|
||||
@@ -1612,7 +1612,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_decimal(parent: ParseNode): ParseNode {
|
||||
parse_decimal(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
const negative = (this.read(current, "-") !== null);
|
||||
@@ -1637,12 +1637,12 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_unsignedDecimal(parent: ParseNode): ParseNode {
|
||||
parse_unsignedDecimal(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
const characteristicNode = new ParseNode(current, "");
|
||||
|
||||
let mantissaNode: ParseNode = null;
|
||||
let mantissaNode: ParseNode | null = null;
|
||||
|
||||
for (let next = this._peek(); this._haveMore() && next >= "0" && next <= "9"; next = this._peek()) {
|
||||
characteristicNode.value += next;
|
||||
@@ -1675,7 +1675,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_enableDisable(parent: ParseNode): ParseNode {
|
||||
parse_enableDisable(parent: ParseNode): ParseNode | null {
|
||||
const next = this._peek();
|
||||
|
||||
if (next === "0" || next === "1") {
|
||||
@@ -1692,7 +1692,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_color(parent: ParseNode): ParseNode {
|
||||
parse_color(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
while (this.read(current, "&") !== null || this.read(current, "H") !== null) { }
|
||||
@@ -1720,7 +1720,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_alpha(parent: ParseNode): ParseNode {
|
||||
parse_alpha(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
while (this.read(current, "&") !== null || this.read(current, "H") !== null) { }
|
||||
@@ -1744,7 +1744,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
parse_colorWithAlpha(parent: ParseNode): ParseNode {
|
||||
parse_colorWithAlpha(parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
const valueNode = this.parse_decimalOrHexInt32(current);
|
||||
@@ -1770,7 +1770,7 @@ class ParserRun {
|
||||
* @param {string} next
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
read(parent: ParseNode, next: string): ParseNode {
|
||||
read(parent: ParseNode, next: string): ParseNode | null {
|
||||
if (this._peek(next.length) !== next) {
|
||||
return null;
|
||||
}
|
||||
@@ -1801,7 +1801,7 @@ class ParserRun {
|
||||
* @param {!ParseNode} parent
|
||||
* @return {ParseNode}
|
||||
*/
|
||||
private _parse_tag_clip_or_iclip(tagName: "clip" | "iclip", parent: ParseNode): ParseNode {
|
||||
private _parse_tag_clip_or_iclip(tagName: "clip" | "iclip", parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (this.read(current, tagName) === null) {
|
||||
@@ -1814,12 +1814,12 @@ class ParserRun {
|
||||
return null;
|
||||
}
|
||||
|
||||
let x1Node: ParseNode = null;
|
||||
let x2Node: ParseNode = null;
|
||||
let y1Node: ParseNode = null;
|
||||
let y2Node: ParseNode = null;
|
||||
let scaleNode: ParseNode = null;
|
||||
let commandsNode: ParseNode = null;
|
||||
let x1Node: ParseNode | null = null;
|
||||
let x2Node: ParseNode | null = null;
|
||||
let y1Node: ParseNode | null = null;
|
||||
let y2Node: ParseNode | null = null;
|
||||
let scaleNode: ParseNode | null = null;
|
||||
let commandsNode: ParseNode | null = null;
|
||||
|
||||
const firstNode = this.parse_decimal(current);
|
||||
|
||||
@@ -1895,19 +1895,18 @@ class ParserRun {
|
||||
function makeTagParserFunction(
|
||||
tagName: string,
|
||||
tagConstructor: { new (value: any): parts.Part },
|
||||
valueParser: (current: ParseNode) => ParseNode,
|
||||
valueParser: (current: ParseNode) => ParseNode | null,
|
||||
required: boolean
|
||||
): void {
|
||||
(ParserRun.prototype as any)[`parse_tag_${ tagName }`] = function (parent: ParseNode): ParseNode {
|
||||
const self = this as ParserRun;
|
||||
(ParserRun.prototype as any)[`parse_tag_${ tagName }`] = function (this: ParserRun, parent: ParseNode): ParseNode | null {
|
||||
const current = new ParseNode(parent);
|
||||
|
||||
if (self.read(current, tagName) === null) {
|
||||
if (this.read(current, tagName) === null) {
|
||||
parent.pop();
|
||||
return null;
|
||||
}
|
||||
|
||||
const valueNode = valueParser.call(self, current);
|
||||
const valueNode: ParseNode | null = valueParser.call(this, current);
|
||||
|
||||
if (valueNode !== null) {
|
||||
current.value = new tagConstructor(valueNode.value);
|
||||
@@ -1975,7 +1974,7 @@ class ParseNode {
|
||||
private _end: number;
|
||||
private _value: any;
|
||||
|
||||
constructor(private _parent: ParseNode, value: any = null) {
|
||||
constructor(private _parent: ParseNode | null, value: any = null) {
|
||||
if (_parent !== null) {
|
||||
_parent.children.push(this);
|
||||
}
|
||||
@@ -2007,7 +2006,7 @@ class ParseNode {
|
||||
/**
|
||||
* @type {ParseNode}
|
||||
*/
|
||||
get parent(): ParseNode {
|
||||
get parent(): ParseNode | null {
|
||||
return this._parent;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ export class StreamParser {
|
||||
|
||||
private _shouldSwallowBom: boolean = true;
|
||||
private _currentSection: Section = Section.ScriptInfo;
|
||||
private _currentAttachment: Attachment = null;
|
||||
private _currentAttachment: Attachment | null = null;
|
||||
|
||||
constructor(private _stream: Stream) {
|
||||
this._stream.nextLine().then(line => this._onNextLine(line), reason => {
|
||||
@@ -118,7 +118,7 @@ export class StreamParser {
|
||||
/**
|
||||
* @param {string} line
|
||||
*/
|
||||
private _onNextLine(line: string): void {
|
||||
private _onNextLine(line: string | null): void {
|
||||
if (line === null) {
|
||||
this.currentSection = Section.EOF;
|
||||
return;
|
||||
@@ -290,10 +290,10 @@ export class SrtStreamParser {
|
||||
|
||||
private _shouldSwallowBom: boolean = true;
|
||||
|
||||
private _currentDialogueNumber: string = null;
|
||||
private _currentDialogueStart: string = null;
|
||||
private _currentDialogueEnd: string = null;
|
||||
private _currentDialogueText: string = null;
|
||||
private _currentDialogueNumber: string | null = null;
|
||||
private _currentDialogueStart: string | null = null;
|
||||
private _currentDialogueEnd: string | null = null;
|
||||
private _currentDialogueText: string | null = null;
|
||||
|
||||
constructor(private _stream: Stream) {
|
||||
this._stream.nextLine().then(line => this._onNextLine(line), reason => {
|
||||
@@ -319,7 +319,7 @@ export class SrtStreamParser {
|
||||
/**
|
||||
* @param {string} line
|
||||
*/
|
||||
private _onNextLine(line: string): void {
|
||||
private _onNextLine(line: string | null): void {
|
||||
if (line === null) {
|
||||
if (this._currentDialogueNumber !== null && this._currentDialogueStart !== null && this._currentDialogueEnd !== null && this._currentDialogueText !== null) {
|
||||
this._ass.dialogues.push(new Dialogue(new Map([
|
||||
|
||||
+16
-16
@@ -65,7 +65,7 @@ export interface Stream {
|
||||
/**
|
||||
* @return {!Promise.<?string>} A promise that will be resolved with the next line, or null if the stream is exhausted.
|
||||
*/
|
||||
nextLine(): Promise<string>;
|
||||
nextLine(): Promise<string | null>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,8 +81,8 @@ export class StringStream implements Stream {
|
||||
/**
|
||||
* @return {!Promise.<?string>} A promise that will be resolved with the next line, or null if the string has been completely read.
|
||||
*/
|
||||
nextLine(): Promise<string> {
|
||||
let result: Promise<string>;
|
||||
nextLine(): Promise<string | null> {
|
||||
let result: Promise<string | null>;
|
||||
|
||||
if (this._readTill < this._str.length) {
|
||||
const nextNewLinePos = this._str.indexOf("\n", this._readTill);
|
||||
@@ -96,7 +96,7 @@ export class StringStream implements Stream {
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = Promise.resolve<string>(null);
|
||||
result = Promise.resolve<string | null>(null);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -111,8 +111,8 @@ export class StringStream implements Stream {
|
||||
*/
|
||||
export class XhrStream implements Stream {
|
||||
private _readTill: number = 0;
|
||||
private _pendingDeferred: DeferredPromise<string> = null;
|
||||
private _failedError: ErrorEvent = null;
|
||||
private _pendingDeferred: DeferredPromise<string | null> | null = null;
|
||||
private _failedError: ErrorEvent | null = null;
|
||||
|
||||
constructor(private _xhr: XMLHttpRequest) {
|
||||
_xhr.addEventListener("progress", () => this._onXhrProgress(), false);
|
||||
@@ -181,7 +181,7 @@ export class XhrStream implements Stream {
|
||||
*/
|
||||
private _tryResolveNextLine(): void {
|
||||
if (this._failedError !== null) {
|
||||
this._pendingDeferred.reject(this._failedError);
|
||||
this._pendingDeferred!.reject(this._failedError);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -189,23 +189,23 @@ export class XhrStream implements Stream {
|
||||
|
||||
const nextNewLinePos = response.indexOf("\n", this._readTill);
|
||||
if (nextNewLinePos !== -1) {
|
||||
this._pendingDeferred.resolve(response.substring(this._readTill, nextNewLinePos));
|
||||
this._pendingDeferred!.resolve(response.substring(this._readTill, nextNewLinePos));
|
||||
this._readTill = nextNewLinePos + 1;
|
||||
this._pendingDeferred = null;
|
||||
}
|
||||
|
||||
else if (this._xhr.readyState === XMLHttpRequest.DONE) {
|
||||
if (this._failedError !== null) {
|
||||
this._pendingDeferred.reject(this._failedError);
|
||||
this._pendingDeferred!.reject(this._failedError);
|
||||
}
|
||||
|
||||
// No more data. This is the last line.
|
||||
else if (this._readTill < response.length) {
|
||||
this._pendingDeferred.resolve(response.substr(this._readTill));
|
||||
this._pendingDeferred!.resolve(response.substr(this._readTill));
|
||||
this._readTill = response.length;
|
||||
}
|
||||
else {
|
||||
this._pendingDeferred.resolve(null);
|
||||
this._pendingDeferred!.resolve(null);
|
||||
}
|
||||
|
||||
this._pendingDeferred = null;
|
||||
@@ -223,11 +223,11 @@ export class BrowserReadableStream implements Stream {
|
||||
private _reader: ReadableStreamReader;
|
||||
private _decoder: TextDecoder;
|
||||
private _buffer: string = "";
|
||||
private _pendingDeferred: DeferredPromise<string> = null;
|
||||
private _pendingDeferred: DeferredPromise<string | null> | null = null;
|
||||
|
||||
constructor(stream: ReadableStream, encoding: string) {
|
||||
this._reader = stream.getReader();
|
||||
this._decoder = new global.TextDecoder(encoding, { ignoreBOM: true });
|
||||
this._decoder = new global.TextDecoder!(encoding, { ignoreBOM: true });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,7 +250,7 @@ export class BrowserReadableStream implements Stream {
|
||||
private _tryResolveNextLine(): void {
|
||||
const nextNewLinePos = this._buffer.indexOf("\n");
|
||||
if (nextNewLinePos !== -1) {
|
||||
this._pendingDeferred.resolve(this._buffer.substr(0, nextNewLinePos));
|
||||
this._pendingDeferred!.resolve(this._buffer.substr(0, nextNewLinePos));
|
||||
this._buffer = this._buffer.substr(nextNewLinePos + 1);
|
||||
this._pendingDeferred = null;
|
||||
}
|
||||
@@ -266,10 +266,10 @@ export class BrowserReadableStream implements Stream {
|
||||
else {
|
||||
// No more data.
|
||||
if (this._buffer.length === 0) {
|
||||
this._pendingDeferred.resolve(null);
|
||||
this._pendingDeferred!.resolve(null);
|
||||
}
|
||||
else {
|
||||
this._pendingDeferred.resolve(this._buffer);
|
||||
this._pendingDeferred!.resolve(this._buffer);
|
||||
this._buffer = "";
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ export function getTtfNames(attachment: Attachment): Set<string> {
|
||||
const reader = { dataView: new DataView(bytes.buffer), position: 0 };
|
||||
|
||||
const offsetTable = OffsetTable.read(reader);
|
||||
let nameTableRecord: TableRecord = null;
|
||||
let nameTableRecord: TableRecord | null = null;
|
||||
for (let i = 0; i < offsetTable.numTables; i++) {
|
||||
const tableRecord = TableRecord.read(reader);
|
||||
if (tableRecord.c1 + tableRecord.c2 + tableRecord.c3 + tableRecord.c4 === "name") {
|
||||
|
||||
+19
-19
@@ -186,14 +186,14 @@ export class Italic {
|
||||
* @param {?boolean|?number} value {\b1} -> true, {\b0} -> false, {\b###} -> weight of the bold (number), {\b} -> null
|
||||
*/
|
||||
export class Bold {
|
||||
constructor(private _value: boolean | number) { }
|
||||
constructor(private _value: boolean | number | null) { }
|
||||
|
||||
/**
|
||||
* The value of this bold tag.
|
||||
*
|
||||
* @type {?boolean|?number}
|
||||
*/
|
||||
get value(): boolean | number {
|
||||
get value(): boolean | number | null {
|
||||
return this._value;
|
||||
}
|
||||
}
|
||||
@@ -384,14 +384,14 @@ export class GaussianBlur {
|
||||
* @param {?string} value {\fn###} -> name (string), {\fn} -> null
|
||||
*/
|
||||
export class FontName {
|
||||
constructor(private _value: string) { }
|
||||
constructor(private _value: string | null) { }
|
||||
|
||||
/**
|
||||
* The value of this font name tag.
|
||||
*
|
||||
* @type {?string}
|
||||
*/
|
||||
get value(): string {
|
||||
get value(): string | null {
|
||||
return this._value;
|
||||
}
|
||||
}
|
||||
@@ -456,14 +456,14 @@ export class FontSizeMinus {
|
||||
* @param {?number} value {\fscx###} -> scale (number), {\fscx} -> null
|
||||
*/
|
||||
export class FontScaleX {
|
||||
constructor(private _value: number) { }
|
||||
constructor(private _value: number | null) { }
|
||||
|
||||
/**
|
||||
* The value of this horizontal font scaling tag.
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
get value(): number {
|
||||
get value(): number | null {
|
||||
return this._value;
|
||||
}
|
||||
}
|
||||
@@ -474,14 +474,14 @@ export class FontScaleX {
|
||||
* @param {?number} value {\fscy###} -> scale (number), {\fscy} -> null
|
||||
*/
|
||||
export class FontScaleY {
|
||||
constructor(private _value: number) { }
|
||||
constructor(private _value: number | null) { }
|
||||
|
||||
/**
|
||||
* The value of this vertical font scaling tag.
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
get value(): number {
|
||||
get value(): number | null {
|
||||
return this._value;
|
||||
}
|
||||
}
|
||||
@@ -852,14 +852,14 @@ export class WrappingStyle {
|
||||
* @param {?string} value {\r###} -> style name (string), {\r} -> null
|
||||
*/
|
||||
export class Reset {
|
||||
constructor(private _value: string) { }
|
||||
constructor(private _value: string | null) { }
|
||||
|
||||
/**
|
||||
* The value of this style reset tag.
|
||||
*
|
||||
* @type {?string}
|
||||
*/
|
||||
get value(): string {
|
||||
get value(): string | null {
|
||||
return this._value;
|
||||
}
|
||||
}
|
||||
@@ -903,7 +903,7 @@ export class Position {
|
||||
* @param {?number} t2
|
||||
*/
|
||||
export class Move {
|
||||
constructor(private _x1: number, private _y1: number, private _x2: number, private _y2: number, private _t1: number, private _t2: number) { }
|
||||
constructor(private _x1: number, private _y1: number, private _x2: number, private _y2: number, private _t1: number | null, private _t2: number | null) { }
|
||||
|
||||
/**
|
||||
* The starting x value of this move tag.
|
||||
@@ -946,7 +946,7 @@ export class Move {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
get t1(): number {
|
||||
get t1(): number | null {
|
||||
return this._t1;
|
||||
}
|
||||
|
||||
@@ -955,7 +955,7 @@ export class Move {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
get t2(): number {
|
||||
get t2(): number | null {
|
||||
return this._t2;
|
||||
}
|
||||
}
|
||||
@@ -1106,14 +1106,14 @@ export class ComplexFade {
|
||||
* @param {!Array.<!libjass.parts.Tag>} tags
|
||||
*/
|
||||
export class Transform {
|
||||
constructor(private _start: number, private _end: number, private _accel: number, private _tags: Part[]) { }
|
||||
constructor(private _start: number | null, private _end: number | null, private _accel: number | null, private _tags: Part[]) { }
|
||||
|
||||
/**
|
||||
* The starting time of this transform tag.
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
get start(): number {
|
||||
get start(): number | null {
|
||||
return this._start;
|
||||
}
|
||||
|
||||
@@ -1122,7 +1122,7 @@ export class Transform {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
get end(): number {
|
||||
get end(): number | null {
|
||||
return this._end;
|
||||
}
|
||||
|
||||
@@ -1131,7 +1131,7 @@ export class Transform {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
get accel(): number {
|
||||
get accel(): number | null {
|
||||
return this._accel;
|
||||
}
|
||||
|
||||
@@ -1299,10 +1299,10 @@ const addToString = function (ctor: Function, ctorName: string) {
|
||||
if (!ctor.prototype.hasOwnProperty("toString")) {
|
||||
const propertyNames = Object.getOwnPropertyNames(ctor.prototype).filter(property => property !== "constructor");
|
||||
|
||||
ctor.prototype.toString = function () {
|
||||
ctor.prototype.toString = function (this: any) {
|
||||
return (
|
||||
ctorName + " { " +
|
||||
propertyNames.map(name => `${ name }: ${ (this as any)[name] }`).join(", ") +
|
||||
propertyNames.map(name => `${ name }: ${ this[name] }`).join(", ") +
|
||||
((propertyNames.length > 0) ? " " : "") +
|
||||
"}"
|
||||
);
|
||||
|
||||
@@ -41,10 +41,10 @@ import { ManualClock } from "./manual";
|
||||
export class AutoClock implements Clock {
|
||||
private _manualClock: ManualClock = new ManualClock();
|
||||
|
||||
private _nextAnimationFrameRequestId: number = null;
|
||||
private _nextAnimationFrameRequestId: number | null = null;
|
||||
|
||||
private _lastKnownExternalTime: number = null;
|
||||
private _lastKnownExternalTimeObtainedAt: number = null;
|
||||
private _lastKnownExternalTime: number | null = null;
|
||||
private _lastKnownExternalTimeObtainedAt: number | null = null;
|
||||
|
||||
constructor(private _getCurrentTime: () => number, private _autoPauseAfter: number) { }
|
||||
|
||||
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* libjass
|
||||
*
|
||||
* https://github.com/Arnavion/libjass
|
||||
*
|
||||
* Copyright 2013 Arnav Singh
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
interface Array<T> {
|
||||
/**
|
||||
* Returns the elements of an array that meet the condition specified in a callback function.
|
||||
* @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
|
||||
}
|
||||
@@ -45,7 +45,7 @@ export class RendererSettings {
|
||||
*
|
||||
* @type {Map.<string, (string|!Array.<string>)>}
|
||||
*/
|
||||
fontMap: Map<string, string | string[]>;
|
||||
fontMap: Map<string, string | string[]> | null;
|
||||
|
||||
/**
|
||||
* Subtitles will be pre-rendered for this amount of time (seconds).
|
||||
@@ -121,13 +121,13 @@ export class RendererSettings {
|
||||
const rule = styleSheet.cssRules[i];
|
||||
|
||||
if (isFontFaceRule(rule)) {
|
||||
const name = rule.style.getPropertyValue("font-family").match(/^["']?(.*?)["']?$/)[1];
|
||||
const name = rule.style.getPropertyValue("font-family").match(/^["']?(.*?)["']?$/)![1];
|
||||
|
||||
let src = rule.style.getPropertyValue("src");
|
||||
if (!src) {
|
||||
src = rule.cssText.split("\n")
|
||||
.map(line => line.match(/src:\s*([^;]+?)\s*;/))
|
||||
.filter(matches => matches !== null)
|
||||
.filter((matches): matches is RegExpMatchArray => matches !== null)
|
||||
.map(matches => matches[1])[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -71,12 +71,8 @@ export class AnimationCollection {
|
||||
* @param {!Array.<!libjass.renderers.Keyframe>} keyframes
|
||||
*/
|
||||
add(timingFunction: string, keyframes: Keyframe[]): void {
|
||||
if (keyframes.length < 1) {
|
||||
throw new Error("Atleast one keyframe must be provided.");
|
||||
}
|
||||
|
||||
let start: number = null;
|
||||
let end: number = null;
|
||||
let start: number | null = null;
|
||||
let end: number | null = null;
|
||||
|
||||
for (const keyframe of keyframes) {
|
||||
if (start === null) {
|
||||
@@ -86,6 +82,10 @@ export class AnimationCollection {
|
||||
end = keyframe.time;
|
||||
}
|
||||
|
||||
if (start === null || end === null) {
|
||||
throw new Error("Atleast one keyframe must be provided.");
|
||||
}
|
||||
|
||||
let ruleCssText = "";
|
||||
|
||||
for (const keyframe of keyframes) {
|
||||
|
||||
@@ -215,7 +215,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
}
|
||||
});
|
||||
|
||||
let fontFetchPromise: Promise<FontFace>;
|
||||
let fontFetchPromise: Promise<FontFace | null>;
|
||||
if (existingFontFaces.length === 0) {
|
||||
const fontFace = new FontFace(fontFamily, source);
|
||||
const quotedFontFace = new FontFace(`"${ fontFamily }"`, source);
|
||||
@@ -254,7 +254,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
|
||||
// A url() URL. Extract the raw URL.
|
||||
return match[2];
|
||||
}).filter(url => url !== null);
|
||||
}).filter((url): url is string => url !== null);
|
||||
|
||||
const attachedFontUrls = attachedFontsMap.get(fontFamily);
|
||||
if (attachedFontUrls !== undefined) {
|
||||
@@ -266,7 +266,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
let fontFetchPromise = fontFetchPromisesCache.get(url);
|
||||
if (fontFetchPromise === undefined) {
|
||||
fontFetchPromise =
|
||||
new Promise<void>((resolve, reject) => {
|
||||
new Promise<null>((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.addEventListener("load", () => {
|
||||
if (debugMode) {
|
||||
@@ -290,7 +290,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
|
||||
const allFontsFetchedPromise =
|
||||
(thisFontFamilysFetchPromises.length === 0) ?
|
||||
Promise.resolve<void>(null) :
|
||||
Promise.resolve(null) :
|
||||
Promise_first(thisFontFamilysFetchPromises).catch(reason => {
|
||||
console.warn(`Fetching fonts for ${ fontFamily } at ${ urls.join(", ") } failed: %o`, reason);
|
||||
return null;
|
||||
@@ -354,7 +354,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
* @param {!libjass.Dialogue} dialogue
|
||||
* @return {PreRenderedSub}
|
||||
*/
|
||||
preRender(dialogue: Dialogue): PreRenderedSub {
|
||||
preRender(dialogue: Dialogue): PreRenderedSub | null {
|
||||
const currentTimeRelativeToDialogueStart = this.clock.currentTime - dialogue.start;
|
||||
|
||||
if (dialogue.containsTransformTag && currentTimeRelativeToDialogueStart < 0) {
|
||||
@@ -389,15 +389,15 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
const svgDefsElement = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
||||
svgElement.appendChild(svgDefsElement);
|
||||
|
||||
let currentSpan: HTMLSpanElement = null;
|
||||
let currentSpan: HTMLSpanElement | null = null;
|
||||
const currentSpanStyles = new SpanStyles(this, dialogue, this._scaleX, this._scaleY, this.settings, this._fontSizeElement, svgDefsElement, this._fontMetricsCache);
|
||||
|
||||
let currentAnimationCollection: AnimationCollection = null;
|
||||
let currentAnimationCollection: AnimationCollection | null = null;
|
||||
|
||||
let previousAddNewLine = false; // If two or more \N's are encountered in sequence, then all but the first will be created using currentSpanStyles.makeNewLine() instead
|
||||
const startNewSpan = (addNewLine: boolean): void => {
|
||||
if (currentSpan !== null && currentSpan.hasChildNodes()) {
|
||||
sub.appendChild(currentSpanStyles.setStylesOnSpan(currentSpan, currentAnimationCollection));
|
||||
sub.appendChild(currentSpanStyles.setStylesOnSpan(currentSpan, currentAnimationCollection!));
|
||||
}
|
||||
|
||||
if (currentAnimationCollection !== null) {
|
||||
@@ -571,11 +571,11 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
else if (part instanceof parts.ColorKaraoke) {
|
||||
startNewSpan(false);
|
||||
|
||||
currentAnimationCollection.add("step-end", [
|
||||
currentAnimationCollection!.add("step-end", [
|
||||
new Keyframe(0, new Map([
|
||||
["color", currentSpanStyles.secondaryColor.withAlpha(currentSpanStyles.secondaryAlpha).toString()],
|
||||
["color", currentSpanStyles.secondaryColor!.withAlpha(currentSpanStyles.secondaryAlpha!).toString()],
|
||||
])), new Keyframe(karaokeTimesAccumulator, new Map([
|
||||
["color", currentSpanStyles.primaryColor.withAlpha(currentSpanStyles.primaryAlpha).toString()],
|
||||
["color", currentSpanStyles.primaryColor!.withAlpha(currentSpanStyles.primaryAlpha!).toString()],
|
||||
]))
|
||||
]);
|
||||
|
||||
@@ -607,10 +607,10 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
dialogueAnimationCollection.add("linear", [new Keyframe(0, new Map([
|
||||
["left", `${ (this._scaleX * part.x1).toFixed(3) }px`],
|
||||
["top", `${ (this._scaleY * part.y1).toFixed(3) }px`],
|
||||
])), new Keyframe(part.t1, new Map([
|
||||
])), new Keyframe(part.t1!, new Map([
|
||||
["left", `${ (this._scaleX * part.x1).toFixed(3) }px`],
|
||||
["top", `${ (this._scaleY * part.y1).toFixed(3) }px`],
|
||||
])), new Keyframe(part.t2, new Map([
|
||||
])), new Keyframe(part.t2!, new Map([
|
||||
["left", `${ (this._scaleX * part.x2).toFixed(3) }px`],
|
||||
["top", `${ (this._scaleY * part.y2).toFixed(3) }px`],
|
||||
])), new Keyframe(dialogue.end - dialogue.start, new Map([
|
||||
@@ -651,7 +651,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
const progression =
|
||||
(currentTimeRelativeToDialogueStart <= part.start) ? 0 :
|
||||
(currentTimeRelativeToDialogueStart >= part.end) ? 1 :
|
||||
Math.pow((currentTimeRelativeToDialogueStart - part.start) / (part.end - part.start), part.accel);
|
||||
Math.pow((currentTimeRelativeToDialogueStart - part.start) / (part.end - part.start), part.accel!);
|
||||
|
||||
for (const tag of part.tags) {
|
||||
if (tag instanceof parts.Border) {
|
||||
@@ -821,7 +821,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
|
||||
else if (tag instanceof parts.PrimaryColor) {
|
||||
if (tag.value !== null) {
|
||||
currentSpanStyles.primaryColor = currentSpanStyles.primaryColor.interpolate(tag.value, progression);
|
||||
currentSpanStyles.primaryColor = currentSpanStyles.primaryColor!.interpolate(tag.value, progression);
|
||||
}
|
||||
else {
|
||||
currentSpanStyles.primaryColor = null;
|
||||
@@ -830,7 +830,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
|
||||
else if (tag instanceof parts.SecondaryColor) {
|
||||
if (tag.value !== null) {
|
||||
currentSpanStyles.secondaryColor = currentSpanStyles.secondaryColor.interpolate(tag.value, progression);
|
||||
currentSpanStyles.secondaryColor = currentSpanStyles.secondaryColor!.interpolate(tag.value, progression);
|
||||
}
|
||||
else {
|
||||
currentSpanStyles.secondaryColor = null;
|
||||
@@ -839,7 +839,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
|
||||
else if (tag instanceof parts.OutlineColor) {
|
||||
if (tag.value !== null) {
|
||||
currentSpanStyles.outlineColor = currentSpanStyles.outlineColor.interpolate(tag.value, progression);
|
||||
currentSpanStyles.outlineColor = currentSpanStyles.outlineColor!.interpolate(tag.value, progression);
|
||||
}
|
||||
else {
|
||||
currentSpanStyles.outlineColor = null;
|
||||
@@ -848,7 +848,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
|
||||
else if (tag instanceof parts.ShadowColor) {
|
||||
if (tag.value !== null) {
|
||||
currentSpanStyles.shadowColor = currentSpanStyles.shadowColor.interpolate(tag.value, progression);
|
||||
currentSpanStyles.shadowColor = currentSpanStyles.shadowColor!.interpolate(tag.value, progression);
|
||||
}
|
||||
else {
|
||||
currentSpanStyles.shadowColor = null;
|
||||
@@ -919,17 +919,17 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
}
|
||||
|
||||
else if (part instanceof parts.DrawingInstructions) {
|
||||
currentSpan.appendChild(currentDrawingStyles.toSVG(part, currentSpanStyles.primaryColor.withAlpha(currentSpanStyles.primaryAlpha)));
|
||||
currentSpan!.appendChild(currentDrawingStyles.toSVG(part, currentSpanStyles.primaryColor!.withAlpha(currentSpanStyles.primaryAlpha!)));
|
||||
startNewSpan(false);
|
||||
}
|
||||
|
||||
else if (part instanceof parts.Text) {
|
||||
currentSpan.appendChild(document.createTextNode(part.value + "\u200C"));
|
||||
currentSpan!.appendChild(document.createTextNode(part.value + "\u200C"));
|
||||
startNewSpan(false);
|
||||
}
|
||||
|
||||
else if (debugMode && part instanceof parts.Comment) {
|
||||
currentSpan.appendChild(document.createTextNode(part.value));
|
||||
currentSpan!.appendChild(document.createTextNode(part.value));
|
||||
startNewSpan(false);
|
||||
}
|
||||
|
||||
@@ -1029,16 +1029,18 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
console.log(dialogue.toString());
|
||||
}
|
||||
|
||||
let preRenderedSub = this._preRenderedSubs.get(dialogue.id);
|
||||
let thePreRenderedSub = this._preRenderedSubs.get(dialogue.id);
|
||||
|
||||
if (preRenderedSub === undefined) {
|
||||
preRenderedSub = this.preRender(dialogue);
|
||||
if (thePreRenderedSub === undefined) {
|
||||
thePreRenderedSub = this.preRender(dialogue)!;
|
||||
|
||||
if (debugMode) {
|
||||
console.log(dialogue.toString());
|
||||
}
|
||||
}
|
||||
|
||||
const preRenderedSub = thePreRenderedSub;
|
||||
|
||||
const result = preRenderedSub.sub.cloneNode(true);
|
||||
|
||||
const applyAnimationDelays = (node: HTMLElement) => {
|
||||
@@ -1069,7 +1071,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
layerWrapper.className = `layer layer${ layer }`;
|
||||
|
||||
// Find the next greater layer div and insert this div before that one
|
||||
let insertBeforeElement: HTMLDivElement = null;
|
||||
let insertBeforeElement: HTMLDivElement | null = null;
|
||||
for (let insertBeforeLayer = layer + 1; insertBeforeLayer < this._layerWrappers.length && insertBeforeElement === null; insertBeforeLayer++) {
|
||||
if (this._layerWrappers[insertBeforeLayer] !== undefined) {
|
||||
insertBeforeElement = this._layerWrappers[insertBeforeLayer];
|
||||
@@ -1089,7 +1091,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
|
||||
// Find the next greater layer,alignment div and insert this div before that one
|
||||
const layerWrapper = this._layerWrappers[layer];
|
||||
let insertBeforeElement: HTMLDivElement = null;
|
||||
let insertBeforeElement: HTMLDivElement | null = null;
|
||||
for (let insertBeforeAlignment = alignment + 1; insertBeforeAlignment < this._layerAlignmentWrappers[layer].length && insertBeforeElement === null; insertBeforeAlignment++) {
|
||||
if (this._layerAlignmentWrappers[layer][insertBeforeAlignment] !== undefined) {
|
||||
insertBeforeElement = this._layerAlignmentWrappers[layer][insertBeforeAlignment];
|
||||
@@ -1113,7 +1115,7 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
|
||||
if (dialogueAnimationStylesElement !== undefined) {
|
||||
const sheet = dialogueAnimationStylesElement.sheet as CSSStyleSheet;
|
||||
if (sheet.cssRules.length === 0) {
|
||||
sheet.cssText = dialogueAnimationStylesElement.textContent;
|
||||
sheet.cssText = dialogueAnimationStylesElement.textContent!;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @param {libjass.Style} newStyle The new defaults to reset the style to. If null, the styles are reset to the default style of the Dialogue.
|
||||
*/
|
||||
reset(newStyle: Style): void {
|
||||
reset(newStyle: Style | undefined | null): void {
|
||||
if (newStyle === undefined || newStyle === null) {
|
||||
newStyle = this._defaultStyle;
|
||||
}
|
||||
@@ -607,7 +607,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {(?boolean|?number)}
|
||||
*/
|
||||
set bold(value: boolean | number) {
|
||||
set bold(value: boolean | number | null) {
|
||||
this._bold = valueOrDefault(value, this._defaultStyle.bold);
|
||||
}
|
||||
|
||||
@@ -634,7 +634,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get outlineWidth(): number {
|
||||
get outlineWidth(): number | null {
|
||||
return this._outlineWidth;
|
||||
}
|
||||
|
||||
@@ -643,7 +643,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set outlineWidth(value: number) {
|
||||
set outlineWidth(value: number | null) {
|
||||
this._outlineWidth = valueOrDefault(value, this._defaultStyle.outlineThickness);
|
||||
}
|
||||
|
||||
@@ -652,7 +652,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get outlineHeight(): number {
|
||||
get outlineHeight(): number | null {
|
||||
return this._outlineHeight;
|
||||
}
|
||||
|
||||
@@ -661,7 +661,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set outlineHeight(value: number) {
|
||||
set outlineHeight(value: number | null) {
|
||||
this._outlineHeight = valueOrDefault(value, this._defaultStyle.outlineThickness);
|
||||
}
|
||||
|
||||
@@ -670,7 +670,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get shadowDepthX(): number {
|
||||
get shadowDepthX(): number | null {
|
||||
return this._shadowDepthX;
|
||||
}
|
||||
|
||||
@@ -679,7 +679,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set shadowDepthX(value: number) {
|
||||
set shadowDepthX(value: number | null) {
|
||||
this._shadowDepthX = valueOrDefault(value, this._defaultStyle.shadowDepth);
|
||||
}
|
||||
|
||||
@@ -688,7 +688,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get shadowDepthY(): number {
|
||||
get shadowDepthY(): number | null {
|
||||
return this._shadowDepthY;
|
||||
}
|
||||
|
||||
@@ -697,7 +697,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set shadowDepthY(value: number) {
|
||||
set shadowDepthY(value: number | null) {
|
||||
this._shadowDepthY = valueOrDefault(value, this._defaultStyle.shadowDepth);
|
||||
}
|
||||
|
||||
@@ -706,7 +706,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get blur(): number {
|
||||
get blur(): number | null {
|
||||
return this._blur;
|
||||
}
|
||||
|
||||
@@ -715,7 +715,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set blur(value: number) {
|
||||
set blur(value: number | null) {
|
||||
this._blur = valueOrDefault(value, 0);
|
||||
}
|
||||
|
||||
@@ -724,7 +724,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get gaussianBlur(): number {
|
||||
get gaussianBlur(): number | null {
|
||||
return this._gaussianBlur;
|
||||
}
|
||||
|
||||
@@ -733,7 +733,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set gaussianBlur(value: number) {
|
||||
set gaussianBlur(value: number | null) {
|
||||
this._gaussianBlur = valueOrDefault(value, 0);
|
||||
}
|
||||
|
||||
@@ -742,7 +742,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?string}
|
||||
*/
|
||||
set fontName(value: string) {
|
||||
set fontName(value: string | null) {
|
||||
this._fontName = valueOrDefault(value, this._defaultStyle.fontName);
|
||||
}
|
||||
|
||||
@@ -751,7 +751,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get fontSize(): number {
|
||||
get fontSize(): number | null {
|
||||
return this._fontSize;
|
||||
}
|
||||
|
||||
@@ -760,7 +760,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set fontSize(value: number) {
|
||||
set fontSize(value: number | null) {
|
||||
this._fontSize = valueOrDefault(value, this._defaultStyle.fontSize);
|
||||
}
|
||||
|
||||
@@ -769,7 +769,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get fontScaleX(): number {
|
||||
get fontScaleX(): number | null {
|
||||
return this._fontScaleX;
|
||||
}
|
||||
|
||||
@@ -778,7 +778,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set fontScaleX(value: number) {
|
||||
set fontScaleX(value: number | null) {
|
||||
this._fontScaleX = valueOrDefault(value, this._defaultStyle.fontScaleX);
|
||||
}
|
||||
|
||||
@@ -787,7 +787,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get fontScaleY(): number {
|
||||
get fontScaleY(): number | null {
|
||||
return this._fontScaleY;
|
||||
}
|
||||
|
||||
@@ -796,7 +796,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set fontScaleY(value: number) {
|
||||
set fontScaleY(value: number | null) {
|
||||
this._fontScaleY = valueOrDefault(value, this._defaultStyle.fontScaleY);
|
||||
}
|
||||
|
||||
@@ -805,7 +805,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get letterSpacing(): number {
|
||||
get letterSpacing(): number | null {
|
||||
return this._letterSpacing;
|
||||
}
|
||||
|
||||
@@ -814,7 +814,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set letterSpacing(value: number) {
|
||||
set letterSpacing(value: number | null) {
|
||||
this._letterSpacing = valueOrDefault(value, this._defaultStyle.letterSpacing);
|
||||
}
|
||||
|
||||
@@ -823,7 +823,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get rotationX(): number {
|
||||
get rotationX(): number | null {
|
||||
return this._rotationX;
|
||||
}
|
||||
|
||||
@@ -832,7 +832,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set rotationX(value: number) {
|
||||
set rotationX(value: number | null) {
|
||||
this._rotationX = valueOrDefault(value, 0);
|
||||
}
|
||||
|
||||
@@ -841,7 +841,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get rotationY(): number {
|
||||
get rotationY(): number | null {
|
||||
return this._rotationY;
|
||||
}
|
||||
|
||||
@@ -850,7 +850,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set rotationY(value: number) {
|
||||
set rotationY(value: number | null) {
|
||||
this._rotationY = valueOrDefault(value, 0);
|
||||
}
|
||||
|
||||
@@ -859,7 +859,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get rotationZ(): number {
|
||||
get rotationZ(): number | null {
|
||||
return this._rotationZ;
|
||||
}
|
||||
|
||||
@@ -868,7 +868,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set rotationZ(value: number) {
|
||||
set rotationZ(value: number | null) {
|
||||
this._rotationZ = valueOrDefault(value, this._defaultStyle.rotationZ);
|
||||
}
|
||||
|
||||
@@ -877,7 +877,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get skewX(): number {
|
||||
get skewX(): number | null {
|
||||
return this._skewX;
|
||||
}
|
||||
|
||||
@@ -886,7 +886,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set skewX(value: number) {
|
||||
set skewX(value: number | null) {
|
||||
this._skewX = valueOrDefault(value, 0);
|
||||
}
|
||||
|
||||
@@ -895,7 +895,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get skewY(): number {
|
||||
get skewY(): number | null {
|
||||
return this._skewY;
|
||||
}
|
||||
|
||||
@@ -904,7 +904,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set skewY(value: number) {
|
||||
set skewY(value: number | null) {
|
||||
this._skewY = valueOrDefault(value, 0);
|
||||
}
|
||||
|
||||
@@ -913,7 +913,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {!libjass.Color}
|
||||
*/
|
||||
get primaryColor(): Color {
|
||||
get primaryColor(): Color | null {
|
||||
return this._primaryColor;
|
||||
}
|
||||
|
||||
@@ -922,7 +922,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {libjass.Color}
|
||||
*/
|
||||
set primaryColor(value: Color) {
|
||||
set primaryColor(value: Color | null) {
|
||||
this._primaryColor = valueOrDefault(value, this._defaultStyle.primaryColor);
|
||||
}
|
||||
|
||||
@@ -931,7 +931,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {!libjass.Color}
|
||||
*/
|
||||
get secondaryColor(): Color {
|
||||
get secondaryColor(): Color | null {
|
||||
return this._secondaryColor;
|
||||
}
|
||||
|
||||
@@ -940,7 +940,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {libjass.Color}
|
||||
*/
|
||||
set secondaryColor(value: Color) {
|
||||
set secondaryColor(value: Color | null) {
|
||||
this._secondaryColor = valueOrDefault(value, this._defaultStyle.secondaryColor);
|
||||
}
|
||||
|
||||
@@ -949,7 +949,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {!libjass.Color}
|
||||
*/
|
||||
get outlineColor(): Color {
|
||||
get outlineColor(): Color | null {
|
||||
return this._outlineColor;
|
||||
}
|
||||
|
||||
@@ -958,7 +958,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {libjass.Color}
|
||||
*/
|
||||
set outlineColor(value: Color) {
|
||||
set outlineColor(value: Color | null) {
|
||||
this._outlineColor = valueOrDefault(value, this._defaultStyle.outlineColor);
|
||||
}
|
||||
|
||||
@@ -967,7 +967,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {!libjass.Color}
|
||||
*/
|
||||
get shadowColor(): Color {
|
||||
get shadowColor(): Color | null {
|
||||
return this._shadowColor;
|
||||
}
|
||||
|
||||
@@ -976,7 +976,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {libjass.Color}
|
||||
*/
|
||||
set shadowColor(value: Color) {
|
||||
set shadowColor(value: Color | null) {
|
||||
this._shadowColor = valueOrDefault(value, this._defaultStyle.shadowColor);
|
||||
}
|
||||
|
||||
@@ -985,7 +985,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get primaryAlpha(): number {
|
||||
get primaryAlpha(): number | null {
|
||||
return this._primaryAlpha;
|
||||
}
|
||||
|
||||
@@ -994,7 +994,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set primaryAlpha(value: number) {
|
||||
set primaryAlpha(value: number | null) {
|
||||
this._primaryAlpha = valueOrDefault(value, this._defaultStyle.primaryColor.alpha);
|
||||
}
|
||||
|
||||
@@ -1003,7 +1003,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get secondaryAlpha(): number {
|
||||
get secondaryAlpha(): number | null {
|
||||
return this._secondaryAlpha;
|
||||
}
|
||||
|
||||
@@ -1012,7 +1012,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set secondaryAlpha(value: number) {
|
||||
set secondaryAlpha(value: number | null) {
|
||||
this._secondaryAlpha = valueOrDefault(value, this._defaultStyle.secondaryColor.alpha);
|
||||
}
|
||||
|
||||
@@ -1021,7 +1021,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get outlineAlpha(): number {
|
||||
get outlineAlpha(): number | null {
|
||||
return this._outlineAlpha;
|
||||
}
|
||||
|
||||
@@ -1030,7 +1030,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set outlineAlpha(value: number) {
|
||||
set outlineAlpha(value: number | null) {
|
||||
this._outlineAlpha = valueOrDefault(value, this._defaultStyle.outlineColor.alpha);
|
||||
}
|
||||
|
||||
@@ -1039,7 +1039,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get shadowAlpha(): number {
|
||||
get shadowAlpha(): number | null {
|
||||
return this._shadowAlpha;
|
||||
}
|
||||
|
||||
@@ -1048,7 +1048,7 @@ export class SpanStyles {
|
||||
*
|
||||
* @type {?number}
|
||||
*/
|
||||
set shadowAlpha(value: number) {
|
||||
set shadowAlpha(value: number | null) {
|
||||
this._shadowAlpha = valueOrDefault(value, this._defaultStyle.shadowColor.alpha);
|
||||
}
|
||||
}
|
||||
@@ -1092,6 +1092,6 @@ function createComponentTransferFilter(color: Color): SVGFEComponentTransferElem
|
||||
* @param {!T} defaultValue
|
||||
* @return {!T}
|
||||
*/
|
||||
function valueOrDefault<T>(newValue: T, defaultValue: T): T {
|
||||
function valueOrDefault<T>(newValue: T | null, defaultValue: T): T {
|
||||
return ((newValue !== null) ? newValue : defaultValue);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es5", "dom"],
|
||||
|
||||
"experimentalDecorators": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": false,
|
||||
"strictNullChecks": true,
|
||||
|
||||
"target": "es5",
|
||||
"module": "amd",
|
||||
|
||||
+7
-7
@@ -38,7 +38,7 @@ import { registerClass as serializable } from "../serialization";
|
||||
|
||||
declare const global: {
|
||||
fetch?(url: string): Promise<{ body: ReadableStream; ok?: boolean; status?: number; }>;
|
||||
ReadableStream?: { prototype: ReadableStream; };
|
||||
ReadableStream?: Function & { prototype: ReadableStream; };
|
||||
TextDecoder?: TextDecoderConstructor;
|
||||
};
|
||||
|
||||
@@ -52,8 +52,8 @@ export class ASS {
|
||||
private _dialogues: Dialogue[] = [];
|
||||
private _attachments: Attachment[] = [];
|
||||
|
||||
private _stylesFormatSpecifier: string[] = null;
|
||||
private _dialoguesFormatSpecifier: string[] = null;
|
||||
private _stylesFormatSpecifier: string[] | null = null;
|
||||
private _dialoguesFormatSpecifier: string[] | null = null;
|
||||
|
||||
/**
|
||||
* The properties of this script.
|
||||
@@ -96,7 +96,7 @@ export class ASS {
|
||||
*
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
get stylesFormatSpecifier(): string[] {
|
||||
get stylesFormatSpecifier(): string[] | null {
|
||||
return this._stylesFormatSpecifier;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ export class ASS {
|
||||
*
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
get dialoguesFormatSpecifier(): string[] {
|
||||
get dialoguesFormatSpecifier(): string[] | null {
|
||||
return this._dialoguesFormatSpecifier;
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ export class ASS {
|
||||
*
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
set stylesFormatSpecifier(value: string[]) {
|
||||
set stylesFormatSpecifier(value: string[] | null) {
|
||||
this._stylesFormatSpecifier = value;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export class ASS {
|
||||
*
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
set dialoguesFormatSpecifier(value: string[]) {
|
||||
set dialoguesFormatSpecifier(value: string[] | null) {
|
||||
this._dialoguesFormatSpecifier = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ export class Dialogue {
|
||||
private _alignment: number;
|
||||
|
||||
private _rawPartsString: string;
|
||||
private _parts: parts.Part[] = null;
|
||||
private _parts: parts.Part[] | null = null;
|
||||
|
||||
private _containsTransformTag: boolean = false;
|
||||
|
||||
@@ -184,7 +184,7 @@ export class Dialogue {
|
||||
this._parsePartsString();
|
||||
}
|
||||
|
||||
return this._parts;
|
||||
return this._parts!;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,7 +221,7 @@ export class Dialogue {
|
||||
}
|
||||
else if (part instanceof parts.Move) {
|
||||
if (part.t1 === null || part.t2 === null) {
|
||||
this._parts[index] =
|
||||
this._parts![index] =
|
||||
new parts.Move(
|
||||
part.x1, part.y1, part.x2, part.y2,
|
||||
0, this._end - this._start
|
||||
@@ -230,7 +230,7 @@ export class Dialogue {
|
||||
}
|
||||
else if (part instanceof parts.Transform) {
|
||||
if (part.start === null || part.end === null || part.accel === null) {
|
||||
this._parts[index] =
|
||||
this._parts![index] =
|
||||
new parts.Transform(
|
||||
(part.start === null) ? 0 : part.start,
|
||||
(part.end === null) ? (this._end - this._start) : part.end,
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ export interface TypedTemplate {
|
||||
* @param {T} defaultValue
|
||||
* @return {T}
|
||||
*/
|
||||
export function valueOrDefault<T>(template: Map<string, string>, key: string, converter: (str: string) => T, validator: (value: T) => boolean, defaultValue: string): T {
|
||||
export function valueOrDefault<T>(template: Map<string, string>, key: string, converter: (str: string) => T, validator: ((value: T) => boolean) | null, defaultValue: string): T {
|
||||
const value = template.get(key);
|
||||
if (value === undefined) {
|
||||
return converter(defaultValue);
|
||||
|
||||
+13
-13
@@ -18,16 +18,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
declare const global: {
|
||||
Map?: typeof Map;
|
||||
};
|
||||
|
||||
export interface Map<K, V> {
|
||||
/**
|
||||
* @param {K} key
|
||||
* @return {?V}
|
||||
*/
|
||||
get(key: K): V;
|
||||
get(key: K): V | undefined;
|
||||
|
||||
/**
|
||||
* @param {K} key
|
||||
@@ -40,7 +36,7 @@ export interface Map<K, V> {
|
||||
* @param {V} value
|
||||
* @return {libjass.Map.<K, V>} This map
|
||||
*/
|
||||
set(key: K, value?: V): Map<K, V>;
|
||||
set(key: K, value: V): this;
|
||||
|
||||
/**
|
||||
* @param {K} key
|
||||
@@ -56,7 +52,7 @@ export interface Map<K, V> {
|
||||
* @param {function(V, K, libjass.Map.<K, V>)} callbackfn A function that is called with each key and value in the map.
|
||||
* @param {*} thisArg
|
||||
*/
|
||||
forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => void, thisArg?: any): void;
|
||||
forEach(callbackfn: (value: V, index: K, map: this) => void, thisArg?: any): void;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
@@ -71,7 +67,7 @@ export interface Map<K, V> {
|
||||
*
|
||||
* @param {!Array.<!Array.<*>>=} iterable Only an array of elements (where each element is a 2-tuple of key and value) is supported.
|
||||
*/
|
||||
class SimpleMap<K, V> {
|
||||
class SimpleMap<K, V> implements Map<K, V> {
|
||||
private _keys: { [key: string]: K };
|
||||
private _values: { [key: string]: V };
|
||||
private _size: number;
|
||||
@@ -96,7 +92,7 @@ class SimpleMap<K, V> {
|
||||
* @param {K} key
|
||||
* @return {?V}
|
||||
*/
|
||||
get(key: K): V {
|
||||
get(key: K): V | undefined {
|
||||
const property = this._keyToProperty(key);
|
||||
|
||||
if (property === null) {
|
||||
@@ -125,7 +121,7 @@ class SimpleMap<K, V> {
|
||||
* @param {V} value
|
||||
* @return {libjass.Map.<K, V>} This map
|
||||
*/
|
||||
set(key: K, value: V): Map<K, V> {
|
||||
set(key: K, value: V): this {
|
||||
const property = this._keyToProperty(key);
|
||||
|
||||
if (property === null) {
|
||||
@@ -176,7 +172,7 @@ class SimpleMap<K, V> {
|
||||
* @param {function(V, K, libjass.Map.<K, V>)} callbackfn A function that is called with each key and value in the map.
|
||||
* @param {*} thisArg
|
||||
*/
|
||||
forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => void, thisArg?: any): void {
|
||||
forEach(callbackfn: (value: V, index: K, map: this) => void, thisArg?: any): void {
|
||||
for (const property of Object.keys(this._keys)) {
|
||||
callbackfn.call(thisArg, this._values[property], this._keys[property], this);
|
||||
}
|
||||
@@ -195,7 +191,7 @@ class SimpleMap<K, V> {
|
||||
* @param {K} key
|
||||
* @return {?string}
|
||||
*/
|
||||
private _keyToProperty(key: K): string {
|
||||
private _keyToProperty(key: K): string | null {
|
||||
if (typeof key === "number") {
|
||||
return `#${ key }`;
|
||||
}
|
||||
@@ -237,12 +233,16 @@ if (typeof Map.prototype.forEach !== "function" || (() => {
|
||||
Map = SimpleMap;
|
||||
}
|
||||
|
||||
declare var global: {
|
||||
Map?: typeof Map;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the Map implementation used by libjass to the provided one. If null, {@link ./utility/map.SimpleMap} is used.
|
||||
*
|
||||
* @param {?function(new:Map, !Array.<!Array.<*>>=)} value
|
||||
*/
|
||||
export function setImplementation(value: typeof Map): void {
|
||||
export function setImplementation(value: typeof Map | null): void {
|
||||
if (value !== null) {
|
||||
Map = value;
|
||||
}
|
||||
|
||||
+23
-22
@@ -18,15 +18,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
declare const global: {
|
||||
Promise?: typeof Promise;
|
||||
MutationObserver?: typeof MutationObserver;
|
||||
WebkitMutationObserver?: typeof MutationObserver;
|
||||
process?: {
|
||||
nextTick(callback: () => void): void;
|
||||
}
|
||||
};
|
||||
|
||||
export interface Thenable<T> {
|
||||
/** @type {function(this:!Thenable.<T>, function(T|!Thenable.<T>), function(*))} */
|
||||
then: ThenableThen<T>;
|
||||
@@ -34,37 +25,38 @@ export interface Thenable<T> {
|
||||
|
||||
export interface ThenableThen<T> {
|
||||
/** @type {function(this:!Thenable.<T>, function(T|!Thenable.<T>), function(*))} */
|
||||
(resolve: (resolution: T | Thenable<T>) => void, reject: (reason: any) => void): void;
|
||||
(this: Thenable<T>, resolve: ((resolution: T | Thenable<T>) => void) | undefined, reject: ((reason: any) => void) | undefined): void;
|
||||
}
|
||||
|
||||
export interface Promise<T> extends Thenable<T> {
|
||||
/**
|
||||
* @param {?function(T):!Thenable.<U>} onFulfilled
|
||||
* @param {function(T):!Thenable.<U>} onFulfilled
|
||||
* @param {?function(*):(U|!Thenable.<U>)} onRejected
|
||||
* @return {!Promise.<U>}
|
||||
*/
|
||||
then<U>(onFulfilled?: (value: T) => Thenable<U>, onRejected?: (reason: any) => U | Thenable<U>): Promise<U>;
|
||||
then<U>(onFulfilled: (value: T) => Thenable<U> | undefined, onRejected?: (reason: any) => U | Thenable<U>): Promise<U>;
|
||||
|
||||
/**
|
||||
* @param {?function(T):U} onFulfilled
|
||||
* @param {function(T):U} onFulfilled
|
||||
* @param {?function(*):(U|!Thenable.<U>)} onRejected
|
||||
* @return {!Promise.<U>}
|
||||
*/
|
||||
then<U>(onFulfilled?: (value: T) => U, onRejected?: (reason: any) => U | Thenable<U>): Promise<U>;
|
||||
then<U>(onFulfilled: (value: T) => U | undefined, onRejected?: (reason: any) => U | Thenable<U>): Promise<U>;
|
||||
|
||||
/**
|
||||
* @param {function(*):(T|!Thenable.<T>)} onRejected
|
||||
* @return {!Promise.<T>}
|
||||
*/
|
||||
catch(onRejected?: (reason: any) => T | Thenable<T>): Promise<T>;
|
||||
catch(onRejected: (reason: any) => T | Thenable<T>): Promise<T>;
|
||||
}
|
||||
|
||||
// Based on https://github.com/petkaantonov/bluebird/blob/1b1467b95442c12378d0ea280ede61d640ab5510/src/schedule.js
|
||||
const enqueueJob: (callback: () => void) => void = (function () {
|
||||
const MutationObserver = global.MutationObserver || global.WebkitMutationObserver;
|
||||
if (global.process !== undefined && typeof global.process.nextTick === "function") {
|
||||
const process = global.process;
|
||||
return (callback: () => void) => {
|
||||
global.process.nextTick(callback);
|
||||
process.nextTick(callback);
|
||||
};
|
||||
}
|
||||
else if (MutationObserver !== undefined) {
|
||||
@@ -115,7 +107,7 @@ class SimplePromise<T> {
|
||||
private _fulfillReactions: FulfilledPromiseReaction<T, any>[] = [];
|
||||
private _rejectReactions: RejectedPromiseReaction<any>[] = [];
|
||||
|
||||
private _fulfilledValue: T = null;
|
||||
private _fulfilledValue: T | null = null;
|
||||
private _rejectedReason: any = null;
|
||||
|
||||
constructor(executor: (resolve: (resolution: T | Thenable<T>) => void, reject: (reason: any) => void) => void) {
|
||||
@@ -137,7 +129,7 @@ class SimplePromise<T> {
|
||||
* @param {?function(*):(U|!Thenable.<U>)} onRejected
|
||||
* @return {!Promise.<U>}
|
||||
*/
|
||||
then<U>(onFulfilled: (value: T) => U | Thenable<U>, onRejected: (reason: any) => U | Thenable<U>): Promise<U> {
|
||||
then<U>(onFulfilled: ((value: T) => U | Thenable<U>) | undefined, onRejected?: (reason: any) => U | Thenable<U>): Promise<U> {
|
||||
const resultCapability = new DeferredPromise<U>();
|
||||
|
||||
if (typeof onFulfilled !== "function") {
|
||||
@@ -165,7 +157,7 @@ class SimplePromise<T> {
|
||||
break;
|
||||
|
||||
case SimplePromiseState.FULFILLED:
|
||||
this._enqueueFulfilledReactionJob(fulfillReaction, this._fulfilledValue);
|
||||
this._enqueueFulfilledReactionJob(fulfillReaction, this._fulfilledValue!);
|
||||
break;
|
||||
|
||||
case SimplePromiseState.REJECTED:
|
||||
@@ -180,8 +172,8 @@ class SimplePromise<T> {
|
||||
* @param {function(*):(T|!Thenable.<T>)} onRejected
|
||||
* @return {!Promise.<T>}
|
||||
*/
|
||||
catch(onRejected?: (reason: any) => T | Thenable<T>): Promise<T> {
|
||||
return this.then(null, onRejected);
|
||||
catch(onRejected: (reason: any) => T | Thenable<T>): Promise<T> {
|
||||
return this.then(undefined, onRejected);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,6 +395,15 @@ export var Promise: {
|
||||
race<T>(values: (T | Thenable<T>)[]): Promise<T>;
|
||||
} = global.Promise || SimplePromise;
|
||||
|
||||
declare var global: {
|
||||
Promise?: typeof Promise;
|
||||
MutationObserver?: typeof MutationObserver;
|
||||
WebkitMutationObserver?: typeof MutationObserver;
|
||||
process?: {
|
||||
nextTick(callback: () => void): void;
|
||||
}
|
||||
};
|
||||
|
||||
interface FulfilledPromiseReaction<T, U> {
|
||||
/** @type {!libjass.DeferredPromise.<U>} */
|
||||
capabilities: DeferredPromise<U>;
|
||||
@@ -439,7 +440,7 @@ enum SimplePromiseState {
|
||||
*
|
||||
* @param {?function(new:Promise)} value
|
||||
*/
|
||||
export function setImplementation(value: typeof Promise): void {
|
||||
export function setImplementation(value: typeof Promise | null): void {
|
||||
if (value !== null) {
|
||||
Promise = value;
|
||||
}
|
||||
|
||||
+11
-11
@@ -18,16 +18,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
declare const global: {
|
||||
Set?: typeof Set;
|
||||
};
|
||||
|
||||
export interface Set<T> {
|
||||
/**
|
||||
* @param {T} value
|
||||
* @return {libjass.Set.<T>} This set
|
||||
*/
|
||||
add(value: T): Set<T>;
|
||||
add(value: T): this;
|
||||
|
||||
/**
|
||||
*/
|
||||
@@ -43,7 +39,7 @@ export interface Set<T> {
|
||||
* @param {function(T, T, libjass.Set.<T>)} callbackfn A function that is called with each value in the set.
|
||||
* @param {*} thisArg
|
||||
*/
|
||||
forEach(callbackfn: (value: T, index: T, set: Set<T>) => void, thisArg?: any): void;
|
||||
forEach(callbackfn: (value: T, index: T, set: this) => void, thisArg?: any): void;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
@@ -58,7 +54,7 @@ export interface Set<T> {
|
||||
*
|
||||
* @param {!Array.<T>=} iterable Only an array of values is supported.
|
||||
*/
|
||||
class SimpleSet<T> {
|
||||
class SimpleSet<T> implements Set<T> {
|
||||
private _elements: { [key: string]: T };
|
||||
private _size: number;
|
||||
|
||||
@@ -82,7 +78,7 @@ class SimpleSet<T> {
|
||||
* @param {T} value
|
||||
* @return {libjass.Set.<T>} This set
|
||||
*/
|
||||
add(value: T): Set<T> {
|
||||
add(value: T): this {
|
||||
const property = this._toProperty(value);
|
||||
|
||||
if (property === null) {
|
||||
@@ -123,7 +119,7 @@ class SimpleSet<T> {
|
||||
* @param {function(T, T, libjass.Set.<T>)} callbackfn A function that is called with each value in the set.
|
||||
* @param {*} thisArg
|
||||
*/
|
||||
forEach(callbackfn: (value: T, index: T, set: Set<T>) => void, thisArg?: any): void {
|
||||
forEach(callbackfn: (value: T, index: T, set: this) => void, thisArg?: any): void {
|
||||
for (const property of Object.keys(this._elements)) {
|
||||
const element = this._elements[property];
|
||||
callbackfn.call(thisArg, element, element, this);
|
||||
@@ -143,7 +139,7 @@ class SimpleSet<T> {
|
||||
* @param {T} value
|
||||
* @return {?string}
|
||||
*/
|
||||
private _toProperty(value: T): string {
|
||||
private _toProperty(value: T): string | null {
|
||||
if (typeof value === "number") {
|
||||
return `#${ value }`;
|
||||
}
|
||||
@@ -181,12 +177,16 @@ if (typeof Set.prototype.forEach !== "function" || (() => {
|
||||
Set = SimpleSet;
|
||||
}
|
||||
|
||||
declare var global: {
|
||||
Set?: typeof Set;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the Set implementation used by libjass to the provided one. If null, {@link ./utility/set.SimpleSet} is used.
|
||||
*
|
||||
* @param {?function(new:Set, !Array.<T>=)} value
|
||||
*/
|
||||
export function setImplementation(value: typeof Set): void {
|
||||
export function setImplementation(value: typeof Set | null): void {
|
||||
if (value !== null) {
|
||||
Set = value;
|
||||
}
|
||||
|
||||
@@ -217,4 +217,4 @@ export class WorkerChannelImpl implements WorkerChannel {
|
||||
}
|
||||
}
|
||||
|
||||
registerWorkerCommand(WorkerCommands.Ping, parameters => Promise.resolve<void>(null));
|
||||
registerWorkerCommand(WorkerCommands.Ping, parameters => Promise.resolve(null));
|
||||
|
||||
@@ -30,7 +30,7 @@ export { WorkerCommands } from "./commands";
|
||||
*/
|
||||
export const supported = typeof Worker !== "undefined";
|
||||
|
||||
const _scriptNode = (typeof document !== "undefined" && document.currentScript !== undefined) ? document.currentScript : null;
|
||||
const _scriptNode = (typeof document !== "undefined" && document.currentScript !== undefined) ? (document.currentScript as HTMLScriptElement) : null;
|
||||
|
||||
/**
|
||||
* Create a new web worker and returns a {@link libjass.webworker.WorkerChannel} to it.
|
||||
|
||||
@@ -41,6 +41,6 @@ export function registerWorkerCommand(command: WorkerCommands, handler: WorkerCo
|
||||
* @param {number} command
|
||||
* @return {?function(*, function(*, *))}
|
||||
*/
|
||||
export function getWorkerCommandHandler(command: WorkerCommands): WorkerCommandHandler {
|
||||
export function getWorkerCommandHandler(command: WorkerCommands): WorkerCommandHandler | undefined {
|
||||
return workerCommands.get(command);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user