Skip to content

Commit

Permalink
some refactorings & improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
sdoomz committed Oct 29, 2018
1 parent 179c974 commit 83449ce
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,32 @@ function buildDependenciesFromEntry({ entry, pattern, storage = new Map() }) {

entries.forEach(entry => {
const filePath = path.resolve(entry);

if (!storage.has(filePath)) {
const fileAST = parseFile(filePath);
const dependencies = new Map();
const interfaces = [];

babelTraverse(fileAST, {
'InterfaceDeclaration|TSInterfaceDeclaration': (path, state) => {
'InterfaceDeclaration|TSInterfaceDeclaration': (path) => {
interfaces.push(path.node);
},
// TODO: add require() support?
'ImportDeclaration': (path) => {
const relateivePath = path.node.source.value;
const relativePath = path.node.source.value;
// convert relative path to absolute
const absolutePath = resolveDependencyPath({ dependency: relateivePath, entryAST: fileAST, entryPath: filePath });
const absolutePath = resolveDependencyPath({ dependency: relativePath, entryAST: fileAST, entryPath: filePath });
const specifiers = [
...(dependencies.get(absolutePath) || []),
...path.node.specifiers,
];

dependencies.set(absolutePath, specifiers)
}
});

storage.set(filePath, { dependencies, fileAST, interfaces });

// traverse recursively
buildDependenciesFromEntry({
entry: resolveDependencies({ entryAST: fileAST, entryPath: filePath, pattern }),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import babelTraverse from '@babel/traverse';
import getVisitorApi from './getVisitorApi';
import traverse from './traverse';
import { withJSDoc } from '../../utils/nodeAST';
Expand Down Expand Up @@ -26,72 +25,66 @@ function buildDocumentationSourceAST({
createApiFunction,
} = getVisitorApi({ tag, visitorPath });

const interfaces = [];
const classDeclarations = [];
const classBodyItems = [];
const functions = [];

// NOTE: read about visitors
// https:/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md#toc-visitors
// https:/babel/babel/blob/master/packages/babel-traverse/src/visitors.js
const visitors = {
// 'InterfaceDeclaration|TSInterfaceDeclaration': (path, state) => {
// console.log('InterfaceDeclaration', state.filePath);
// },
...createApiVisitor((path, options, state) => {
const interfaceVisitor = {
// TODO: add support for flow with GenericTypeAnnotation
'TSTypeReference': (path, state) => {
const file = state.store.get(state.filePath);
//console.log('WTF TSTypeReference', path.node);
if (file) {
const typeName = path.node.typeName.name;
// NOTE: it might be the case when more than 1 import exists.
// Example:
// import { MyType } from './types';
// import { MyType } from './another-type';
// in this case both of them would be added to the doc
file.dependencies.forEach((importSpecifiers, absoluteFilePath) => {
const importSpecifier = importSpecifiers.find(specifier => specifier.local.name === typeName);

if (importSpecifier) {
const interfaceFile = state.store.get(absoluteFilePath);

if (interfaceFile) {
const importName = t.isImportDefaultSpecifier(importSpecifier) ?
importSpecifier.local.name :
importSpecifier.imported.name;
const interfaceNode = interfaceFile.interfaces.find(node => node.id.name === importName);

if (interfaceNode) {
state.interfaces.push(
createApiInterface(interfaceNode)
);
}
}
const interfaceVisitor = {
'GenericTypeAnnotation|TSTypeReference': (path, state) => {
const file = state.dependenciesTree.get(state.filePath);

if (file) {
// flow support with GenericTypeAnnotation, how to verify?
const typeName = t.isTSTypeReference(path.node) ? path.node.typeName.name : path.node.id.name;
// NOTE: it might be the case when more than 1 import exists.
// Example:
// import { MyType } from './types';
// import { MyType } from './another-type';
// in this case both of them would be added to the doc
file.dependencies.forEach((importSpecifiers, absoluteFilePath) => {
const importSpecifier = importSpecifiers.find(specifier => specifier.local.name === typeName);

if (importSpecifier) {
const interfaceFile = state.dependenciesTree.get(absoluteFilePath);

if (interfaceFile) {
const importName = t.isImportDefaultSpecifier(importSpecifier) ?
importSpecifier.local.name :
importSpecifier.imported.name;
const interfaceNode = interfaceFile.interfaces.find(node => node.id.name === importName);

if (interfaceNode) {
state.interfaces.push(
createApiInterface(interfaceNode)
);
}
});
}
}
},
};
});
}
},
};

const traverseInterfaces = (path, state) => path.traverse(interfaceVisitor, state);

const visitors = {
...createApiVisitor((path, options, state) => {
if (path.isClassDeclaration()) {
state.classDeclarations.push(
createApiClassDeclaration(path.node, path, options),
);
path.traverse(interfaceVisitor, state);
traverseInterfaces(path, state);
return;
}

if (path.isClassMethod()) {
state.classBodyItems.push(createApiClassMethod(path.node, path, options));
path.traverse(interfaceVisitor, state);
traverseInterfaces(path, state);
return;
}

if (path.isClassProperty(path)) {
state.classBodyItems.push(createApiClassProperty(path.node, path, options));
path.traverse(interfaceVisitor, state);
traverseInterfaces(path, state);
return;
}

Expand All @@ -101,19 +94,20 @@ function buildDocumentationSourceAST({
path.isArrowFunctionExpression()
) {
state.functions.push(createApiFunction(path.node, path, options));
traverseInterfaces(path, state);
}
}),
};

const dependenciesTree = buildDependenciesTree({ entry, pattern, source });
traverse({
const { interfaces, classDeclarations, classBodyItems, functions } = traverse({
dependenciesTree,
visitors,
options: {
interfaces,
functions,
classDeclarations,
classBodyItems,
interfaces: [],
functions: [],
classDeclarations: [],
classBodyItems: [],
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ function traverse({ dependenciesTree, visitors, options }) {
dependenciesTree.forEach((node, filePath) => {
babelTraverse(node.fileAST, visitors, null , {
filePath,
store: dependenciesTree,
dependenciesTree,
...options,
});
});
return options;
}

export default traverse;

0 comments on commit 83449ce

Please sign in to comment.