UNPKG

solidity-antlr4

Version:

Solidity Lang Lexer and Parser by official ANTLR4 grammar

195 lines (194 loc) 6.49 kB
import { BasePrinter } from "./base.js"; export class PrinterDeclaration extends BasePrinter { printContractDefinition = ({ node, print, path }) => { const groupId = Symbol(node.type); const parts = []; if (node.abstract && node.contractKind === "contract") { parts.push("abstract", this.space, node.contractKind); } else { parts.push(node.contractKind); } parts.push(this.space, path.call(print, "name")); if (node.baseContracts.length) { const bases = [ this.builders.line, "is", this.space, this.builders.fill(this.paramater(path.map(print, "baseContracts"))) ]; parts.push(this.builders.indentIfBreak(bases, { groupId })); } const nodes = path.map((p) => [print(p), this.pangu(p)], "nodes"); return [ this.builders.group(parts, { id: groupId }), this.builders.ifBreak(this.builders.line, this.space, { groupId }), this.block( [this.builders.breakParent, this.builders.join(this.builders.hardline, nodes)], !node.nodes.length ) ]; }; printEnumDefinition = ({ print, path }) => { const enumMember = [this.builders.breakParent, this.paramater(path.map(print, "members"))]; return ["enum", this.space, path.call(print, "name"), this.space, this.block(enumMember)]; }; printErrorDefinition = ({ path, print }) => { return [ "error", this.space, path.call(print, "name"), this.tuple(this.paramater(path.map(print, "parameters"))), this.semi ]; }; printEventDefinition = ({ path, print }) => { return [ "event", this.space, path.call(print, "name"), this.tuple(this.paramater(path.map(print, "parameters"))), this.semi ]; }; printFunctionDefinition = ({ node, path, print }) => { const groupId = Symbol(node.type); const functionMeta = []; switch (node.functionKind) { case "constructor": case "fallback": case "receive": functionMeta.push(node.functionKind); break; case "function": default: functionMeta.push("function", this.space, path.call(print, "name")); break; } const parameters = node.parameters?.length ? path.map(print, "parameters") : []; const parameterSeparator = this.builders.ifBreak( [this.comma, this.builders.hardline], [this.comma, this.builders.line], { groupId } ); functionMeta.push(this.tuple(this.paramater(parameters, parameterSeparator), groupId)); const functionInfo = []; if (node.visibility !== null) functionInfo.push(node.visibility); if (node.stateMutability !== null) functionInfo.push(node.stateMutability); if (node.modifiers !== null && node.modifiers.length) { path.map((modifierPath) => functionInfo.push(print(modifierPath)), "modifiers"); } if (node.virtual === true) functionInfo.push("virtual"); if (node.override !== null) { functionInfo.push( node.override.length ? ["override", this.tuple(this.paramater(path.map(print, "override")))] : "override" ); } if (node.returnParameters !== null) { functionInfo.push( this.builders.group( ["returns", this.space, this.tuple(this.paramater(path.map(print, "returnParameters")))], { shouldBreak: false } ) ); } const line = this.builders.indentIfBreak(this.builders.line, { groupId }); const functionInfoGroup = this.builders.group(this.builders.join(line, functionInfo), { id: groupId }); const parts = [ this.builders.group( functionInfo.length ? [functionMeta, this.space, functionInfoGroup] : [functionMeta], { id: groupId } ) ]; if (node.body !== null) { parts.push(this.space, path.call(print, "body")); } else { parts.push(this.semi); } return parts; }; printModifierDefinition = ({ path, print }) => { return [ "modifier", this.space, path.call(print, "name"), this.tuple(this.paramater(path.map(print, "parameters"))), this.space, path.call(print, "body") ]; }; // printStateMutability: PrintFunc<ast.StateMutability> = ({ node }) => node.name || ''; printStructDefinition = ({ node, path, print }) => { const structMember = []; if (node.members.length) { const content = this.builders.join(this.builders.line, path.map(print, "members")); structMember.push(this.builders.breakParent, content); } return [ "struct", this.space, path.call(print, "name"), this.space, this.block(structMember, !structMember.length) ]; }; printStructMember = ({ path, print }) => { return [path.call(print, "typeName"), this.space, path.call(print, "name"), this.semi]; }; printUserDefinedValueTypeDefinition = ({ path, print }) => { const content = this.builders.join(this.space, [ "type", path.call(print, "name"), "is", path.call(print, "typeName") ]); return [content, this.semi]; }; printVariableDeclaration = ({ node, path, print }) => { const parts = [path.call(print, "typeName")]; if (node.dataLocation !== null) parts.push(this.space, path.call(print, "dataLocation")); if (node.public) parts.push(this.space, "public"); if (node.private) parts.push(this.space, "private"); if (node.internal) parts.push(this.space, "internal"); if (node.constant) parts.push(this.space, "constant"); if (node.indexed) parts.push(this.space, "indexed"); if (node.immutable) parts.push(this.space, "immutable"); if (node.override !== null) { parts.push(this.space, "override"); if (node.override.length) parts.push(this.tuple(this.paramater(path.map(print, "override")))); } if (node.name !== null) parts.push(this.space, path.call(print, "name")); if (node.expression !== null) { parts.push( this.space, "=", this.builders.ifBreak(this.builders.indent(this.builders.line), this.space), path.call(print, "expression") ); } if (!node.parameter) parts.push(this.semi); return this.builders.group(parts); }; // printVisibility: PrintFunc<ast.Visibility> = ({ node }) => node.name || ''; // TODO: Implement for type printFunctionTypeName = this.printFunctionDefinition; }