Skip to content

Commit 97dc47c

Browse files
committed
dom types parsing
1 parent ca0b61e commit 97dc47c

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

types/TYPES.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# TypeScript and IDE suggestion for CssChain
2+
3+
CssChain.d.ts uses DOM definitions from
4+
5+
# types generation
6+
## 1. Generate initial CssChain.d.ts
7+
[Creating .d.ts Files from .js files](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)
8+
9+
npx -p typescript tsc src/*.js --declaration --allowJs --emitDeclarationOnly --outDir types
10+
## 2. combine whole HTMLElement dependency tree
11+
From [typescript/lib/lib.dom.d.ts](https://github.com/microsoft/TypeScript/blob/main/lib/lib.dom.d.ts).
12+
13+
1. Traverse over `lib.dom.d.ts` AST and create the inheritance tree for all interfaces.
14+
2. From inheritance tree collect all related to HTMLElement as collection of names
15+
3. by iterating over AST, dump out bodies of the interfaces from collection into DomMixinInterface
16+
17+
#links
18+
* [Using TypeScript compiler](https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API)

types/ast-parse.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import ts from "typescript";
2+
3+
let checker;
4+
5+
function getParents( node /* ts.ClassDeclaration*/ )
6+
{
7+
if( !node.heritageClauses )
8+
return [];
9+
let ret = [];
10+
node.heritageClauses
11+
.filter( clause => clause.token == ts.SyntaxKind.ExtendsKeyword
12+
|| clause.token == ts.SyntaxKind.ImplementsKeyword )
13+
.map( clause =>
14+
clause.types.map( t =>
15+
{ let symbol = checker.getSymbolAtLocation( t.expression );
16+
symbol && ret.push( checker.getFullyQualifiedName( symbol ) );
17+
}));
18+
return ret;
19+
}
20+
21+
const mapInterfaceName2deps = {
22+
// HTMLElement: // given for sample
23+
// {
24+
// extends: [ 'Element', 'DocumentAndElementEventHandlers', 'ElementCSSInlineStyle', 'ElementContentEditable', 'GlobalEventHandlers', 'HTMLOrSVGElement' ],
25+
// inheritedBy: [ 'HTMLEmbedElement' ]
26+
// }
27+
};
28+
29+
const assureMemberAsMap = ( o, field ) => o[field] || ( o[field] = { extends: {}, inheritedBy: {} } );
30+
31+
/**
32+
* Prints out particular nodes from a source file
33+
*
34+
* @param file a path to a file
35+
*/
36+
function extract( file )
37+
{
38+
// Create a Program to represent the project, then pull out the
39+
// source file to parse its AST.
40+
let program = ts.createProgram( [ file ], { allowJs: true } );
41+
checker = program.getTypeChecker();
42+
43+
const sourceFile = program.getSourceFile( file );
44+
// To print the AST, we'll use TypeScript's printer
45+
const printer = ts.createPrinter( { newLine: ts.NewLineKind.LineFeed } );
46+
// To give constructive error messages, keep track of found and un-found identifiers
47+
const foundNodes = [];
48+
// Loop through the root AST nodes of the file
49+
// @ts-ignore
50+
ts.forEachChild( sourceFile, node =>
51+
{
52+
let name = "";
53+
// This is an incomplete set of AST nodes which could have a top level identifier
54+
// it's left to you to expand this list, which you can do by using
55+
// https://ts-ast-viewer.com/ to see the AST of a file then use the same patterns
56+
// as below
57+
if( ts.isFunctionDeclaration( node ) )
58+
{
59+
// @ts-ignore
60+
name = node.name.text;
61+
// Hide the method body when printing
62+
// @ts-ignore
63+
node.body = undefined;
64+
}else if( ts.isVariableStatement( node ) )
65+
{
66+
name = node.declarationList.declarations[ 0 ].name.getText( sourceFile );
67+
}else if( ts.isInterfaceDeclaration( node ) )
68+
{
69+
name = node.name.text;
70+
foundNodes.push( [ name, node ] );
71+
let deps = assureMemberAsMap( mapInterfaceName2deps, name );
72+
const classes = getParents( node );
73+
classes.map( c =>
74+
{
75+
deps.extends[ c ] = 1;
76+
assureMemberAsMap( mapInterfaceName2deps, c ).inheritedBy[name]=1;
77+
} );
78+
}
79+
} );
80+
}
81+
82+
// Run the extract function with the script's arguments
83+
// extract(process.argv[2], process.argv.slice(3));
84+
extract( "node_modules/typescript/lib/lib.dom.d.ts" );
85+
const interfaces = Object.keys(mapInterfaceName2deps);
86+
console.log( mapInterfaceName2deps );

0 commit comments

Comments
 (0)