Skip to content

Commit

Permalink
Merge pull request #35 from RyuuGan/va/comments
Browse files Browse the repository at this point in the history
Support comments on top Level

relates #19
  • Loading branch information
RyuuGan authored May 17, 2020
2 parents dc7e2a0 + 4155290 commit 8754c6d
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 40 deletions.
77 changes: 72 additions & 5 deletions lib/antlr/visitors/exportVisitor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CharStreams, CommonTokenStream } from 'antlr4ts';
import { CharStreams, CommonTokenStream, Token } from 'antlr4ts';
import { ParseTreeWalker } from 'antlr4ts/tree/ParseTreeWalker';
import { ExportType } from '../../types';
import { SolidityLexer } from '../generated/SolidityLexer';
import { SolidityListener } from '../generated/SolidityListener';
import {
Expand All @@ -10,11 +11,14 @@ import {
SourceUnitContext,
StructDefinitionContext,
} from '../generated/SolidityParser';
import { ExportType, ExportVisitResult, VisitCallback } from './types';
import { ExportVisitResult, VisitCallback } from './types';

const HIDDEN_CHANNEL = 1;

export class SolidityExportVisitor {
#inputContent: string;
#antlrTree: SourceUnitContext;
#comments: Token[] = [];
constructor(inputContent: string) {
this.#inputContent = inputContent;

Expand All @@ -23,11 +27,74 @@ export class SolidityExportVisitor {
const tokens = new CommonTokenStream(lexer);
const parser = new SolidityParser(tokens);
this.#antlrTree = parser.sourceUnit();

this.#comments = tokens
.getRange(0, tokens.size)
.filter((t) => t.channel === HIDDEN_CHANNEL);
}

visit(onVisit: VisitCallback<ExportVisitResult>) {
const listener: SolidityListener = new ExportVisitor(onVisit);
const listener: SolidityListener = new ExportVisitor((visitResult) => {
this.onVisit(visitResult, onVisit);
});
ParseTreeWalker.DEFAULT.walk(listener, this.#antlrTree);
this.flushComments(onVisit);
}

private onVisit(
visitResult: ExportVisitResult,
onVisit: VisitCallback<ExportVisitResult>,
) {
if (!this.#comments.length) {
return onVisit(visitResult);
}
this.emitCommentsBefore(visitResult, onVisit);
onVisit(visitResult);
}

private emitCommentsBefore(
visitResult: ExportVisitResult,
onVisit: VisitCallback<ExportVisitResult>,
) {
while (
this.#comments.length &&
this.#comments[0].startIndex < visitResult.start
) {
const comment = this.#comments.shift();
if (!comment) {
continue;
}
onVisit(this.buildComment(comment));
}
while (
this.#comments.length &&
this.#comments[0].stopIndex < visitResult.end
) {
this.#comments.shift();
}
}

private flushComments(onVisit: VisitCallback<ExportVisitResult>) {
if (!this.#comments.length) {
return;
}

this.#comments.forEach((comment) => onVisit(this.buildComment(comment)));
}

private buildComment(comment: Token): ExportVisitResult {
return {
abstract: false,
body: {
start: comment.startIndex,
end: comment.stopIndex,
},
start: comment.startIndex,
end: comment.stopIndex,
is: null,
name: `Comment#${comment.startIndex}`,
type: ExportType.comment,
};
}
}

Expand Down Expand Up @@ -109,7 +176,7 @@ class ExportVisitor implements SolidityListener {
start,
end,
abstract: false,
type: 'struct',
type: ExportType.struct,
body: {
start: bodyStart + 1,
end,
Expand Down Expand Up @@ -145,7 +212,7 @@ class ExportVisitor implements SolidityListener {
start,
end,
abstract: false,
type: 'enum',
type: ExportType.enum,
body: {
start: bodyStart + 1,
end,
Expand Down
10 changes: 5 additions & 5 deletions lib/antlr/visitors/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ExportType } from '../../types';

export interface RangeVisitResult {
start: number;
end: number;
Expand All @@ -6,21 +8,19 @@ export interface RangeVisitResult {
export interface ImportVisitResult extends RangeVisitResult {
filename: string;
globalRename: string | null;
namedImports: ImportVisitNamedImport[] | null
namedImports: ImportVisitNamedImport[] | null;
}

export interface ImportVisitNamedImport {
name: string;
as: string | null
as: string | null;
}

export type ExportType = 'contract' | 'library' | 'interface' | 'struct' | 'enum';

export interface ExportVisitResult extends RangeVisitResult {
abstract: boolean;
type: ExportType;
name: string;
body: RangeVisitResult,
body: RangeVisitResult;
is: RangeVisitResult | null;
}

Expand Down
8 changes: 5 additions & 3 deletions lib/exportsAnalyzer.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import Debug from 'debug';
import parser from 'solidity-parser-antlr';
import { SolidityExportVisitor } from './antlr/visitors/exportVisitor';
import { ExportType } from './types';

const error = Debug('sol-merger:error');

export interface ExportsAnalyzerResult {
type: 'contract' | 'library' | 'interface' | 'struct' | 'enum';
type: ExportType;
name: string;
is: string;
body: string;
Expand Down Expand Up @@ -33,7 +33,9 @@ export class ExportsAnalyzer {
type: e.type,
name: e.name,
body: this.contents.substring(e.body.start, e.body.end + 1).trim(),
is: e.is ? this.contents.substring(e.is.start, e.is.end + 1).trimLeft() : '',
is: e.is
? this.contents.substring(e.is.start, e.is.end + 1).trimLeft()
: '',
});
});
return results;
Expand Down
7 changes: 6 additions & 1 deletion lib/fileAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import fs from 'fs-extra';
import stripComments from 'strip-json-comments';
import { ExportsAnalyzer, ExportsAnalyzerResult } from './exportsAnalyzer';
import { RegistredImport } from './importRegistry';
import { ImportsAnalyzerResult, ImportsAnalyzer } from './importsAnalyzer';
import { ImportsAnalyzer, ImportsAnalyzerResult } from './importsAnalyzer';
import { ExportType } from './types';

export class FileAnalyzer {
filename: string;
Expand All @@ -16,6 +17,10 @@ export class FileAnalyzer {
newName: string | null,
globalRenames: RegistredImport[],
): string {
if (e.type === ExportType.comment) {
return e.body;
}

let is = e.is;
if (is) {
globalRenames.forEach((i) => {
Expand Down
10 changes: 3 additions & 7 deletions lib/importsAnalyzer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import parser from 'solidity-parser-antlr';
import { Utils } from './utils';
import { SolidityImportVisitor } from './antlr/visitors/importVisitor';
import { ImportVisitResult } from './antlr/visitors/types';
Expand Down Expand Up @@ -38,18 +37,13 @@ export class ImportsAnalyzer {
*/
analyzeImports(): ImportsAnalyzerResult[] {
const imports: ImportsAnalyzerResult[] = [];
const ast = Utils.getAstNode(this.contents);

const importDirectives: ImportVisitResult[] = [];
const visitor = new SolidityImportVisitor(this.contents);
visitor.visit((i) => {
importDirectives.push(i);
});

if (!ast) {
return [];
}

for (const importDirective of importDirectives) {
const analyzedImport = this.analyzeImport(importDirective);
imports.push(analyzedImport);
Expand All @@ -65,7 +59,9 @@ export class ImportsAnalyzer {
* 3. Extract filename from import
*
*/
private analyzeImport(importVisitResult: ImportVisitResult): ImportsAnalyzerResult {
private analyzeImport(
importVisitResult: ImportVisitResult,
): ImportsAnalyzerResult {
return {
file: importVisitResult.filename,
globalRenameImport: importVisitResult.globalRename,
Expand Down
13 changes: 12 additions & 1 deletion lib/merger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ExportsAnalyzerResult } from './exportsAnalyzer';
import { FileAnalyzer, FileAnalyzerResult } from './fileAnalyzer';
import { ImportsRegistry } from './importRegistry';
import { ImportsAnalyzer, ImportsAnalyzerResult } from './importsAnalyzer';
import { ExportType } from './types';
import { Utils } from './utils';

const error = Debug('sol-merger:error');
Expand Down Expand Up @@ -64,7 +65,11 @@ export class Merger {
await this.init(file);
}
if (this.importRegistry.isImportProcessed(parentImport?.importStatement)) {
debug(' %s Import statement already processed: %s', '⚠', parentImport?.importStatement);
debug(
' %s Import statement already processed: %s',
'⚠',
parentImport?.importStatement,
);
return '';
}
if (parentImport) {
Expand Down Expand Up @@ -150,6 +155,12 @@ export class Merger {
);

const shouldBeImported = (exportName: string) => {
if (
e.type === ExportType.comment &&
(isAllImport || isRenameGlobalImport)
) {
return true;
}
return (
isAllImport ||
isRenameGlobalImport ||
Expand Down
8 changes: 8 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export enum ExportType {
contract = 'contract',
library = 'library',
interface = 'interface',
struct = 'struct',
enum = 'enum',
comment = 'comment'
}
10 changes: 0 additions & 10 deletions lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import parser, { ASTNode } from 'solidity-parser-antlr';

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

static getAstNode(contents: string): ASTNode | null {
try {
return parser.parse(contents, { loc: true, range: true });
} catch {
return null;
}
}
}
5 changes: 0 additions & 5 deletions package-lock.json

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

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"debug": "^4.1.1",
"fs-extra": "^8.0.1",
"glob": "^7.1.2",
"solidity-parser-antlr": "^0.4.11",
"strip-json-comments": "^3.0.1"
},
"pre-commit": [
Expand Down
2 changes: 2 additions & 0 deletions test/compiled/ContactWithKeywordsInsideString.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ contract ConflictingInheritance {

}

// This contract will not be detected

contract B {
uint private b;

Expand Down
21 changes: 21 additions & 0 deletions test/compiled/GlobalComments.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
pragma solidity 0.6.0;


/*
* Multiline Comment Before
*/

// This is not included Before

contract MyContract {
// This is included
function myFunction() {
// This is included
}
}

// This is not included After

/*
* Multiline Comment After
*/
2 changes: 1 addition & 1 deletion test/contracts/Enum.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pragma solidity ^0.4.0;

enum State1 { Created1, Locked1, Inactive1 } // Enum
enum State1 { Created1, Locked1, Inactive1 }

contract Purchase {
enum State { Created, Locked, Inactive } // Enum
Expand Down
16 changes: 16 additions & 0 deletions test/contracts/GlobalComments.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pragma solidity 0.6.0;

/*
* Multiline Comment Before
*/
// This is not included Before
contract MyContract {
// This is included
function myFunction() {
// This is included
}
}
// This is not included After
/*
* Multiline Comment After
*/
Loading

0 comments on commit 8754c6d

Please sign in to comment.