Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"node": ">=6.0.0"
},
"scripts": {
"clean": "rimraf dist",
"clean": "rimraf dist && rimraf .rollup.cache",
"lint": "eslint .",
"start": "node scripts/setup-playground.js && npm run generate-typescript && rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript -w",
"generate-typescript": "rimraf src/generated && tsx src.compiler/typescript/AlphaTabGenerator.ts",
Expand Down
110 changes: 84 additions & 26 deletions src.compiler/BuilderHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import * as ts from 'typescript';
import * as path from 'path'
import * as path from 'path';

const ignoredFiles = [
/rollup.*/
]
const ignoredFiles = [/rollup.*/];

export function transpileFilter(file: string): boolean {
const fileName = path.basename(file);
Expand Down Expand Up @@ -58,7 +56,7 @@ function findNode(node: ts.Node, kind: ts.SyntaxKind): ts.Node | null {

export function getTypeWithNullableInfo(
checker: ts.TypeChecker,
node: ts.TypeNode | undefined,
node: ts.TypeNode | ts.Type | undefined,
allowUnionAsPrimitive: boolean
) {
if (!node) {
Expand All @@ -72,31 +70,53 @@ export function getTypeWithNullableInfo(
let isNullable = false;
let isUnionType = false;
let type: ts.Type | null = null;
if (ts.isUnionTypeNode(node)) {
for (const t of node.types) {
if (t.kind === ts.SyntaxKind.NullKeyword) {
isNullable = true;
} else if (ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword) {
isNullable = true;
} else if (type !== null) {
if (allowUnionAsPrimitive) {
isUnionType = true;
type = checker.getTypeAtLocation(node);
break;
if ('kind' in node) {
if (ts.isUnionTypeNode(node)) {
for (const t of node.types) {
if (t.kind === ts.SyntaxKind.NullKeyword) {
isNullable = true;
} else if (ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword) {
isNullable = true;
} else if (type !== null) {
if (allowUnionAsPrimitive) {
isUnionType = true;
type = checker.getTypeAtLocation(node);
break;
} else {
throw new Error(
'Multi union types on JSON settings not supported: ' +
node.getSourceFile().fileName +
':' +
node.getText()
);
}
} else {
type = checker.getTypeAtLocation(t);
}
}
} else {
type = checker.getTypeAtLocation(node);
}
} else if ('flags' in node) {
if (node.isUnion()) {
for (const t of node.types) {
if ((t.flags & ts.TypeFlags.Null) !== 0 || (t.flags & ts.TypeFlags.Undefined) !== 0) {
isNullable = true;
} else if (type !== null) {
if (allowUnionAsPrimitive) {
isUnionType = true;
type = node;
break;
} else {
throw new Error('Multi union types on JSON settings not supported: ' + node.symbol.name);
}
} else {
throw new Error(
'Multi union types on JSON settings not supported: ' +
node.getSourceFile().fileName +
':' +
node.getText()
);
type = t;
}
} else {
type = checker.getTypeAtLocation(t);
}
} else {
type = node;
}
} else {
type = checker.getTypeAtLocation(node);
}

return {
Expand Down Expand Up @@ -201,3 +221,41 @@ function markNodeSynthesized(node: ts.Node): ts.Node {
});
return node;
}

export function cloneTypeNode<T extends ts.Node>(node: T): T {
if (ts.isUnionTypeNode(node)) {
return ts.factory.createUnionTypeNode(node.types.map(cloneTypeNode)) as any as T;
} else if (
node.kind === ts.SyntaxKind.StringKeyword ||
node.kind === ts.SyntaxKind.NumberKeyword ||
node.kind === ts.SyntaxKind.BooleanKeyword ||
node.kind === ts.SyntaxKind.UnknownKeyword ||
node.kind === ts.SyntaxKind.AnyKeyword ||
node.kind === ts.SyntaxKind.VoidKeyword
) {
return ts.factory.createKeywordTypeNode(node.kind) as any as T;
} else if (ts.isLiteralTypeNode(node)) {
switch (node.literal.kind) {
case ts.SyntaxKind.StringLiteral:
return ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(node.literal.text)) as any as T;
default:
return ts.factory.createLiteralTypeNode(node.literal) as any as T;
}
} else if (ts.isArrayTypeNode(node)) {
return ts.factory.createArrayTypeNode(cloneTypeNode(node.elementType)) as any as T;
} else if (ts.isTypeReferenceNode(node)) {
return ts.factory.createTypeReferenceNode(cloneTypeNode(node.typeName),
node.typeArguments?.map(a => cloneTypeNode(a))
) as any as T;
} else if (ts.isIdentifier(node)) {
return ts.factory.createIdentifier(node.text) as any as T;
} else if (ts.isQualifiedName(node)) {
if (typeof node.right === 'string') {
return ts.factory.createQualifiedName(cloneTypeNode(node.left), node.right) as any as T;
} else {
return ts.factory.createQualifiedName(cloneTypeNode(node.left), cloneTypeNode(node.right)) as any as T;
}
}

throw new Error(`Unsupported TypeNode: '${ts.SyntaxKind[node.kind]}' extend type node cloning`);
}
2 changes: 1 addition & 1 deletion src.compiler/csharp/CSharpAstTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export default class CSharpAstTransformer {
} else {
additionalNonExportDeclarations.push(s);
}
} else {
} else if(!this.shouldSkip(s, false)) {
this._context.addTsNodeDiagnostics(
s,
'Only FunctionType type aliases are allowed',
Expand Down
4 changes: 4 additions & 0 deletions src.compiler/typescript/AlphaTabGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import { GENERATED_FILE_HEADER } from './EmitterBase';
import serializerEmit from './SerializerEmitter';
import transpiler from '../TranspilerBase';
import * as fs from 'fs';
import jsonDeclarationEmit from './JsonDeclarationEmitter';

transpiler([{
name: 'Clone',
emit: cloneEmit
}, {
name: 'Serializer',
emit: serializerEmit
}, {
name: 'JSON Declarations',
emit: jsonDeclarationEmit
}], false);

// Write version file
Expand Down
4 changes: 2 additions & 2 deletions src.compiler/typescript/EmitterBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export default function createEmitter(

const result = generate(program, classDeclaration);
const defaultClass = result.statements.find(
stmt => ts.isClassDeclaration(stmt) && stmt.modifiers!.find(m => m.kind === ts.SyntaxKind.ExportKeyword)
) as ts.ClassDeclaration;
stmt => (ts.isClassDeclaration(stmt) || ts.isInterfaceDeclaration(stmt)) && stmt.modifiers!.find(m => m.kind === ts.SyntaxKind.ExportKeyword)
) as ts.DeclarationStatement;

const targetFileName = path.join(
path.resolve(program.getCompilerOptions().baseUrl!),
Expand Down
Loading