Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,10 @@ export function graph(files, options = {}) {
opts.fillcolor = opts.color;
}
}


if(cluster == null)
return;

cluster.addNode(nodeName(name, contractName), opts);
},

Expand Down Expand Up @@ -478,7 +481,7 @@ export function graph(files, options = {}) {
}

// check which usingFor contract the method resolves to (best effort first match)
let matchingContracts = [...contractUsingForDefinitions].filter(contract => functionsPerContract[contract].includes(name));
let matchingContracts = [...contractUsingForDefinitions].filter(contract => functionsPerContract[contract] != undefined ? functionsPerContract[contract].includes(name) : false);

if(matchingContracts.length > 0){
// we found at least one matching contract. use the first. don't know what to do if multiple are matching :/
Expand All @@ -493,7 +496,7 @@ export function graph(files, options = {}) {
} else if (contractUsingFor[contractName].hasOwnProperty('*') &&
functionsPerContract.hasOwnProperty(contractUsingFor[contractName]['*'])) {
// check which usingFor contract the method resolves to (best effort first match)
let matchingContracts = [...contractUsingFor[contractName]['*']].filter(contract => functionsPerContract[contract].includes(name));
let matchingContracts = [...contractUsingFor[contractName]['*']].filter(contract => functionsPerContract[contract] != undefined ? functionsPerContract[contract].includes(name) : false);

if(matchingContracts.length > 0){
// we found at least one matching contract. use the first. don't know what to do if multiple are matching :/
Expand All @@ -512,7 +515,7 @@ export function graph(files, options = {}) {
} else if(object === 'this') {
opts.color = colorScheme.call.this;
} else if (object === 'super') {
let matchingContracts = [...dependencies[contractName]].filter(contract => functionsPerContract[contract].includes(name));
let matchingContracts = [...dependencies[contractName]].filter(contract => functionsPerContract[contract] != undefined ? functionsPerContract[contract].includes(name) : false);

if(matchingContracts.length > 0){
localContractName = matchingContracts[0];
Expand Down
5 changes: 3 additions & 2 deletions src/graphSimple.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function graphSimple(files, options = {}) {
let structsPerContract = {null:[]};
let contractUsingFor = {};
let contractNames = [];
let customErrorNames = [];

for (let file of files) {

Expand Down Expand Up @@ -304,9 +305,9 @@ export function graphSimple(files, options = {}) {
structsOfDependencies = structsOfDependencies.concat(structsPerContract[dep]);
}
}

if(
parserHelpers.isRegularFunctionCall(node, contractNames, eventsOfDependencies, structsOfDependencies)
parserHelpers.isRegularFunctionCall(node, contractNames, eventsOfDependencies, structsOfDependencies, customErrorNames)
) {
opts.color = colorScheme.call.regular;
name = expr.name;
Expand Down
64 changes: 53 additions & 11 deletions src/utils/importer.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,25 +77,67 @@ export function resolveImportPath(baseFilePath, importedFilePath, projectDir = p
if (importedFilePath.slice(0, 1) === '.' || importedFilePath.slice(0, 1) === '/') {
resolvedPath = path.resolve(baseDirPath, importedFilePath);
} else {
// It's most likely a special case using a remapping to node_modules directory.
// It's most likely a special case using a remapping to another directory (ie node_modules or lib).
let currentDir = path.resolve(baseDirPath, '..');
let currentDirArray = baseDirPath.split(path.sep);
let currentDirName = currentDirArray.pop();
let nodeModulesDir = '';
let targetImportDir = '';
let currentDirContents = '';
let keepLooping = true;
let nodeModulesBool = false;
let forgeRemappingsBool = false;
let forgeRemappingInput = '';
let forgeRemappingOutput = '';

while (!fs.readdirSync(currentDir).includes('node_modules') && !nodeModulesDir) {
if (topmostDirArray.length >= currentDirArray.length) {
throw new Error(`Import statement seems to be a Truffle "node_modules remapping," but no 'node_modules' directory could be found.`);
while (keepLooping) {
if (topmostDirArray.length > currentDirArray.length) {
throw new Error(`Import statement seems to be a Truffle "node_modules remapping" or Forge "remappings.txt", but no corresponding directory could be found.`);
}
currentDirContents = fs.readdirSync(currentDir);
// Assumes that both remappings.txt and node_modules are on the same level, also that they can co-exist
nodeModulesBool = currentDirContents.includes('node_modules');
forgeRemappingsBool = currentDirContents.includes('remappings.txt');
keepLooping = forgeRemappingsBool || nodeModulesBool ? false : true;

if(keepLooping) {
currentDirName = currentDirArray.pop();
currentDir = path.resolve(currentDir, '..');
}
currentDirName = currentDirArray.pop();
currentDir = path.resolve(currentDir, '..');
}

// We've found the directory containing node_modules.
nodeModulesDir = path.join(currentDir, 'node_modules');
resolvedPath = path.join(nodeModulesDir, importedFilePath);
}
if (forgeRemappingsBool) {
let remappingsFile = fs.readFileSync(path.join(currentDir, "remappings.txt"), 'utf-8');
let remappingsArray = remappingsFile.split(/\r?\n/);
let importBase = importedFilePath.split("/")[0];

// Scan remappings
for (let idx=0;idx<remappingsArray.length;idx++) {
let remappingSplit = remappingsArray[idx].split("=");

// Assumes only one '=' in the string
if (remappingSplit.length > 2) {
throw new Error(`Multiple assignment symbols found in remappings.txt.`);
}

if (remappingSplit[0].includes(importBase)) {
forgeRemappingInput = remappingSplit[0];
forgeRemappingOutput = remappingSplit[1];
break;
}
}

// We've found the directory containing remappings.txt.
resolvedPath = path.join(currentDir, importedFilePath.replace(forgeRemappingInput, forgeRemappingOutput));
}

if (!forgeRemappingsBool || (forgeRemappingsBool && !forgeRemappingInput)) {
// Use the directory containing node_modules.
targetImportDir = path.join(currentDir, "node_modules");
resolvedPath = path.join(targetImportDir, importedFilePath);
}

}

// Verify that the resolved path is actually a file.
if (!fs.existsSync(resolvedPath) || !fs.statSync(resolvedPath).isFile()) {
throw new Error(`Import path not resolved to a file: ${resolvedPath}`);
Expand Down