Skip to content

Commit

Permalink
Merge pull request #9 from ulixee/document-property-types
Browse files Browse the repository at this point in the history
Document property types
  • Loading branch information
blakebyrnes committed Jul 2, 2020
2 parents a0d0f4e + 89071b2 commit 3ec9d5c
Show file tree
Hide file tree
Showing 10 changed files with 234,628 additions and 9,560 deletions.
121,999 changes: 117,243 additions & 4,756 deletions builds/awaited-dom/docs.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion builds/awaited-dom/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "awaited-dom",
"version": "1.1.2",
"version": "1.1.4",
"description": "Library for converting WebIDLs to Typescript interfaces and classes",
"homepage": "https://github.com/ulixee/noderdom",
"author": "Data Liberation Foundation",
Expand Down
Binary file modified files/1-processed/main.db
Binary file not shown.
121,999 changes: 117,243 additions & 4,756 deletions files/2-finalized/awaited-dom/docs.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "noderdom",
"version": "1.1.2",
"version": "1.1.4",
"description": "Library for converting WebIDLs to Typescript interfaces and classes",
"homepage": "https://github.com/ulixee/noderdom",
"author": "Data Liberation Foundation",
Expand Down
11 changes: 8 additions & 3 deletions scripts/1-process/dbGenerator/insertInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,14 @@ for (const mdnInterface of mdnInterfaces) {
}

