Skip to content

Commit

Permalink
feat(GlobalRename): add support for global renames
Browse files Browse the repository at this point in the history
  • Loading branch information
RyuuGan committed Jun 23, 2019
1 parent a42c11e commit 8f43b8e
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 34 deletions.
20 changes: 15 additions & 5 deletions lib/fileAnalyzer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fs from 'fs-extra';
import stripComments from 'strip-json-comments';
import { RegistredImport } from './merger';

export class FileAnalyzer {
filename: string;
Expand All @@ -9,10 +10,17 @@ export class FileAnalyzer {
static buildExportBody(
analyzedFile: FileAnalyzerResult,
e: FileAnalyzerExportsResult,
newName?: string,
newName: string,
globalRenames: RegistredImport[],
): string {
let is = e.is;
if (is) {
globalRenames.forEach((i) => {
is = is.replace(
`${i.globalRename}.${i.name}`,
`${i.globalRename}$${i.name}`,
);
});
analyzedFile.imports.forEach((i) => {
if (i.namedImports) {
i.namedImports.forEach((ni) => {
Expand Down Expand Up @@ -199,10 +207,12 @@ export interface FileAnalyzerResult {
export interface FileAnalyzerImportsResult {
file: string;
globalRenameImport: string | null;
namedImports: Array<{
name: string;
as: string;
}> | null;
namedImports: FileAnalyzerNamedImportResult[] | null;
}

export interface FileAnalyzerNamedImportResult {
name: string;
as: string;
}

export interface FileAnalyzerExportsResult {
Expand Down
95 changes: 66 additions & 29 deletions lib/merger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
FileAnalyzer,
FileAnalyzerImportsResult,
FileAnalyzerResult,
FileAnalyzerNamedImportResult,
FileAnalyzerExportsResult,
} from './fileAnalyzer';

const error = Debug('sol-merger:error');
Expand Down Expand Up @@ -102,48 +104,82 @@ export class Merger {
analyzedFile: FileAnalyzerResult,
parentImport?: FileAnalyzerImportsResult,
): Promise<string[]> {
const isAllImport =
!parentImport ||
(parentImport.globalRenameImport === null &&
parentImport.namedImports === null);

const shouldBeImported = (exportName: string) =>
isAllImport ||
parentImport.namedImports.find(
(namedImport) => namedImport.name === exportName,
const isAllImport = Utils.isAllImport(parentImport);

const isRenameGlobalImport = Utils.isRenameGlobalImport(parentImport);

const shouldBeImported = (exportName: string) => {
return (
isAllImport ||
isRenameGlobalImport ||
parentImport.namedImports.find(
(namedImport) => namedImport.name === exportName,
)
);
};

const result: string[] = [];

analyzedFile.exports.forEach((e) => {
const beImported = shouldBeImported(e.name);
const as =
typeof beImported === 'object' && beImported !== null
? beImported.as
: null;
const isImported = this.isImported(analyzedFile.filename, e.name, as);
if (isImported) {
log('%s %s %s', '⚠', e.name, analyzedFile.filename);
return;
}
if (beImported) {
const body = FileAnalyzer.buildExportBody(analyzedFile, e, as);
result.push(body);
this.registerImport({
as: as,
file: analyzedFile.filename,
name: e.name,
});
return;
}
this.processExport(
analyzedFile,
parentImport,
e,
shouldBeImported,
isRenameGlobalImport,
result,
);
});
return result;
}

processExport(
analyzedFile: FileAnalyzerResult,
parentImport: FileAnalyzerImportsResult | undefined,
e: FileAnalyzerExportsResult,
shouldBeImported: (e: string) => boolean | FileAnalyzerNamedImportResult,
isRenameGlobalImport: boolean,
result: string[],
): void {
const beImported = shouldBeImported(e.name);
let rename =
typeof beImported === 'object' && beImported !== null
? beImported.as
: null;
const isImported = this.isImported(analyzedFile.filename, e.name, rename);
if (isImported) {
log('%s %s %s', '⚠', e.name, analyzedFile.filename);
return;
}
if (beImported) {
if (isRenameGlobalImport) {
rename = `${parentImport.globalRenameImport}$${e.name}`;
}
const globalRenames = this.getGlobalImports();
const body = FileAnalyzer.buildExportBody(
analyzedFile,
e,
rename,
globalRenames,
);
result.push(body);
this.registerImport({
as: rename,
file: analyzedFile.filename,
name: e.name,
globalRename: parentImport && parentImport.globalRenameImport,
});
}
}

registerImport(i: RegistredImport): void {
this.registeredImports.push(i);
}

getGlobalImports(): RegistredImport[] {
return this.registeredImports.filter((i) => i.globalRename);
}

stripImports(contents: string): string {
return contents.replace(this.getImportRegex(), '').trim();
}
Expand Down Expand Up @@ -171,4 +207,5 @@ export interface RegistredImport {
file: string;
name: string;
as: string;
globalRename: string;
}
16 changes: 16 additions & 0 deletions lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import { FileAnalyzerImportsResult } from './fileAnalyzer';

export class Utils {
static isRelative(file: string) {
return file.startsWith('.');
}

static isAllImport(parentImport?: FileAnalyzerImportsResult) {
return (
!parentImport ||
(parentImport !== null &&
parentImport.globalRenameImport === null &&
parentImport.namedImports === null)
);
}

static isRenameGlobalImport(parentImport?: FileAnalyzerImportsResult) {
return parentImport && parentImport.globalRenameImport !== null;
}

}
27 changes: 27 additions & 0 deletions test/compiled/GlobalRenamedImports.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pragma solidity ^0.4.11;

contract GlobalRenamed$Ownable {
address public owner;

function Ownable() {
owner = msg.sender;
}

modifier onlyOwner() {
require(msg.sender == owner);
_;
}

function transferOwnership(address newOwner) onlyOwner {
if (newOwner != address(0)) {
owner = newOwner;
}
}

}

contract MyOwned is GlobalRenamed$Ownable {
string public constant name = "My Owned";

function MyOwned() {}
}
9 changes: 9 additions & 0 deletions test/contracts/GlobalRenamedImports.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pragma solidity ^0.4.11;

import * as GlobalRenamed from "./imports/ownable.sol";

contract MyOwned is GlobalRenamed.Ownable {
string public constant name = "My Owned";

function MyOwned() {}
}
4 changes: 4 additions & 0 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ describe('Solidity Merger', () => {
await testFile('RenamedImports');
});

it('should allow basic global renamed imports', async () => {
await testFile('GlobalRenamedImports');
});

it('should not import twice same ', async () => {
await testFile('MultiImports');
});
Expand Down

0 comments on commit 8f43b8e

Please sign in to comment.