fix subtle bug in recursion in getDependencyGraph

pull/5370/head
Joseph Izang 6 months ago
parent bc30d10195
commit 8e62933dfb
  1. 6
      apps/remix-ide/src/app/plugins/contractFlattener.tsx
  2. 42
      libs/remix-ui/solidity-compiler/src/lib/logic/flattenerUtilities.ts

@ -1,3 +1,4 @@
/* eslint-disable prefer-const */
import React from 'react'
import { Plugin } from '@remixproject/engine'
import { customAction } from '@remixproject/plugin-api'
@ -57,11 +58,12 @@ export class ContractFlattener extends Plugin {
let sorted
let result
let sources
let order: string[] = []
try {
dependencyGraph = getDependencyGraph(ast, filePath, input.settings.remappings)
dependencyGraph = getDependencyGraph(ast, filePath, input.settings.remappings, order)
sorted = dependencyGraph.isEmpty() ? [filePath] : dependencyGraph.sort().reverse()
sources = source.sources
result = concatSourceFiles(sorted, sources)
result = concatSourceFiles(sorted, sources, order)
} catch (err) {
console.warn(err)
}

@ -4,39 +4,49 @@ const IMPORT_SOLIDITY_REGEX = /^\s*import(\s+).*$/gm;
const SPDX_SOLIDITY_REGEX = /^\s*\/\/ SPDX-License-Identifier:.*$/gm;
type Visited = { [key: string]: number }
export function getDependencyGraph(ast: { [name: string]: CompilationSource }, target: string, remappings: string[]) {
export function getDependencyGraph(ast: { [name: string]: CompilationSource }, target: string, remappings: string[], order: string[]) {
const graph = tsort();
const visited = {};
visited[target] = 1;
_traverse(graph, visited, ast, target, remappings);
_traverse(graph, visited, ast, target, remappings, order);
return graph;
}
export function concatSourceFiles(files: any[], sources: any) {
let concat = '';
for (const file of files) {
const source = sources[file].content;
const sourceWithoutImport = source.replace(IMPORT_SOLIDITY_REGEX, '');
const sourceWithoutSPDX = sourceWithoutImport.replace(SPDX_SOLIDITY_REGEX, '');
concat += `\n// File: ${file}\n\n`;
concat += sourceWithoutSPDX;
}
return concat;
export function concatSourceFiles(files: any[], sources: any, order: string[]) {
let concat = ''
order.reverse().forEach((importName) => {
for (const file of files) {
if (file === importName) {
const source = sources[file].content
const sourceWithoutImport = source.replace(IMPORT_SOLIDITY_REGEX, '')
const sourceWithoutSPDX = sourceWithoutImport.replace(SPDX_SOLIDITY_REGEX, '')
concat += `\n// File: ${file}\n\n`
concat += sourceWithoutSPDX
}
const source = sources[importName].content
const sourceWithoutImport = source.replace(IMPORT_SOLIDITY_REGEX, '')
const sourceWithoutSPDX = sourceWithoutImport.replace(SPDX_SOLIDITY_REGEX, '')
concat += `\n// File: ${importName}\n\n`
concat += sourceWithoutSPDX
}
})
return concat
}
function _traverse(graph: Graph, visited: Visited, ast: { [name: string]: CompilationSource }, name: string, remappings: string[]) {
function _traverse(graph: Graph, visited: Visited, ast: { [name: string]: CompilationSource }, name: string, remappings: string[], order: string[]) {
let currentAst = null
currentAst = ast[name].ast
const dependencies = _getDependencies(currentAst);
for (const dependency of dependencies) {
const path = resolve(name, dependency, remappings);
if (path in visited) {
// continue; // fixes wrong ordering of source in flattened file
continue; // fixes wrong ordering of source in flattened file
}
visited[path] = 1;
graph.add(name, path);
_traverse(graph, visited, ast, path, remappings);
_traverse(graph, visited, ast, path, remappings, order);
}
order.push(name)
}
function _getDependencies(ast: AstNode) {
@ -191,4 +201,4 @@ export function normalizeContractPath(contractPath: string): string[] {
}
const resultingPath = `${folders}${filename}`
return [folders,resultingPath, filename]
}
}

Loading…
Cancel
Save