Skip to content

Commit

Permalink
Merge pull request #56 from ConsenSys/ast-postprocessing-priority
Browse files Browse the repository at this point in the history
Priority-based AST postprocessing
  • Loading branch information
blitz-1306 authored Aug 25, 2021
2 parents 35d7167 + e895e0a commit 5300261
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 84 deletions.
4 changes: 2 additions & 2 deletions src/ast/ast_node_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,7 @@ export class ASTNodeFactory {
): T {
const node = this.makeUnfinalized(type, ...args);

this.postprocessor.process(node, this.context);
this.postprocessor.processNode(node, this.context);

return node;
}
Expand All @@ -1101,7 +1101,7 @@ export class ASTNodeFactory {
for (const child of clone.getChildren(true)) {
this.patchIds(child, cache);

postprocessor.process(child, context);
postprocessor.processNode(child, context);
}

return clone;
Expand Down
46 changes: 27 additions & 19 deletions src/ast/ast_reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ASTNode, ASTNodeConstructor } from "./ast_node";
import { SourceUnit } from "./implementation/meta/source_unit";
import { LegacyConfiguration } from "./legacy";
import { ModernConfiguration } from "./modern";
import { DefaultPostprocessorMapping } from "./postprocessing/mapping";
import { DefaultNodePostprocessorList } from "./postprocessing";
import { sequence } from "./utils";

export interface ASTNodeProcessor<T extends ASTNode> {
Expand All @@ -13,6 +13,11 @@ export interface ASTNodeProcessor<T extends ASTNode> {
): ConstructorParameters<ASTNodeConstructor<T>>;
}

export interface ASTNodePostprocessor<T extends ASTNode> {
process(node: T, context: ASTContext, sources?: Map<string, string>): void;
isSupportedNode(node: ASTNode): node is T;
}

export interface ASTReadingRule {
constructor: ASTNodeConstructor<ASTNode>;
processor: ASTNodeProcessor<ASTNode>;
Expand Down Expand Up @@ -115,28 +120,36 @@ export class ASTContext {
}
}

export interface ASTNodePostprocessor {
process(node: ASTNode, context: ASTContext, sources?: Map<string, string>): void;
}

