fix(providence): correctly handle exports like "const x=3; export {x};"

Co-authored-by: Thijs Louisse<Thijs.Louisse@ing.com>
This commit is contained in:
Joshua Hewitt 2021-10-28 17:33:27 +02:00 committed by Thijs Louisse
parent eb61cbfed2
commit a0b313c650
3 changed files with 44 additions and 4 deletions

View file

@ -0,0 +1,5 @@
---
'providence-analytics': patch
---
correctly handle exports like "const x=3; export {x};"

View file

@ -37,7 +37,7 @@ function getBindingAndSourceReexports(astPath, identifierName) {
if (found) {
bindingPath = path;
bindingType = 'ExportSpecifier';
source = path.parentPath.node.source.value;
source = path.parentPath.node.source ? path.parentPath.node.source.value : '[current]';
path.stop();
}
},
@ -46,11 +46,14 @@ function getBindingAndSourceReexports(astPath, identifierName) {
}
/**
* @desc returns source and importedIdentifierName: We might be an import that was locally renamed.
* Retrieves source (like '@lion/core') and importedIdentifierName (like 'lit') from ast for
* current file.
* We might be an import that was locally renamed.
* Since we are traversing, we are interested in the imported name. Or in case of a re-export,
* the local name.
* @param {object} astPath Babel ast traversal path
* @param {string} identifierName the name that should be tracked (and that exists inside scope of astPath)
* @returns {{ source:string, importedIdentifierName:string }}
*/
function getImportSourceFromAst(astPath, identifierName) {
let source;
@ -183,7 +186,8 @@ async function trackDownIdentifierFn(source, identifierName, currentFilePath, ro
* export { x }
*/
newSource = getImportSourceFromAst(path, identifierName).source;
if (!newSource) {
if (!newSource || newSource === '[current]') {
/**
* @example
* const x = 12;

View file

@ -137,6 +137,37 @@ describe('trackdownIdentifier', () => {
});
});
it(`tracks down locally declared, reexported identifiers (without a source defined)`, async () => {
mockProject(
{
'./src/declarationOfMyNumber.js': `
const myNumber = 3;
export { myNumber };
`,
'./currentFile.js': `
import { myNumber } from './src/declarationOfMyNumber.js';
`,
},
{
projectName: 'my-project',
projectPath: '/my/project',
},
);
// Let's say we want to track down 'MyClass' in the code above
const source = './src/declarationOfMyNumber.js';
const identifierName = 'myNumber';
const currentFilePath = '/my/project/currentFile.js';
const rootPath = '/my/project';
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
expect(rootFile).to.eql({
file: './src/declarationOfMyNumber.js',
specifier: 'myNumber',
});
});
// TODO: improve perf
describe.skip('Caching', () => {});
});