fix subtle bug in recursion in getDependencyGraph

pull/4814/head
Joseph Izang 8 months ago
parent bfa4dacfba
commit 1db68bb1ee
  1. 6
      apps/remix-ide/src/app/plugins/contractFlattener.tsx
  2. 40
      libs/remix-ui/solidity-compiler/src/lib/logic/flattenerUtilities.ts

@ -1,3 +1,4 @@
/* eslint-disable prefer-const */
import React from 'react' import React from 'react'
import { Plugin } from '@remixproject/engine' import { Plugin } from '@remixproject/engine'
import { customAction } from '@remixproject/plugin-api' import { customAction } from '@remixproject/plugin-api'
@ -57,11 +58,12 @@ export class ContractFlattener extends Plugin {
let sorted let sorted
let result let result
let sources let sources
let order: string[] = []
try { try {
dependencyGraph = getDependencyGraph(ast, filePath, input.settings.remappings) dependencyGraph = getDependencyGraph(ast, filePath, input.settings.remappings, order)
sorted = dependencyGraph.isEmpty() ? [filePath] : dependencyGraph.sort().reverse() sorted = dependencyGraph.isEmpty() ? [filePath] : dependencyGraph.sort().reverse()
sources = source.sources sources = source.sources
result = concatSourceFiles(sorted, sources) result = concatSourceFiles(sorted, sources, order)
} catch (err) { } catch (err) {
console.warn(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; const SPDX_SOLIDITY_REGEX = /^\s*\/\/ SPDX-License-Identifier:.*$/gm;
type Visited = { [key: string]: number } 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 graph = tsort();
const visited = {}; const visited = {};
visited[target] = 1; visited[target] = 1;
_traverse(graph, visited, ast, target, remappings); _traverse(graph, visited, ast, target, remappings, order);
return graph; return graph;
} }
export function concatSourceFiles(files: any[], sources: any) { export function concatSourceFiles(files: any[], sources: any, order: string[]) {
let concat = ''; let concat = ''
for (const file of files) { order.reverse().forEach((importName) => {
const source = sources[file].content; for (const file of files) {
const sourceWithoutImport = source.replace(IMPORT_SOLIDITY_REGEX, ''); if (file === importName) {
const sourceWithoutSPDX = sourceWithoutImport.replace(SPDX_SOLIDITY_REGEX, ''); const source = sources[file].content
concat += `\n// File: ${file}\n\n`; const sourceWithoutImport = source.replace(IMPORT_SOLIDITY_REGEX, '')
concat += sourceWithoutSPDX; const sourceWithoutSPDX = sourceWithoutImport.replace(SPDX_SOLIDITY_REGEX, '')
} concat += `\n// File: ${file}\n\n`
return concat; 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 let currentAst = null
currentAst = ast[name].ast currentAst = ast[name].ast
const dependencies = _getDependencies(currentAst); const dependencies = _getDependencies(currentAst);
for (const dependency of dependencies) { for (const dependency of dependencies) {
const path = resolve(name, dependency, remappings); const path = resolve(name, dependency, remappings);
if (path in visited) { 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; visited[path] = 1;
graph.add(name, path); graph.add(name, path);
_traverse(graph, visited, ast, path, remappings); _traverse(graph, visited, ast, path, remappings, order);
} }
order.push(name)
} }
function _getDependencies(ast: AstNode) { function _getDependencies(ast: AstNode) {

Loading…
Cancel
Save