Skip to content

Commit

Permalink
Merge pull request #119 from ConsenSys/file_mapping_report
Browse files Browse the repository at this point in the history
Report resolved paths in CompileResult
  • Loading branch information
cd1m0 authored May 23, 2022
2 parents 4f3cc8a + c967d6d commit 9bccd3f
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 17 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 15 additions & 6 deletions src/compile/inference/imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,14 @@ function computeSourceUnitName(
async function resolveSourceUnitName(
sourceUnitName: string,
resolvers: ImportResolver[]
): Promise<string | undefined> {
): Promise<[string, string] | undefined> {
for (const resolver of resolvers) {
const resolvedPath = resolver.resolve(sourceUnitName);

if (resolvedPath !== undefined) {
return fse.readFile(resolvedPath, "utf-8");
const contents = await fse.readFile(resolvedPath, "utf-8");

return [contents, resolvedPath];
}
}

Expand All @@ -111,10 +113,12 @@ async function resolveSourceUnitName(
* Given a partial map `files` from **source unit names** to file contents, a list of
* `remappings` and a list of `ImportResolver`s - `resolvers`, find all
* files that are imported from the starting set `files` but are
* **missing** in `files` and add them into the files map.
* **missing** in `files` and add them into the `files` map. Also for each imported file
* add a mapping from its source unit name to the actual file name in `fileNames`.
*/
export async function findAllFiles(
files: Map<string, string>,
fileNames: Map<string, string>,
remappings: Remapping[],
resolvers: ImportResolver[],
visited = new Set<string>()
Expand All @@ -138,15 +142,20 @@ export async function findAllFiles(

let content = files.get(sourceUnitName);

// Missing contents - try and fill them in from the resolvers
/**
* Missing contents - try and fill them in from the resolvers
*/
if (content === undefined) {
content = await resolveSourceUnitName(sourceUnitName, resolvers);
const result = await resolveSourceUnitName(sourceUnitName, resolvers);

if (content === undefined) {
if (result === undefined) {
throw new CompileInferenceError(`Couldn't find ${sourceUnitName}`);
}

content = result[0];

files.set(sourceUnitName, content);
fileNames.set(sourceUnitName, result[1]);
}

let flds: AnyFileLevelNode[];
Expand Down
61 changes: 56 additions & 5 deletions src/compile/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,33 @@ export interface MemoryStorage {
}

export interface CompileResult {
/**
* Raw compiler JSON output
*/
data: any;

/**
* Compiler version used
*/
compilerVersion?: string;

/**
* Map from file-names (either passed in by caller, or source unit names of imported files)
* to the contents of the respective files.
*/
files: Map<string, string>;

/**
* Map from file-names appearing in the `files` map, to the
* actual resolved paths on disk (if any).
*
* For `compileJSONData()` this map is empty (since nothing was resolved on disk).
*/
resolvedFileNames: Map<string, string>;

/**
* Map from file-names to the remapping inferred to resolve that given file-name
*/
inferredRemappings: Map<string, Remapping>;
}

Expand All @@ -48,7 +72,7 @@ export class CompileFailedError extends Error {
this.failures = entries;

const formattedErrorStr = entries.map(
(entry) => `==== ${entry.compilerVersion} ===:\n ${entry.errors.join("\n")}\n`
(entry) => `==== ${entry.compilerVersion} ====:\n ${entry.errors.join("\n")}\n`
);

this.message = `Compiler Errors: ${formattedErrorStr}`;
Expand Down Expand Up @@ -187,8 +211,9 @@ export async function compileSourceString(

const parsedRemapping = parsePathRemapping(remapping);
const files = new Map([[fileName, sourceCode]]);
const resolvedFileNames = new Map([[fileName, fileName]]);

await findAllFiles(files, parsedRemapping, resolvers);
await findAllFiles(files, resolvedFileNames, parsedRemapping, resolvers);

const compilerVersionStrategy = getCompilerVersionStrategy([...files.values()], version);
const failures: CompileFailure[] = [];
Expand All @@ -210,6 +235,7 @@ export async function compileSourceString(
data,
compilerVersion,
files,
resolvedFileNames,
inferredRemappings
};
}
Expand Down Expand Up @@ -257,6 +283,7 @@ export async function compileSol(
const parsedRemapping = parsePathRemapping(remapping);

const files = new Map<string, string>();
const resolvedFileNames = new Map<string, string>();
const visited = new Set<string>();

const isDynamicBasePath = pathOptions.basePath === undefined;
Expand All @@ -277,7 +304,18 @@ export async function compileSol(

files.set(resolvedFileName, sourceCode);

await findAllFiles(files, parsedRemapping, resolvers, visited);
/**
* Add self-mapping as we need every key in `files`
* to also be defined in `resolvedFileNames`
*/
resolvedFileNames.set(resolvedFileName, resolvedFileName);

/**
* Set the resolved path for every file passed in by the caller as well
*/
resolvedFileNames.set(fileName, resolvedFileName);

await findAllFiles(files, resolvedFileNames, parsedRemapping, resolvers, visited);
}

const compilerVersionStrategy = getCompilerVersionStrategy([...files.values()], version);
Expand All @@ -300,6 +338,7 @@ export async function compileSol(
data,
compilerVersion,
files,
resolvedFileNames,
inferredRemappings
};
}
Expand Down Expand Up @@ -336,7 +375,13 @@ export async function compileJsonData(

fillFilesFromSources(files, sources);

return { data, compilerVersion, files, inferredRemappings: new Map() };
return {
data,
compilerVersion,
files,
resolvedFileNames: new Map(),
inferredRemappings: new Map()
};
}

if (consistentlyContainsOneOf(sources, "source")) {
Expand All @@ -360,7 +405,13 @@ export async function compileJsonData(
const errors = detectCompileErrors(compileData);

if (errors.length === 0) {
return { data: compileData, compilerVersion, files, inferredRemappings: new Map() };
return {
data: compileData,
compilerVersion,
files,
resolvedFileNames: new Map(),
inferredRemappings: new Map()
};
}

failures.push({ compilerVersion, errors });
Expand Down
11 changes: 6 additions & 5 deletions test/unit/compile/inference/findAllFiles.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import expect from "expect";
import fse from "fs-extra";
import { join } from "path";
import { FileSystemResolver } from "../../../../src";
import { findAllFiles } from "../../../../src/compile/inference";
import { FileSystemResolver, findAllFiles } from "../../../../src";

const SAMPLES_DIR = join("test", "samples", "solidity");

Expand Down Expand Up @@ -52,7 +51,7 @@ describe("findAllFiles() find all needed imports", () => {
const contents = fse.readFileSync(fileName).toString();
const files = new Map<string, string>([[fileName, contents]]);

await findAllFiles(files, [], [new FileSystemResolver()]);
await findAllFiles(files, new Map(), [], [new FileSystemResolver()]);

expect(new Set(files.keys())).toEqual(new Set(expectedAllFiles));
});
Expand All @@ -71,7 +70,9 @@ contract Foo {
]
]);

await expect(findAllFiles(files, [], [])).rejects.toThrow(/Failed parsing imports/);
await expect(findAllFiles(files, new Map(), [], [])).rejects.toThrow(
/Failed parsing imports/
);
});

it("Missing file error", async () => {
Expand All @@ -85,6 +86,6 @@ contract Foo {
]
]);

await expect(findAllFiles(files, [], [])).rejects.toThrow(/Couldn't find a.sol/);
await expect(findAllFiles(files, new Map(), [], [])).rejects.toThrow(/Couldn't find a.sol/);
});
});

0 comments on commit 9bccd3f

Please sign in to comment.