const tags: string[] = [];
if (['HTMLDocument', 'XMLDocument', 'DocumentFragment'].includes(mdnInterface.name)) {
if (['Document', 'HTMLDocument', 'XMLDocument', 'DocumentFragment'].includes(mdnInterface.name)) {
tags.push('Document');
} else if (['Node', 'Element', 'Comment', 'Text', 'HTMLElement'].includes(mdnInterface.name)) {
} else if (['Node', 'Element', 'Comment', 'Text'].includes(mdnInterface.name)) {
tags.push('Node');
} else if (['NodeList', 'RadioNodeList', 'HTMLCollection', 'HTMLOptionsCollection'].includes(mdnInterface.name)) {
tags.push('ArrayLike');
} else if (['EventTarget', 'Attr'].includes(mdnInterface.name)) {
tags.push('Miscellaneous');
}
if (mdnInterface.category === 'HTMLElements') {
tags.push('HTMLElement');
Expand Down Expand Up @@ -118,7 +122,8 @@ for (const inter of Object.values(interfacesByName)) {
};
const existing = db.prepare(`SELECT * FROM interfaces WHERE name=?`).get([inter.name]);
if (existing) {
db.prepare('UPDATE interfaces SET isDocumented=? WHERE name=?').run([data.isDocumented, inter.name]);
const values = [data.isDocumented, data.tags, inter.name];
db.prepare('UPDATE interfaces SET isDocumented=?, tags=? WHERE name=?').run(values);
} else {
const fields = Object.keys(data).join(', ');
const values = Object.values(data);
Expand Down
131 changes: 110 additions & 21 deletions scripts/2-finalize/generateDocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,76 @@ import * as Path from 'path';
import db from '../../db';
import config from '../../config';
import IDomType, { DomType } from '../../src/interfaces/IDomType';
import Components from '../../src/Components';
import DependencyCollector from '../../src/DependencyCollector';
import IComponentFilters from '../../src/interfaces/IComponentFilters';

const componentFilteringPath = Path.join(config.filesImportedDir, 'component-filters-awaited.json');
const componentsPath = Path.resolve(__dirname, config.filesProcessedDir, 'components-standard.json');
if (!Fs.existsSync(componentsPath)) throw new Error(`components-standard.json was not found: ${componentsPath}`);

const componentFilters: IComponentFilters = JSON.parse(Fs.readFileSync(componentFilteringPath, 'utf-8'));
const componentsData = JSON.parse(Fs.readFileSync(componentsPath, 'utf-8'));
const components = new Components(componentsData);
const dependencyCollector = new DependencyCollector(components, DomType.awaited);

const domType: IDomType = DomType.awaited;
const docs: any[] = [];
const docsByName: { [name: string]: any } = {};
const allInheritedKlassNames: Set<string> = new Set();

const allInterfaces = db.prepare('SELECT * FROM interfaces WHERE hasDefinedIDL=1 ORDER BY name').all();
const allSupers = db.prepare('SELECT * FROM supers ORDER BY name').all();
const docsPath = Path.join(config.filesFinalizedDir, `${domType}-dom`, 'docs.json');

allInterfaces.map(inter => {
console.log('\n-- SKIPPING ------------------');
const filteredInterfaces = allInterfaces.filter(i => {
if (i.tags) return true;
console.log(i.name);
return false;
});

console.log('\n-- DOCUMENTING ---------------');

filteredInterfaces.map(inter => {
const name = inter.name;
const tags = inter.tags.split(',').filter((t: string) => t);
const variableName = extractVariableName(name, tags);
const inheritsFrom = dependencyCollector.get(inter.name, true, false);
const inheritedKlassNames = inheritsFrom.klassNames.concat(inheritsFrom.mixinNames);
inheritedKlassNames.forEach(n => allInheritedKlassNames.add(n));
console.log(name);

const propertiesSql = `SELECT * FROM properties WHERE interfaceName=? AND hasDefinedIDL=1 ORDER BY localName COLLATE NOCASE`;
const properties = db.prepare(propertiesSql).all([inter.name]);
const directPropsSql = `SELECT * FROM properties WHERE interfaceName=? AND hasDefinedIDL=1 ORDER BY localName COLLATE NOCASE`;
const directProps = db.prepare(directPropsSql).all([inter.name]);
const properties = directProps.map(p => convertToProperty(name, p));

const methodsSql = `SELECT * FROM methods WHERE interfaceName=? AND hasDefinedIDL=1 ORDER BY localName COLLATE NOCASE`;
const methods = db.prepare(methodsSql).all([inter.name]);
const directMethodsSql = `SELECT * FROM methods WHERE interfaceName=? AND hasDefinedIDL=1 ORDER BY localName COLLATE NOCASE`;
const directMethods = db.prepare(directMethodsSql).all([inter.name]);
const methods = directMethods.map(m => convertToMethod(name, m));

docs.push({

for (const klassName of inheritedKlassNames) {
const inheritedPropsSql = `SELECT * FROM properties WHERE interfaceName=? AND hasDefinedIDL=1 ORDER BY localName COLLATE NOCASE`;
const inheritedProps = db.prepare(inheritedPropsSql).all([klassName]);
inheritedProps.forEach(p => properties.push(convertToProperty(klassName, p)));

const inheritedMethodsSql = `SELECT * FROM methods WHERE interfaceName=? AND hasDefinedIDL=1 ORDER BY localName COLLATE NOCASE`;
const inheritedMethods = db.prepare(inheritedMethodsSql).all([klassName]);
inheritedMethods.forEach(m => methods.push(convertToMethod(klassName, m)));
}

const doc = {
name,
variableName,
mdnCategory: inter.mdnCategory,
tags: inter.tags,
tags: tags.join(','),
overview: inter.docOverview,
properties: properties.map(p => ({
name: p.localName,
overview: p.docOverview,
})),
methods: methods.map(m => ({
name: m.localName,
overview: m.docOverview,
})),
});
properties: properties,
methods: methods,
};
docs.push(doc);
docsByName[doc.name] = doc;
});

allSupers.map(sup => {
Expand All @@ -43,19 +83,68 @@ allSupers.map(sup => {
const interSql = `SELECT * FROM interfaces WHERE name=? AND hasDefinedIDL=1`;
const inter = db.prepare(interSql).get([sup.interfaceName]);

const dependenciesSql = `SELECT * FROM super_isolates WHERE superName=? ORDER BY interfaceName COLLATE NOCASE`;
const dependencies = db.prepare(dependenciesSql).all([sup.name]);
const isolatesSql = `SELECT * FROM super_isolates WHERE superName=? ORDER BY interfaceName COLLATE NOCASE`;
const isolates = db.prepare(isolatesSql).all([sup.name]);
const dependencies: { name: string }[] = [];

isolates.forEach(d => {
const iSql = `SELECT * FROM interfaces WHERE name=? AND hasDefinedIDL=1`;
const i = db.prepare(iSql).get([d.interfaceName]);
if (i.type !== 'interface') return;
if (!componentFilters[i.name]) return;
if (!docsByName[d.interfaceName]) {
console.log('MISSING DEPENDENCY: ', d.interfaceName, allInheritedKlassNames.has(d.interfaceName));
}
dependencies.push({
name: d.interfaceName,
});
});

docs.push({
name,
tags: 'Super',
overview: inter.docOverview,
dependencies: dependencies.map(d => ({
name: d.interfaceName,
})),
dependencies: dependencies,
properties: [],
methods: [],
});
});

Fs.writeFileSync(docsPath, JSON.stringify(docs, null, 2));

function extractVariableName(name: string, tags: string[]) {
if (name === 'Element' || tags.includes('HTMLElement') || tags.includes('SVGElement')) {
return 'elem';
}
if (tags.includes('Node')) {
return 'node';
}
if (tags.includes('Document')) {
return 'doc';
}
}

function convertToProperty(componentName: string, property: any) {
const componentFilter = componentFilters[componentName];
if (!componentFilter) throw new Error(`MISSING COMPONENT FILTER: ${componentName}`);

return {
name: property.localName,
overview: property.docOverview,
componentName: componentName,
returnType: property.customReturnTypes || property.nativeReturnTypes,
isImplemented: !!componentFilter.propertiesByName[property.localName]?.isEnabled,
};
}

function convertToMethod(componentName: string, method: any) {
const componentFilter = componentFilters[componentName];
if (!componentFilter) throw new Error(`MISSING COMPONENT FILTER: ${componentName}`);

return {
name: method.localName,
overview: method.docOverview,
componentName: componentName,
isImplemented: !!componentFilter.methodsByName[method.localName]?.isEnabled,
};
}
8 changes: 4 additions & 4 deletions src/ComponentCleaner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ export default class ComponentCleaner {
private referencedIDLTypes: Set<string>;
private unexposedTypes = new Set<string>();
private readonly components: Components;
private readonly componentFiltersPath: string;
private readonly componentFilteringPath: string;

constructor(components: Components, componentFilteringPath?: string) {
this.components = components;
this.componentFiltersPath = componentFilteringPath || '';
this.componentFilteringPath = componentFilteringPath || '';
}

public run() {
Expand Down Expand Up @@ -69,8 +69,8 @@ export default class ComponentCleaner {
}

private runComponentFiltering() {
if (!this.componentFiltersPath) return;
const componentFilters: IComponentFilters = JSON.parse(Fs.readFileSync(this.componentFiltersPath, 'utf-8'));
if (!this.componentFilteringPath) return;
const componentFilters: IComponentFilters = JSON.parse(Fs.readFileSync(this.componentFilteringPath, 'utf-8'));

const callbackInterfaceNames = Object.keys(this.components.callbackInterfaces);
const interfacesNames = Object.keys(this.components.interfaces);
Expand Down
26 changes: 13 additions & 13 deletions src/DependencyCollector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ interface ICodeDependenciesByName {
}

interface IClassCollection {
officialMixins: Set<string>;
isolateMixins: Set<string>;
mixinNames: Set<string>;
klassNames: Set<string>;
}

interface IVisits {
Expand Down Expand Up @@ -47,19 +47,19 @@ export default class DependencyCollector {
}
}

public get(name: string) {
public get(name: string, collectUpstream: boolean = true, collectDownstream: boolean = true) {
const visits: IVisits = { upstream: new Set(), downstream: new Set() };
const classCollection: IClassCollection = {
isolateMixins: new Set(),
officialMixins: new Set(),
klassNames: new Set(),
mixinNames: new Set(),
};

this.collectUpstreamClasses(name, classCollection, visits);
this.collectDownstreamClasses(name, classCollection, visits);
if (collectUpstream) this.collectUpstreamClasses(name, classCollection, visits);
if (collectDownstream) this.collectDownstreamClasses(name, classCollection, visits);

return {
isolateMixins: Array.from(classCollection.isolateMixins),
officialMixins: Array.from(classCollection.officialMixins),
klassNames: Array.from(classCollection.klassNames),
mixinNames: Array.from(classCollection.mixinNames),
};
}

Expand All @@ -68,9 +68,9 @@ export default class DependencyCollector {
visits.upstream.add(name);
for (const n of this.upstreamByName[name]) {
if (this.components.mixins[n]) {
classCollection.officialMixins.add(n);
classCollection.mixinNames.add(n);
} else {
classCollection.isolateMixins.add(n);
classCollection.klassNames.add(n);
}
this.collectUpstreamClasses(n, classCollection, visits);
}
Expand All @@ -81,9 +81,9 @@ export default class DependencyCollector {
visits.downstream.add(name);
for (const n of this.downstreamByName[name]) {
if (this.components.mixins[n]) {
classCollection.officialMixins.add(n);
classCollection.mixinNames.add(n);
} else {
classCollection.isolateMixins.add(n);
classCollection.klassNames.add(n);
}
this.collectUpstreamClasses(n, classCollection, visits);
this.collectDownstreamClasses(n, classCollection, visits);
Expand Down
10 changes: 5 additions & 5 deletions src/SuperGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ export default class SuperGenerator {

superInterface.implements = [];

inheritsFrom.officialMixins.forEach(name => {
superInterface.implements!.push(name);
inheritsFrom.mixinNames.forEach(mixinName => {
superInterface.implements!.push(mixinName);
});

inheritsFrom.isolateMixins.forEach(name => {
const isolateName = `${name}Isolate`;
const isolateInterface = Object.assign({}, components.allInterfacesMap[name], { name: isolateName });
inheritsFrom.klassNames.forEach(klassName => {
const isolateName = `${klassName}Isolate`;
const isolateInterface = Object.assign({}, components.allInterfacesMap[klassName], { name: isolateName });

isolateInterface.properties = Object.assign({}, isolateInterface.properties);
isolateInterface.methods = Object.assign({}, isolateInterface.methods);
Expand Down

0 comments on commit 3ec9d5c

Please sign in to comment.