UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

80 lines 3.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.normalizedAstToMermaid = normalizedAstToMermaid; exports.normalizedAstToMermaidUrl = normalizedAstToMermaidUrl; const type_1 = require("../../r-bridge/lang-4.x/ast/model/type"); const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call"); const flowr_file_1 = require("../../project/context/flowr-file"); const info_1 = require("./info"); const model_1 = require("../../r-bridge/lang-4.x/ast/model/model"); const mermaid_1 = require("./mermaid"); function identifyMermaidDirection(prefix) { const directionMatch = prefix.match(/flowchart (TD|LR|RL|BT)/); if (directionMatch) { return directionMatch[1]; } return 'TD'; } /** * Serialize the normalized AST to mermaid format */ function normalizedAstToMermaid(ast, { prefix = 'flowchart TD\n', markStyle = info_1.MermaidDefaultMarkStyle, includeOnlyIds, mark } = {}) { let output = prefix; function showNode(n) { if (includeOnlyIds && !includeOnlyIds.has(n.info.id)) { return; } const name = `${n.type} (${n.info.id})\\n${n.lexeme ?? ' '}`; output += ` n${n.info.id}(["${mermaid_1.Mermaid.escape(name)}"])\n`; if (mark?.has(n.info.id)) { output += ` style n${n.info.id} ${markStyle.vertex}\n`; } if (n.info.parent !== undefined && (!includeOnlyIds || includeOnlyIds.has(n.info.parent))) { const context = n.info; const roleSuffix = context.role === "el-c" /* RoleInParent.ExpressionListChild */ || context.role === "call-arg" /* RoleInParent.FunctionCallArgument */ || context.role === "param" /* RoleInParent.FunctionDefinitionParameter */ ? `-${context.index}` : ''; output += ` n${n.info.parent} -->|"${context.role}${roleSuffix}"| n${n.info.id}\n`; } if (n.type === type_1.RType.ExpressionList && n.grouping !== undefined) { output += ` n${n.info.id} -.-|"group-open"| n${n.grouping[0].info.id}\n`; output += ` n${n.info.id} -.-|"group-close"| n${n.grouping[1].info.id}\n`; } } function showAst(ast) { model_1.RNode.visitAst(ast, n => { showNode(n); if (n.type === 'RAccess' && (n.operator !== '[' && n.operator !== '[[')) { for (const k of n.access) { if (k !== r_function_call_1.EmptyArgument) { showNode(k); } } } return false; }); } if (ast.type === type_1.RType.Project) { for (const f of ast.files) { // add a subgraph for each file if (ast.files.length !== 1 || (f.filePath && f.filePath !== flowr_file_1.FlowrFile.INLINE_PATH)) { const direction = identifyMermaidDirection(prefix); output += ` subgraph "File: ${mermaid_1.Mermaid.escape(f.filePath ?? flowr_file_1.FlowrFile.INLINE_PATH)}" direction ${direction}\n`; showAst(f.root); output += ' end\n'; } else { showAst(f.root); } } } else { showAst(ast); } return output; } /** * Use mermaid to visualize the normalized AST. */ function normalizedAstToMermaidUrl(ast, info) { return mermaid_1.Mermaid.codeToUrl(normalizedAstToMermaid(ast, info ?? {})); } //# sourceMappingURL=ast.js.map