export class ASTPostprocessor {
mapping: Map<ASTNodeConstructor<ASTNode>, ASTNodePostprocessor[]>;
nodePostprocessors: Array<ASTNodePostprocessor<ASTNode>>;

constructor(mapping = DefaultPostprocessorMapping) {
this.mapping = mapping;
constructor(nodePostProcessors = DefaultNodePostprocessorList) {
this.nodePostprocessors = nodePostProcessors;
}

process(node: ASTNode, context: ASTContext, sources?: Map<string, string>): void {
const postprocessors = this.mapping.get(node.constructor as ASTNodeConstructor<ASTNode>);
getPostprocessorsForNode(node: ASTNode): Array<ASTNodePostprocessor<ASTNode>> {
return this.nodePostprocessors.filter((postprocessor) =>
postprocessor.isSupportedNode(node)
);
}

if (postprocessors === undefined) {
return;
}
processNode(node: ASTNode, context: ASTContext, sources?: Map<string, string>): void {
const postprocessors = this.getPostprocessorsForNode(node);

for (const postprocessor of postprocessors) {
postprocessor.process(node, context, sources);
}
}

processContext(context: ASTContext, sources?: Map<string, string>): void {
for (const postprocessor of this.nodePostprocessors) {
for (const node of context.nodes) {
if (postprocessor.isSupportedNode(node)) {
postprocessor.process(node, context, sources);
}
}
}
}
}

export enum ASTKind {
Expand Down Expand Up @@ -209,12 +222,7 @@ export class ASTReader {
result.push(sourceUnit);
}

const context = this.context;
const postprocessor = this.postprocessor;

for (const node of context.nodes) {
postprocessor.process(node, context, sources);
}
this.postprocessor.processContext(this.context, sources);

return result;
}
Expand Down
12 changes: 12 additions & 0 deletions src/ast/implementation/declaration/enum_definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,16 @@ export class EnumDefinition extends ASTNodeWithChildren<EnumValue> {
get vScope(): ContractDefinition | SourceUnit {
return this.parent as ContractDefinition | SourceUnit;
}

toUintTypeString(): string {
const length = this.children.length;

for (let n = 8; n <= 32; n += 8) {
if (length < 2 ** n) {
return "uint" + n;
}
}

throw new Error("Unable to detect enum type size - member count exceeds 2 ** 32");
}
}
12 changes: 1 addition & 11 deletions src/ast/implementation/declaration/variable_declaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,17 +184,7 @@ export class VariableDeclaration extends ASTNode {
}

if (declaration instanceof EnumDefinition) {
const length = declaration.children.length;

for (let n = 8; n <= 32; n += 8) {
if (length < 2 ** n) {
return "uint" + n;
}
}

throw new Error(
"Unable to detect enum type size - member count exceeds 2 ** 32"
);
return declaration.toUintTypeString();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@ import { UserDefinedTypeName } from "../implementation/type/user_defined_type_na

type SupportedNode = Identifier | MemberAccess | IdentifierPath | UserDefinedTypeName;

export class BuiltinReferencedDeclarationNormalizer implements ASTNodePostprocessor {
process(node: ASTNode, context: ASTContext): void {
if (!this.isSupportedNode(node)) {
throw new Error(`Supplied node "${node.constructor.name}" is not supported`);
}

export class BuiltinReferencedDeclarationNormalizer implements ASTNodePostprocessor<SupportedNode> {
process(node: SupportedNode, context: ASTContext): void {
if (
node.referencedDeclaration >= 0 &&
context.locate(node.referencedDeclaration) === undefined
Expand All @@ -21,7 +17,7 @@ export class BuiltinReferencedDeclarationNormalizer implements ASTNodePostproces
}
}

private isSupportedNode(node: ASTNode): node is SupportedNode {
isSupportedNode(node: ASTNode): node is SupportedNode {
return (
node instanceof Identifier ||
node instanceof MemberAccess ||
Expand Down
2 changes: 1 addition & 1 deletion src/ast/postprocessing/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from "./mapping";
export * from "./builtin_referenced_declaration_normalizer";
export * from "./list";
export * from "./structured_documentation_reconstruction";
12 changes: 12 additions & 0 deletions src/ast/postprocessing/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ASTNode } from "../ast_node";
import { ASTNodePostprocessor } from "../ast_reader";
import { BuiltinReferencedDeclarationNormalizer } from "./builtin_referenced_declaration_normalizer";
import { StructuredDocumentationReconstructingPostprocessor } from "./structured_documentation_reconstruction";

/**
* Note that order here really matters
*/
export const DefaultNodePostprocessorList: Array<ASTNodePostprocessor<ASTNode>> = [
new BuiltinReferencedDeclarationNormalizer(),
new StructuredDocumentationReconstructingPostprocessor()
];
32 changes: 0 additions & 32 deletions src/ast/postprocessing/mapping.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,12 @@ type SupportedNode =
| EventDefinition
| ModifierDefinition;

export class StructuredDocumentationReconstructingPostprocessor implements ASTNodePostprocessor {
export class StructuredDocumentationReconstructingPostprocessor
implements ASTNodePostprocessor<SupportedNode>
{
private reconstructor = new StructuredDocumentationReconstructor();

process(node: ASTNode, context: ASTContext, sources?: Map<string, string>): void {
if (!this.isSupportedNode(node)) {
return;
}

process(node: SupportedNode, context: ASTContext, sources?: Map<string, string>): void {
if (node.documentation instanceof StructuredDocumentation || sources === undefined) {
return;
}
Expand All @@ -160,7 +158,7 @@ export class StructuredDocumentationReconstructingPostprocessor implements ASTNo
structDocNode.parent = node;
}

private isSupportedNode(node: ASTNode): node is SupportedNode {
isSupportedNode(node: ASTNode): node is SupportedNode {
return (
node instanceof FunctionDefinition ||
node instanceof ContractDefinition ||
Expand Down
7 changes: 2 additions & 5 deletions src/ast/writing/ast_mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,7 @@ class SourceUnitWriter extends ASTNodeWriter {
result.push(...flatten(node.vImportDirectives.map(writeLineFn)), wrap);
}

const typeDefs = node.vEnums.concat(node.vStructs);
const typeDefs = [...node.vEnums, ...node.vStructs];

if (typeDefs.length > 0) {
result.push(...flatJoin(typeDefs.map(writeLineFn), wrap), wrap);
Expand All @@ -1315,10 +1315,7 @@ class SourceUnitWriter extends ASTNodeWriter {
result.push(...flatten(node.vVariables.map((n) => [...writeFn(n), ";", wrap])), wrap);
}

const otherDefs = (node.vErrors as readonly ASTNode[]).concat(
node.vFunctions,
node.vContracts
);
const otherDefs = [...node.vErrors, ...node.vFunctions, ...node.vContracts];

if (otherDefs.length > 0) {
result.push(...flatJoin(otherDefs.map(writeLineFn), wrap));
Expand Down

0 comments on commit 5300261

Please sign in to comment.