@ b062e657e · fetching

a9cc69061 · a9cc69061c0503b6e714c27d0bcadb4b5595c035

Add data about top native APIs (#36)

reading declarations

Changes to data/list-native-imports.js. All files

data/list-native-imports.js

new file mode 100644@@ -0,0 +1,110 @@+// Collects data about functions imported from node.exe by all packages installed under the+// current directory. Currently Windows only. See README.md for details.++const childProc = require('child_process');+const fs = require('fs');+const path = require('path');++const rootDir = process.cwd();++summarizeImports();++function summarizeImports() {+    let summaryImports = [];+    let packageNames = fs.readdirSync(path.join(rootDir, 'node_modules'));+    packageNames.forEach(packageName => {+        let packageImports = getImportsForPackage(packageName);+        packageImports.forEach(packageImport => {+            let summaryImport = summaryImports.find(i => i.signature === packageImport.signature);+            if (summaryImport) {+                summaryImport.packages.push(packageName);+            } else {+                packageImport.packages = [packageName];+                summaryImports.push(packageImport);+            }+        });+    });++    console.log('Pkg count,Package names,Imported name,Imported signature');+    summaryImports.sort((a, b) => a.packages.length > b.packages.length ? -1 : 1).forEach(i => {+        console.log(+            i.packages.length + ',"' ++            i.packages.join(', ') + '","' ++            i.name + '","' ++            i.signature + '"');+    });+}++function getImportsForPackage(packageName) {+    let packageNativeModules = getNativeModulesForPackage(packageName);++    let nativeImports = [];+    packageNativeModules.forEach(nativeModule => {+        let moduleImports = getImportsForNativeModule(nativeModule);+        moduleImports.forEach(moduleImport => {+            if (!nativeImports.find(i => i.signature === moduleImport.signature)) {+                nativeImports.push(moduleImport);+            }+        });+    });+    return nativeImports;+}++function getNativeModulesForPackage(packageName) {+    let packageDir = path.join(rootDir, 'node_modules', packageName);+    return findFiles(packageDir, relativePath => {+        return relativePath.endsWith('.node') &&+            !relativePath.startsWith('node_modules') &&+            relativePath.indexOf('ia32') < 0;+    }).map(relativePath => path.join(packageDir, relativePath));+}++function getImportsForNativeModule(modulePath) {+    const dumpbinExe =+        'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\dumpbin.exe';+    const undnameExe =+        'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\undname.exe';+    const importRegex = /^ *[0-9A-F]+ +0 +([^ ]+) *$/;+    const undnameRegex = /is :- "([^"]+)"/;+    const fnameRegex = /([\w:~]+)\(/;++    let p = childProc.spawnSync(dumpbinExe, ['/imports:node.exe', modulePath]);+    let lines = p.stdout.toString().split('\r\n');++    let imports = [];+    lines.forEach(line => {+        let m = importRegex.exec(line);+        if (m) {+            let decoratedName = m[1];+            p = childProc.spawnSync(undnameExe, [decoratedName]);+            let output = p.stdout.toString();+            m = undnameRegex.exec(output);+            if (m) {+                let signature = m[1];+                m = fnameRegex.exec(signature);+                let name = (m ? m[1] : signature);+                imports.push({ name, signature });+            }+        }+    });++    return imports;+}++function findFiles(rootDir, filter, relativeDir) {+    let results = [];+    let childNames = fs.readdirSync(path.join(rootDir, relativeDir || ''));+    childNames.forEach(childName => {+        let relativePath = path.join(relativeDir || '', childName);+        let childStats = fs.statSync(path.join(rootDir, relativePath));+        if (childStats.isDirectory()) {+            let childResults = findFiles(rootDir, filter, relativePath);+            results = results.concat(childResults);+        } else {+            if (filter(relativePath)) {+                results.push(relativePath);+            }+        }+    });+    return results;+}