Added a own declaration builder
This commit is contained in:
parent
63a5974390
commit
1d4a428284
4 changed files with 529 additions and 0 deletions
357
build/dtsgen/declarator.ts
Normal file
357
build/dtsgen/declarator.ts
Normal file
|
@ -0,0 +1,357 @@
|
||||||
|
import * as ts from "typescript";
|
||||||
|
import {SyntaxKind} from "typescript";
|
||||||
|
|
||||||
|
if (!Array.prototype.last){
|
||||||
|
Array.prototype.last = function(){
|
||||||
|
if(this.length == 0) return undefined;
|
||||||
|
return this[this.length - 1];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function has_modifier<T extends ts.Modifier["kind"]>(modifiers: ts.ModifiersArray | undefined, target: T) : boolean {
|
||||||
|
if(modifiers) {
|
||||||
|
for(const modifier of modifiers)
|
||||||
|
if(modifier.kind == target)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function append_modifier<T extends ts.Modifier["kind"]>(modifiers: ts.ModifiersArray | undefined, target: T) : ts.ModifiersArray {
|
||||||
|
if(has_modifier(modifiers, target)) return modifiers;
|
||||||
|
|
||||||
|
return ts.createNodeArray([ts.createModifier(target as number), ...(modifiers || [])], (modifiers || {hasTrailingComma: false}).hasTrailingComma);
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove_modifier<T extends ts.Modifier["kind"]>(modifiers: ts.ModifiersArray | undefined, target: T) : ts.ModifiersArray {
|
||||||
|
if(!has_modifier(modifiers, target)) return modifiers;
|
||||||
|
|
||||||
|
const new_modifiers: ts.Modifier[] = [];
|
||||||
|
for(const modifier of (modifiers || []))
|
||||||
|
if(modifier.kind != target)
|
||||||
|
new_modifiers.push(modifier);
|
||||||
|
|
||||||
|
return new_modifiers.length == 0 ? undefined : ts.createNodeArray(new_modifiers, (modifiers || {hasTrailingComma: false}).hasTrailingComma);
|
||||||
|
}
|
||||||
|
|
||||||
|
const has_declare = (modifiers?: ts.ModifiersArray) => has_modifier(modifiers, SyntaxKind.DeclareKeyword);
|
||||||
|
const has_private = (modifiers?: ts.ModifiersArray) => has_modifier(modifiers, SyntaxKind.PrivateKeyword);
|
||||||
|
const append_declare = (modifiers?: ts.ModifiersArray, flag: boolean = true) => flag ? append_modifier(modifiers, SyntaxKind.DeclareKeyword) : remove_modifier(modifiers, SyntaxKind.DeclareKeyword);
|
||||||
|
const append_export = (modifiers?: ts.ModifiersArray, flag: boolean = true) => flag ? append_modifier(modifiers, SyntaxKind.ExportKeyword) : remove_modifier(modifiers, SyntaxKind.ExportKeyword);
|
||||||
|
|
||||||
|
interface StackParameter {
|
||||||
|
flag_declare: boolean,
|
||||||
|
flag_namespace: boolean
|
||||||
|
flag_class: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
class StackParameters implements StackParameter {
|
||||||
|
flag_declare: boolean = false;
|
||||||
|
flag_namespace: boolean = false;
|
||||||
|
flag_class: boolean = false;
|
||||||
|
|
||||||
|
stack: StackParameter[] = [];
|
||||||
|
|
||||||
|
recalculate() {
|
||||||
|
{
|
||||||
|
this.flag_declare = false;
|
||||||
|
for(const layer of this.stack) {
|
||||||
|
if(layer.flag_declare) {
|
||||||
|
this.flag_declare = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
this.flag_namespace = false;
|
||||||
|
for(const layer of this.stack) {
|
||||||
|
if(layer.flag_namespace) {
|
||||||
|
this.flag_namespace = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
this.flag_class = false;
|
||||||
|
for(const layer of this.stack) {
|
||||||
|
if(layer.flag_class) {
|
||||||
|
this.flag_class = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
push(layer: StackParameter) {
|
||||||
|
this.stack.push(layer);
|
||||||
|
this.recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
pop?() : StackParameter {
|
||||||
|
const result = this.stack.pop();
|
||||||
|
if(result)
|
||||||
|
this.recalculate();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const generators: {[key: number]:((settings: _Settings, stack: StackParameters, node: ts.Node) => ts.Node | undefined) | undefined} = {};
|
||||||
|
|
||||||
|
function _generate(settings: _Settings, stack: StackParameters, layer: ts.Node[], node: ts.Node) {
|
||||||
|
//console.log(SyntaxKind[node.kind]);
|
||||||
|
if(generators[node.kind]) {
|
||||||
|
const result = generators[node.kind](settings, stack, node);
|
||||||
|
if(result)
|
||||||
|
layer.push(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(node.kind) {
|
||||||
|
case SyntaxKind.Identifier:
|
||||||
|
console.log("Unknown identifier %s", (<ts.Identifier>node).text);
|
||||||
|
break;
|
||||||
|
case SyntaxKind.SourceFile: /* yeah we have something */
|
||||||
|
node.forEachChild(n => _generate(settings, stack, layer, n));
|
||||||
|
break;
|
||||||
|
case SyntaxKind.EndOfFileToken: /* oh no, we're at the end */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("Unhandled type %s", SyntaxKind[node.kind]);
|
||||||
|
//node.forEachChild(n => _generate(settings, stack, layer, n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Settings {
|
||||||
|
remove_private?: {
|
||||||
|
field?: boolean;
|
||||||
|
method?: boolean;
|
||||||
|
} | boolean;
|
||||||
|
|
||||||
|
log?: {
|
||||||
|
unhandled_types: boolean;
|
||||||
|
} | boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _Settings implements Settings {
|
||||||
|
remove_private: {
|
||||||
|
field: boolean;
|
||||||
|
method: boolean;
|
||||||
|
} = {
|
||||||
|
field: false,
|
||||||
|
method: false
|
||||||
|
};
|
||||||
|
|
||||||
|
log?: {
|
||||||
|
unhandled_types: boolean;
|
||||||
|
} = {
|
||||||
|
unhandled_types: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function specify_settings(settings?: Settings) : _Settings {
|
||||||
|
const result: _Settings = new _Settings();
|
||||||
|
Object.assign(result, settings);
|
||||||
|
if(!settings)
|
||||||
|
settings = {};
|
||||||
|
|
||||||
|
if(typeof(settings.remove_private) === "boolean")
|
||||||
|
result.remove_private = {
|
||||||
|
field: settings.remove_private,
|
||||||
|
method: settings.remove_private
|
||||||
|
};
|
||||||
|
|
||||||
|
if(typeof(settings.log) === "boolean")
|
||||||
|
result.log = {
|
||||||
|
unhandled_types: settings.log,
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generate(file: ts.SourceFile, settings?: Settings) : ts.Node[]{
|
||||||
|
const layer: ts.Node[] = [];
|
||||||
|
const stack = new StackParameters();
|
||||||
|
const _settings = specify_settings(settings);
|
||||||
|
|
||||||
|
_generate(_settings, stack, layer, file);
|
||||||
|
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function print(nodes: ts.Node[]) : string {
|
||||||
|
const dummy_file = ts.createSourceFile(
|
||||||
|
"dummy_file",
|
||||||
|
"",
|
||||||
|
ts.ScriptTarget.ES2016,
|
||||||
|
false,
|
||||||
|
ts.ScriptKind.TS
|
||||||
|
);
|
||||||
|
|
||||||
|
const printer = ts.createPrinter({
|
||||||
|
newLine: ts.NewLineKind.LineFeed
|
||||||
|
});
|
||||||
|
|
||||||
|
return printer.printList(
|
||||||
|
ts.ListFormat.SpaceBetweenBraces | ts.ListFormat.MultiLine | ts.ListFormat.PreferNewLine,
|
||||||
|
nodes as any,
|
||||||
|
dummy_file
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generator impl */
|
||||||
|
generators[SyntaxKind.ModuleBlock] = (settings, stack, node: ts.ModuleBlock) => {
|
||||||
|
const layer = [] as ts.Node[];
|
||||||
|
node.forEachChild(n => _generate(settings, stack, layer, n));
|
||||||
|
return ts.createModuleBlock(layer as any);
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.ModuleDeclaration] = (settings, stack, node: ts.ModuleDeclaration) => {
|
||||||
|
switch (node.flags) {
|
||||||
|
case ts.NodeFlags.Namespace:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//throw "flag " + node.flags + " isn't supported yet!"; /* TODO wrap with more info */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stack.push({
|
||||||
|
flag_declare: true,
|
||||||
|
flag_namespace: true,
|
||||||
|
flag_class: false
|
||||||
|
});
|
||||||
|
const body = generators[node.body.kind](settings, stack, node.body) as ts.ModuleBlock;
|
||||||
|
stack.pop();
|
||||||
|
|
||||||
|
return ts.createModuleDeclaration(node.decorators, append_declare(node.modifiers, !stack.flag_declare), node.name, body, node.flags);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const _generate_param_declare = (settings, stack, params: ts.NodeArray<ts.ParameterDeclaration>) => {
|
||||||
|
const parms: any[] = [];
|
||||||
|
for(const parm of params)
|
||||||
|
parms.push(generators[parm.kind](settings, stack, parm));
|
||||||
|
return parms;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* functions */
|
||||||
|
generators[SyntaxKind.Parameter] = (settings, stack, node: ts.ParameterDeclaration) => {
|
||||||
|
return ts.createParameter(node.decorators, node.modifiers, node.dotDotDotToken, node.name, node.questionToken || (node.initializer ? ts.createToken(SyntaxKind.QuestionToken) : undefined), node.type, undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.Constructor] = (settings, stack, node: ts.ConstructorDeclaration) => {
|
||||||
|
if(settings.remove_private.method && has_private(node.modifiers)) return;
|
||||||
|
|
||||||
|
return ts.createConstructor(node.decorators, node.modifiers, _generate_param_declare(settings, stack, node.parameters), undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.FunctionDeclaration] = (settings, stack, node: ts.FunctionDeclaration) => {
|
||||||
|
if(stack.flag_namespace && !has_modifier(node.modifiers, SyntaxKind.ExportKeyword)) return;
|
||||||
|
|
||||||
|
return ts.createFunctionDeclaration(node.decorators, append_declare(node.modifiers, !stack.flag_declare), node.asteriskToken, node.name, node.typeParameters, _generate_param_declare(settings, stack, node.parameters), node.type, undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
generators[SyntaxKind.MethodDeclaration] = (settings, stack, node: ts.MethodDeclaration) => {
|
||||||
|
if(settings.remove_private.method && has_private(node.modifiers)) return;
|
||||||
|
|
||||||
|
return ts.createMethod(node.decorators, node.modifiers, node.asteriskToken, node.name, node.questionToken, node.typeParameters, _generate_param_declare(settings, stack, node.parameters), node.type, undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.GetAccessor] = (settings, stack, node: ts.GetAccessorDeclaration) => {
|
||||||
|
if(settings.remove_private.method && has_private(node.modifiers)) return;
|
||||||
|
|
||||||
|
node = ts.createGetAccessor(node.decorators, node.modifiers, node.name, _generate_param_declare(settings, stack, node.parameters), node.type, undefined);
|
||||||
|
return ts.addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, " @ts-ignore", true);
|
||||||
|
};
|
||||||
|
generators[SyntaxKind.SetAccessor] = (settings, stack, node: ts.SetAccessorDeclaration) => {
|
||||||
|
if(settings.remove_private.method && has_private(node.modifiers)) return;
|
||||||
|
node = ts.createSetAccessor(node.decorators, node.modifiers, node.name, _generate_param_declare(settings, stack, node.parameters), undefined);
|
||||||
|
return ts.addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, " @ts-ignore", true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* variables or properties */
|
||||||
|
generators[SyntaxKind.PropertyDeclaration] = (settings, stack, node: ts.PropertyDeclaration) => {
|
||||||
|
if(settings.remove_private.field && has_private(node.modifiers)) return;
|
||||||
|
|
||||||
|
return ts.createProperty(node.decorators, append_declare(node.modifiers, !stack.flag_declare), node.name, node.questionToken, node.type, undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* class types */
|
||||||
|
generators[SyntaxKind.ClassDeclaration] = (settings, stack, node: ts.ClassDeclaration) => {
|
||||||
|
const members = [] as ts.Node[];
|
||||||
|
{
|
||||||
|
stack.push({
|
||||||
|
flag_declare: true,
|
||||||
|
flag_namespace: false,
|
||||||
|
flag_class: true
|
||||||
|
});
|
||||||
|
|
||||||
|
node.forEachChild(n => {
|
||||||
|
if(n.kind == SyntaxKind.Identifier) return; /* class identifier */
|
||||||
|
if(ts.isModifier(n)) return; /* we have already class modifiers */
|
||||||
|
|
||||||
|
_generate(settings, stack, members, n)
|
||||||
|
});
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
members.sort((a, b) => {
|
||||||
|
if(a.kind > b.kind) return 1;
|
||||||
|
if(a.kind < b.kind) return -1;
|
||||||
|
|
||||||
|
if(a.kind == SyntaxKind.FunctionDeclaration)
|
||||||
|
return (<ts.FunctionDeclaration>b).name.escapedText.toString().localeCompare((<ts.FunctionDeclaration>a).name.escapedText.toString());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
return ts.createClassDeclaration(node.decorators, append_export(append_declare(node.modifiers, !stack.flag_declare), stack.flag_namespace), node.name, node.typeParameters, node.heritageClauses, members as any);
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.InterfaceDeclaration] = (settings, stack, node: ts.InterfaceDeclaration) => {
|
||||||
|
if(settings.remove_private.field && has_private(node.modifiers)) return;
|
||||||
|
if(stack.flag_namespace && !has_modifier(node.modifiers, SyntaxKind.ExportKeyword)) return;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.VariableDeclaration] = (settings, stack, node: ts.VariableDeclaration) => {
|
||||||
|
return ts.createVariableDeclaration(node.name, node.type, undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.VariableDeclarationList] = (settings, stack, node: ts.VariableDeclarationList) => {
|
||||||
|
const decls: any[] = [];
|
||||||
|
for(const decl of node.declarations)
|
||||||
|
decls.push(generators[SyntaxKind.VariableDeclaration](settings, stack, decl) as any);
|
||||||
|
return ts.createVariableDeclarationList(decls, node.flags);
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.VariableStatement] = (settings, stack, node: ts.VariableStatement) => {
|
||||||
|
if(settings.remove_private.field && has_private(node.modifiers)) return;
|
||||||
|
|
||||||
|
if(stack.flag_class) {
|
||||||
|
|
||||||
|
} else if(stack.flag_namespace) {
|
||||||
|
if(!has_modifier(node.modifiers, SyntaxKind.ExportKeyword)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ts.createVariableStatement(append_declare(node.modifiers, !stack.flag_declare), generators[node.declarationList.kind](settings, stack, node.declarationList) as any);
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.TypeAliasDeclaration] = (settings, stack, node: ts.TypeAliasDeclaration) => {
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.EnumMember] = (settings, stack, node: ts.EnumMember) => {
|
||||||
|
return ts.createEnumMember(node.name, undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
generators[SyntaxKind.EnumDeclaration] = (settings, stack, node: ts.EnumDeclaration) => {
|
||||||
|
const members: any[] = [];
|
||||||
|
for(const member of node.members)
|
||||||
|
members.push(generators[SyntaxKind.EnumMember](settings, stack, member));
|
||||||
|
return ts.createEnumDeclaration(undefined, append_export(append_declare(node.modifiers, !stack.flag_declare), stack.flag_namespace), node.name, members);
|
||||||
|
};
|
90
build/dtsgen/index.ts
Normal file
90
build/dtsgen/index.ts
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import {readFileSync, writeFileSync} from "fs";
|
||||||
|
import {isArray, isString} from "util";
|
||||||
|
import * as ts from "typescript";
|
||||||
|
import * as decl from "./declarator";
|
||||||
|
import * as glob from "glob";
|
||||||
|
import * as path from "path";
|
||||||
|
|
||||||
|
let source_files: string[] = [];
|
||||||
|
let exclude_files: string[] = [];
|
||||||
|
let target_file: string = "out.d.ts";
|
||||||
|
let verbose: boolean = false;
|
||||||
|
let config_file: string = undefined;
|
||||||
|
let base_path = process.cwd();
|
||||||
|
|
||||||
|
let args = process.argv.slice(2);
|
||||||
|
while(args.length > 0) {
|
||||||
|
if(args[0] == "--file") {
|
||||||
|
source_files.push(args[1]);
|
||||||
|
args = args.slice(2);
|
||||||
|
} else if(args[0] == "--exclude") {
|
||||||
|
exclude_files.push(args[1]);
|
||||||
|
args = args.slice(2);
|
||||||
|
} else if(args[0] == "--destination") {
|
||||||
|
target_file = args[1];
|
||||||
|
args = args.slice(2);
|
||||||
|
} else if(args[0] == "-v" || args[0] == "--verbose") {
|
||||||
|
verbose = true;
|
||||||
|
args = args.slice(1);
|
||||||
|
} else if(args[0] == "-c" || args[0] == "--config") {
|
||||||
|
config_file = args[1];
|
||||||
|
base_path = path.normalize(path.dirname(config_file));
|
||||||
|
args = args.slice(2);
|
||||||
|
} else {
|
||||||
|
console.error("Invalid command line option %s", args[0]);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config_file) {
|
||||||
|
console.log("Loading config file");
|
||||||
|
const json = JSON.parse(readFileSync(config_file).toString());
|
||||||
|
if(!json) {
|
||||||
|
console.error("Failed to parse config!");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isArray(json["source_files"]))
|
||||||
|
source_files.push(...json["source_files"]);
|
||||||
|
if(isArray(json["exclude"]))
|
||||||
|
exclude_files.push(...json["exclude"]);
|
||||||
|
if(isString(json["target_file"]))
|
||||||
|
target_file = json["target_file"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(verbose) {
|
||||||
|
console.log("Base path: " + base_path);
|
||||||
|
console.log("Input files:");
|
||||||
|
for(const file of source_files)
|
||||||
|
console.log(" - " + file);
|
||||||
|
console.log("Target file: " + target_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
const negate_files: string[] = [].concat.apply([], exclude_files.map(file => glob.sync(base_path + "/" + file))).map(file => path.normalize(file));
|
||||||
|
|
||||||
|
let result = "";
|
||||||
|
source_files.forEach(file => {
|
||||||
|
glob.sync(base_path + "/" + file).forEach(_file => {
|
||||||
|
_file = path.normalize(_file);
|
||||||
|
for(const n_file of negate_files) {
|
||||||
|
if(n_file == _file) {
|
||||||
|
console.log("Skipping %s", _file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let source = ts.createSourceFile(
|
||||||
|
_file,
|
||||||
|
readFileSync(_file).toString(),
|
||||||
|
ts.ScriptTarget.ES2015,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("Compile " + _file);
|
||||||
|
result += "\n/* File: " + _file + " */\n" + decl.print(decl.generate(source, {
|
||||||
|
remove_private: false
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
writeFileSync(base_path + "/" + target_file, result);
|
33
build/dtsgen/test/test_01.ts
Normal file
33
build/dtsgen/test/test_01.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
function test() : string {
|
||||||
|
|
||||||
|
return "IDK!";
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
|
||||||
|
}
|
||||||
|
function test2() : C {
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
function test4() : D {
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace T {
|
||||||
|
function C() {
|
||||||
|
|
||||||
|
}
|
||||||
|
export function D() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace T {
|
||||||
|
namespace Y {
|
||||||
|
function T() {}
|
||||||
|
|
||||||
|
export function Y() {}
|
||||||
|
}
|
||||||
|
}
|
49
build/dtsgen/test/test_02.ts
Normal file
49
build/dtsgen/test/test_02.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
class A {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
a() : void{ }
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace B {
|
||||||
|
export class C {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
a() : void{ }
|
||||||
|
|
||||||
|
get c() { return undefined; }
|
||||||
|
set c(_) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare class XXX {
|
||||||
|
private static _audioInstances;
|
||||||
|
private static _globalReplayScheduler;
|
||||||
|
private static _timeIndex;
|
||||||
|
private static _audioDestinationStream;
|
||||||
|
static initializeAudioController(): void;
|
||||||
|
speakerContext: AudioContext;
|
||||||
|
private playerState;
|
||||||
|
private audioCache;
|
||||||
|
private playingAudioCache;
|
||||||
|
private _volume;
|
||||||
|
private _codecCache;
|
||||||
|
private _timeIndex;
|
||||||
|
private _latencyBufferLength;
|
||||||
|
private _buffer_timeout;
|
||||||
|
allowBuffering: boolean;
|
||||||
|
onSpeaking: () => void;
|
||||||
|
onSilence: () => void;
|
||||||
|
constructor();
|
||||||
|
initialize(): void;
|
||||||
|
close(): void;
|
||||||
|
playBuffer(buffer: AudioBuffer): void;
|
||||||
|
private playQueue;
|
||||||
|
private removeNode;
|
||||||
|
stopAudio(now?: boolean): void;
|
||||||
|
private testBufferQueue;
|
||||||
|
private reset_buffer_timeout;
|
||||||
|
volume: number;
|
||||||
|
private applyVolume;
|
||||||
|
codecCache(codec: number): CodecClientCache;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue