UNPKG

@sourcefield/lsif-typescript

Version:
1,961 lines (1,935 loc) 117 kB
import { test } from 'uvu'; import * as lsif from './lsif'; import * as fs from 'fs'; import * as path from 'path'; import * as assert from 'uvu/assert'; import { Input } from './Input'; import { FileIndexer } from './FileIndexer'; import * as ts from 'typescript'; import { ProjectOptions } from './CommandLineOptions'; import { Counter } from './Counter'; import { Packages } from './Packages'; import { LsifSymbol } from './LsifSymbol'; import { DefinitionRange } from './DefinitionRange'; import { createLanguageService, ProjectIndexer } from './ProjectIndexer'; let ignoreSkipParameter: boolean = false; let counter = new Counter(); let options: ProjectOptions = { cwd: '/Users/ericmeadows/git/echarts', yarnWorkspaces: false, yarnBerryWorkspaces: false, inferTsconfig: false, output: '/Users/ericmeadows/git/lsif-spike/temp/lsif-ts.lsif', progressBar: true, indexedProjects: new Set<string>(['/Users/ericmeadows/git/echarts']), projectRoot: '/Users/ericmeadows/git/echarts', projectDisplayName: '/Users/ericmeadows/git/echarts', writeIndex: (partialIndex: any): void => {}, counter, dev: true, }; let compilerOptions: ts.CompilerOptions = { target: 1, noImplicitAny: true, noImplicitThis: true, strictBindCallApply: true, removeComments: false, sourceMap: true, moduleResolution: 2, declaration: true, declarationMap: false, jsx: ts.JsxEmit.ReactJSX, importHelpers: true, pretty: true, outDir: '/Users/ericmeadows/git/echarts/lib', configFilePath: undefined, }; let program = ts.createProgram([], compilerOptions); let checker = program.getTypeChecker(); let packages = new Packages(options.projectRoot); let symbolCache: Map<ts.Node, LsifSymbol> = new Map(); const filesToIndex: ts.SourceFile[] = []; const declarations: Map<number, DefinitionRange> = new Map<number, DefinitionRange>(); const references: Map<number, DefinitionRange[]> = new Map<number, DefinitionRange[]>(); const languageService = createLanguageService( filesToIndex.map(function (file) { return file.fileName; }), {} ); type TestArray = { name: string; codeToParse: string; numItemsInHeirarchy: number; operandsDesired: (string | number | bigint)[][]; operatorsDesired: string[][]; skip: boolean; scriptKind?: ts.ScriptKind; }; const testItems: TestArray[] = [ { name: 'simple function', skip: false, codeToParse: ` export function log(str: string, onlyOnce?: boolean) { outputLog("log", str, onlyOnce); } `, numItemsInHeirarchy: 2, operandsDesired: [ ['log', 'str', 'onlyOnce', 'outputLog', '"log"', 'str', 'onlyOnce'], ['log', 'str', 'onlyOnce', 'outputLog', '"log"', 'str', 'onlyOnce'], ], operatorsDesired: [ ['export', 'function', '()', ':', 'string', ',', '?', ':', 'boolean', '{}', '()', ',', ','], ['export', 'function', '()', ':', 'string', ',', '?', ':', 'boolean', '{}', '()', ',', ','], ], }, { name: '2dArrays (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/2dArrays.ts)', skip: false, codeToParse: ` class Cell { } class Ship { isSunk: boolean; } class Board { ships: Ship[]; cells: Cell[]; private allShipsSunk() { return this.ships.every(function (val) { return val.isSunk; }); } } `, numItemsInHeirarchy: 8, operandsDesired: [ [ 'Cell', 'Ship', 'isSunk', 'Board', 'ships', 'Ship', 'cells', 'Cell', 'allShipsSunk', 'ships', 'every', 'val', 'val', 'isSunk', ], ['Cell'], ['Ship', 'isSunk'], ['isSunk'], ['Board', 'ships', 'Ship', 'cells', 'Cell', 'allShipsSunk', 'ships', 'every', 'val', 'val', 'isSunk'], ['ships', 'Ship'], ['cells', 'Cell'], ['allShipsSunk', 'ships', 'every', 'val', 'val', 'isSunk'], ], operatorsDesired: [ [ 'class', '{}', 'class', '{}', ':', 'boolean', 'class', '{}', ':', '[]', ':', '[]', 'private', '()', '{}', 'return', 'this', '.', '.', '()', 'function', '()', '{}', 'return', '.', ], ['class', '{}'], [ 'class', '{}', ':', 'boolean', // ';' ], [':', 'boolean'], [ 'class', '{}', ':', '[]', // ';', ':', '[]', // ';', 'private', '()', '{}', 'return', 'this', '.', '.', '()', 'function', '()', '{}', 'return', '.', // ';', // ';', ], [ ':', '[]', // ';' ], [ ':', '[]', // ';' ], [ 'private', '()', '{}', 'return', 'this', '.', '.', '()', 'function', '()', '{}', 'return', '.', // ';', // ';', ], ], }, { name: 'ArrowFunctionExpression (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ArrowFunctionExpression1.ts)', skip: false, codeToParse: ` var v = (public x: string) => { }; `, numItemsInHeirarchy: 1, operandsDesired: [['v', 'x']], operatorsDesired: [ [ 'var', '=', '()', 'public', ':', 'string', '=>', '{}', // ';' ], ], }, { name: 'ClassDeclaration10 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration10.ts)', skip: false, codeToParse: ` class C { constructor(); foo(); } `, numItemsInHeirarchy: 4, operandsDesired: [['C', 'foo'], ['C', 'foo'], [], ['foo']], operatorsDesired: [ [ 'class', '{}', 'constructor', '()', // ';', '()', // ';', ], [ 'class', '{}', 'constructor', '()', // ';', '()', // ';', ], [ 'constructor', '()', // ';', ], [ '()', // ';', ], ], }, { name: 'ClassDeclaration11 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration11.ts)', skip: false, codeToParse: ` class C { constructor(); foo() { } } `, numItemsInHeirarchy: 4, operandsDesired: [['C', 'foo'], ['C', 'foo'], [], ['foo']], operatorsDesired: [ [ 'class', '{}', 'constructor', '()', // ';', '()', '{}', ], [ 'class', '{}', 'constructor', '()', // ';', '()', '{}', ], [ 'constructor', '()', // ';', ], ['()', '{}'], ], }, { name: 'ClassDeclaration13 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration13.ts)', skip: false, codeToParse: ` class C { foo(); bar() { } } `, numItemsInHeirarchy: 4, operandsDesired: [['C', 'foo', 'bar'], ['C', 'foo', 'bar'], ['foo'], ['bar']], operatorsDesired: [ [ 'class', '{}', '()', // ';', '()', '{}', ], [ 'class', '{}', '()', // ';', '()', '{}', ], [ '()', // ';', ], ['()', '{}'], ], }, { name: 'ClassDeclaration15 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration15.ts)', skip: false, codeToParse: ` class C { foo(); constructor() { } } `, numItemsInHeirarchy: 4, operandsDesired: [['C', 'foo'], ['C', 'foo'], ['foo'], []], operatorsDesired: [ [ 'class', '{}', '()', // ';', 'constructor', '()', '{}', ], [ 'class', '{}', '()', // ';', 'constructor', '()', '{}', ], [ '()', // ';', ], ['constructor', '()', '{}'], ], }, { name: 'ClassDeclaration21 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration21.ts)', skip: false, codeToParse: ` class C { 0(); 1() { } } `, numItemsInHeirarchy: 4, operandsDesired: [['C', '0', '1'], ['C', '0', '1'], ['0'], ['1']], operatorsDesired: [['class', '{}', '()', '()', '{}'], ['class', '{}', '()', '()', '{}'], ['()'], ['()', '{}']], }, { name: 'ClassDeclaration22 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration22.ts)', skip: false, codeToParse: ` class C { "foo"(); "bar"() { } } `, numItemsInHeirarchy: 4, operandsDesired: [['C', '"foo"', '"bar"'], ['C', '"foo"', '"bar"'], ['"foo"'], ['"bar"']], operatorsDesired: [ [ 'class', '{}', '()', // ';', '()', '{}', ], [ 'class', '{}', '()', // ';', '()', '{}', ], [ '()', // ';' ], ['()', '{}'], ], }, { name: 'ClassDeclaration24 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration24.ts)', skip: false, codeToParse: ` class any { } `, numItemsInHeirarchy: 2, operandsDesired: [[], []], operatorsDesired: [ ['class', 'any', '{}'], ['class', 'any', '{}'], ], }, { name: 'ClassDeclaration25 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration25.ts)', skip: false, codeToParse: ` interface IList<T> { data(): T; next(): string; } class List<U> implements IList<U> { data(): U; next(): string; } `, numItemsInHeirarchy: 7, operandsDesired: [ ['IList', 'T', 'data', 'T', 'next', 'List', 'U', 'IList', 'U', 'data', 'U', 'next'], ['IList', 'T', 'data', 'T', 'next'], ['data', 'T'], ['next'], ['List', 'U', 'IList', 'U', 'data', 'U', 'next'], ['data', 'U'], ['next'], ], operatorsDesired: [ [ 'interface', '<>', '{}', '()', ':', // ';', '()', ':', 'string', // ';' 'class', '<>', 'implements', '<>', '{}', '()', ':', // ';', '()', ':', // ';', 'string', ], [ 'interface', '<>', '{}', '()', ':', // ';', '()', ':', 'string', // ';' ], [ '()', ':', // ';' ], [ '()', ':', 'string', // ';' ], [ 'class', '<>', 'implements', '<>', '{}', '()', ':', // ';', '()', ':', 'string', // ';' ], [ '()', ':', // ';' ], [ '()', ':', 'string', // ';' ], ], }, { name: 'ClassDeclaration26 -- parse error! (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration26.ts)', skip: false, codeToParse: ` class C { public const var export foo = 10; var constructor() { } } `, numItemsInHeirarchy: 1, operandsDesired: [[]], operatorsDesired: [['()', '{}']], }, { name: 'ClassDeclaration8 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration8.ts)', skip: false, codeToParse: ` class C { constructor(); } `, numItemsInHeirarchy: 3, operandsDesired: [['C'], ['C'], []], operatorsDesired: [ [ 'class', '{}', 'constructor', '()', // ';' ], [ 'class', '{}', 'constructor', '()', // ';' ], [ 'constructor', '()', // ';' ], ], }, { name: 'ClassDeclaration9 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclaration9.ts)', skip: false, codeToParse: ` class C { foo(); } `, numItemsInHeirarchy: 3, operandsDesired: [['C', 'foo'], ['C', 'foo'], ['foo']], operatorsDesired: [ [ 'class', '{}', '()', // ';' ], [ 'class', '{}', '()', // ';' ], [ '()', // ';' ], ], }, { name: 'ClassDeclarationWithInvalidConstOnPropertyDeclaration (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclarationWithInvalidConstOnPropertyDeclaration.ts)', skip: false, codeToParse: ` class AtomicNumbers { static const H = 1; } `, numItemsInHeirarchy: 3, operandsDesired: [ ['AtomicNumbers', 'H', '1'], ['AtomicNumbers', 'H', '1'], ['H', '1'], ], operatorsDesired: [ [ 'class', '{}', 'static', 'const', '=', // ';' ], [ 'class', '{}', 'static', 'const', '=', // ';' ], [ 'static', 'const', '=', // ';' ], ], }, { name: 'ClassDeclarationWithInvalidConstOnPropertyDeclaration2 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ClassDeclarationWithInvalidConstOnPropertyDeclaration2.ts)', skip: false, codeToParse: ` class C { const x = 10; } `, numItemsInHeirarchy: 4, operandsDesired: [['C', 'x', '10'], ['C', 'x', '10'], [], ['x', '10']], operatorsDesired: [ [ 'class', '{}', 'const', '=', // ';' ], [ 'class', '{}', 'const', '=', // ';' ], ['const'], [ '=', // ';' ], ], }, { name: 'DateTimeFormatAndNumberFormatES2021 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/DateTimeFormatAndNumberFormatES2021.ts)', skip: false, codeToParse: ` // @lib: es2021 Intl.NumberFormat.prototype.formatRange Intl.DateTimeFormat.prototype.formatRange new Intl.NumberFormat().formatRange new Intl.NumberFormat().formatRangeToParts new Intl.DateTimeFormat().formatRange new Intl.DateTimeFormat().formatRangeToParts `, numItemsInHeirarchy: 1, operandsDesired: [ [ 'Intl', 'NumberFormat', 'prototype', 'formatRange', 'Intl', 'DateTimeFormat', 'prototype', 'formatRange', 'Intl', 'NumberFormat', 'formatRange', 'Intl', 'NumberFormat', 'formatRangeToParts', 'Intl', 'DateTimeFormat', 'formatRange', 'Intl', 'DateTimeFormat', 'formatRangeToParts', ], ], operatorsDesired: [ [ '.', '.', '.', '.', '.', '.', 'new', '.', '()', '.', 'new', '.', '()', '.', 'new', '.', '()', '.', 'new', '.', '()', '.', ], ], }, { name: 'DeclarationErrorsNoEmitOnError (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/DeclarationErrorsNoEmitOnError.ts)', skip: false, codeToParse: ` // @module: commonjs // @declaration: true // @noEmitOnError: true type T = { x : number } export interface I { f: T; } `, numItemsInHeirarchy: 3, operandsDesired: [ ['T', 'x', 'I', 'f', 'T'], ['T', 'x'], ['I', 'f', 'T'], ], operatorsDesired: [ [ 'type', '=', '{}', ':', 'number', 'export', 'interface', '{}', ':', // ';' ], ['type', '=', '{}', ':', 'number'], [ 'export', 'interface', '{}', ':', // ';' ], ], }, { name: 'ExportAssignment7 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ExportAssignment7.ts)', skip: false, codeToParse: ` export class C { } export = B; `, numItemsInHeirarchy: 2, operandsDesired: [['C', 'B'], ['C']], operatorsDesired: [ [ 'export', 'class', '{}', 'export', '=', // ';' ], ['export', 'class', '{}'], ], }, { name: 'ExportAssignment8 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ExportAssignment8.ts)', skip: false, codeToParse: ` export = B; export class C { } `, numItemsInHeirarchy: 2, operandsDesired: [['B', 'C'], ['C']], operatorsDesired: [ [ 'export', '=', 'export', 'class', '{}', // ';' ], ['export', 'class', '{}'], ], }, { name: 'FunctionDeclaration3 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/FunctionDeclaration3.ts)', skip: false, codeToParse: ` function foo(); `, numItemsInHeirarchy: 2, operandsDesired: [['foo'], ['foo']], operatorsDesired: [ ['function', '()'], ['function', '()'], ], }, { name: 'FunctionDeclaration4 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/FunctionDeclaration4.ts)', skip: false, codeToParse: ` function foo(); function bar() { } `, numItemsInHeirarchy: 3, operandsDesired: [['foo', 'bar'], ['foo'], ['bar']], operatorsDesired: [ [ 'function', '()', // ';', 'function', '()', '{}', ], [ 'function', '()', // ';', ], ['function', '()', '{}'], ], }, { name: 'FunctionDeclaration6 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/FunctionDeclaration6.ts)', skip: false, codeToParse: ` { function foo(); function bar() { } } `, numItemsInHeirarchy: 3, operandsDesired: [['foo', 'bar'], ['foo'], ['bar']], operatorsDesired: [ [ '{}', 'function', '()', // ';', 'function', '()', '{}', ], [ 'function', '()', // ';', ], ['function', '()', '{}'], ], }, { name: 'FunctionDeclaration7 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/FunctionDeclaration7.ts)', skip: false, codeToParse: ` module M { function foo(); } `, numItemsInHeirarchy: 3, operandsDesired: [['M', 'foo'], ['M', 'foo'], ['foo']], operatorsDesired: [ [ 'module', '{}', 'function', '()', // ';' ], [ 'module', '{}', 'function', '()', // ';' ], [ 'function', '()', // ';' ], ], }, { name: 'InterfaceDeclaration8 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/InterfaceDeclaration8.ts)', skip: false, codeToParse: ` interface string { } `, numItemsInHeirarchy: 2, operandsDesired: [[], []], operatorsDesired: [ ['interface', 'string', '{}'], ['interface', 'string', '{}'], ], }, { name: 'MemberAccessorDeclaration15 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/MemberAccessorDeclaration15.ts)', skip: false, codeToParse: ` class C { set Foo(public a: number) { } } `, numItemsInHeirarchy: 3, operandsDesired: [ ['C', 'Foo', 'a'], ['C', 'Foo', 'a'], ['Foo', 'a'], ], operatorsDesired: [ ['class', '{}', 'set', '()', 'public', ':', 'number', '{}'], ['class', '{}', 'set', '()', 'public', ':', 'number', '{}'], ['set', '()', 'public', ':', 'number', '{}'], ], }, { name: 'ParameterList13 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ParameterList13.ts', skip: false, codeToParse: ` interface I { new (public x); } `, numItemsInHeirarchy: 3, operandsDesired: [['I', 'x'], ['I', 'x'], ['x']], operatorsDesired: [ [ 'interface', '{}', 'new', '()', 'public', // ';' ], [ 'interface', '{}', 'new', '()', 'public', // ';' ], [ 'new', '()', 'public', // ';' ], ], }, { name: 'ParameterList4 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ParameterList4.ts)', skip: false, codeToParse: ` function F(public A) { } `, numItemsInHeirarchy: 2, operandsDesired: [ ['F', 'A'], ['F', 'A'], ], operatorsDesired: [ ['function', '()', 'public', '{}'], ['function', '()', 'public', '{}'], ], }, { name: 'ParameterList5 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ParameterList5.ts)', skip: false, codeToParse: ` function A(): (public B) => C { } `, numItemsInHeirarchy: 2, operandsDesired: [ ['A', 'B', 'C'], ['A', 'B', 'C'], ], operatorsDesired: [ [ 'function', '()', ':', '()', 'public', '=>', // TODO: This token is not coming through - will need deeper '{}', ], [ 'function', '()', ':', '()', 'public', '=>', // TODO: This token is not coming through - will need deeper '{}', ], ], }, { name: 'ParameterList6 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ParameterList6.ts)', skip: false, codeToParse: ` class C { constructor(C: (public A) => any) { } } `, numItemsInHeirarchy: 3, operandsDesired: [ ['C', 'C', 'A'], ['C', 'C', 'A'], ['C', 'A'], ], operatorsDesired: [ ['class', '{}', 'constructor', '()', ':', '()', 'public', '=>', 'any', '{}'], ['class', '{}', 'constructor', '()', ':', '()', 'public', '=>', 'any', '{}'], ['constructor', '()', ':', '()', 'public', '=>', 'any', '{}'], ], }, { name: 'ParameterList7 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ParameterList7.ts', skip: false, codeToParse: ` class C1 { constructor(public p1:string); // ERROR constructor(private p2:number); // ERROR constructor(public p3:any) {} // OK } `, numItemsInHeirarchy: 5, operandsDesired: [['C1', 'p1', 'p2', 'p3'], ['C1', 'p1', 'p2', 'p3'], ['p1'], ['p2'], ['p3']], operatorsDesired: [ [ 'class', '{}', 'constructor', '()', 'public', ':', 'string', // ';', 'constructor', '()', 'private', ':', 'number', // ';', 'constructor', '()', 'public', ':', 'any', '{}', ], [ 'class', '{}', 'constructor', '()', 'public', ':', 'string', // ';', 'constructor', '()', 'private', ':', 'number', // ';', 'constructor', '()', 'public', ':', 'any', '{}', ], [ 'constructor', '()', 'public', ':', 'string', // ';', ], [ 'constructor', '()', 'private', ':', 'number', // ';', ], ['constructor', '()', 'public', ':', 'any', '{}'], ], }, { name: 'ParameterList8 (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/ParameterList8.ts)', skip: false, codeToParse: ` declare class C2 { constructor(public p1:string); // ERROR constructor(private p2:number); // ERROR constructor(public p3:any); // ERROR } `, numItemsInHeirarchy: 5, operandsDesired: [['C2', 'p1', 'p2', 'p3'], ['C2', 'p1', 'p2', 'p3'], ['p1'], ['p2'], ['p3']], operatorsDesired: [ [ 'declare', 'class', '{}', 'constructor', '()', 'public', ':', 'string', // ';', 'constructor', '()', 'private', ':', 'number', // ';', 'constructor', '()', 'public', ':', 'any', // ';', ], [ 'declare', 'class', '{}', 'constructor', '()', 'public', ':', 'string', // ';', 'constructor', '()', 'private', ':', 'number', // ';', 'constructor', '()', 'public', ':', 'any', // ';', ], [ 'constructor', '()', 'public', ':', 'string', // ';', ], [ 'constructor', '()', 'private', ':', 'number', // ';', ], [ 'constructor', '()', 'public', ':', 'any', // ';', ], ], }, { name: 'SystemModuleForStatementNoInitializer (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/SystemModuleForStatementNoInitializer.ts)', skip: false, codeToParse: ` //@module: system export { }; let i = 0; let limit = 10; for (; i < limit; ++i) { break; } for (; ; ++i) { break; } for (; ;) { break; } `, numItemsInHeirarchy: 1, operandsDesired: [['i', '0', 'limit', '10', 'i', 'limit', 'i', 'i']], operatorsDesired: [ [ 'export', '{}', // ';', 'let', '=', // ';', 'let', '=', // ';', 'for', '()', ';', '<', ';', '++', '{}', 'break', // ';', 'for', '()', ';', ';', '++', '{}', 'break', // ';', 'for', '()', ';', ';', '{}', 'break', // ';', ], ], }, { name: 'abstractClassInLocalScope (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/abstractClassInLocalScope.ts)', skip: false, codeToParse: ` (() => { abstract class A {} class B extends A {} new B(); return A; })(); `, numItemsInHeirarchy: 3, operandsDesired: [['A', 'B', 'A', 'B', 'A'], ['A'], ['B', 'A']], operatorsDesired: [ [ '()', '()', '=>', '{}', 'abstract', 'class', '{}', 'class', 'extends', '{}', 'new', '()', // ';', 'return', // ';', '()', ], ['abstract', 'class', '{}'], ['class', 'extends', '{}'], ], }, { name: 'abstractClassUnionInstantiation (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/abstractClassUnionInstantiation.ts)', skip: false, codeToParse: ` class ConcreteA {} class ConcreteB {} `, numItemsInHeirarchy: 3, operandsDesired: [['ConcreteA', 'ConcreteB'], ['ConcreteA'], ['ConcreteB']], operatorsDesired: [ ['class', '{}', 'class', '{}'], ['class', '{}'], ['class', '{}'], ], }, { name: 'Abstract Classes', skip: false, codeToParse: ` abstract class AbstractA { a: string; } abstract class AbstractB { b: string; } `, numItemsInHeirarchy: 5, operandsDesired: [['AbstractA', 'a', 'AbstractB', 'b'], ['AbstractA', 'a'], ['a'], ['AbstractB', 'b'], ['b']], operatorsDesired: [ [ 'abstract', 'class', '{}', ':', 'string', // ';', 'abstract', 'class', '{}', ':', 'string', // ';', ], [ 'abstract', 'class', '{}', ':', 'string', // ';', ], [ ':', 'string', // ';', ], [ 'abstract', 'class', '{}', ':', 'string', // ';', ], [ ':', 'string', // ';', ], ], }, { name: 'Classes with Union Type', skip: false, codeToParse: ` type Abstracts = typeof AbstractA | typeof AbstractB; type Concretes = typeof ConcreteA | typeof ConcreteB; type ConcretesOrAbstracts = Concretes | Abstracts; `, numItemsInHeirarchy: 4, operandsDesired: [ [ 'Abstracts', 'AbstractA', 'AbstractB', 'Concretes', 'ConcreteA', 'ConcreteB', 'ConcretesOrAbstracts', 'Concretes', 'Abstracts', ], ['Abstracts', 'AbstractA', 'AbstractB'], ['Concretes', 'ConcreteA', 'ConcreteB'], ['ConcretesOrAbstracts', 'Concretes', 'Abstracts'], ], operatorsDesired: [ [ 'type', '=', 'typeof', '|', 'typeof', // ';', 'type', '=', 'typeof', '|', 'typeof', // ';', 'type', '=', '|', // ';', ], [ 'type', '=', 'typeof', '|', 'typeof', // ';', ], [ 'type', '=', 'typeof', '|', 'typeof', // ';', ], [ 'type', '=', '|', // ';', ], ], }, { name: 'Const implementations of Class', skip: false, codeToParse: ` declare const cls1: ConcretesOrAbstracts; declare const cls2: Abstracts; declare const cls3: Concretes; `, numItemsInHeirarchy: 1, operandsDesired: [['cls1', 'ConcretesOrAbstracts', 'cls2', 'Abstracts', 'cls3', 'Concretes']], operatorsDesired: [ [ 'declare', 'const', ':', // ';', 'declare', 'const', ':', // ';', 'declare', 'const', ':', // ';', ], ], }, { name: 'Instation of new classes', skip: false, codeToParse: ` new cls1(); // should error new cls2(); // should error new cls3(); // should work `, numItemsInHeirarchy: 1, operandsDesired: [['cls1', 'cls2', 'cls3']], operatorsDesired: [ [ 'new', '()', // ';', 'new', '()', // ';', 'new', '()', // ';', ], ], }, { name: 'Array mapping with Arrow Functions', skip: true, // Skipping due to error below codeToParse: ` [ConcreteA, AbstractA, AbstractB].map(cls => new cls()); // should error [ConcreteA, ConcreteB].map(cls => new cls()); // should work `, numItemsInHeirarchy: 1, operandsDesired: [ ['ConcreteA', 'AbstractA', 'AbstractB', 'map', 'cls', 'cls', 'ConcreteA', 'ConcreteB', 'map', 'cls', 'cls'], ], operatorsDesired: [ [ '[]', ',', ',', '.', '()', // '()', // TODO: This shows up, but is erroneous - skipping this test '=>', 'new', '()', // ';' '[]', ',', '.', '()', // '()', // TODO: This shows up, but is erroneous - skipping this test '=>', 'new', '()', // ';' ], ], }, { name: 'abstractIdentifierNameStrict (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/abstractIdentifierNameStrict.ts)', skip: false, codeToParse: ` var abstract = true; function foo() { "use strict"; var abstract = true; } `, numItemsInHeirarchy: 2, operandsDesired: [ ['foo', '"use strict"'], ['foo', '"use strict"'], ], operatorsDesired: [ [ 'var', 'abstract', '=', 'true', // ';', 'function', '()', '{}', 'var', 'abstract', '=', 'true', // ';' ], [ 'function', '()', '{}', 'var', 'abstract', '=', 'true', // ';' ], ], }, { name: 'abstractInterfaceIdentifierName (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/abstractInterfaceIdentifierName.ts)', skip: false, codeToParse: ` interface abstract { abstract(): void; } `, numItemsInHeirarchy: 3, operandsDesired: [[], [], []], operatorsDesired: [ [ 'interface', 'abstract', '{}', 'abstract', '()', ':', 'void', // ';' ], [ 'interface', 'abstract', '{}', 'abstract', '()', ':', 'void', // ';' ], [ 'abstract', '()', ':', 'void', // ';' ], ], }, { name: 'abstractPropertyBasics (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/abstractPropertyBasics.ts)', skip: false, codeToParse: ` abstract class B implements A { abstract prop: string; abstract readonly ro: string; abstract get readonlyProp(): string; abstract set readonlyProp(val: string); abstract m(): void; } `, numItemsInHeirarchy: 7, operandsDesired: [ ['B', 'A', 'prop', 'ro', 'readonlyProp', 'readonlyProp', 'val', 'm'], ['B', 'A', 'prop', 'ro', 'readonlyProp', 'readonlyProp', 'val', 'm'], ['prop'], ['ro'], ['readonlyProp'], ['readonlyProp', 'val'], ['m'], ], operatorsDesired: [ [ 'abstract', 'class', 'implements', '{}', 'abstract', ':', 'string', // ';', 'abstract', 'readonly', ':', 'string', // ';', 'abstract', 'get', '()', ':', 'string', // ';', 'abstract', 'set', '()', ':', 'string', // ';', 'abstract', '()', ':', 'void', // ';', ], [ 'abstract', 'class', 'implements', '{}', 'abstract', ':', 'string', // ';', 'abstract', 'readonly', ':', 'string', // ';', 'abstract', 'get', '()', ':', 'string', // ';', 'abstract', 'set', '()', ':', 'string', // ';', 'abstract', '()', ':', 'void', // ';', ], [ 'abstract', ':', 'string', // ';', ], [ 'abstract', 'readonly', ':', 'string', // ';', ], [ 'abstract', 'get', '()', ':', 'string', // ';', ], [ 'abstract', 'set', '()', ':', 'string', // ';', ], [ 'abstract', '()', ':', 'void', // ';', ], ], }, { name: 'abstractPropertyInConstructor (https://github.com/microsoft/TypeScript/blob/main/tests/cases/compiler/abstractPropertyInConstructor.ts)', skip: false, codeToParse: ` abstract class DerivedAbstractClass extends AbstractClass { cb = (s: string) => {}; constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) { super(str, other); // there is no implementation of 'prop' in any base class this.cb(this.prop.toLowerCase()); } } `, numItemsInHeirarchy: 4, operandsDesired: [ [ 'DerivedAbstractClass', 'AbstractClass', 'cb', 's', 'str', 'other', 'AbstractClass', 'yetAnother', 'DerivedAbstractClass', 'str', 'other', 'cb', 'prop', 'toLowerCase', ], [ 'DerivedAbstractClass', 'AbstractClass', 'cb', 's', 'str', 'other', 'AbstractClass', 'yetAnother', 'DerivedAbstractClass', 'str', 'other', 'cb', 'prop', 'toLowerCase', ], ['cb', 's'], [ 'str', 'other', 'AbstractClass', 'yetAnother', 'DerivedAbstractClass', 'str', 'other', 'cb', 'prop', 'toLowerCase', ], ], operatorsDesired: [ [ 'abstract', 'class', 'extends', '{}', '=', '()', ':', 'string', '=>', '{}', 'constructor', '()', ':', 'string', ',', ':', ',', ':', '{}', 'super', '()', ',', 'this', '.', '()', 'this', '.', '.', '()', ], [ 'abstract', 'class', 'extends', '{}', '=', '()', ':', 'string', '=>', '{}', 'constructor', '()', ':', 'string', ',', ':', ',', ':', '{}', 'super', '()', ',', 'this', '.', '()', 'this', '.', '.', '()', ], ['=', '()', ':', 'string', '=>', '{}'], [ 'constructor', '()', ':', 'string', ',', ':', ',', ':', '{}', 'super', '()', ',', 'this', '.', '()', 'this', '.', '.', '()', ], ], }, { name: 'Abstract Properties and Constructor with Type & This assignments + named parameters', skip: false, codeToParse: ` abstract class C1 { abstract x: string; abstract y: string; constructor() { let self = this; // ok let { x, y: y1 } = this; // error ({ x, y: y1, "y": y1 } = this); // error } } `,