From 5e29b1a79d734c3ff613f486b76d9e62544ce4c2 Mon Sep 17 00:00:00 2001 From: Florian Sihler Date: Thu, 30 Apr 2026 08:45:02 +0200 Subject: [PATCH 01/10] refactor(wip): first ggplot2 cutthrough --- .../call/built-in/built-in-library.ts | 29 +++++++++-- .../main/libraries/link-libraries.test.ts | 49 +++++++++++++++++++ 2 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 test/functionality/dataflow/main/libraries/link-libraries.test.ts diff --git a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts index 1d7f826078a..a15858854a4 100644 --- a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts +++ b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts @@ -4,14 +4,16 @@ import { processKnownFunctionCall } from '../known-call-handling'; import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate'; import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call'; import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol'; -import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id'; +import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id'; import { dataflowLogger } from '../../../../../logger'; import { unpackNonameArg } from '../argument/unpack-argument'; import type { RString } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-string'; import { RType } from '../../../../../../r-bridge/lang-4.x/ast/model/type'; import { wrapArgumentsUnnamed } from '../argument/make-argument'; -import { Identifier } from '../../../../../environments/identifier'; +import { Identifier, ReferenceType } from '../../../../../environments/identifier'; import { BuiltInProcName } from '../../../../../environments/built-in-proc-name'; +import { Environment } from '../../../../../environments/environment'; +import { EdgeType } from '../../../../../graph/edge'; /** * Process a library call like `library` or `require` @@ -28,6 +30,7 @@ export function processLibrary( return processKnownFunctionCall({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information; } const nameToLoad = unpackNonameArg(args[0]); + if(nameToLoad === undefined || nameToLoad.type !== RType.Symbol) { dataflowLogger.warn('No library name provided, skipping'); return processKnownFunctionCall({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information; @@ -47,9 +50,29 @@ export function processLibrary( str: Identifier.getName(nameToLoad.content) } }; - return processKnownFunctionCall({ + const info = processKnownFunctionCall({ name, args: wrapArgumentsUnnamed([newArg], data.completeAst.idMap), rootId, data, hasUnknownSideEffect: true, origin: BuiltInProcName.Library }).information; + + + // console.log(nameToLoad?.lexeme);g + // console.log(data.ctx.deps.getDependency(nameToLoad?.lexeme ?? '')) + const oldParent = info.environment.current.parent; + let ggplotEnv = new Environment(oldParent); + ggplotEnv.n = nameToLoad?.lexeme; + ggplotEnv = ggplotEnv.define({ + name: Identifier.make('ggplot', 'ggplot2'), + type: ReferenceType.Function, + nodeId: NodeId.toBuiltIn('ggplot'), + definedAt: NodeId.toBuiltIn('ggplot2'), + }); + info.environment.current.parent = ggplotEnv; + info.environment = { + level: info.environment.level + 1, + current: info.environment.current + }; + info.graph.addEdge(NodeId.toBuiltIn('ggplot'), rootId, EdgeType.Reads); + return info; } diff --git a/test/functionality/dataflow/main/libraries/link-libraries.test.ts b/test/functionality/dataflow/main/libraries/link-libraries.test.ts new file mode 100644 index 00000000000..595bd96a270 --- /dev/null +++ b/test/functionality/dataflow/main/libraries/link-libraries.test.ts @@ -0,0 +1,49 @@ +import { describe, test } from 'vitest'; +import { withTreeSitter } from '../../../_helper/shell'; +import { FlowrAnalyzerBuilder } from '../../../../../src/project/flowr-analyzer-builder'; +import { Package } from '../../../../../src/project/plugins/package-version-plugins/package'; +import { FlowrNamespaceFile } from '../../../../../src/project/plugins/file-plugins/files/flowr-namespace-file'; +import { FlowrInlineTextFile } from '../../../../../src/project/context/flowr-file'; +import { Dataflow } from '../../../../../src/dataflow/graph/df-helper'; + +describe('Link libraries', withTreeSitter(ts => { + test('foo', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.addRequest('library(ggplot2)\nggplot()'); + const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)); + }); +})); \ No newline at end of file From be6409f444bf7049275a5643cc5abb758817f5e9 Mon Sep 17 00:00:00 2001 From: Naomi Panda Date: Mon, 4 May 2026 23:01:46 +0200 Subject: [PATCH 02/10] feat: dynamically links read dependencies --- README.md | 21 ++-- .../call/built-in/built-in-library.ts | 58 ++++++++-- .../main/libraries/link-libraries.test.ts | 109 +++++++++++++++++- wiki/Capabilities.md | 10 +- wiki/Core.md | 20 ++-- wiki/Interface.md | 57 ++++----- 6 files changed, 214 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 2e02339d12e..b6ad0e54a54 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ It offers a wide variety of features, for example: ╰ Absolute Paths (absolute-file-paths): ╰ certain: ╰ Path `/root/x.txt` at 1.1-23 - ╰ Metadata: totalConsidered: 1, totalUnknown: 0, searchTimeMs: 1, processTimeMs: 0 + ╰ Metadata: totalConsidered: 1, totalUnknown: 0, searchTimeMs: 0, processTimeMs: 0 ╰ Unused Definitions (unused-definitions): ╰ Metadata: totalConsidered: 0, searchTimeMs: 0, processTimeMs: 0 ╰ Naming Convention (naming-convention): @@ -53,7 +53,7 @@ It offers a wide variety of features, for example: ╰ Network Functions (network-functions): ╰ Metadata: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0 ╰ Dataframe Access Validation (dataframe-access-validation): - ╰ Metadata: numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 0 + ╰ Metadata: numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 1 ╰ Dead Code (dead-code): ╰ Metadata: consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0 ╰ Useless Loops (useless-loop): @@ -61,10 +61,10 @@ It offers a wide variety of features, for example: ╰ Problematic inputs (problematic-inputs): ╰ Metadata: searchTimeMs: 0, processTimeMs: 0 ╰ Stop without call.=False argument (stop-call): - ╰ Metadata: consideredNodes: 0, searchTimeMs: 1, processTimeMs: 0 + ╰ Metadata: consideredNodes: 0, searchTimeMs: 0, processTimeMs: 0 ╰ Roxygen Arguments (roxygen-arguments): ╰ Metadata: searchTimeMs: 0, processTimeMs: 0 - All queries together required ≈2 ms (1ms accuracy, total 3 ms) + All queries together required ≈2 ms (1ms accuracy, total 2 ms) ``` @@ -86,9 +86,9 @@ It offers a wide variety of features, for example: _Results (prettified and summarized):_ - Query: **linter** (2 ms)\ + Query: **linter** (1 ms)\    ╰ **Deprecated Functions** (deprecated-functions):\ -        ╰ _Metadata_: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 1, processTimeMs: 0\ +        ╰ _Metadata_: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0\    ╰ **File Path Validity** (file-path-validity):\        ╰ certain:\            ╰ Path `/root/x.txt` at 1.1-23\ @@ -121,7 +121,7 @@ It offers a wide variety of features, for example:
Show Detailed Results as Json - The analysis required _2.4 ms_ (including parsing and normalization and the query) within the generation environment. + The analysis required _2.0 ms_ (including parsing and normalization and the query) within the generation environment. In general, the JSON contains the Ids of the nodes in question as they are present in the normalized AST or the dataflow graph of flowR. Please consult the [Interface](https://github.com/flowr-analysis/flowr/wiki/Interface) wiki page for more information on how to get those. @@ -138,7 +138,7 @@ It offers a wide variety of features, for example: ".meta": { "totalCalls": 0, "totalFunctionDefinitions": 0, - "searchTimeMs": 1, + "searchTimeMs": 0, "processTimeMs": 0 } }, @@ -273,7 +273,7 @@ It offers a wide variety of features, for example: } }, ".meta": { - "timing": 2 + "timing": 1 } }, ".meta": { @@ -436,6 +436,7 @@ It offers a wide variety of features, for example: ```text https://mermaid.live/view#base64:eyJjb2RlIjoiZmxvd2NoYXJ0IEJUXG4gICAgMChbXCJgIzkxO1JTeW1ib2wjOTM7IHRlc3RcbiAgICAgICgwKVxuICAgICAgKjEuMS00KmBcIl0pXG4gICAlJSBObyBlZGdlcyBmb3VuZCBmb3IgMFxuICAgIDEoW1wiYCM5MTtSU3ltYm9sIzkzOyB0ZXN0ZmlsZXNcbiAgICAgICgxKVxuICAgICAgKjEuNi0xNCpgXCJdKVxuICAgJSUgTm8gZWRnZXMgZm91bmQgZm9yIDFcbiAgICAyW1tcImAjOTE7UkJpbmFyeU9wIzkzOyAvXG4gICAgICAoMilcbiAgICAgICoxLjEtMTQqXG4gICAgKDAsIDEpYFwiXV1cbiAgICBidWlsdC1pbjpfW1wiYEJ1aWx0LUluOlxuL2BcIl1cbiAgICBzdHlsZSBidWlsdC1pbjpfIHN0cm9rZTpncmF5LGZpbGw6Z3JheSxzdHJva2Utd2lkdGg6MnB4LG9wYWNpdHk6Ljg7XG4gICAgMyhbXCJgIzkxO1JTeW1ib2wjOTM7IGV4YW1wbGUuUlxuICAgICAgKDMpXG4gICAgICAqMS4xNi0yNCpgXCJdKVxuICAgJSUgTm8gZWRnZXMgZm91bmQgZm9yIDNcbiAgICA0W1tcImAjOTE7UkJpbmFyeU9wIzkzOyAvXG4gICAgICAoNClcbiAgICAgICoxLjEtMjQqXG4gICAgKDIsIDMpYFwiXV1cbiAgICAyIC0tPnxcInJlYWRzLCBhcmd1bWVudFwifCAwXG4gICAgMiAtLT58XCJyZWFkcywgYXJndW1lbnRcInwgMVxuICAgIDIgLS4tPnxcInJlYWRzLCBjYWxsc1wifCBidWlsdC1pbjpfXG4gICAgbGlua1N0eWxlIDIgc3Ryb2tlOmdyYXk7XG4gICAgNCAtLT58XCJyZWFkcywgYXJndW1lbnRcInwgMlxuICAgIDQgLS0+fFwicmVhZHMsIGFyZ3VtZW50XCJ8IDNcbiAgICA0IC0uLT58XCJyZWFkcywgY2FsbHNcInwgYnVpbHQtaW46X1xuICAgIGxpbmtTdHlsZSA1IHN0cm9rZTpncmF5OyIsIm1lcm1haWQiOnsiYXV0b1N5bmMiOnRydWV9fQ== + Copied mermaid url to clipboard (dataflow: 0ms). ``` @@ -734,7 +735,7 @@ It offers a wide variety of features, for example: ``` - (The analysis required _1.8 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) + (The analysis required _1.6 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) diff --git a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts index a15858854a4..7ec19f5e5cc 100644 --- a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts +++ b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts @@ -14,6 +14,7 @@ import { Identifier, ReferenceType } from '../../../../../environments/identifie import { BuiltInProcName } from '../../../../../environments/built-in-proc-name'; import { Environment } from '../../../../../environments/environment'; import { EdgeType } from '../../../../../graph/edge'; +import { isUndefined } from '../../../../../../util/assert'; /** * Process a library call like `library` or `require` @@ -56,23 +57,66 @@ export function processLibrary( origin: BuiltInProcName.Library }).information; + const dependency = data.ctx.deps.getDependency(nameToLoad.lexeme); + /*if(dependency && dependency.name === 'ggplot2'){ + if(dependency.namespaceInfo?.exportedSymbols.find(v => v === 'ggplot')){ + linkLibraryGlob('ggplot', dependency.name, info, rootId); + } + }*/ + if(dependency){ + dependency.namespaceInfo?.exportedSymbols.forEach(v => linkLibraryGlob(v, dependency.name, info, rootId)); + } + return info; +} +function linkLibraryGlob(func: string, pack: string, info: DataflowInformation, rootId: NodeId): void{ + const globalEnv = getGlobalEnv(info); + if(isUndefined(globalEnv)){ + return; + } + const oldGlobParent = globalEnv.parent; + let ggplotEnv = new Environment(oldGlobParent); + ggplotEnv.n = pack; + ggplotEnv = ggplotEnv.define({ + name: Identifier.make(func, pack), + type: ReferenceType.Function, + nodeId: NodeId.toBuiltIn(func), + definedAt: NodeId.toBuiltIn(pack), + }); + globalEnv.parent = ggplotEnv; + info.environment = { + level: info.environment.level + 1, + current: info.environment.current + }; + info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); +} + +function getGlobalEnv(info: DataflowInformation){ + if(info.environment.level < 0){ + return undefined; + } + let env = info.environment.current; + for(let i = 0; i < info.environment.level; i++){ + env = env.parent; + } + return env; +} +/*function linkLibrary(func: string, pack: string, info: DataflowInformation, rootId: NodeId): void{ // console.log(nameToLoad?.lexeme);g // console.log(data.ctx.deps.getDependency(nameToLoad?.lexeme ?? '')) const oldParent = info.environment.current.parent; let ggplotEnv = new Environment(oldParent); - ggplotEnv.n = nameToLoad?.lexeme; + ggplotEnv.n = pack; ggplotEnv = ggplotEnv.define({ - name: Identifier.make('ggplot', 'ggplot2'), + name: Identifier.make(func, pack), type: ReferenceType.Function, - nodeId: NodeId.toBuiltIn('ggplot'), - definedAt: NodeId.toBuiltIn('ggplot2'), + nodeId: NodeId.toBuiltIn(func), + definedAt: NodeId.toBuiltIn(pack), }); info.environment.current.parent = ggplotEnv; info.environment = { level: info.environment.level + 1, current: info.environment.current }; - info.graph.addEdge(NodeId.toBuiltIn('ggplot'), rootId, EdgeType.Reads); - return info; -} + info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads); +}*/ diff --git a/test/functionality/dataflow/main/libraries/link-libraries.test.ts b/test/functionality/dataflow/main/libraries/link-libraries.test.ts index 595bd96a270..420d1c53c5f 100644 --- a/test/functionality/dataflow/main/libraries/link-libraries.test.ts +++ b/test/functionality/dataflow/main/libraries/link-libraries.test.ts @@ -1,13 +1,23 @@ -import { describe, test } from 'vitest'; +import { describe, expect, test } from 'vitest'; import { withTreeSitter } from '../../../_helper/shell'; import { FlowrAnalyzerBuilder } from '../../../../../src/project/flowr-analyzer-builder'; import { Package } from '../../../../../src/project/plugins/package-version-plugins/package'; import { FlowrNamespaceFile } from '../../../../../src/project/plugins/file-plugins/files/flowr-namespace-file'; import { FlowrInlineTextFile } from '../../../../../src/project/context/flowr-file'; import { Dataflow } from '../../../../../src/dataflow/graph/df-helper'; +import { EdgeType } from '../../../../../src/dataflow/graph/edge'; describe('Link libraries', withTreeSitter(ts => { - test('foo', async() => { + test('No dependencies set', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.addRequest('library(ggplot2)\nggplot()'); + const df = await analyzer.dataflow(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)).toBeUndefined(); + expect(df.graph.outgoingEdges(5)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + }); + test('ggplot links to ggplot2', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -42,8 +52,101 @@ import(rlang) importFrom(scales,alpha) importFrom(stats,setNames)`)).content().current })); - analyzer.addRequest('library(ggplot2)\nggplot()'); + analyzer.addRequest('library(ggplot2)\nggplot()\nggplot()'); + const df = await analyzer.dataflow(); + expect(df.graph.outgoingEdges(5)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges(7)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + }); + test('Several methods of same library', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.addRequest('library(ggplot2)\nggplot(data = NULL, mapping = aes())'); + const df = await analyzer.dataflow(); + expect(df.graph.outgoingEdges(12)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)?.types === EdgeType.Calls + EdgeType.Reads).toBeTruthy(); + expect(df.graph.outgoingEdges(10)?.get('built-in:aes')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:aes')?.get(3)?.types === EdgeType.Calls + EdgeType.Reads).toBeTruthy(); + }); + test('Links to several libraries', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'dplyr', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(across)')).content().current + })); + analyzer.addRequest('library(ggplot2)\nlibrary(dplyr)\nggplot(data = NULL, mapping = aes())\nacross()'); const df = await analyzer.dataflow(); console.log(Dataflow.visualize.mermaid.url(df.graph)); + expect(df.graph.outgoingEdges(16)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges(3)?.get(1)?.types === EdgeType.Argument).toBeTruthy(); + expect(df.graph.outgoingEdges(18)?.get('built-in:across')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:across')?.get(7)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges(7)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); }); })); \ No newline at end of file diff --git a/wiki/Capabilities.md b/wiki/Capabilities.md index 7bf1f7f39bf..c1d3d9508a5 100644 --- a/wiki/Capabilities.md +++ b/wiki/Capabilities.md @@ -1,4 +1,4 @@ -_This document was generated from '[src/documentation/doc-capabilities.ts](https://github.com/flowr-analysis/flowr/tree/main//src/documentation/doc-capabilities.ts)' on 2026-04-08, 21:01:33 UTC presenting an overview of flowR's flowR capabilities overview (v2.10.3, using R v4.5.3). Please do not edit this file/wiki page directly._ +_This document was generated from '[src/documentation/doc-capabilities.ts](https://github.com/flowr-analysis/flowr/tree/main//src/documentation/doc-capabilities.ts)' on 2026-05-04, 20:59:38 UTC presenting an overview of flowR's flowR capabilities overview (v2.10.4, using R v4.5.2). Please do not edit this file/wiki page directly._ Each capability has an id that can be used to link to it (use the link symbol to get a direct link to the capability). The internal id is also mentioned in the capability description. This id can be used to reference the capability in a labeled test within flowR. @@ -138,7 +138,7 @@ Besides, we use colored bullets like this: > > R Code of the (simplified) Dataflow Graph > - > The analysis required _0.9 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment. + > The analysis required _1.3 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment. > We encountered unknown side effects (with ids: 23 (linked)) during the analysis. > > @@ -450,7 +450,7 @@ See [flowr#633](https://github.com/flowr-analysis/flowr/issues/633) for more inf 1. **Non-Strict Logical Operators** 🔗 (29 tests, desugar: 20, dataflow: 9)\ 🟩 _Handle `&&`, `||`, ..._ (internal ID: `non-strict-logical-operators`) - 2. **Pipe and Pipe-Bind** 🔗 (18 tests, dataflow: 14, slice: 2, desugar: 2)\ + 2. **Pipe and Pipe-Bind** 🔗\ 🔶 _Handle the [new (4.1) pipe and pipe-bind syntax](https://www.r-bloggers.com/2021/05/the-new-r-pipe/): `|>`, and `=>`._; Similarly support the other pipe binds (internal ID: `pipe-and-pipe-bind`) 3. **Sequencing** 🔗 (1 test, slice: 1)\ 🔴 _Handle `:`, `seq`, ... by gathering value information using abstract interpretation._ (internal ID: `built-in-sequencing`) @@ -460,7 +460,7 @@ See [flowr#633](https://github.com/flowr-analysis/flowr/issues/633) for more inf 🔴 _Handle `options`, `getOption`, ..._ Currently, we do not support the function at all. (internal ID: `built-in-options`) 6. **Help** 🔗 (3 tests, desugar: 2, dataflow: 1)\ 🔶 _Handle `help`, `?`, ..._ We do not support the function in a sensible way but just ignore it (although this does not happen resolved). (internal ID: `built-in-help`) - 7. **Reflection / "Computing on the Language"** 🔗 (10 tests, dataflow: 10)\ + 7. **Reflection / "Computing on the Language"** 🔗\ (internal ID: `reflection-"computing-on-the-language"`) @@ -471,7 +471,7 @@ See [flowr#633](https://github.com/flowr-analysis/flowr/issues/633) for more inf 🔴 _Handle `body`, `formals`, `environment` to access the respective parts of a function._ We do not support the functions at all. (internal ID: `get-function-structure`) 2. **Modify Function Structure** 🔗\ 🔴 _Handle `body<-`, `formals<-`, `environment<-` to modify the respective parts of a function._ We do not support the functions at all. (internal ID: `modify-function-structure`) - 3. **Quoting** 🔗 (3 tests, dataflow: 2, slice: 1)\ + 3. **Quoting** 🔗 (1 test, slice: 1)\ 🔶 _Handle `quote`, `substitute`, `bquote`, ..._ We partially ignore some of them but most likely not all. (internal ID: `built-in-quoting`) 4. **Evaluation** 🔗 (6 tests, slice: 6)\ 🔶 _Handle `eval`, `evalq`, `eval.parent`, ..._ We do not handle them at all. (internal ID: `built-in-evaluation`) diff --git a/wiki/Core.md b/wiki/Core.md index 082a25467ad..8afdde48495 100644 --- a/wiki/Core.md +++ b/wiki/Core.md @@ -1,4 +1,4 @@ -_This document was generated from '[src/documentation/wiki-core.ts](https://github.com/flowr-analysis/flowr/tree/main//src/documentation/wiki-core.ts)' on 2026-04-23, 20:28:52 UTC presenting an overview of flowR's core (v2.10.4, using R v4.5.0). Please do not edit this file/wiki page directly._ +_This document was generated from '[src/documentation/wiki-core.ts](https://github.com/flowr-analysis/flowr/tree/main//src/documentation/wiki-core.ts)' on 2026-05-04, 20:59:38 UTC presenting an overview of flowR's core (v2.10.4, using R v4.5.2). Please do not edit this file/wiki page directly._ This wiki page provides an overview of the inner workings of _flowR_. It is mostly intended for developers that want to extend the capabilities of _flowR_ @@ -18,7 +18,7 @@ and the [Contributing Guidelines](https://github.com/flowr-analysis/flowr/tree/m > > ```shell > $ docker run -it --rm eagleoutice/flowr # or npm run flowr -> flowR repl using flowR v2.10.4, R v4.5.0 (r-shell engine) +> flowR repl using flowR v2.10.4, R v4.5.2 (r-shell engine) > R> :parse "x <- 1; print(x)" > ``` > @@ -280,7 +280,7 @@ To explore these steps, let's use the REPL with the (very simple and contrived) ```shell $ docker run -it --rm eagleoutice/flowr # or npm run flowr -flowR repl using flowR v2.10.4, R v4.5.0 (r-shell engine) +flowR repl using flowR v2.10.4, R v4.5.2 (r-shell engine) R> :parse "x <- 1; print(x)" ``` @@ -323,6 +323,7 @@ R> :normalize* "x <- 1; print(x)" ```text https://mermaid.live/view#base64:eyJjb2RlIjoiZmxvd2NoYXJ0IFREXG4gICAgbjcoW1wiUkV4cHJlc3Npb25MaXN0ICg3KVxuIFwiXSlcbiAgICBuMihbXCJSQmluYXJ5T3AgKDIpXG4jNjA7IzQ1O1wiXSlcbiAgICBuNyAtLT58XCJlbC1jLTBcInwgbjJcbiAgICBuMChbXCJSU3ltYm9sICgwKVxueFwiXSlcbiAgICBuMiAtLT58XCJiaW4tbFwifCBuMFxuICAgIG4xKFtcIlJOdW1iZXIgKDEpXG4xXCJdKVxuICAgIG4yIC0tPnxcImJpbi1yXCJ8IG4xXG4gICAgbjYoW1wiUkZ1bmN0aW9uQ2FsbCAoNilcbnByaW50XCJdKVxuICAgIG43IC0tPnxcImVsLWMtMVwifCBuNlxuICAgIG4zKFtcIlJTeW1ib2wgKDMpXG5wcmludFwiXSlcbiAgICBuNiAtLT58XCJjYWxsLW5hbWVcInwgbjNcbiAgICBuNShbXCJSQXJndW1lbnQgKDUpXG54XCJdKVxuICAgIG42IC0tPnxcImNhbGwtYXJnLTFcInwgbjVcbiAgICBuNChbXCJSU3ltYm9sICg0KVxueFwiXSlcbiAgICBuNSAtLT58XCJhcmctdlwifCBuNFxuIiwibWVybWFpZCI6eyJhdXRvU3luYyI6dHJ1ZX19 +Copied mermaid url to clipboard (normalize: 0ms). ``` @@ -358,7 +359,7 @@ x"]) ``` -(The analysis required _3.5 ms_ (including parsing with the [r-shell](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) +(The analysis required _1.6 ms_ (including parsing with the [r-shell](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) @@ -376,6 +377,7 @@ R> :dataflow* "x <- 1; print(x)" ```text https://mermaid.live/view#base64:eyJjb2RlIjoiZmxvd2NoYXJ0IEJUXG4gICAgMXt7XCJgIzkxO1JOdW1iZXIjOTM7IDFcbiAgICAgICgxKVxuICAgICAgKjEuNipgXCJ9fVxuICAgJSUgTm8gZWRnZXMgZm91bmQgZm9yIDFcbiAgICAwW1wiYCM5MTtSU3ltYm9sIzkzOyB4XG4gICAgICAoMCwgc291cmNlczogWzFdKVxuICAgICAgKjEuMSpgXCJdXG4gICAgMltbXCJgIzkxO1JCaW5hcnlPcCM5MzsgIzYwOyM0NTtcbiAgICAgICgyKVxuICAgICAgKjEuMS02KlxuICAgICgwLCAxKWBcIl1dXG4gICAgYnVpbHQtaW46Xy1bXCJgQnVpbHQtSW46XG4jNjA7IzQ1O2BcIl1cbiAgICBzdHlsZSBidWlsdC1pbjpfLSBzdHJva2U6Z3JheSxmaWxsOmdyYXksc3Ryb2tlLXdpZHRoOjJweCxvcGFjaXR5Oi44O1xuICAgIDQoW1wiYCM5MTtSU3ltYm9sIzkzOyB4XG4gICAgICAoNClcbiAgICAgICoxLjE1KmBcIl0pXG4gICAgNltbXCJgIzkxO1JGdW5jdGlvbkNhbGwjOTM7IHByaW50XG4gICAgICAoNilcbiAgICAgICoxLjktMTYqXG4gICAgKDQpYFwiXV1cbiAgICBidWlsdC1pbjpwcmludFtcImBCdWlsdC1JbjpcbnByaW50YFwiXVxuICAgIHN0eWxlIGJ1aWx0LWluOnByaW50IHN0cm9rZTpncmF5LGZpbGw6Z3JheSxzdHJva2Utd2lkdGg6MnB4LG9wYWNpdHk6Ljg7XG4gICAgMCAtLT58XCJkZWZpbmVkLWJ5XCJ8IDFcbiAgICAwIC0tPnxcImRlZmluZWQtYnlcInwgMlxuICAgIDIgLS0+fFwicmVhZHMsIGFyZ3VtZW50XCJ8IDFcbiAgICAyIC0tPnxcInJldHVybnMsIGFyZ3VtZW50XCJ8IDBcbiAgICAyIC0uLT58XCJyZWFkcywgY2FsbHNcInwgYnVpbHQtaW46Xy1cbiAgICBsaW5rU3R5bGUgNCBzdHJva2U6Z3JheTtcbiAgICA0IC0tPnxcInJlYWRzXCJ8IDBcbiAgICA2IC0tPnxcInJlYWRzLCByZXR1cm5zLCBhcmd1bWVudFwifCA0XG4gICAgNiAtLi0+fFwicmVhZHMsIGNhbGxzXCJ8IGJ1aWx0LWluOnByaW50XG4gICAgbGlua1N0eWxlIDcgc3Ryb2tlOmdyYXk7IiwibWVybWFpZCI6eyJhdXRvU3luYyI6dHJ1ZX19 +Copied mermaid url to clipboard (dataflow: 0ms). ``` @@ -423,7 +425,7 @@ print`"] ``` -(The analysis required _1.7 ms_ (including parse and normalize, using the [r-shell](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) +(The analysis required _1.3 ms_ (including parse and normalize, using the [r-shell](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) @@ -496,6 +498,7 @@ Especially when you are just starting with flowR, we recommend using the REPL to > > ```text > https://mermaid.live/view#base64:eyJjb2RlIjoiZmxvd2NoYXJ0IFREXG4gICAgbjcoW1wiUkV4cHJlc3Npb25MaXN0ICg3KVxuIFwiXSlcbiAgICBuMihbXCJSQmluYXJ5T3AgKDIpXG4jNjA7IzQ1O1wiXSlcbiAgICBuNyAtLT58XCJlbC1jLTBcInwgbjJcbiAgICBuMChbXCJSU3ltYm9sICgwKVxueFwiXSlcbiAgICBuMiAtLT58XCJiaW4tbFwifCBuMFxuICAgIG4xKFtcIlJOdW1iZXIgKDEpXG4xXCJdKVxuICAgIG4yIC0tPnxcImJpbi1yXCJ8IG4xXG4gICAgbjYoW1wiUkZ1bmN0aW9uQ2FsbCAoNilcbnByaW50XCJdKVxuICAgIG43IC0tPnxcImVsLWMtMVwifCBuNlxuICAgIG4zKFtcIlJTeW1ib2wgKDMpXG5wcmludFwiXSlcbiAgICBuNiAtLT58XCJjYWxsLW5hbWVcInwgbjNcbiAgICBuNShbXCJSQXJndW1lbnQgKDUpXG54XCJdKVxuICAgIG42IC0tPnxcImNhbGwtYXJnLTFcInwgbjVcbiAgICBuNChbXCJSU3ltYm9sICg0KVxueFwiXSlcbiAgICBuNSAtLT58XCJhcmctdlwifCBuNFxuIiwibWVybWFpZCI6eyJhdXRvU3luYyI6dHJ1ZX19 +> Copied mermaid url to clipboard (normalize: 0ms). > ``` > > @@ -531,7 +534,7 @@ Especially when you are just starting with flowR, we recommend using the REPL to > > ``` > -> (The analysis required _0.5 ms_ (including parsing with the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) +> (The analysis required _0.4 ms_ (including parsing with the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) > > > @@ -549,6 +552,7 @@ Especially when you are just starting with flowR, we recommend using the REPL to > > ```text > https://mermaid.live/view#base64:eyJjb2RlIjoiZmxvd2NoYXJ0IEJUXG4gICAgMXt7XCJgIzkxO1JOdW1iZXIjOTM7IDFcbiAgICAgICgxKVxuICAgICAgKjEuNipgXCJ9fVxuICAgJSUgTm8gZWRnZXMgZm91bmQgZm9yIDFcbiAgICAwW1wiYCM5MTtSU3ltYm9sIzkzOyB4XG4gICAgICAoMCwgc291cmNlczogWzFdKVxuICAgICAgKjEuMSpgXCJdXG4gICAgMltbXCJgIzkxO1JCaW5hcnlPcCM5MzsgIzYwOyM0NTtcbiAgICAgICgyKVxuICAgICAgKjEuMS02KlxuICAgICgwLCAxKWBcIl1dXG4gICAgYnVpbHQtaW46Xy1bXCJgQnVpbHQtSW46XG4jNjA7IzQ1O2BcIl1cbiAgICBzdHlsZSBidWlsdC1pbjpfLSBzdHJva2U6Z3JheSxmaWxsOmdyYXksc3Ryb2tlLXdpZHRoOjJweCxvcGFjaXR5Oi44O1xuICAgIDQoW1wiYCM5MTtSU3ltYm9sIzkzOyB4XG4gICAgICAoNClcbiAgICAgICoxLjE1KmBcIl0pXG4gICAgNltbXCJgIzkxO1JGdW5jdGlvbkNhbGwjOTM7IHByaW50XG4gICAgICAoNilcbiAgICAgICoxLjktMTYqXG4gICAgKDQpYFwiXV1cbiAgICBidWlsdC1pbjpwcmludFtcImBCdWlsdC1JbjpcbnByaW50YFwiXVxuICAgIHN0eWxlIGJ1aWx0LWluOnByaW50IHN0cm9rZTpncmF5LGZpbGw6Z3JheSxzdHJva2Utd2lkdGg6MnB4LG9wYWNpdHk6Ljg7XG4gICAgMCAtLT58XCJkZWZpbmVkLWJ5XCJ8IDFcbiAgICAwIC0tPnxcImRlZmluZWQtYnlcInwgMlxuICAgIDIgLS0+fFwicmVhZHMsIGFyZ3VtZW50XCJ8IDFcbiAgICAyIC0tPnxcInJldHVybnMsIGFyZ3VtZW50XCJ8IDBcbiAgICAyIC0uLT58XCJyZWFkcywgY2FsbHNcInwgYnVpbHQtaW46Xy1cbiAgICBsaW5rU3R5bGUgNCBzdHJva2U6Z3JheTtcbiAgICA0IC0tPnxcInJlYWRzXCJ8IDBcbiAgICA2IC0tPnxcInJlYWRzLCByZXR1cm5zLCBhcmd1bWVudFwifCA0XG4gICAgNiAtLi0+fFwicmVhZHMsIGNhbGxzXCJ8IGJ1aWx0LWluOnByaW50XG4gICAgbGlua1N0eWxlIDcgc3Ryb2tlOmdyYXk7IiwibWVybWFpZCI6eyJhdXRvU3luYyI6dHJ1ZX19 +> Copied mermaid url to clipboard (dataflow: 0ms). > ``` > > @@ -596,7 +600,7 @@ Especially when you are just starting with flowR, we recommend using the REPL to > ``` > > -> (The analysis required _0.5 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) +> (The analysis required _0.4 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.) > > > @@ -1392,7 +1396,7 @@ product <- 1 N <- 10 for(i in 1:(N-1)) product <- product i product -All queries together required ≈4 ms (1ms accuracy, total 5 ms) +All queries together required ≈2 ms (1ms accuracy, total 3 ms) ``` diff --git a/wiki/Interface.md b/wiki/Interface.md index 4017873045f..871d09317a4 100644 --- a/wiki/Interface.md +++ b/wiki/Interface.md @@ -1,4 +1,4 @@ -_This document was generated from '[src/documentation/wiki-interface.ts](https://github.com/flowr-analysis/flowr/tree/main//src/documentation/wiki-interface.ts)' on 2026-04-23, 20:28:52 UTC presenting an overview of flowR's interface (v2.10.4, using R v4.5.0). Please do not edit this file/wiki page directly._ +_This document was generated from '[src/documentation/wiki-interface.ts](https://github.com/flowr-analysis/flowr/tree/main//src/documentation/wiki-interface.ts)' on 2026-05-04, 20:59:37 UTC presenting an overview of flowR's interface (v2.10.4, using R v4.5.2). Please do not edit this file/wiki page directly._ Although far from being as detailed as the in-depth explanation of [_flowR_](https://github.com/flowr-analysis/flowr/wiki/core), this wiki page explains how to interface with _flowR_ in more detail. @@ -96,6 +96,7 @@ R> :dataflow* y <- 1 + x ```text https://mermaid.live/view#base64:eyJjb2RlIjoiZmxvd2NoYXJ0IEJUXG4gICAgMXt7XCJgIzkxO1JOdW1iZXIjOTM7IDFcbiAgICAgICgxKVxuICAgICAgKjEuNipgXCJ9fVxuICAgJSUgTm8gZWRnZXMgZm91bmQgZm9yIDFcbiAgICAyKFtcImAjOTE7UlN5bWJvbCM5MzsgeFxuICAgICAgKDIpXG4gICAgICAqMS4xMCpgXCJdKVxuICAgJSUgTm8gZWRnZXMgZm91bmQgZm9yIDJcbiAgICAzW1tcImAjOTE7UkJpbmFyeU9wIzkzOyAjNDM7XG4gICAgICAoMylcbiAgICAgICoxLjYtMTAqXG4gICAgKDEsIDIpYFwiXV1cbiAgICBidWlsdC1pbjpfW1wiYEJ1aWx0LUluOlxuIzQzO2BcIl1cbiAgICBzdHlsZSBidWlsdC1pbjpfIHN0cm9rZTpncmF5LGZpbGw6Z3JheSxzdHJva2Utd2lkdGg6MnB4LG9wYWNpdHk6Ljg7XG4gICAgMFtcImAjOTE7UlN5bWJvbCM5MzsgeVxuICAgICAgKDAsIHNvdXJjZXM6IFszXSlcbiAgICAgICoxLjEqYFwiXVxuICAgIDRbW1wiYCM5MTtSQmluYXJ5T3AjOTM7ICM2MDsjNDU7XG4gICAgICAoNClcbiAgICAgICoxLjEtMTAqXG4gICAgKDAsIDMpYFwiXV1cbiAgICBidWlsdC1pbjpfLVtcImBCdWlsdC1JbjpcbiM2MDsjNDU7YFwiXVxuICAgIHN0eWxlIGJ1aWx0LWluOl8tIHN0cm9rZTpncmF5LGZpbGw6Z3JheSxzdHJva2Utd2lkdGg6MnB4LG9wYWNpdHk6Ljg7XG4gICAgMyAtLT58XCJyZWFkcywgYXJndW1lbnRcInwgMVxuICAgIDMgLS0+fFwicmVhZHMsIGFyZ3VtZW50XCJ8IDJcbiAgICAzIC0uLT58XCJyZWFkcywgY2FsbHNcInwgYnVpbHQtaW46X1xuICAgIGxpbmtTdHlsZSAyIHN0cm9rZTpncmF5O1xuICAgIDAgLS0+fFwiZGVmaW5lZC1ieVwifCAzXG4gICAgMCAtLT58XCJkZWZpbmVkLWJ5XCJ8IDRcbiAgICA0IC0tPnxcInJlYWRzLCBhcmd1bWVudFwifCAzXG4gICAgNCAtLT58XCJyZXR1cm5zLCBhcmd1bWVudFwifCAwXG4gICAgNCAtLi0+fFwicmVhZHMsIGNhbGxzXCJ8IGJ1aWx0LWluOl8tXG4gICAgbGlua1N0eWxlIDcgc3Ryb2tlOmdyYXk7IiwibWVybWFpZCI6eyJhdXRvU3luYyI6dHJ1ZX19 +Copied mermaid url to clipboard (dataflow: 0ms). ``` @@ -148,7 +149,7 @@ flowchart LR R Code of the Dataflow Graph -The analysis required _0.5 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment. +The analysis required _0.4 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment. We encountered no unknown side effects during the analysis. @@ -370,10 +371,10 @@ R> :query @df-shape "x <- data.frame(a = 1:10, b = 1:10)\ny <- x$a" ```text -Query: df-shape (1 ms) +Query: df-shape (0 ms) ╰ 12: (colnames: [{"a", "b"}, {}], cols: [2, 2], rows: [10, 10]) ╰ 0: (colnames: [{"a", "b"}, {}], cols: [2, 2], rows: [10, 10]) -All queries together required ≈3 ms (1ms accuracy, total 4 ms) +All queries together required ≈1 ms (1ms accuracy, total 1 ms) ``` @@ -401,7 +402,7 @@ Query: linter (1 ms) ╰ certain: ╰ Code at 1.11-16 ╰ Metadata: consideredNodes: 7, searchTimeMs: 1, processTimeMs: 0 -All queries together required ≈1 ms (1ms accuracy, total 2 ms) +All queries together required ≈1 ms (1ms accuracy, total 1 ms) ``` @@ -819,7 +820,7 @@ The message looks like this: "clientName": "client-0", "versions": { "flowr": "2.10.4", - "r": "4.5.0", + "r": "4.5.2", "engine": "r-shell" } } @@ -919,7 +920,7 @@ The first message is always a hello message. "clientName": "client-0", "versions": { "flowr": "2.10.4", - "r": "4.5.0", + "r": "4.5.2", "engine": "r-shell" } } @@ -979,7 +980,7 @@ The `results` field of the response effectively contains three keys of importanc _As the code is pretty long, we inhibit pretty printing and syntax highlighting (JSON, hiding built-in):_ ```text -{"type":"response-file-analysis","format":"json","id":"1","results":{"parse":{"files":[{"parsed":"[1,1,1,6,7,0,\"expr\",false,\"x <- 1\"],[1,1,1,1,1,3,\"SYMBOL\",true,\"x\"],[1,1,1,1,3,7,\"expr\",false,\"x\"],[1,3,1,4,2,7,\"LEFT_ASSIGN\",true,\"<-\"],[1,6,1,6,4,5,\"NUM_CONST\",true,\"1\"],[1,6,1,6,5,7,\"expr\",false,\"1\"],[2,1,2,5,16,0,\"expr\",false,\"x + 1\"],[2,1,2,1,10,12,\"SYMBOL\",true,\"x\"],[2,1,2,1,12,16,\"expr\",false,\"x\"],[2,3,2,3,11,16,\"'+'\",true,\"+\"],[2,5,2,5,13,14,\"NUM_CONST\",true,\"1\"],[2,5,2,5,14,16,\"expr\",false,\"1\"]","filePath":"/tmp/tmp-8880-pdAgfQ1zSGIa-.R"}],".meta":{"timing":2}},"normalize":{"ast":{"type":"RProject","files":[{"root":{"type":"RExpressionList","children":[{"type":"RBinaryOp","location":[1,3,1,4],"lhs":{"type":"RSymbol","location":[1,1,1,1],"content":"x","lexeme":"x","info":{"fullRange":[1,1,1,1],"adToks":[],"id":0,"parent":2,"role":"bin-l","index":0,"nesting":0,"file":"/tmp/tmp-8880-pdAgfQ1zSGIa-.R"}},"rhs":{"location":[1,6,1,6],"lexeme":"1","info":{"fullRange":[1,6,1,6],"adToks":[],"id":1,"parent":2,"role":"bin-r","index":1,"nesting":0,"file":"/tmp/tmp-8880-pdAgfQ1zSGIa-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"operator":"<-","lexeme":"<-","info":{"fullRange":[1,1,1,6],"adToks":[],"id":2,"parent":6,"nesting":0,"file":"/tmp/tmp-8880-pdAgfQ1zSGIa-.R","index":0,"role":"el-c"}},{"type":"RBinaryOp","location":[2,3,2,3],"lhs":{"type":"RSymbol","location":[2,1,2,1],"content":"x","lexeme":"x","info":{"fullRange":[2,1,2,1],"adToks":[],"id":3,"parent":5,"role":"bin-l","index":0,"nesting":0,"file":"/tmp/tmp-8880-pdAgfQ1zSGIa-.R"}},"rhs":{"location":[2,5,2,5],"lexeme":"1","info":{"fullRange":[2,5,2,5],"adToks":[],"id":4,"parent":5,"role":"bin-r","index":1,"nesting":0,"file":"/tmp/tmp-8880-pdAgfQ1zSGIa-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"operator":"+","lexeme":"+","info":{"fullRange":[2,1,2,5],"adToks":[],"id":5,"parent":6,"nesting":0,"file":"/tmp/tmp-8880-pdAgfQ1zSGIa-.R","index":1,"role":"el-c"}}],"info":{"adToks":[],"id":6,"nesting":0,"file":"/tmp/tmp-8880-pdAgfQ1zSGIa-.R","role":"root","index":0}},"filePath":"/tmp/tmp-8880-pdAgfQ1zSGIa-.R"}],"info":{"id":7}},".meta":{"timing":0}},"dataflow":{"unknownReferences":[],"in":[{"nodeId":2,"name":"<-","type":2},{"nodeId":5,"name":"+","type":2}],"out":[{"nodeId":0,"name":"x","type":4,"definedAt":2,"value":[1]}],"environment":{"current":{"id":2610,"parent":"","memory":[["x",[{"nodeId":0,"name":"x","type":4,"definedAt":2,"value":[1]}]]]},"level":0},"graph":{"rootVertices":[1,0,2,3,4,5],"vertexInformation":[[1,{"tag":"value","id":1}],[0,{"tag":"vdef","id":0,"source":[1]}],[2,{"tag":"fcall","id":2,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":0,"type":32},{"nodeId":1,"type":32}],"origin":["builtin:assignment"]}],[3,{"tag":"use","id":3}],[4,{"tag":"value","id":4}],[5,{"tag":"fcall","id":5,"name":"+","onlyBuiltin":true,"args":[{"nodeId":3,"type":32},{"nodeId":4,"type":32}],"origin":["builtin:default"]}]],"edgeInformation":[[2,[[1,{"types":65}],[0,{"types":72}],["built-in:<-",{"types":5}]]],[0,[[1,{"types":2}],[2,{"types":2}]]],[3,[[0,{"types":1}]]],[5,[[3,{"types":65}],[4,{"types":65}],["built-in:+",{"types":5}]]]],"_unknownSideEffects":[]},"entryPoint":2,"exitPoints":[{"type":0,"nodeId":5}],"hooks":[],".meta":{"timing":1}}}} +{"type":"response-file-analysis","format":"json","id":"1","results":{"parse":{"files":[{"parsed":"[1,1,1,6,7,0,\"expr\",false,\"x <- 1\"],[1,1,1,1,1,3,\"SYMBOL\",true,\"x\"],[1,1,1,1,3,7,\"expr\",false,\"x\"],[1,3,1,4,2,7,\"LEFT_ASSIGN\",true,\"<-\"],[1,6,1,6,4,5,\"NUM_CONST\",true,\"1\"],[1,6,1,6,5,7,\"expr\",false,\"1\"],[2,1,2,5,16,0,\"expr\",false,\"x + 1\"],[2,1,2,1,10,12,\"SYMBOL\",true,\"x\"],[2,1,2,1,12,16,\"expr\",false,\"x\"],[2,3,2,3,11,16,\"'+'\",true,\"+\"],[2,5,2,5,13,14,\"NUM_CONST\",true,\"1\"],[2,5,2,5,14,16,\"expr\",false,\"1\"]","filePath":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-rO2Y8fL93t4H-.R"}],".meta":{"timing":2}},"normalize":{"ast":{"type":"RProject","files":[{"root":{"type":"RExpressionList","children":[{"type":"RBinaryOp","location":[1,3,1,4],"lhs":{"type":"RSymbol","location":[1,1,1,1],"content":"x","lexeme":"x","info":{"fullRange":[1,1,1,1],"adToks":[],"id":0,"parent":2,"role":"bin-l","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-rO2Y8fL93t4H-.R"}},"rhs":{"location":[1,6,1,6],"lexeme":"1","info":{"fullRange":[1,6,1,6],"adToks":[],"id":1,"parent":2,"role":"bin-r","index":1,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-rO2Y8fL93t4H-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"operator":"<-","lexeme":"<-","info":{"fullRange":[1,1,1,6],"adToks":[],"id":2,"parent":6,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-rO2Y8fL93t4H-.R","index":0,"role":"el-c"}},{"type":"RBinaryOp","location":[2,3,2,3],"lhs":{"type":"RSymbol","location":[2,1,2,1],"content":"x","lexeme":"x","info":{"fullRange":[2,1,2,1],"adToks":[],"id":3,"parent":5,"role":"bin-l","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-rO2Y8fL93t4H-.R"}},"rhs":{"location":[2,5,2,5],"lexeme":"1","info":{"fullRange":[2,5,2,5],"adToks":[],"id":4,"parent":5,"role":"bin-r","index":1,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-rO2Y8fL93t4H-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"operator":"+","lexeme":"+","info":{"fullRange":[2,1,2,5],"adToks":[],"id":5,"parent":6,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-rO2Y8fL93t4H-.R","index":1,"role":"el-c"}}],"info":{"adToks":[],"id":6,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-rO2Y8fL93t4H-.R","role":"root","index":0}},"filePath":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-rO2Y8fL93t4H-.R"}],"info":{"id":7}},".meta":{"timing":0}},"dataflow":{"unknownReferences":[],"in":[{"nodeId":2,"name":"<-","type":2},{"nodeId":5,"name":"+","type":2}],"out":[{"nodeId":0,"name":"x","type":4,"definedAt":2,"value":[1]}],"environment":{"current":{"id":2591,"parent":"","memory":[["x",[{"nodeId":0,"name":"x","type":4,"definedAt":2,"value":[1]}]]]},"level":0},"graph":{"rootVertices":[1,0,2,3,4,5],"vertexInformation":[[1,{"tag":"value","id":1}],[0,{"tag":"vdef","id":0,"source":[1]}],[2,{"tag":"fcall","id":2,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":0,"type":32},{"nodeId":1,"type":32}],"origin":["builtin:assignment"]}],[3,{"tag":"use","id":3}],[4,{"tag":"value","id":4}],[5,{"tag":"fcall","id":5,"name":"+","onlyBuiltin":true,"args":[{"nodeId":3,"type":32},{"nodeId":4,"type":32}],"origin":["builtin:default"]}]],"edgeInformation":[[2,[[1,{"types":65}],[0,{"types":72}],["built-in:<-",{"types":5}]]],[0,[[1,{"types":2}],[2,{"types":2}]]],[3,[[0,{"types":1}]]],[5,[[3,{"types":65}],[4,{"types":65}],["built-in:+",{"types":5}]]]],"_unknownSideEffects":[]},"entryPoint":2,"exitPoints":[{"type":0,"nodeId":5}],"hooks":[],".meta":{"timing":0}}}} ``` @@ -988,7 +989,7 @@ _As the code is pretty long, we inhibit pretty printing and syntax highlighting -The complete round-trip took 8.1 ms (including time required to validate the messages, start, and stop the internal mock server). +The complete round-trip took 7.1 ms (including time required to validate the messages, start, and stop the internal mock server).
@@ -1021,7 +1022,7 @@ The first message is always a hello message. "clientName": "client-0", "versions": { "flowr": "2.10.4", - "r": "4.5.0", + "r": "4.5.2", "engine": "r-shell" } } @@ -1071,7 +1072,7 @@ The first message is always a hello message. "id": "1", "type": "error", "fatal": false, - "reason": "Error while analyzing file sample.R: GuardError: unable to parse R code (see the log for more information) for request {\"request\":\"text\",\"content\":\"x <-\"}}\n Report a Bug: https://github.com/flowr-analysis/flowr/issues/new?body=%3C!%2D%2D%20Please%20describe%20your%20issue%20in%20more%20detail%20below!%20%2D%2D%3E%0A%0A%0A%3C!%2D%2D%20Automatically%20generated%20issue%20metadata%2C%20please%20do%20not%20edit%20or%20delete%20content%20below%20this%20line%20%2D%2D%3E%0A%2D%2D%2D%0A%0AflowR%20version%3A%202.10.4%0Anode%20version%3A%20v25.6.1%0Anode%20arch%3A%20x64%0Anode%20platform%3A%20linux%0Amessage%3A%20%60unable%20to%20parse%20R%20code%20%28see%20the%20log%20for%20more%20information%29%20for%20request%20%7B%22request%22%3A%22text%22%2C%22content%22%3A%22x%20%3C%2D%22%7D%7D%60%0Astack%20trace%3A%0A%60%60%60%0A%20%20%20%20at%20guard%20%28%3C%3E%2Fsrc%2Futil%2Fassert.ts%3A128%3A9%29%0A%20%20%20%20at%20guardRetrievedOutput%20%28%3C%3E%2Fsrc%2Fr%2Dbridge%2Fretriever.ts%3A221%3A7%29%0A%20%20%20%20at%20%2Fhome%2Frunner%2Fwork%2Fflowr%2Fflowr%2Fsrc%2Fr%2Dbridge%2Fretriever.ts%3A182%3A4%0A%20%20%20%20at%20processTicksAndRejections%20%28node%3Ainternal%2Fprocess%2Ftask_queues%3A104%3A5%29%0A%20%20%20%20at%20async%20Object.parseRequests%20%5Bas%20processor%5D%20%28%3C%3E%2Fsrc%2Fr%2Dbridge%2Fparser.ts%3A104%3A19%29%0A%20%20%20%20at%20async%20PipelineExecutor.nextStep%20%28%3C%3E%2Fsrc%2Fcore%2Fpipeline%2Dexecutor.ts%3A192%3A25%29%0A%20%20%20%20at%20async%20FlowrAnalyzerCache.runTapeUntil%20%28%3C%3E%2Fsrc%2Fproject%2Fcache%2Fflowr%2Danalyzer%2Dcache.ts%3A92%3A4%29%0A%20%20%20%20at%20async%20FlowRServerConnection.sendFileAnalysisResponse%20%28%3C%3E%2Fsrc%2Fcli%2Frepl%2Fserver%2Fconnection.ts%3A163%3A52%29%0A%60%60%60%0A%0A%2D%2D%2D%0A%09" + "reason": "Error while analyzing file sample.R: GuardError: unable to parse R code (see the log for more information) for request {\"request\":\"text\",\"content\":\"x <-\"}}\n Report a Bug: https://github.com/flowr-analysis/flowr/issues/new?body=%3C!%2D%2D%20Please%20describe%20your%20issue%20in%20more%20detail%20below!%20%2D%2D%3E%0A%0A%0A%3C!%2D%2D%20Automatically%20generated%20issue%20metadata%2C%20please%20do%20not%20edit%20or%20delete%20content%20below%20this%20line%20%2D%2D%3E%0A%2D%2D%2D%0A%0AflowR%20version%3A%202.10.4%0Anode%20version%3A%20v24.10.0%0Anode%20arch%3A%20arm64%0Anode%20platform%3A%20darwin%0Amessage%3A%20%60unable%20to%20parse%20R%20code%20%28see%20the%20log%20for%20more%20information%29%20for%20request%20%7B%22request%22%3A%22text%22%2C%22content%22%3A%22x%20%3C%2D%22%7D%7D%60%0Astack%20trace%3A%0A%60%60%60%0A%20%20%20%20at%20guard%20%28%3C%3E%2Fsrc%2Futil%2Fassert.ts%3A128%3A9%29%0A%20%20%20%20at%20guardRetrievedOutput%20%28%3C%3E%2Fsrc%2Fr%2Dbridge%2Fretriever.ts%3A221%3A7%29%0A%20%20%20%20at%20%2FUsers%2Fnaomipanda%2FLibrary%2FMobile%20Documents%2Fcom~apple~CloudDocs%2FUni%2FFlowr%2Fflowr%2Fsrc%2Fr%2Dbridge%2Fretriever.ts%3A182%3A4%0A%20%20%20%20at%20processTicksAndRejections%20%28node%3Ainternal%2Fprocess%2Ftask_queues%3A105%3A5%29%0A%20%20%20%20at%20async%20Object.parseRequests%20%5Bas%20processor%5D%20%28%3C%3E%2Fsrc%2Fr%2Dbridge%2Fparser.ts%3A104%3A19%29%0A%20%20%20%20at%20async%20PipelineExecutor.nextStep%20%28%3C%3E%2Fsrc%2Fcore%2Fpipeline%2Dexecutor.ts%3A192%3A25%29%0A%20%20%20%20at%20async%20FlowrAnalyzerCache.runTapeUntil%20%28%3C%3E%2Fsrc%2Fproject%2Fcache%2Fflowr%2Danalyzer%2Dcache.ts%3A92%3A4%29%0A%20%20%20%20at%20async%20FlowRServerConnection.sendFileAnalysisResponse%20%28%3C%3E%2Fsrc%2Fcli%2Frepl%2Fserver%2Fconnection.ts%3A163%3A52%29%0A%60%60%60%0A%0A%2D%2D%2D%0A%09" } ``` @@ -1081,7 +1082,7 @@ The first message is always a hello message. -The complete round-trip took 6.6 ms (including time required to validate the messages, start, and stop the internal mock server). +The complete round-trip took 6.4 ms (including time required to validate the messages, start, and stop the internal mock server). @@ -1121,7 +1122,7 @@ The first message is always a hello message. "clientName": "client-0", "versions": { "flowr": "2.10.4", - "r": "4.5.0", + "r": "4.5.2", "engine": "r-shell" } } @@ -1172,7 +1173,7 @@ If you are interested in a visual representation of the control flow graph, see _As the code is pretty long, we inhibit pretty printing and syntax highlighting (JSON, hiding built-in):_ ```text -{"type":"response-file-analysis","format":"json","id":"1","cfg":{"returns":[],"entryPoints":[32],"exitPoints":["32-e"],"breaks":[],"nexts":[],"graph":{"roots":[32,15,"15-e",0,1,2,"2-e",8,5,6,7,"7-e","8-e",14,11,12,13,"13-e","14-e",16,31,17,18,19,"19-e",30,22,25,"25-e",24,23,"24-e",26,29,"29-e",28,27,"28-e","30-e","31-e","32-e"],"vtxInfos":[[32,[2,32,null,["32-e"]]],[15,[1,15,["2-e"],["15-e"]]],["15-e","15-e"],[0,[2,0]],[1,[2,1]],[2,[2,2,null,["2-e"]]],["2-e","2-e"],[8,[2,8,null,["8-e"]]],[5,[2,5]],[6,[2,6]],[7,[2,7,null,["7-e"]]],["7-e","7-e"],["8-e","8-e"],[14,[2,14,null,["14-e"]]],[11,[2,11]],[12,[2,12]],[13,[2,13,null,["13-e"]]],["13-e","13-e"],["14-e","14-e"],[16,[2,16]],[31,[1,31,[16],["31-e"]]],[17,[2,17]],[18,[2,18]],[19,[2,19,null,["19-e"]]],["19-e","19-e"],[30,[2,30,null,["30-e"]]],[22,[2,22]],[25,[1,25,[22],["25-e"]]],["25-e","25-e"],[24,[2,24,[24],["24-e"]]],[23,[2,23]],["24-e","24-e"],[26,[2,26]],[29,[1,29,[26],["29-e"]]],["29-e","29-e"],[28,[2,28,[28],["28-e"]]],[27,[2,27]],["28-e","28-e"],["30-e","30-e"],["31-e","31-e"],["32-e","32-e"]],"bbChildren":[],"edgeInfos":[[15,[[32,0]]],[1,[[0,0]]],[0,[[2,0]]],["2-e",[[1,0]]],[7,[[8,0]]],[6,[[5,0]]],[5,[[7,0]]],["7-e",[[6,0]]],["8-e",[["7-e",0]]],[13,[[14,0]]],[12,[[11,0]]],[11,[[13,0]]],["13-e",[[12,0]]],["14-e",[["13-e",0]]],[8,[["2-e",[15,"TRUE"]]]],[14,[["2-e",[15,"FALSE"]]]],[2,[[15,0]]],["15-e",[["8-e",0],["14-e",0]]],[31,[["15-e",0],["30-e",0]]],[18,[[17,0]]],[17,[[19,0]]],["19-e",[[18,0]]],[25,[[30,0]]],[22,[[25,0]]],[23,[[24,0]]],["24-e",[[23,0]]],[24,[[22,0]]],["25-e",[["24-e",0]]],[29,[["25-e",0]]],[26,[[29,0]]],[27,[[28,0]]],["28-e",[[27,0]]],[28,[[26,0]]],["29-e",[["28-e",0]]],["30-e",[["29-e",0]]],[19,[[31,0]]],[16,[["19-e",0]]],[30,[[16,[31,"TRUE"]]]],["31-e",[[16,[31,"FALSE"]]]],["32-e",[["31-e",0]]]],"revEdgeInfos":[[32,[[15,0]]],[0,[[1,0]]],[2,[[0,0]]],[1,[["2-e",0]]],[8,[[7,0]]],[5,[[6,0]]],[7,[[5,0]]],[6,[["7-e",0]]],["7-e",[["8-e",0]]],[14,[[13,0]]],[11,[[12,0]]],[13,[[11,0]]],[12,[["13-e",0]]],["13-e",[["14-e",0]]],["2-e",[[8,[15,"TRUE"]],[14,[15,"FALSE"]]]],[15,[[2,0]]],["8-e",[["15-e",0]]],["14-e",[["15-e",0]]],["15-e",[[31,0]]],[17,[[18,0]]],[19,[[17,0]]],[18,[["19-e",0]]],[30,[[25,0]]],[25,[[22,0]]],[24,[[23,0]]],[23,[["24-e",0]]],[22,[[24,0]]],["24-e",[["25-e",0]]],["25-e",[[29,0]]],[29,[[26,0]]],[28,[[27,0]]],[27,[["28-e",0]]],[26,[[28,0]]],["28-e",[["29-e",0]]],["29-e",[["30-e",0]]],[31,[[19,0]]],["19-e",[[16,0]]],[16,[[30,[31,"TRUE"]],["31-e",[31,"FALSE"]]]],["30-e",[[31,0]]],["31-e",[["32-e",0]]]],"_mayBB":false}},"results":{"parse":{"files":[{"parsed":"[1,1,1,42,38,0,\"expr\",false,\"if(unknown > 0) { x <- 2 } else { x <- 5 }\"],[1,1,1,2,1,38,\"IF\",true,\"if\"],[1,3,1,3,2,38,\"'('\",true,\"(\"],[1,4,1,14,9,38,\"expr\",false,\"unknown > 0\"],[1,4,1,10,3,5,\"SYMBOL\",true,\"unknown\"],[1,4,1,10,5,9,\"expr\",false,\"unknown\"],[1,12,1,12,4,9,\"GT\",true,\">\"],[1,14,1,14,6,7,\"NUM_CONST\",true,\"0\"],[1,14,1,14,7,9,\"expr\",false,\"0\"],[1,15,1,15,8,38,\"')'\",true,\")\"],[1,17,1,26,22,38,\"expr\",false,\"{ x <- 2 }\"],[1,17,1,17,12,22,\"'{'\",true,\"{\"],[1,19,1,24,19,22,\"expr\",false,\"x <- 2\"],[1,19,1,19,13,15,\"SYMBOL\",true,\"x\"],[1,19,1,19,15,19,\"expr\",false,\"x\"],[1,21,1,22,14,19,\"LEFT_ASSIGN\",true,\"<-\"],[1,24,1,24,16,17,\"NUM_CONST\",true,\"2\"],[1,24,1,24,17,19,\"expr\",false,\"2\"],[1,26,1,26,18,22,\"'}'\",true,\"}\"],[1,28,1,31,23,38,\"ELSE\",true,\"else\"],[1,33,1,42,35,38,\"expr\",false,\"{ x <- 5 }\"],[1,33,1,33,25,35,\"'{'\",true,\"{\"],[1,35,1,40,32,35,\"expr\",false,\"x <- 5\"],[1,35,1,35,26,28,\"SYMBOL\",true,\"x\"],[1,35,1,35,28,32,\"expr\",false,\"x\"],[1,37,1,38,27,32,\"LEFT_ASSIGN\",true,\"<-\"],[1,40,1,40,29,30,\"NUM_CONST\",true,\"5\"],[1,40,1,40,30,32,\"expr\",false,\"5\"],[1,42,1,42,31,35,\"'}'\",true,\"}\"],[2,1,2,36,84,0,\"expr\",false,\"for(i in 1:x) { print(x); print(i) }\"],[2,1,2,3,41,84,\"FOR\",true,\"for\"],[2,4,2,13,53,84,\"forcond\",false,\"(i in 1:x)\"],[2,4,2,4,42,53,\"'('\",true,\"(\"],[2,5,2,5,43,53,\"SYMBOL\",true,\"i\"],[2,7,2,8,44,53,\"IN\",true,\"in\"],[2,10,2,12,51,53,\"expr\",false,\"1:x\"],[2,10,2,10,45,46,\"NUM_CONST\",true,\"1\"],[2,10,2,10,46,51,\"expr\",false,\"1\"],[2,11,2,11,47,51,\"':'\",true,\":\"],[2,12,2,12,48,50,\"SYMBOL\",true,\"x\"],[2,12,2,12,50,51,\"expr\",false,\"x\"],[2,13,2,13,49,53,\"')'\",true,\")\"],[2,15,2,36,81,84,\"expr\",false,\"{ print(x); print(i) }\"],[2,15,2,15,54,81,\"'{'\",true,\"{\"],[2,17,2,24,64,81,\"expr\",false,\"print(x)\"],[2,17,2,21,55,57,\"SYMBOL_FUNCTION_CALL\",true,\"print\"],[2,17,2,21,57,64,\"expr\",false,\"print\"],[2,22,2,22,56,64,\"'('\",true,\"(\"],[2,23,2,23,58,60,\"SYMBOL\",true,\"x\"],[2,23,2,23,60,64,\"expr\",false,\"x\"],[2,24,2,24,59,64,\"')'\",true,\")\"],[2,25,2,25,65,81,\"';'\",true,\";\"],[2,27,2,34,77,81,\"expr\",false,\"print(i)\"],[2,27,2,31,68,70,\"SYMBOL_FUNCTION_CALL\",true,\"print\"],[2,27,2,31,70,77,\"expr\",false,\"print\"],[2,32,2,32,69,77,\"'('\",true,\"(\"],[2,33,2,33,71,73,\"SYMBOL\",true,\"i\"],[2,33,2,33,73,77,\"expr\",false,\"i\"],[2,34,2,34,72,77,\"')'\",true,\")\"],[2,36,2,36,78,81,\"'}'\",true,\"}\"]","filePath":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}],".meta":{"timing":2}},"normalize":{"ast":{"type":"RProject","files":[{"root":{"type":"RExpressionList","children":[{"type":"RIfThenElse","condition":{"type":"RBinaryOp","location":[1,12,1,12],"lhs":{"type":"RSymbol","location":[1,4,1,10],"content":"unknown","lexeme":"unknown","info":{"fullRange":[1,4,1,10],"adToks":[],"id":0,"parent":2,"role":"bin-l","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},"rhs":{"location":[1,14,1,14],"lexeme":"0","info":{"fullRange":[1,14,1,14],"adToks":[],"id":1,"parent":2,"role":"bin-r","index":1,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"},"type":"RNumber","content":{"num":0,"complexNumber":false,"markedAsInt":false}},"operator":">","lexeme":">","info":{"fullRange":[1,4,1,14],"adToks":[],"id":2,"parent":15,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","role":"if-c"}},"then":{"type":"RExpressionList","children":[{"type":"RBinaryOp","location":[1,21,1,22],"lhs":{"type":"RSymbol","location":[1,19,1,19],"content":"x","lexeme":"x","info":{"fullRange":[1,19,1,19],"adToks":[],"id":5,"parent":7,"role":"bin-l","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},"rhs":{"location":[1,24,1,24],"lexeme":"2","info":{"fullRange":[1,24,1,24],"adToks":[],"id":6,"parent":7,"role":"bin-r","index":1,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"},"type":"RNumber","content":{"num":2,"complexNumber":false,"markedAsInt":false}},"operator":"<-","lexeme":"<-","info":{"fullRange":[1,19,1,24],"adToks":[],"id":7,"parent":8,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":0,"role":"el-c"}}],"grouping":[{"type":"RSymbol","location":[1,17,1,17],"content":"{","lexeme":"{","info":{"fullRange":[1,17,1,26],"adToks":[],"id":3,"role":"el-g","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},{"type":"RSymbol","location":[1,26,1,26],"content":"}","lexeme":"}","info":{"fullRange":[1,17,1,26],"adToks":[],"id":4,"role":"el-g","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}}],"info":{"adToks":[],"id":8,"parent":15,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":1,"role":"if-then"}},"location":[1,1,1,2],"lexeme":"if","info":{"fullRange":[1,1,1,42],"adToks":[],"id":15,"parent":32,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":0,"role":"el-c"},"otherwise":{"type":"RExpressionList","children":[{"type":"RBinaryOp","location":[1,37,1,38],"lhs":{"type":"RSymbol","location":[1,35,1,35],"content":"x","lexeme":"x","info":{"fullRange":[1,35,1,35],"adToks":[],"id":11,"parent":13,"role":"bin-l","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},"rhs":{"location":[1,40,1,40],"lexeme":"5","info":{"fullRange":[1,40,1,40],"adToks":[],"id":12,"parent":13,"role":"bin-r","index":1,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"},"type":"RNumber","content":{"num":5,"complexNumber":false,"markedAsInt":false}},"operator":"<-","lexeme":"<-","info":{"fullRange":[1,35,1,40],"adToks":[],"id":13,"parent":14,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":0,"role":"el-c"}}],"grouping":[{"type":"RSymbol","location":[1,33,1,33],"content":"{","lexeme":"{","info":{"fullRange":[1,33,1,42],"adToks":[],"id":9,"role":"el-g","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},{"type":"RSymbol","location":[1,42,1,42],"content":"}","lexeme":"}","info":{"fullRange":[1,33,1,42],"adToks":[],"id":10,"role":"el-g","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}}],"info":{"adToks":[],"id":14,"parent":15,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":2,"role":"if-other"}}},{"type":"RForLoop","variable":{"type":"RSymbol","location":[2,5,2,5],"content":"i","lexeme":"i","info":{"adToks":[],"id":16,"parent":31,"role":"for-var","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},"vector":{"type":"RBinaryOp","location":[2,11,2,11],"lhs":{"location":[2,10,2,10],"lexeme":"1","info":{"fullRange":[2,10,2,10],"adToks":[],"id":17,"parent":19,"role":"bin-l","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"rhs":{"type":"RSymbol","location":[2,12,2,12],"content":"x","lexeme":"x","info":{"fullRange":[2,12,2,12],"adToks":[],"id":18,"parent":19,"role":"bin-r","index":1,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},"operator":":","lexeme":":","info":{"fullRange":[2,10,2,12],"adToks":[],"id":19,"parent":31,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":1,"role":"for-vec"}},"body":{"type":"RExpressionList","children":[{"type":"RFunctionCall","named":true,"location":[2,17,2,21],"lexeme":"print","functionName":{"type":"RSymbol","location":[2,17,2,21],"content":"print","lexeme":"print","info":{"fullRange":[2,17,2,24],"adToks":[],"id":22,"parent":25,"role":"call-name","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},"arguments":[{"type":"RArgument","location":[2,23,2,23],"lexeme":"x","value":{"type":"RSymbol","location":[2,23,2,23],"content":"x","lexeme":"x","info":{"fullRange":[2,23,2,23],"adToks":[],"id":23,"parent":24,"role":"arg-v","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},"info":{"fullRange":[2,23,2,23],"adToks":[],"id":24,"parent":25,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[2,17,2,24],"adToks":[],"id":25,"parent":30,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":0,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[2,27,2,31],"lexeme":"print","functionName":{"type":"RSymbol","location":[2,27,2,31],"content":"print","lexeme":"print","info":{"fullRange":[2,27,2,34],"adToks":[],"id":26,"parent":29,"role":"call-name","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},"arguments":[{"type":"RArgument","location":[2,33,2,33],"lexeme":"i","value":{"type":"RSymbol","location":[2,33,2,33],"content":"i","lexeme":"i","info":{"fullRange":[2,33,2,33],"adToks":[],"id":27,"parent":28,"role":"arg-v","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},"info":{"fullRange":[2,33,2,33],"adToks":[],"id":28,"parent":29,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[2,27,2,34],"adToks":[],"id":29,"parent":30,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":1,"role":"el-c"}}],"grouping":[{"type":"RSymbol","location":[2,15,2,15],"content":"{","lexeme":"{","info":{"fullRange":[2,15,2,36],"adToks":[],"id":20,"role":"el-g","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}},{"type":"RSymbol","location":[2,36,2,36],"content":"}","lexeme":"}","info":{"fullRange":[2,15,2,36],"adToks":[],"id":21,"role":"el-g","index":0,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}}],"info":{"adToks":[],"id":30,"parent":31,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":2,"role":"for-b"}},"lexeme":"for","info":{"fullRange":[2,1,2,36],"adToks":[],"id":31,"parent":32,"nesting":1,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","index":1,"role":"el-c"},"location":[2,1,2,3]}],"info":{"adToks":[],"id":32,"nesting":0,"file":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R","role":"root","index":0}},"filePath":"/tmp/tmp-8880-qp7mLBR2Tt0O-.R"}],"info":{"id":33}},".meta":{"timing":1}},"dataflow":{"unknownReferences":[],"in":[{"nodeId":15,"name":"if","type":2},{"nodeId":0,"name":"unknown","type":1},{"nodeId":2,"name":">","type":2},{"nodeId":7,"name":"<-","cds":[{"id":15,"when":true}],"type":2},{"nodeId":13,"name":"<-","cds":[{"id":15,"when":false}],"type":2},{"nodeId":8,"name":"{","cds":[{"id":15,"when":true}],"type":2},{"nodeId":14,"name":"{","cds":[{"id":15,"when":false}],"type":2},{"nodeId":31,"name":"for","type":2},{"nodeId":27,"name":"i","type":4},{"nodeId":19,"name":":","type":2},{"nodeId":25,"name":"print","type":2},{"nodeId":29,"name":"print","type":2}],"out":[{"nodeId":5,"name":"x","type":4,"definedAt":7,"cds":[{"id":15,"when":true}],"value":[6]},{"nodeId":11,"name":"x","type":4,"definedAt":13,"cds":[{"id":15,"when":true},{"id":15,"when":false}],"value":[12]},{"nodeId":16,"name":"i","type":1}],"environment":{"current":{"id":2696,"parent":"","memory":[["x",[{"nodeId":5,"name":"x","type":4,"definedAt":7,"cds":[{"id":15,"when":true},{"id":15,"when":false}],"value":[6]},{"nodeId":11,"name":"x","type":4,"definedAt":13,"cds":[{"id":15,"when":true},{"id":15,"when":false}],"value":[12]}]],["i",[{"nodeId":16,"name":"i","type":4,"definedAt":31}]]]},"level":0},"graph":{"rootVertices":[0,1,2,6,5,7,8,12,11,13,14,15,16,17,18,19,23,25,27,29,30,31],"vertexInformation":[[0,{"tag":"use","id":0}],[1,{"tag":"value","id":1}],[2,{"tag":"fcall","id":2,"name":">","onlyBuiltin":true,"args":[{"nodeId":0,"type":32},{"nodeId":1,"type":32}],"origin":["builtin:default"]}],[6,{"tag":"value","id":6}],[5,{"tag":"vdef","id":5,"cds":[{"id":15,"when":true}],"source":[6]}],[7,{"tag":"fcall","id":7,"name":"<-","onlyBuiltin":true,"cds":[{"id":15,"when":true}],"args":[{"nodeId":5,"type":32},{"nodeId":6,"type":32}],"origin":["builtin:assignment"]}],[8,{"tag":"fcall","id":8,"name":"{","onlyBuiltin":true,"cds":[{"id":15,"when":true}],"args":[{"nodeId":7,"type":32}],"origin":["builtin:expression-list"]}],[12,{"tag":"value","id":12}],[11,{"tag":"vdef","id":11,"cds":[{"id":15,"when":false}],"source":[12]}],[13,{"tag":"fcall","id":13,"name":"<-","onlyBuiltin":true,"cds":[{"id":15,"when":false}],"args":[{"nodeId":11,"type":32},{"nodeId":12,"type":32}],"origin":["builtin:assignment"]}],[14,{"tag":"fcall","id":14,"name":"{","onlyBuiltin":true,"cds":[{"id":15,"when":false}],"args":[{"nodeId":13,"type":32}],"origin":["builtin:expression-list"]}],[15,{"tag":"fcall","id":15,"name":"if","onlyBuiltin":true,"args":[{"nodeId":2,"type":32},{"nodeId":8,"type":32},{"nodeId":14,"type":32}],"origin":["builtin:if-then-else"]}],[16,{"tag":"vdef","id":16,"source":[19]}],[17,{"tag":"value","id":17}],[18,{"tag":"use","id":18}],[19,{"tag":"fcall","id":19,"name":":","onlyBuiltin":true,"args":[{"nodeId":17,"type":32},{"nodeId":18,"type":32}],"origin":["builtin:default"]}],[23,{"tag":"use","id":23,"cds":[{"id":31,"when":true}]}],[25,{"tag":"fcall","id":25,"name":"print","onlyBuiltin":true,"cds":[{"id":31,"when":true}],"args":[{"nodeId":23,"type":32}],"origin":["builtin:default"]}],[27,{"tag":"use","id":27,"cds":[{"id":31,"when":true}]}],[29,{"tag":"fcall","id":29,"name":"print","onlyBuiltin":true,"cds":[{"id":31,"when":true}],"args":[{"nodeId":27,"type":32}],"origin":["builtin:default"]}],[30,{"tag":"fcall","id":30,"name":"{","onlyBuiltin":true,"cds":[{"id":31,"when":true}],"args":[{"nodeId":25,"type":32},{"nodeId":29,"type":32}],"origin":["builtin:expression-list"]}],[31,{"tag":"fcall","id":31,"name":"for","onlyBuiltin":true,"args":[{"nodeId":16,"type":32},{"nodeId":19,"type":32},{"nodeId":30,"type":32}],"origin":["builtin:for-loop"]}]],"edgeInformation":[[2,[[0,{"types":65}],[1,{"types":65}],["built-in:>",{"types":5}]]],[7,[[6,{"types":65}],[5,{"types":72}],["built-in:<-",{"types":5}]]],[5,[[6,{"types":2}],[7,{"types":2}]]],[8,[[7,{"types":72}],["built-in:{",{"types":5}]]],[15,[[8,{"types":72}],[14,{"types":72}],[2,{"types":65}],["built-in:if",{"types":5}]]],[13,[[12,{"types":65}],[11,{"types":72}],["built-in:<-",{"types":5}]]],[11,[[12,{"types":2}],[13,{"types":2}]]],[14,[[13,{"types":72}],["built-in:{",{"types":5}]]],[19,[[17,{"types":65}],[18,{"types":65}],["built-in::",{"types":5}]]],[18,[[5,{"types":1}],[11,{"types":1}]]],[25,[[23,{"types":73}],["built-in:print",{"types":5}]]],[23,[[5,{"types":1}],[11,{"types":1}]]],[29,[[27,{"types":73}],["built-in:print",{"types":5}]]],[27,[[16,{"types":1}]]],[30,[[25,{"types":64}],[29,{"types":72}],["built-in:{",{"types":5}]]],[16,[[19,{"types":2}]]],[31,[[16,{"types":64}],[19,{"types":65}],[30,{"types":320}],["built-in:for",{"types":5}]]]],"_unknownSideEffects":[{"id":25,"linkTo":{"type":"link-to-last-call","callName":{}}},{"id":29,"linkTo":{"type":"link-to-last-call","callName":{}}}]},"entryPoint":15,"exitPoints":[{"type":0,"nodeId":31}],"hooks":[],"cfgQuick":{"graph":{"roots":[32,15,"15-e",0,1,2,"2-e",8,5,6,7,"7-e","8-e",14,11,12,13,"13-e","14-e",16,31,17,18,19,"19-e",30,22,25,"25-e",24,23,"24-e",26,29,"29-e",28,27,"28-e","30-e","31-e","32-e"],"vtxInfos":[[32,[2,32,null,["32-e"]]],[15,[1,15,["2-e"],["15-e"]]],["15-e","15-e"],[0,[2,0]],[1,[2,1]],[2,[2,2,null,["2-e"]]],["2-e","2-e"],[8,[2,8,null,["8-e"]]],[5,[2,5]],[6,[2,6]],[7,[2,7,null,["7-e"]]],["7-e","7-e"],["8-e","8-e"],[14,[2,14,null,["14-e"]]],[11,[2,11]],[12,[2,12]],[13,[2,13,null,["13-e"]]],["13-e","13-e"],["14-e","14-e"],[16,[2,16]],[31,[1,31,[16],["31-e"]]],[17,[2,17]],[18,[2,18]],[19,[2,19,null,["19-e"]]],["19-e","19-e"],[30,[2,30,null,["30-e"]]],[22,[2,22]],[25,[1,25,[22],["25-e"]]],["25-e","25-e"],[24,[2,24,[24],["24-e"]]],[23,[2,23]],["24-e","24-e"],[26,[2,26]],[29,[1,29,[26],["29-e"]]],["29-e","29-e"],[28,[2,28,[28],["28-e"]]],[27,[2,27]],["28-e","28-e"],["30-e","30-e"],["31-e","31-e"],["32-e","32-e"]],"bbChildren":[],"edgeInfos":[[15,[[32,0]]],[1,[[0,0]]],[0,[[2,0]]],["2-e",[[1,0]]],[7,[[8,0]]],[6,[[5,0]]],[5,[[7,0]]],["7-e",[[6,0]]],["8-e",[["7-e",0]]],[13,[[14,0]]],[12,[[11,0]]],[11,[[13,0]]],["13-e",[[12,0]]],["14-e",[["13-e",0]]],[8,[["2-e",[15,"TRUE"]]]],[14,[["2-e",[15,"FALSE"]]]],[2,[[15,0]]],["15-e",[["8-e",0],["14-e",0]]],[31,[["15-e",0],["30-e",0]]],[18,[[17,0]]],[17,[[19,0]]],["19-e",[[18,0]]],[25,[[30,0]]],[22,[[25,0]]],[23,[[24,0]]],["24-e",[[23,0]]],[24,[[22,0]]],["25-e",[["24-e",0]]],[29,[["25-e",0]]],[26,[[29,0]]],[27,[[28,0]]],["28-e",[[27,0]]],[28,[[26,0]]],["29-e",[["28-e",0]]],["30-e",[["29-e",0]]],[19,[[31,0]]],[16,[["19-e",0]]],[30,[[16,[31,"TRUE"]]]],["31-e",[[16,[31,"FALSE"]]]],["32-e",[["31-e",0]]]],"revEdgeInfos":[[32,[[15,0]]],[0,[[1,0]]],[2,[[0,0]]],[1,[["2-e",0]]],[8,[[7,0]]],[5,[[6,0]]],[7,[[5,0]]],[6,[["7-e",0]]],["7-e",[["8-e",0]]],[14,[[13,0]]],[11,[[12,0]]],[13,[[11,0]]],[12,[["13-e",0]]],["13-e",[["14-e",0]]],["2-e",[[8,[15,"TRUE"]],[14,[15,"FALSE"]]]],[15,[[2,0]]],["8-e",[["15-e",0]]],["14-e",[["15-e",0]]],["15-e",[[31,0]]],[17,[[18,0]]],[19,[[17,0]]],[18,[["19-e",0]]],[30,[[25,0]]],[25,[[22,0]]],[24,[[23,0]]],[23,[["24-e",0]]],[22,[[24,0]]],["24-e",[["25-e",0]]],["25-e",[[29,0]]],[29,[[26,0]]],[28,[[27,0]]],[27,[["28-e",0]]],[26,[[28,0]]],["28-e",[["29-e",0]]],["29-e",[["30-e",0]]],[31,[[19,0]]],["19-e",[[16,0]]],[16,[[30,[31,"TRUE"]],["31-e",[31,"FALSE"]]]],["30-e",[[31,0]]],["31-e",[["32-e",0]]]],"_mayBB":false},"breaks":[],"nexts":[],"returns":[],"exitPoints":["32-e"],"entryPoints":[32]},".meta":{"timing":0}}}} +{"type":"response-file-analysis","format":"json","id":"1","cfg":{"returns":[],"entryPoints":[32],"exitPoints":["32-e"],"breaks":[],"nexts":[],"graph":{"roots":[32,15,"15-e",0,1,2,"2-e",8,5,6,7,"7-e","8-e",14,11,12,13,"13-e","14-e",16,31,17,18,19,"19-e",30,22,25,"25-e",24,23,"24-e",26,29,"29-e",28,27,"28-e","30-e","31-e","32-e"],"vtxInfos":[[32,[2,32,null,["32-e"]]],[15,[1,15,["2-e"],["15-e"]]],["15-e","15-e"],[0,[2,0]],[1,[2,1]],[2,[2,2,null,["2-e"]]],["2-e","2-e"],[8,[2,8,null,["8-e"]]],[5,[2,5]],[6,[2,6]],[7,[2,7,null,["7-e"]]],["7-e","7-e"],["8-e","8-e"],[14,[2,14,null,["14-e"]]],[11,[2,11]],[12,[2,12]],[13,[2,13,null,["13-e"]]],["13-e","13-e"],["14-e","14-e"],[16,[2,16]],[31,[1,31,[16],["31-e"]]],[17,[2,17]],[18,[2,18]],[19,[2,19,null,["19-e"]]],["19-e","19-e"],[30,[2,30,null,["30-e"]]],[22,[2,22]],[25,[1,25,[22],["25-e"]]],["25-e","25-e"],[24,[2,24,[24],["24-e"]]],[23,[2,23]],["24-e","24-e"],[26,[2,26]],[29,[1,29,[26],["29-e"]]],["29-e","29-e"],[28,[2,28,[28],["28-e"]]],[27,[2,27]],["28-e","28-e"],["30-e","30-e"],["31-e","31-e"],["32-e","32-e"]],"bbChildren":[],"edgeInfos":[[15,[[32,0]]],[1,[[0,0]]],[0,[[2,0]]],["2-e",[[1,0]]],[7,[[8,0]]],[6,[[5,0]]],[5,[[7,0]]],["7-e",[[6,0]]],["8-e",[["7-e",0]]],[13,[[14,0]]],[12,[[11,0]]],[11,[[13,0]]],["13-e",[[12,0]]],["14-e",[["13-e",0]]],[8,[["2-e",[15,"TRUE"]]]],[14,[["2-e",[15,"FALSE"]]]],[2,[[15,0]]],["15-e",[["8-e",0],["14-e",0]]],[31,[["15-e",0],["30-e",0]]],[18,[[17,0]]],[17,[[19,0]]],["19-e",[[18,0]]],[25,[[30,0]]],[22,[[25,0]]],[23,[[24,0]]],["24-e",[[23,0]]],[24,[[22,0]]],["25-e",[["24-e",0]]],[29,[["25-e",0]]],[26,[[29,0]]],[27,[[28,0]]],["28-e",[[27,0]]],[28,[[26,0]]],["29-e",[["28-e",0]]],["30-e",[["29-e",0]]],[19,[[31,0]]],[16,[["19-e",0]]],[30,[[16,[31,"TRUE"]]]],["31-e",[[16,[31,"FALSE"]]]],["32-e",[["31-e",0]]]],"revEdgeInfos":[[32,[[15,0]]],[0,[[1,0]]],[2,[[0,0]]],[1,[["2-e",0]]],[8,[[7,0]]],[5,[[6,0]]],[7,[[5,0]]],[6,[["7-e",0]]],["7-e",[["8-e",0]]],[14,[[13,0]]],[11,[[12,0]]],[13,[[11,0]]],[12,[["13-e",0]]],["13-e",[["14-e",0]]],["2-e",[[8,[15,"TRUE"]],[14,[15,"FALSE"]]]],[15,[[2,0]]],["8-e",[["15-e",0]]],["14-e",[["15-e",0]]],["15-e",[[31,0]]],[17,[[18,0]]],[19,[[17,0]]],[18,[["19-e",0]]],[30,[[25,0]]],[25,[[22,0]]],[24,[[23,0]]],[23,[["24-e",0]]],[22,[[24,0]]],["24-e",[["25-e",0]]],["25-e",[[29,0]]],[29,[[26,0]]],[28,[[27,0]]],[27,[["28-e",0]]],[26,[[28,0]]],["28-e",[["29-e",0]]],["29-e",[["30-e",0]]],[31,[[19,0]]],["19-e",[[16,0]]],[16,[[30,[31,"TRUE"]],["31-e",[31,"FALSE"]]]],["30-e",[[31,0]]],["31-e",[["32-e",0]]]],"_mayBB":false}},"results":{"parse":{"files":[{"parsed":"[1,1,1,42,38,0,\"expr\",false,\"if(unknown > 0) { x <- 2 } else { x <- 5 }\"],[1,1,1,2,1,38,\"IF\",true,\"if\"],[1,3,1,3,2,38,\"'('\",true,\"(\"],[1,4,1,14,9,38,\"expr\",false,\"unknown > 0\"],[1,4,1,10,3,5,\"SYMBOL\",true,\"unknown\"],[1,4,1,10,5,9,\"expr\",false,\"unknown\"],[1,12,1,12,4,9,\"GT\",true,\">\"],[1,14,1,14,6,7,\"NUM_CONST\",true,\"0\"],[1,14,1,14,7,9,\"expr\",false,\"0\"],[1,15,1,15,8,38,\"')'\",true,\")\"],[1,17,1,26,22,38,\"expr\",false,\"{ x <- 2 }\"],[1,17,1,17,12,22,\"'{'\",true,\"{\"],[1,19,1,24,19,22,\"expr\",false,\"x <- 2\"],[1,19,1,19,13,15,\"SYMBOL\",true,\"x\"],[1,19,1,19,15,19,\"expr\",false,\"x\"],[1,21,1,22,14,19,\"LEFT_ASSIGN\",true,\"<-\"],[1,24,1,24,16,17,\"NUM_CONST\",true,\"2\"],[1,24,1,24,17,19,\"expr\",false,\"2\"],[1,26,1,26,18,22,\"'}'\",true,\"}\"],[1,28,1,31,23,38,\"ELSE\",true,\"else\"],[1,33,1,42,35,38,\"expr\",false,\"{ x <- 5 }\"],[1,33,1,33,25,35,\"'{'\",true,\"{\"],[1,35,1,40,32,35,\"expr\",false,\"x <- 5\"],[1,35,1,35,26,28,\"SYMBOL\",true,\"x\"],[1,35,1,35,28,32,\"expr\",false,\"x\"],[1,37,1,38,27,32,\"LEFT_ASSIGN\",true,\"<-\"],[1,40,1,40,29,30,\"NUM_CONST\",true,\"5\"],[1,40,1,40,30,32,\"expr\",false,\"5\"],[1,42,1,42,31,35,\"'}'\",true,\"}\"],[2,1,2,36,84,0,\"expr\",false,\"for(i in 1:x) { print(x); print(i) }\"],[2,1,2,3,41,84,\"FOR\",true,\"for\"],[2,4,2,13,53,84,\"forcond\",false,\"(i in 1:x)\"],[2,4,2,4,42,53,\"'('\",true,\"(\"],[2,5,2,5,43,53,\"SYMBOL\",true,\"i\"],[2,7,2,8,44,53,\"IN\",true,\"in\"],[2,10,2,12,51,53,\"expr\",false,\"1:x\"],[2,10,2,10,45,46,\"NUM_CONST\",true,\"1\"],[2,10,2,10,46,51,\"expr\",false,\"1\"],[2,11,2,11,47,51,\"':'\",true,\":\"],[2,12,2,12,48,50,\"SYMBOL\",true,\"x\"],[2,12,2,12,50,51,\"expr\",false,\"x\"],[2,13,2,13,49,53,\"')'\",true,\")\"],[2,15,2,36,81,84,\"expr\",false,\"{ print(x); print(i) }\"],[2,15,2,15,54,81,\"'{'\",true,\"{\"],[2,17,2,24,64,81,\"expr\",false,\"print(x)\"],[2,17,2,21,55,57,\"SYMBOL_FUNCTION_CALL\",true,\"print\"],[2,17,2,21,57,64,\"expr\",false,\"print\"],[2,22,2,22,56,64,\"'('\",true,\"(\"],[2,23,2,23,58,60,\"SYMBOL\",true,\"x\"],[2,23,2,23,60,64,\"expr\",false,\"x\"],[2,24,2,24,59,64,\"')'\",true,\")\"],[2,25,2,25,65,81,\"';'\",true,\";\"],[2,27,2,34,77,81,\"expr\",false,\"print(i)\"],[2,27,2,31,68,70,\"SYMBOL_FUNCTION_CALL\",true,\"print\"],[2,27,2,31,70,77,\"expr\",false,\"print\"],[2,32,2,32,69,77,\"'('\",true,\"(\"],[2,33,2,33,71,73,\"SYMBOL\",true,\"i\"],[2,33,2,33,73,77,\"expr\",false,\"i\"],[2,34,2,34,72,77,\"')'\",true,\")\"],[2,36,2,36,78,81,\"'}'\",true,\"}\"]","filePath":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}],".meta":{"timing":2}},"normalize":{"ast":{"type":"RProject","files":[{"root":{"type":"RExpressionList","children":[{"type":"RIfThenElse","condition":{"type":"RBinaryOp","location":[1,12,1,12],"lhs":{"type":"RSymbol","location":[1,4,1,10],"content":"unknown","lexeme":"unknown","info":{"fullRange":[1,4,1,10],"adToks":[],"id":0,"parent":2,"role":"bin-l","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},"rhs":{"location":[1,14,1,14],"lexeme":"0","info":{"fullRange":[1,14,1,14],"adToks":[],"id":1,"parent":2,"role":"bin-r","index":1,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"},"type":"RNumber","content":{"num":0,"complexNumber":false,"markedAsInt":false}},"operator":">","lexeme":">","info":{"fullRange":[1,4,1,14],"adToks":[],"id":2,"parent":15,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","role":"if-c"}},"then":{"type":"RExpressionList","children":[{"type":"RBinaryOp","location":[1,21,1,22],"lhs":{"type":"RSymbol","location":[1,19,1,19],"content":"x","lexeme":"x","info":{"fullRange":[1,19,1,19],"adToks":[],"id":5,"parent":7,"role":"bin-l","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},"rhs":{"location":[1,24,1,24],"lexeme":"2","info":{"fullRange":[1,24,1,24],"adToks":[],"id":6,"parent":7,"role":"bin-r","index":1,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"},"type":"RNumber","content":{"num":2,"complexNumber":false,"markedAsInt":false}},"operator":"<-","lexeme":"<-","info":{"fullRange":[1,19,1,24],"adToks":[],"id":7,"parent":8,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":0,"role":"el-c"}}],"grouping":[{"type":"RSymbol","location":[1,17,1,17],"content":"{","lexeme":"{","info":{"fullRange":[1,17,1,26],"adToks":[],"id":3,"role":"el-g","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},{"type":"RSymbol","location":[1,26,1,26],"content":"}","lexeme":"}","info":{"fullRange":[1,17,1,26],"adToks":[],"id":4,"role":"el-g","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}}],"info":{"adToks":[],"id":8,"parent":15,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":1,"role":"if-then"}},"location":[1,1,1,2],"lexeme":"if","info":{"fullRange":[1,1,1,42],"adToks":[],"id":15,"parent":32,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":0,"role":"el-c"},"otherwise":{"type":"RExpressionList","children":[{"type":"RBinaryOp","location":[1,37,1,38],"lhs":{"type":"RSymbol","location":[1,35,1,35],"content":"x","lexeme":"x","info":{"fullRange":[1,35,1,35],"adToks":[],"id":11,"parent":13,"role":"bin-l","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},"rhs":{"location":[1,40,1,40],"lexeme":"5","info":{"fullRange":[1,40,1,40],"adToks":[],"id":12,"parent":13,"role":"bin-r","index":1,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"},"type":"RNumber","content":{"num":5,"complexNumber":false,"markedAsInt":false}},"operator":"<-","lexeme":"<-","info":{"fullRange":[1,35,1,40],"adToks":[],"id":13,"parent":14,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":0,"role":"el-c"}}],"grouping":[{"type":"RSymbol","location":[1,33,1,33],"content":"{","lexeme":"{","info":{"fullRange":[1,33,1,42],"adToks":[],"id":9,"role":"el-g","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},{"type":"RSymbol","location":[1,42,1,42],"content":"}","lexeme":"}","info":{"fullRange":[1,33,1,42],"adToks":[],"id":10,"role":"el-g","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}}],"info":{"adToks":[],"id":14,"parent":15,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":2,"role":"if-other"}}},{"type":"RForLoop","variable":{"type":"RSymbol","location":[2,5,2,5],"content":"i","lexeme":"i","info":{"adToks":[],"id":16,"parent":31,"role":"for-var","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},"vector":{"type":"RBinaryOp","location":[2,11,2,11],"lhs":{"location":[2,10,2,10],"lexeme":"1","info":{"fullRange":[2,10,2,10],"adToks":[],"id":17,"parent":19,"role":"bin-l","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"rhs":{"type":"RSymbol","location":[2,12,2,12],"content":"x","lexeme":"x","info":{"fullRange":[2,12,2,12],"adToks":[],"id":18,"parent":19,"role":"bin-r","index":1,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},"operator":":","lexeme":":","info":{"fullRange":[2,10,2,12],"adToks":[],"id":19,"parent":31,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":1,"role":"for-vec"}},"body":{"type":"RExpressionList","children":[{"type":"RFunctionCall","named":true,"location":[2,17,2,21],"lexeme":"print","functionName":{"type":"RSymbol","location":[2,17,2,21],"content":"print","lexeme":"print","info":{"fullRange":[2,17,2,24],"adToks":[],"id":22,"parent":25,"role":"call-name","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},"arguments":[{"type":"RArgument","location":[2,23,2,23],"lexeme":"x","value":{"type":"RSymbol","location":[2,23,2,23],"content":"x","lexeme":"x","info":{"fullRange":[2,23,2,23],"adToks":[],"id":23,"parent":24,"role":"arg-v","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},"info":{"fullRange":[2,23,2,23],"adToks":[],"id":24,"parent":25,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[2,17,2,24],"adToks":[],"id":25,"parent":30,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":0,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[2,27,2,31],"lexeme":"print","functionName":{"type":"RSymbol","location":[2,27,2,31],"content":"print","lexeme":"print","info":{"fullRange":[2,27,2,34],"adToks":[],"id":26,"parent":29,"role":"call-name","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},"arguments":[{"type":"RArgument","location":[2,33,2,33],"lexeme":"i","value":{"type":"RSymbol","location":[2,33,2,33],"content":"i","lexeme":"i","info":{"fullRange":[2,33,2,33],"adToks":[],"id":27,"parent":28,"role":"arg-v","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},"info":{"fullRange":[2,33,2,33],"adToks":[],"id":28,"parent":29,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[2,27,2,34],"adToks":[],"id":29,"parent":30,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":1,"role":"el-c"}}],"grouping":[{"type":"RSymbol","location":[2,15,2,15],"content":"{","lexeme":"{","info":{"fullRange":[2,15,2,36],"adToks":[],"id":20,"role":"el-g","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}},{"type":"RSymbol","location":[2,36,2,36],"content":"}","lexeme":"}","info":{"fullRange":[2,15,2,36],"adToks":[],"id":21,"role":"el-g","index":0,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}}],"info":{"adToks":[],"id":30,"parent":31,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":2,"role":"for-b"}},"lexeme":"for","info":{"fullRange":[2,1,2,36],"adToks":[],"id":31,"parent":32,"nesting":1,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","index":1,"role":"el-c"},"location":[2,1,2,3]}],"info":{"adToks":[],"id":32,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R","role":"root","index":0}},"filePath":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-EQWnUfZmmWxw-.R"}],"info":{"id":33}},".meta":{"timing":0}},"dataflow":{"unknownReferences":[],"in":[{"nodeId":15,"name":"if","type":2},{"nodeId":0,"name":"unknown","type":1},{"nodeId":2,"name":">","type":2},{"nodeId":7,"name":"<-","cds":[{"id":15,"when":true}],"type":2},{"nodeId":13,"name":"<-","cds":[{"id":15,"when":false}],"type":2},{"nodeId":8,"name":"{","cds":[{"id":15,"when":true}],"type":2},{"nodeId":14,"name":"{","cds":[{"id":15,"when":false}],"type":2},{"nodeId":31,"name":"for","type":2},{"nodeId":27,"name":"i","type":4},{"nodeId":19,"name":":","type":2},{"nodeId":25,"name":"print","type":2},{"nodeId":29,"name":"print","type":2}],"out":[{"nodeId":5,"name":"x","type":4,"definedAt":7,"cds":[{"id":15,"when":true}],"value":[6]},{"nodeId":11,"name":"x","type":4,"definedAt":13,"cds":[{"id":15,"when":true},{"id":15,"when":false}],"value":[12]},{"nodeId":16,"name":"i","type":1}],"environment":{"current":{"id":2677,"parent":"","memory":[["x",[{"nodeId":5,"name":"x","type":4,"definedAt":7,"cds":[{"id":15,"when":true},{"id":15,"when":false}],"value":[6]},{"nodeId":11,"name":"x","type":4,"definedAt":13,"cds":[{"id":15,"when":true},{"id":15,"when":false}],"value":[12]}]],["i",[{"nodeId":16,"name":"i","type":4,"definedAt":31}]]]},"level":0},"graph":{"rootVertices":[0,1,2,6,5,7,8,12,11,13,14,15,16,17,18,19,23,25,27,29,30,31],"vertexInformation":[[0,{"tag":"use","id":0}],[1,{"tag":"value","id":1}],[2,{"tag":"fcall","id":2,"name":">","onlyBuiltin":true,"args":[{"nodeId":0,"type":32},{"nodeId":1,"type":32}],"origin":["builtin:default"]}],[6,{"tag":"value","id":6}],[5,{"tag":"vdef","id":5,"cds":[{"id":15,"when":true}],"source":[6]}],[7,{"tag":"fcall","id":7,"name":"<-","onlyBuiltin":true,"cds":[{"id":15,"when":true}],"args":[{"nodeId":5,"type":32},{"nodeId":6,"type":32}],"origin":["builtin:assignment"]}],[8,{"tag":"fcall","id":8,"name":"{","onlyBuiltin":true,"cds":[{"id":15,"when":true}],"args":[{"nodeId":7,"type":32}],"origin":["builtin:expression-list"]}],[12,{"tag":"value","id":12}],[11,{"tag":"vdef","id":11,"cds":[{"id":15,"when":false}],"source":[12]}],[13,{"tag":"fcall","id":13,"name":"<-","onlyBuiltin":true,"cds":[{"id":15,"when":false}],"args":[{"nodeId":11,"type":32},{"nodeId":12,"type":32}],"origin":["builtin:assignment"]}],[14,{"tag":"fcall","id":14,"name":"{","onlyBuiltin":true,"cds":[{"id":15,"when":false}],"args":[{"nodeId":13,"type":32}],"origin":["builtin:expression-list"]}],[15,{"tag":"fcall","id":15,"name":"if","onlyBuiltin":true,"args":[{"nodeId":2,"type":32},{"nodeId":8,"type":32},{"nodeId":14,"type":32}],"origin":["builtin:if-then-else"]}],[16,{"tag":"vdef","id":16,"source":[19]}],[17,{"tag":"value","id":17}],[18,{"tag":"use","id":18}],[19,{"tag":"fcall","id":19,"name":":","onlyBuiltin":true,"args":[{"nodeId":17,"type":32},{"nodeId":18,"type":32}],"origin":["builtin:default"]}],[23,{"tag":"use","id":23,"cds":[{"id":31,"when":true}]}],[25,{"tag":"fcall","id":25,"name":"print","onlyBuiltin":true,"cds":[{"id":31,"when":true}],"args":[{"nodeId":23,"type":32}],"origin":["builtin:default"]}],[27,{"tag":"use","id":27,"cds":[{"id":31,"when":true}]}],[29,{"tag":"fcall","id":29,"name":"print","onlyBuiltin":true,"cds":[{"id":31,"when":true}],"args":[{"nodeId":27,"type":32}],"origin":["builtin:default"]}],[30,{"tag":"fcall","id":30,"name":"{","onlyBuiltin":true,"cds":[{"id":31,"when":true}],"args":[{"nodeId":25,"type":32},{"nodeId":29,"type":32}],"origin":["builtin:expression-list"]}],[31,{"tag":"fcall","id":31,"name":"for","onlyBuiltin":true,"args":[{"nodeId":16,"type":32},{"nodeId":19,"type":32},{"nodeId":30,"type":32}],"origin":["builtin:for-loop"]}]],"edgeInformation":[[2,[[0,{"types":65}],[1,{"types":65}],["built-in:>",{"types":5}]]],[7,[[6,{"types":65}],[5,{"types":72}],["built-in:<-",{"types":5}]]],[5,[[6,{"types":2}],[7,{"types":2}]]],[8,[[7,{"types":72}],["built-in:{",{"types":5}]]],[15,[[8,{"types":72}],[14,{"types":72}],[2,{"types":65}],["built-in:if",{"types":5}]]],[13,[[12,{"types":65}],[11,{"types":72}],["built-in:<-",{"types":5}]]],[11,[[12,{"types":2}],[13,{"types":2}]]],[14,[[13,{"types":72}],["built-in:{",{"types":5}]]],[19,[[17,{"types":65}],[18,{"types":65}],["built-in::",{"types":5}]]],[18,[[5,{"types":1}],[11,{"types":1}]]],[25,[[23,{"types":73}],["built-in:print",{"types":5}]]],[23,[[5,{"types":1}],[11,{"types":1}]]],[29,[[27,{"types":73}],["built-in:print",{"types":5}]]],[27,[[16,{"types":1}]]],[30,[[25,{"types":64}],[29,{"types":72}],["built-in:{",{"types":5}]]],[16,[[19,{"types":2}]]],[31,[[16,{"types":64}],[19,{"types":65}],[30,{"types":320}],["built-in:for",{"types":5}]]]],"_unknownSideEffects":[{"id":25,"linkTo":{"type":"link-to-last-call","callName":{}}},{"id":29,"linkTo":{"type":"link-to-last-call","callName":{}}}]},"entryPoint":15,"exitPoints":[{"type":0,"nodeId":31}],"hooks":[],"cfgQuick":{"graph":{"roots":[32,15,"15-e",0,1,2,"2-e",8,5,6,7,"7-e","8-e",14,11,12,13,"13-e","14-e",16,31,17,18,19,"19-e",30,22,25,"25-e",24,23,"24-e",26,29,"29-e",28,27,"28-e","30-e","31-e","32-e"],"vtxInfos":[[32,[2,32,null,["32-e"]]],[15,[1,15,["2-e"],["15-e"]]],["15-e","15-e"],[0,[2,0]],[1,[2,1]],[2,[2,2,null,["2-e"]]],["2-e","2-e"],[8,[2,8,null,["8-e"]]],[5,[2,5]],[6,[2,6]],[7,[2,7,null,["7-e"]]],["7-e","7-e"],["8-e","8-e"],[14,[2,14,null,["14-e"]]],[11,[2,11]],[12,[2,12]],[13,[2,13,null,["13-e"]]],["13-e","13-e"],["14-e","14-e"],[16,[2,16]],[31,[1,31,[16],["31-e"]]],[17,[2,17]],[18,[2,18]],[19,[2,19,null,["19-e"]]],["19-e","19-e"],[30,[2,30,null,["30-e"]]],[22,[2,22]],[25,[1,25,[22],["25-e"]]],["25-e","25-e"],[24,[2,24,[24],["24-e"]]],[23,[2,23]],["24-e","24-e"],[26,[2,26]],[29,[1,29,[26],["29-e"]]],["29-e","29-e"],[28,[2,28,[28],["28-e"]]],[27,[2,27]],["28-e","28-e"],["30-e","30-e"],["31-e","31-e"],["32-e","32-e"]],"bbChildren":[],"edgeInfos":[[15,[[32,0]]],[1,[[0,0]]],[0,[[2,0]]],["2-e",[[1,0]]],[7,[[8,0]]],[6,[[5,0]]],[5,[[7,0]]],["7-e",[[6,0]]],["8-e",[["7-e",0]]],[13,[[14,0]]],[12,[[11,0]]],[11,[[13,0]]],["13-e",[[12,0]]],["14-e",[["13-e",0]]],[8,[["2-e",[15,"TRUE"]]]],[14,[["2-e",[15,"FALSE"]]]],[2,[[15,0]]],["15-e",[["8-e",0],["14-e",0]]],[31,[["15-e",0],["30-e",0]]],[18,[[17,0]]],[17,[[19,0]]],["19-e",[[18,0]]],[25,[[30,0]]],[22,[[25,0]]],[23,[[24,0]]],["24-e",[[23,0]]],[24,[[22,0]]],["25-e",[["24-e",0]]],[29,[["25-e",0]]],[26,[[29,0]]],[27,[[28,0]]],["28-e",[[27,0]]],[28,[[26,0]]],["29-e",[["28-e",0]]],["30-e",[["29-e",0]]],[19,[[31,0]]],[16,[["19-e",0]]],[30,[[16,[31,"TRUE"]]]],["31-e",[[16,[31,"FALSE"]]]],["32-e",[["31-e",0]]]],"revEdgeInfos":[[32,[[15,0]]],[0,[[1,0]]],[2,[[0,0]]],[1,[["2-e",0]]],[8,[[7,0]]],[5,[[6,0]]],[7,[[5,0]]],[6,[["7-e",0]]],["7-e",[["8-e",0]]],[14,[[13,0]]],[11,[[12,0]]],[13,[[11,0]]],[12,[["13-e",0]]],["13-e",[["14-e",0]]],["2-e",[[8,[15,"TRUE"]],[14,[15,"FALSE"]]]],[15,[[2,0]]],["8-e",[["15-e",0]]],["14-e",[["15-e",0]]],["15-e",[[31,0]]],[17,[[18,0]]],[19,[[17,0]]],[18,[["19-e",0]]],[30,[[25,0]]],[25,[[22,0]]],[24,[[23,0]]],[23,[["24-e",0]]],[22,[[24,0]]],["24-e",[["25-e",0]]],["25-e",[[29,0]]],[29,[[26,0]]],[28,[[27,0]]],[27,[["28-e",0]]],[26,[[28,0]]],["28-e",[["29-e",0]]],["29-e",[["30-e",0]]],[31,[[19,0]]],["19-e",[[16,0]]],[16,[[30,[31,"TRUE"]],["31-e",[31,"FALSE"]]]],["30-e",[[31,0]]],["31-e",[["32-e",0]]]],"_mayBB":false},"breaks":[],"nexts":[],"returns":[],"exitPoints":["32-e"],"entryPoints":[32]},".meta":{"timing":1}}}} ``` @@ -1181,7 +1182,7 @@ _As the code is pretty long, we inhibit pretty printing and syntax highlighting -The complete round-trip took 7.8 ms (including time required to validate the messages, start, and stop the internal mock server). +The complete round-trip took 7.1 ms (including time required to validate the messages, start, and stop the internal mock server). @@ -1221,7 +1222,7 @@ The first message is always a hello message. "clientName": "client-0", "versions": { "flowr": "2.10.4", - "r": "4.5.0", + "r": "4.5.2", "engine": "r-shell" } } @@ -1283,7 +1284,7 @@ _As the code is pretty long, we inhibit pretty printing and syntax highlighting -The complete round-trip took 6.8 ms (including time required to validate the messages, start, and stop the internal mock server). +The complete round-trip took 5.3 ms (including time required to validate the messages, start, and stop the internal mock server). @@ -1320,7 +1321,7 @@ The first message is always a hello message. "clientName": "client-0", "versions": { "flowr": "2.10.4", - "r": "4.5.0", + "r": "4.5.2", "engine": "r-shell" } } @@ -1370,7 +1371,7 @@ Please note, that the base message format is still JSON. Only the individual res _As the code is pretty long, we inhibit pretty printing and syntax highlighting (JSON, hiding built-in):_ ```text -{"type":"response-file-analysis","format":"compact","id":"1","cfg":"ᯡ࠳䅬̀坐ᶡ乀஠洢琣℥犸ŜHߐএ妔Ǔ㗠ߙ⣬啕㑡偍ȱ琢᩠ѐې矏ġ巊☼Ćモ⏤䏽缣剁ϥ⏳⁏ᆼ夤ڲ堨㉋ᐪ㠼ᠨĸ䪼㉙⦷ḷ剋剁ǧᨮ㉟剞娷ေ᪾㉛㔵㉄ᮽ㉅扐㉓⤵㐡ΩЯ㉈䠦栺㉒㉑઴牐䄯琳搾ဪᷩ倽堷屼ᨾ剅戭㉟剛ㄳ㉎⏹㉑┬圦伤㉈牕劻牗㉏⤡⡉圠㘨籇㉺ত堷⡜ਖ਼礫൧䌦ᠶ簠籡ੂ缠੗牏⤧䔥੐牕⤠ǻဵ੖䉜こ⦲性੓੕㋡䟾ߴੂ攸䠡ੑԩ੆䁳⠨䩔㉉⏰䩗ੇ樧‱䀴Ⅲ੔ᑝ呒戵䩝䩃Խ໪≗ḧ䩚ੋ䧹帨⩐堣䩁ᇤᠣ僻磻㔶⠪⩅ᔦ⩇㌫␮䬳ద則৬扜毻6㠭༺∯⇯ᠥ䬯ḽ堥缮礵眾⩘⏬⼫㇬橏⠫㲱┶⠭氵凶⩞橚ㇾ⌲剌扚剖≖剃⩔ᯫ⩃'⩐栦∶᩿⩃琱ᯤ片ᤵ眩橀䅫㇢ᩋ凭翿⹹੽簻㑏皠ľᩌ儺啭⩎剏⻡䬷ৠ✼4ᠠᠣᎯ椲᲼㖲㱗昹ᩍ簵ᩛ✮ᩜ婑決㸧䑇悮婜槣橝⩞恭叵橅婐࿠ଥ㻲⿡੆᱊ɉ牎廡婙帵囪挼憯嫫䩁ㄨ㫼㔲㩋抨㫾娹簹✽缾㩌懡䢤婀㘩㩖澻Ⓗ㩁⩢ᦤ⤼呁熭㾷样㩔员㌨汊栶簲ᜤ怰样ုᠧ䠳搦栴⡁≒缰積┴呓匹穏㩌⣯ਗ਼桋ɗᴭ䧹Ǵ唵㥳⠲唧⬧Ꮾ䏥䬤娩䏳ᏺ揲䏢ف栱ᐦ挷栠氦ϡ样栱緹緵緾㜱穙Ŀᔳϲ怮唧緲怡㬪局䩈䙞⌴ٛ可搢ق䲴瑺ل搶يᗡϯ棩ٍ句ٍفϣٖ笫ٓ⠴䙊焻䙇ᔠDZᐻ濪߱Dz怰♌䙖砳叴Ᏺ䙋娺䙜䏪Ϯ䙋娮ّ䙑ّ牏⻵䙞ϱϦ撫䙔♀፤徳⠬♀♄᱾䤺徿♈晜♃叩㷷ᏼن♊援ᣦ揾䙞ى䙕♑∮Ͻىϳٟ婄扴晗栽䤷ِ♈⤠䙘㯦ᦳ⠨ᙇ礼䙔㷺♑䏶♂Ϯ晆ّ♁䙁ٙ䙂ᨽ♍晋♓晒缤ᙋ眷䙅Ю㐠DZጸ晝ǧᙇ䀽䤿巢♒晌ْᙔ′ن䙖ᙁ♑䏩♑ᙙ晞緵ك♃䙄ᯪ䱃渳ᙋ␷晏♈噛䀠ᙜ䢯㰥紳⿺ૹĠ傼⑆₼ᙞ䏪䙖時䏮噊噁噉晙ٕ晝䙝晓䙝ᙌ㙘㙌䇢徺怪渹穏ᠵ灙ㆤ摞ḿ㙐栰癈ᔼǥ䉆䁴癜癔嗷渦癇䀢癆न㽴擾棨燪癇圾㽧ʽ嶳紲棸ᆭ癜懣癘ᑾ棲㴩棷撩ᬩᾢ๟击玫ي๎缢๒䤩巨䙍䑑ᩍ̻Ὣ巹ๆ決๝ⶱ穓巢堳๋汩⦩๏㸥๚绹砠乕๚仼绢乒癀ㇽᙋ绦也憺乄乗汬䬥累䨲䠱乔緽乄報乐⇮乃噀㘠傣乏乓䬧乓久乆婙㱋义ޣ栯九癀⹘汈⹓欲⹏ቇ⒥⹈唴乞娵⧻㔧⹛๗㮡≝∯⹅ణ䓯江ᪧ⹂ℼ⹕ㆪ湟⹛᮱穘⹞䄼ê湛⹕穵㱔擶簨籁⹆๝ᙃ湂䩇䔷湑慪㈦⑇⏤泿乛湐⹛ุṈ㩞㣳㔪&䤨伲乑ܦ㸮Ṕ溵橫湇๝ᙙṞṃ⼭⹋ṕṑ瑘梹䈵䨡ṇ您幟Ṛ啷Ǵ㼬幄幀町幇ṅ䩙穄堶Ώ㔢㠸椲䠹幖湁䞱穕幊椣幔⩑幝幟ϥ湒䜷⹐栤㹓幍ឱ穖簼㹒ब㹁๘⺣ж⠫ཱṙ䔱㹙㹖乜ṉ⹎咭㹉ོ产㹒睠摎)㹟ᑉ⥴擶ᠸ繓湐๑⹛产㹈籏摋\"繂籊㈼繑䊨♋⿬ⷱ㹕繃㹃Ṃṙ䰥繛ᐿ棿ᪿ繌=幼繜㹋ັ㹆㹝Ṁ湝ᙌŎ๞繈繄㹁䷡繂⌱冢ŅŁ挱冬ṇ繋㹏繑㹕ş拵᷿œŅ冱猹穋䠸呉ާ幂䅞恢㹜㞻幜䅕穛Ⓔ䅊呓紱㪳㑲屽䅀瑻ņŏ⻵㩎⬫䅐ᰧ呰⅐Ṓ౩烦抭棳Į䅎窢ᨿ䅎ᱧ屳抸ᓮ㱷Ŀʷ搯ᗽ缠コ৪繓㹗婉䉗Ő༳⅏ᗧ根Я早᷵≔潽琲䧼憳奩堪攷栾ȧᆠ巷栮慁慚⅞撶⅀⩖摩慅慛岦㩆慗㐧慐᱖ᩎᾪ砱㯯䨭砦⼸䙘朣欫⠴ᅍ䑂ᅀ岻繗䅖ᐮ⅓✦ᅎԬᅕ嚲ᅒ婄ᅃ3ᅁᅖ⡪⼽ᅄ剂楨样ᅉᅎ湙仵ᅌ䀬兖ᅙ剁⼸兖Q兆伤ᑛḼ淹兜䚪䠭兇䅒兏䅓慔婃兕兗᩵෰ㅋ兄婨Ỵㅎ䉫ෲㅑ䉭慂咣慏婗繍ᅗᅅ党ڶㅍ朦ㅜㅘᅎ兘າ怼∵嚢⅚ㅅㅖ洿ㅑᐥᑫᇺ兝漹兄煆怠煎癑6兎Էㅔ煅ⅈ充ㅋ䈦⟿ਗ਼ᅝ煜求克幊兟兀㘱煜䩣煇ᅇㅔ्䜥ㅓ兌≊ू癎ㅗ璡ㅏ⅑朴ㅌॉ煚॒ेㅎ䤼⧸♛漹克ॏ煒㹀॑ㅟⅆ兏ू䈫⽿᪸ृ䳼䥅䡙児ቆेㅞ䥞क़墱ॉ㏹ॅㅉ䥃ㅃ䥏扖䥅ㅈㅠ䔩忹兟䥍჻ⅇŗ⅍䥔娪䥊ᡖ\"呄ㅏ䥝゠僤ሼ汱擫ᅑᅕ効⥙ྵ⥞ヴ⥙ᅜ⥄䉃䐣⥞ᅛᅛ㄰楜ᅛᅞ唬癑癘癕唲楈癜Ƕ愩䗸䠭␪楈毱䟫扏䈵䏲灔〦◲䐾⻷䏳楓㟼↭⻰☣璽氠㗩吭屪ᐣ楟䏴娼簻⑔ಳ璶揢缠癅楛ㄥ᥎楔㗳揢楷/已未䤨ෳ⧦ϸ毮⇾␥堻氫䔷水ȱ㙅♟⥜䀼痺㷱┧᥋ᥔ擩奇揯ᥙ砠奓簢ᨸ奇ጬ套ᐢ奀吪奁ᙉ㙜扙䰥㗻⒵奇樫㗹奜㩗堧᥍奁䢥䤳奝噖ᐧ奋㠯奇氠吸غ奉ᙝᙌ痻ㄺ㥜ر奒㥜㗤神嬣奏㗰奍叭㥔奇ᐳ㥃䐲᏾緱晆奔㥐ᠿ㥙帺㥁奄唯㸦㥎䉝⤧祁㥞⢩㥒祋奙仦祒怣㥀㥁祛㥘㥅祑穇ٛ⒮㸫祊㈩՗祋煕㤧祗ᥑ㥟᥄Յ㥉吠揷奎祊՘倨㥙祗㥉ㅇ⤦唿⤳Ո祄ሷ㸨唭՛穙收㸠՚⧢祁痯Չ┨儰䕜奟ᐺՈ䠧㥙晊幕㸪䕋梥䕁䕖䕈Ṝ╛1祅墺╆1祜祘䀹㥈奀䕝㥈䕏䕄䕆Ռ䕈╝梾╂㼾╚Ꮽ乘甼∱䡱䕓ə夸㙌末㑁═Ն₸Ճ䕕╛䕝╗䕒奛╙♜䕄䥄太敔敌⡬⹄敆教Շק敐ᕜ敇濡਼㙚敌敋ՈՇՑ敚祍╖祕敐㥝救噖奒ᕗ敊⛢椤ᕚᕒ╘ᕚ怬ᕇज़ᕀ啎敊撡敘෩敐Ꮵ敟奓╔䕃敗╓夫㙉椸㙈ᕝ栥啐啝繀夽啔啛格啊祛契ᕂՃ╒奎啍ᕕ祗䌩啊↻啗愾䱣啚૲㸦ᕞ敎ᕂ啁ᕙ敉ᕆ啍敀╖Փ敌彾䱭䧶㕏ᕃ䈶㕎㕈⻱!㕑㕌啙㕟啌Ր㕒Ֆ啔㕄㥑穒㸿㕋帨敄ስ峣෤畈溣畄•畗啊畔Տ⻼Վ畓㕉神啖奇畋ᕌ摸島敟唪峡╋畒䦲൑╄笠൓䕘൘㕅ᕋ㕇╂െ൑ᔹൕ啐唦╗稼睯ᔵ䕁㻽䕅㕀㕍㕈㕙ᕟ䕌ൌ㕗์䵈唧㝱簵䕂㝭䵁䕑൓冨䵁േ啍栯啐ൕ㥖畓ു祁畎՝ᙗ䵕䵕Ր畐礩Մ䵗ὶ㠾ⵍ䕙╗Ւ啖叺啞祘倵ᕑ畝ᙎⵔ╇彩ⵝ䵓傣&ⵋ佴浆䕅ⵅ╕㕊啝㕋ⵑ═╖奟ⵅ䵙ア测䵐畊䇷栻䵅Ƴ浏畀ⵍ൝ⵄ奖䵃㕋㥛൜൜㕑媺䇳䇺䇵啗浛浏皮ᵟ䵁ᠠᵆ浃ⵎ浘䕁浛㕁啇䒣䇾▦ᵕ啑⇨ᩞ␾ᵞ౏⩈ᵏ浙ᵒ䵚畈ൄⵎ䵛ⵌᵑ䵝ᙐ嵈ᵏწ嵇ጠ嵍嵋㠶╉޹嵝嵂嵁⦪嵈ⵟՆ䵄ോു䵗ⵂ䕙䗳嵘徠≚㵒怭留繊⇤嵃㌱㒪〿嵐ⵝൖ嵄ᵞ䵖ϧൂᵑ䢶呪൒戵㵗畐畄絏䵄ቇ䇷畝㵅ᵚ䵖浘ᵞ浜ⵇ㕝愪⇼亩㵕啃⠸䏸䀹㵑ܳ絁⏻絉ᵀ㵕ⵞᕛᏴ⌹ࠪᠥ௦1䀨毫㵞浇ⵂⵒ㵎ᐵ牂挥⏣絕͇絟㲽͐̓㵆ϧ搢䢶煐䙈渺͘㵞絔㵌ⵞ͙絈憹͍㬫͇樲痣͔显䍛ͅᵂكൎ嵉絛ᵛร痧䔩䍎䍛嵂楾䍆結㵄㠵䍖̓ᵃ䍖奛䍛⒰⍐畛痡䍆嘮⍙䍘⍟嗱䏭䍛㵞嵜㵁͋敄*෧䔱⍇樮⍞⍝ᘰ捉⍘ͅ㕔⍄㵔ⵋ╁嵂㵛⍗⍛⒤捘ሣἩ∥∭∳琳Ƞ丿´縯∹娴⨱␨娶䈬刣ἧ畕㻪栫岥䩷啜㲦଩日㕕‭䀴琺倵⠹ઠᴵᐵ㵃ଫ㗺䀷⠲嬬䀠፞ᰧ␾䈷-䀫ፐ搰娸䈸砷砿砫䏽嬰ፎ〲ȫ⠤卅;䂴∲濴ȯᠾԨ怶槩㏩吻״氧唿砯∳•ȷ卓⨦␠㍅ȫᐳ⤼䚵燧⧪熰㕜༨ျ‸卌䀸湔∨嗨ြဩ㍃䐷ፓ㰪᧠卆倳㍘䠩卖ȴ娱ȭ南栣卌᧫卝栧卝ضబ㍒核㍃樨ⰾ獕Ȳ㍑厳↦㍇㔡᥋栮䈠縫䀸䀨␵፟䇽ፄ琥‵‧ਤ㠮䀪倠午卉Ȥ㠱䀼㍝∫䘬吢ୁᰨፅ‭䀣ፎ卖堤㠱୊ဵୀ࿽ୗ;‫㗶୅搤㠢䀨䭆倫㗱㍎ୖ刺ଢ଼㍛ୀᠲୁ䭌⢻㨸ᰠ䭁䭐樵⠬汽ⶬ恋㠷㐴䠯枠࿡䈨癈⭝Ʒ堲㘱Ч唵䭇嬡楟䰭⠳絟㰷⠰簾ⰽᜨ "} +{"type":"response-file-analysis","format":"compact","id":"1","cfg":"ᯡ࠳䅬̀坐ᶡ乀஠洢琣℥犸ŜHߐএ妔Ǔ㗠ߙ⣬啕㑡偍ȱ琢᩠ѐې矏ġ巊☼Ćモ -The complete round-trip took 43.9 ms (including time required to validate the messages, start, and stop the internal mock server). +The complete round-trip took 46.4 ms (including time required to validate the messages, start, and stop the internal mock server). @@ -1510,7 +1511,7 @@ The first message is always a hello message. "clientName": "client-0", "versions": { "flowr": "2.10.4", - "r": "4.5.0", + "r": "4.5.2", "engine": "r-shell" } } @@ -1566,7 +1567,7 @@ See [above](#message-request-file-analysis) for the general structure of the res _As the code is pretty long, we inhibit pretty printing and syntax highlighting (JSON, hiding built-in):_ ```text -{"type":"response-file-analysis","format":"json","id":"1","results":{"parse":{"files":[{"parsed":"[1,1,1,6,7,0,\"expr\",false,\"x <- 1\"],[1,1,1,1,1,3,\"SYMBOL\",true,\"x\"],[1,1,1,1,3,7,\"expr\",false,\"x\"],[1,3,1,4,2,7,\"LEFT_ASSIGN\",true,\"<-\"],[1,6,1,6,4,5,\"NUM_CONST\",true,\"1\"],[1,6,1,6,5,7,\"expr\",false,\"1\"],[2,1,2,5,16,0,\"expr\",false,\"x + 1\"],[2,1,2,1,10,12,\"SYMBOL\",true,\"x\"],[2,1,2,1,12,16,\"expr\",false,\"x\"],[2,3,2,3,11,16,\"'+'\",true,\"+\"],[2,5,2,5,13,14,\"NUM_CONST\",true,\"1\"],[2,5,2,5,14,16,\"expr\",false,\"1\"]","filePath":"/tmp/tmp-8880-EdJ7lBQBonTP-.R"}],".meta":{"timing":1}},"normalize":{"ast":{"type":"RProject","files":[{"root":{"type":"RExpressionList","children":[{"type":"RBinaryOp","location":[1,3,1,4],"lhs":{"type":"RSymbol","location":[1,1,1,1],"content":"x","lexeme":"x","info":{"fullRange":[1,1,1,1],"adToks":[],"id":0,"parent":2,"role":"bin-l","index":0,"nesting":0,"file":"/tmp/tmp-8880-EdJ7lBQBonTP-.R"}},"rhs":{"location":[1,6,1,6],"lexeme":"1","info":{"fullRange":[1,6,1,6],"adToks":[],"id":1,"parent":2,"role":"bin-r","index":1,"nesting":0,"file":"/tmp/tmp-8880-EdJ7lBQBonTP-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"operator":"<-","lexeme":"<-","info":{"fullRange":[1,1,1,6],"adToks":[],"id":2,"parent":6,"nesting":0,"file":"/tmp/tmp-8880-EdJ7lBQBonTP-.R","index":0,"role":"el-c"}},{"type":"RBinaryOp","location":[2,3,2,3],"lhs":{"type":"RSymbol","location":[2,1,2,1],"content":"x","lexeme":"x","info":{"fullRange":[2,1,2,1],"adToks":[],"id":3,"parent":5,"role":"bin-l","index":0,"nesting":0,"file":"/tmp/tmp-8880-EdJ7lBQBonTP-.R"}},"rhs":{"location":[2,5,2,5],"lexeme":"1","info":{"fullRange":[2,5,2,5],"adToks":[],"id":4,"parent":5,"role":"bin-r","index":1,"nesting":0,"file":"/tmp/tmp-8880-EdJ7lBQBonTP-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"operator":"+","lexeme":"+","info":{"fullRange":[2,1,2,5],"adToks":[],"id":5,"parent":6,"nesting":0,"file":"/tmp/tmp-8880-EdJ7lBQBonTP-.R","index":1,"role":"el-c"}}],"info":{"adToks":[],"id":6,"nesting":0,"file":"/tmp/tmp-8880-EdJ7lBQBonTP-.R","role":"root","index":0}},"filePath":"/tmp/tmp-8880-EdJ7lBQBonTP-.R"}],"info":{"id":7}},".meta":{"timing":1}},"dataflow":{"unknownReferences":[],"in":[{"nodeId":2,"name":"<-","type":2},{"nodeId":5,"name":"+","type":2}],"out":[{"nodeId":0,"name":"x","type":4,"definedAt":2,"value":[1]}],"environment":{"current":{"id":2722,"parent":"","memory":[["x",[{"nodeId":0,"name":"x","type":4,"definedAt":2,"value":[1]}]]]},"level":0},"graph":{"rootVertices":[1,0,2,3,4,5],"vertexInformation":[[1,{"tag":"value","id":1}],[0,{"tag":"vdef","id":0,"source":[1]}],[2,{"tag":"fcall","id":2,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":0,"type":32},{"nodeId":1,"type":32}],"origin":["builtin:assignment"]}],[3,{"tag":"use","id":3}],[4,{"tag":"value","id":4}],[5,{"tag":"fcall","id":5,"name":"+","onlyBuiltin":true,"args":[{"nodeId":3,"type":32},{"nodeId":4,"type":32}],"origin":["builtin:default"]}]],"edgeInformation":[[2,[[1,{"types":65}],[0,{"types":72}],["built-in:<-",{"types":5}]]],[0,[[1,{"types":2}],[2,{"types":2}]]],[3,[[0,{"types":1}]]],[5,[[3,{"types":65}],[4,{"types":65}],["built-in:+",{"types":5}]]]],"_unknownSideEffects":[]},"entryPoint":2,"exitPoints":[{"type":0,"nodeId":5}],"hooks":[],".meta":{"timing":0}}}} +{"type":"response-file-analysis","format":"json","id":"1","results":{"parse":{"files":[{"parsed":"[1,1,1,6,7,0,\"expr\",false,\"x <- 1\"],[1,1,1,1,1,3,\"SYMBOL\",true,\"x\"],[1,1,1,1,3,7,\"expr\",false,\"x\"],[1,3,1,4,2,7,\"LEFT_ASSIGN\",true,\"<-\"],[1,6,1,6,4,5,\"NUM_CONST\",true,\"1\"],[1,6,1,6,5,7,\"expr\",false,\"1\"],[2,1,2,5,16,0,\"expr\",false,\"x + 1\"],[2,1,2,1,10,12,\"SYMBOL\",true,\"x\"],[2,1,2,1,12,16,\"expr\",false,\"x\"],[2,3,2,3,11,16,\"'+'\",true,\"+\"],[2,5,2,5,13,14,\"NUM_CONST\",true,\"1\"],[2,5,2,5,14,16,\"expr\",false,\"1\"]","filePath":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-LGHJy2rphRe2-.R"}],".meta":{"timing":2}},"normalize":{"ast":{"type":"RProject","files":[{"root":{"type":"RExpressionList","children":[{"type":"RBinaryOp","location":[1,3,1,4],"lhs":{"type":"RSymbol","location":[1,1,1,1],"content":"x","lexeme":"x","info":{"fullRange":[1,1,1,1],"adToks":[],"id":0,"parent":2,"role":"bin-l","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-LGHJy2rphRe2-.R"}},"rhs":{"location":[1,6,1,6],"lexeme":"1","info":{"fullRange":[1,6,1,6],"adToks":[],"id":1,"parent":2,"role":"bin-r","index":1,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-LGHJy2rphRe2-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"operator":"<-","lexeme":"<-","info":{"fullRange":[1,1,1,6],"adToks":[],"id":2,"parent":6,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-LGHJy2rphRe2-.R","index":0,"role":"el-c"}},{"type":"RBinaryOp","location":[2,3,2,3],"lhs":{"type":"RSymbol","location":[2,1,2,1],"content":"x","lexeme":"x","info":{"fullRange":[2,1,2,1],"adToks":[],"id":3,"parent":5,"role":"bin-l","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-LGHJy2rphRe2-.R"}},"rhs":{"location":[2,5,2,5],"lexeme":"1","info":{"fullRange":[2,5,2,5],"adToks":[],"id":4,"parent":5,"role":"bin-r","index":1,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-LGHJy2rphRe2-.R"},"type":"RNumber","content":{"num":1,"complexNumber":false,"markedAsInt":false}},"operator":"+","lexeme":"+","info":{"fullRange":[2,1,2,5],"adToks":[],"id":5,"parent":6,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-LGHJy2rphRe2-.R","index":1,"role":"el-c"}}],"info":{"adToks":[],"id":6,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-LGHJy2rphRe2-.R","role":"root","index":0}},"filePath":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-LGHJy2rphRe2-.R"}],"info":{"id":7}},".meta":{"timing":0}},"dataflow":{"unknownReferences":[],"in":[{"nodeId":2,"name":"<-","type":2},{"nodeId":5,"name":"+","type":2}],"out":[{"nodeId":0,"name":"x","type":4,"definedAt":2,"value":[1]}],"environment":{"current":{"id":2703,"parent":"","memory":[["x",[{"nodeId":0,"name":"x","type":4,"definedAt":2,"value":[1]}]]]},"level":0},"graph":{"rootVertices":[1,0,2,3,4,5],"vertexInformation":[[1,{"tag":"value","id":1}],[0,{"tag":"vdef","id":0,"source":[1]}],[2,{"tag":"fcall","id":2,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":0,"type":32},{"nodeId":1,"type":32}],"origin":["builtin:assignment"]}],[3,{"tag":"use","id":3}],[4,{"tag":"value","id":4}],[5,{"tag":"fcall","id":5,"name":"+","onlyBuiltin":true,"args":[{"nodeId":3,"type":32},{"nodeId":4,"type":32}],"origin":["builtin:default"]}]],"edgeInformation":[[2,[[1,{"types":65}],[0,{"types":72}],["built-in:<-",{"types":5}]]],[0,[[1,{"types":2}],[2,{"types":2}]]],[3,[[0,{"types":1}]]],[5,[[3,{"types":65}],[4,{"types":65}],["built-in:+",{"types":5}]]]],"_unknownSideEffects":[]},"entryPoint":2,"exitPoints":[{"type":0,"nodeId":5}],"hooks":[],".meta":{"timing":0}}}} ``` @@ -1631,7 +1632,7 @@ The `results` field of the response contains two keys of importance: -The complete round-trip took 7.0 ms (including time required to validate the messages, start, and stop the internal mock server). +The complete round-trip took 6.0 ms (including time required to validate the messages, start, and stop the internal mock server). @@ -1770,7 +1771,7 @@ The first message is always a hello message. "clientName": "client-0", "versions": { "flowr": "2.10.4", - "r": "4.5.0", + "r": "4.5.2", "engine": "r-shell" } } @@ -1894,7 +1895,7 @@ You can combine commands by separating them with a semicolon ;. -The complete round-trip took 1.0 ms (including time required to validate the messages, start, and stop the internal mock server). +The complete round-trip took 0.8 ms (including time required to validate the messages, start, and stop the internal mock server). @@ -2003,7 +2004,7 @@ The first message is always a hello message. "clientName": "client-0", "versions": { "flowr": "2.10.4", - "r": "4.5.0", + "r": "4.5.2", "engine": "r-shell" } } @@ -2076,7 +2077,7 @@ See [above](#message-request-file-analysis) for the general structure of the res _As the code is pretty long, we inhibit pretty printing and syntax highlighting (JSON, hiding built-in):_ ```text -{"type":"response-file-analysis","format":"json","id":"1","results":{"parse":{"files":[{"parsed":"[1,1,1,15,10,0,\"expr\",false,\"library(ggplot)\"],[1,1,1,7,1,3,\"SYMBOL_FUNCTION_CALL\",true,\"library\"],[1,1,1,7,3,10,\"expr\",false,\"library\"],[1,8,1,8,2,10,\"'('\",true,\"(\"],[1,9,1,14,4,6,\"SYMBOL\",true,\"ggplot\"],[1,9,1,14,6,10,\"expr\",false,\"ggplot\"],[1,15,1,15,5,10,\"')'\",true,\")\"],[2,1,2,14,23,0,\"expr\",false,\"library(dplyr)\"],[2,1,2,7,14,16,\"SYMBOL_FUNCTION_CALL\",true,\"library\"],[2,1,2,7,16,23,\"expr\",false,\"library\"],[2,8,2,8,15,23,\"'('\",true,\"(\"],[2,9,2,13,17,19,\"SYMBOL\",true,\"dplyr\"],[2,9,2,13,19,23,\"expr\",false,\"dplyr\"],[2,14,2,14,18,23,\"')'\",true,\")\"],[3,1,3,14,36,0,\"expr\",false,\"library(readr)\"],[3,1,3,7,27,29,\"SYMBOL_FUNCTION_CALL\",true,\"library\"],[3,1,3,7,29,36,\"expr\",false,\"library\"],[3,8,3,8,28,36,\"'('\",true,\"(\"],[3,9,3,13,30,32,\"SYMBOL\",true,\"readr\"],[3,9,3,13,32,36,\"expr\",false,\"readr\"],[3,14,3,14,31,36,\"')'\",true,\")\"],[5,1,5,25,42,-59,\"COMMENT\",true,\"# read data with read_csv\"],[6,1,6,28,59,0,\"expr\",false,\"data <- read_csv('data.csv')\"],[6,1,6,4,45,47,\"SYMBOL\",true,\"data\"],[6,1,6,4,47,59,\"expr\",false,\"data\"],[6,6,6,7,46,59,\"LEFT_ASSIGN\",true,\"<-\"],[6,9,6,28,57,59,\"expr\",false,\"read_csv('data.csv')\"],[6,9,6,16,48,50,\"SYMBOL_FUNCTION_CALL\",true,\"read_csv\"],[6,9,6,16,50,57,\"expr\",false,\"read_csv\"],[6,17,6,17,49,57,\"'('\",true,\"(\"],[6,18,6,27,51,53,\"STR_CONST\",true,\"'data.csv'\"],[6,18,6,27,53,57,\"expr\",false,\"'data.csv'\"],[6,28,6,28,52,57,\"')'\",true,\")\"],[7,1,7,30,76,0,\"expr\",false,\"data2 <- read_csv('data2.csv')\"],[7,1,7,5,62,64,\"SYMBOL\",true,\"data2\"],[7,1,7,5,64,76,\"expr\",false,\"data2\"],[7,7,7,8,63,76,\"LEFT_ASSIGN\",true,\"<-\"],[7,10,7,30,74,76,\"expr\",false,\"read_csv('data2.csv')\"],[7,10,7,17,65,67,\"SYMBOL_FUNCTION_CALL\",true,\"read_csv\"],[7,10,7,17,67,74,\"expr\",false,\"read_csv\"],[7,18,7,18,66,74,\"'('\",true,\"(\"],[7,19,7,29,68,70,\"STR_CONST\",true,\"'data2.csv'\"],[7,19,7,29,70,74,\"expr\",false,\"'data2.csv'\"],[7,30,7,30,69,74,\"')'\",true,\")\"],[9,1,9,17,98,0,\"expr\",false,\"m <- mean(data$x)\"],[9,1,9,1,81,83,\"SYMBOL\",true,\"m\"],[9,1,9,1,83,98,\"expr\",false,\"m\"],[9,3,9,4,82,98,\"LEFT_ASSIGN\",true,\"<-\"],[9,6,9,17,96,98,\"expr\",false,\"mean(data$x)\"],[9,6,9,9,84,86,\"SYMBOL_FUNCTION_CALL\",true,\"mean\"],[9,6,9,9,86,96,\"expr\",false,\"mean\"],[9,10,9,10,85,96,\"'('\",true,\"(\"],[9,11,9,16,91,96,\"expr\",false,\"data$x\"],[9,11,9,14,87,89,\"SYMBOL\",true,\"data\"],[9,11,9,14,89,91,\"expr\",false,\"data\"],[9,15,9,15,88,91,\"'$'\",true,\"$\"],[9,16,9,16,90,91,\"SYMBOL\",true,\"x\"],[9,17,9,17,92,96,\"')'\",true,\")\"],[10,1,10,8,110,0,\"expr\",false,\"print(m)\"],[10,1,10,5,101,103,\"SYMBOL_FUNCTION_CALL\",true,\"print\"],[10,1,10,5,103,110,\"expr\",false,\"print\"],[10,6,10,6,102,110,\"'('\",true,\"(\"],[10,7,10,7,104,106,\"SYMBOL\",true,\"m\"],[10,7,10,7,106,110,\"expr\",false,\"m\"],[10,8,10,8,105,110,\"')'\",true,\")\"],[12,1,14,20,158,0,\"expr\",false,\"data %>%\\n\\tggplot(aes(x = x, y = y)) +\\n\\tgeom_point()\"],[12,1,13,33,149,158,\"expr\",false,\"data %>%\\n\\tggplot(aes(x = x, y = y))\"],[12,1,12,4,116,118,\"SYMBOL\",true,\"data\"],[12,1,12,4,118,149,\"expr\",false,\"data\"],[12,6,12,8,117,149,\"SPECIAL\",true,\"%>%\"],[13,9,13,33,147,149,\"expr\",false,\"ggplot(aes(x = x, y = y))\"],[13,9,13,14,120,122,\"SYMBOL_FUNCTION_CALL\",true,\"ggplot\"],[13,9,13,14,122,147,\"expr\",false,\"ggplot\"],[13,15,13,15,121,147,\"'('\",true,\"(\"],[13,16,13,32,142,147,\"expr\",false,\"aes(x = x, y = y)\"],[13,16,13,18,123,125,\"SYMBOL_FUNCTION_CALL\",true,\"aes\"],[13,16,13,18,125,142,\"expr\",false,\"aes\"],[13,19,13,19,124,142,\"'('\",true,\"(\"],[13,20,13,20,126,142,\"SYMBOL_SUB\",true,\"x\"],[13,22,13,22,127,142,\"EQ_SUB\",true,\"=\"],[13,24,13,24,128,130,\"SYMBOL\",true,\"x\"],[13,24,13,24,130,142,\"expr\",false,\"x\"],[13,25,13,25,129,142,\"','\",true,\",\"],[13,27,13,27,134,142,\"SYMBOL_SUB\",true,\"y\"],[13,29,13,29,135,142,\"EQ_SUB\",true,\"=\"],[13,31,13,31,136,138,\"SYMBOL\",true,\"y\"],[13,31,13,31,138,142,\"expr\",false,\"y\"],[13,32,13,32,137,142,\"')'\",true,\")\"],[13,33,13,33,143,147,\"')'\",true,\")\"],[13,35,13,35,148,158,\"'+'\",true,\"+\"],[14,9,14,20,156,158,\"expr\",false,\"geom_point()\"],[14,9,14,18,151,153,\"SYMBOL_FUNCTION_CALL\",true,\"geom_point\"],[14,9,14,18,153,156,\"expr\",false,\"geom_point\"],[14,19,14,19,152,156,\"'('\",true,\"(\"],[14,20,14,20,154,156,\"')'\",true,\")\"],[16,1,16,22,184,0,\"expr\",false,\"plot(data2$x, data2$y)\"],[16,1,16,4,163,165,\"SYMBOL_FUNCTION_CALL\",true,\"plot\"],[16,1,16,4,165,184,\"expr\",false,\"plot\"],[16,5,16,5,164,184,\"'('\",true,\"(\"],[16,6,16,12,170,184,\"expr\",false,\"data2$x\"],[16,6,16,10,166,168,\"SYMBOL\",true,\"data2\"],[16,6,16,10,168,170,\"expr\",false,\"data2\"],[16,11,16,11,167,170,\"'$'\",true,\"$\"],[16,12,16,12,169,170,\"SYMBOL\",true,\"x\"],[16,13,16,13,171,184,\"','\",true,\",\"],[16,15,16,21,179,184,\"expr\",false,\"data2$y\"],[16,15,16,19,175,177,\"SYMBOL\",true,\"data2\"],[16,15,16,19,177,179,\"expr\",false,\"data2\"],[16,20,16,20,176,179,\"'$'\",true,\"$\"],[16,21,16,21,178,179,\"SYMBOL\",true,\"y\"],[16,22,16,22,180,184,\"')'\",true,\")\"],[17,1,17,24,209,0,\"expr\",false,\"points(data2$x, data2$y)\"],[17,1,17,6,188,190,\"SYMBOL_FUNCTION_CALL\",true,\"points\"],[17,1,17,6,190,209,\"expr\",false,\"points\"],[17,7,17,7,189,209,\"'('\",true,\"(\"],[17,8,17,14,195,209,\"expr\",false,\"data2$x\"],[17,8,17,12,191,193,\"SYMBOL\",true,\"data2\"],[17,8,17,12,193,195,\"expr\",false,\"data2\"],[17,13,17,13,192,195,\"'$'\",true,\"$\"],[17,14,17,14,194,195,\"SYMBOL\",true,\"x\"],[17,15,17,15,196,209,\"','\",true,\",\"],[17,17,17,23,204,209,\"expr\",false,\"data2$y\"],[17,17,17,21,200,202,\"SYMBOL\",true,\"data2\"],[17,17,17,21,202,204,\"expr\",false,\"data2\"],[17,22,17,22,201,204,\"'$'\",true,\"$\"],[17,23,17,23,203,204,\"SYMBOL\",true,\"y\"],[17,24,17,24,205,209,\"')'\",true,\")\"],[19,1,19,20,235,0,\"expr\",false,\"print(mean(data2$k))\"],[19,1,19,5,215,217,\"SYMBOL_FUNCTION_CALL\",true,\"print\"],[19,1,19,5,217,235,\"expr\",false,\"print\"],[19,6,19,6,216,235,\"'('\",true,\"(\"],[19,7,19,19,230,235,\"expr\",false,\"mean(data2$k)\"],[19,7,19,10,218,220,\"SYMBOL_FUNCTION_CALL\",true,\"mean\"],[19,7,19,10,220,230,\"expr\",false,\"mean\"],[19,11,19,11,219,230,\"'('\",true,\"(\"],[19,12,19,18,225,230,\"expr\",false,\"data2$k\"],[19,12,19,16,221,223,\"SYMBOL\",true,\"data2\"],[19,12,19,16,223,225,\"expr\",false,\"data2\"],[19,17,19,17,222,225,\"'$'\",true,\"$\"],[19,18,19,18,224,225,\"SYMBOL\",true,\"k\"],[19,19,19,19,226,230,\"')'\",true,\")\"],[19,20,19,20,231,235,\"')'\",true,\")\"]","filePath":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}],".meta":{"timing":3}},"normalize":{"ast":{"type":"RProject","files":[{"root":{"type":"RExpressionList","children":[{"type":"RFunctionCall","named":true,"location":[1,1,1,7],"lexeme":"library","functionName":{"type":"RSymbol","location":[1,1,1,7],"content":"library","lexeme":"library","info":{"fullRange":[1,1,1,15],"adToks":[],"id":0,"parent":3,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[1,9,1,14],"lexeme":"ggplot","value":{"type":"RSymbol","location":[1,9,1,14],"content":"ggplot","lexeme":"ggplot","info":{"fullRange":[1,9,1,14],"adToks":[],"id":1,"parent":2,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[1,9,1,14],"adToks":[],"id":2,"parent":3,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[1,1,1,15],"adToks":[],"id":3,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[2,1,2,7],"lexeme":"library","functionName":{"type":"RSymbol","location":[2,1,2,7],"content":"library","lexeme":"library","info":{"fullRange":[2,1,2,14],"adToks":[],"id":4,"parent":7,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[2,9,2,13],"lexeme":"dplyr","value":{"type":"RSymbol","location":[2,9,2,13],"content":"dplyr","lexeme":"dplyr","info":{"fullRange":[2,9,2,13],"adToks":[],"id":5,"parent":6,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[2,9,2,13],"adToks":[],"id":6,"parent":7,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[2,1,2,14],"adToks":[],"id":7,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[3,1,3,7],"lexeme":"library","functionName":{"type":"RSymbol","location":[3,1,3,7],"content":"library","lexeme":"library","info":{"fullRange":[3,1,3,14],"adToks":[],"id":8,"parent":11,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[3,9,3,13],"lexeme":"readr","value":{"type":"RSymbol","location":[3,9,3,13],"content":"readr","lexeme":"readr","info":{"fullRange":[3,9,3,13],"adToks":[],"id":9,"parent":10,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[3,9,3,13],"adToks":[],"id":10,"parent":11,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[3,1,3,14],"adToks":[],"id":11,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":2,"role":"el-c"}},{"type":"RBinaryOp","location":[6,6,6,7],"lhs":{"type":"RSymbol","location":[6,1,6,4],"content":"data","lexeme":"data","info":{"fullRange":[6,1,6,4],"adToks":[],"id":12,"parent":17,"role":"bin-l","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"rhs":{"type":"RFunctionCall","named":true,"location":[6,9,6,16],"lexeme":"read_csv","functionName":{"type":"RSymbol","location":[6,9,6,16],"content":"read_csv","lexeme":"read_csv","info":{"fullRange":[6,9,6,28],"adToks":[],"id":13,"parent":16,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[6,18,6,27],"lexeme":"'data.csv'","value":{"type":"RString","location":[6,18,6,27],"content":{"str":"data.csv","quotes":"'"},"lexeme":"'data.csv'","info":{"fullRange":[6,18,6,27],"adToks":[],"id":14,"parent":15,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[6,18,6,27],"adToks":[],"id":15,"parent":16,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[6,9,6,28],"adToks":[],"id":16,"parent":17,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"bin-r"}},"operator":"<-","lexeme":"<-","info":{"fullRange":[6,1,6,28],"adToks":[{"type":"RComment","location":[5,1,5,25],"lexeme":"# read data with read_csv","info":{"fullRange":[6,1,6,28],"adToks":[]}}],"id":17,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":3,"role":"el-c"}},{"type":"RBinaryOp","location":[7,7,7,8],"lhs":{"type":"RSymbol","location":[7,1,7,5],"content":"data2","lexeme":"data2","info":{"fullRange":[7,1,7,5],"adToks":[],"id":18,"parent":23,"role":"bin-l","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"rhs":{"type":"RFunctionCall","named":true,"location":[7,10,7,17],"lexeme":"read_csv","functionName":{"type":"RSymbol","location":[7,10,7,17],"content":"read_csv","lexeme":"read_csv","info":{"fullRange":[7,10,7,30],"adToks":[],"id":19,"parent":22,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[7,19,7,29],"lexeme":"'data2.csv'","value":{"type":"RString","location":[7,19,7,29],"content":{"str":"data2.csv","quotes":"'"},"lexeme":"'data2.csv'","info":{"fullRange":[7,19,7,29],"adToks":[],"id":20,"parent":21,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[7,19,7,29],"adToks":[],"id":21,"parent":22,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[7,10,7,30],"adToks":[],"id":22,"parent":23,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"bin-r"}},"operator":"<-","lexeme":"<-","info":{"fullRange":[7,1,7,30],"adToks":[],"id":23,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":4,"role":"el-c"}},{"type":"RBinaryOp","location":[9,3,9,4],"lhs":{"type":"RSymbol","location":[9,1,9,1],"content":"m","lexeme":"m","info":{"fullRange":[9,1,9,1],"adToks":[],"id":24,"parent":32,"role":"bin-l","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"rhs":{"type":"RFunctionCall","named":true,"location":[9,6,9,9],"lexeme":"mean","functionName":{"type":"RSymbol","location":[9,6,9,9],"content":"mean","lexeme":"mean","info":{"fullRange":[9,6,9,17],"adToks":[],"id":25,"parent":31,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[9,11,9,16],"lexeme":"data$x","value":{"type":"RAccess","location":[9,15,9,15],"lexeme":"$","accessed":{"type":"RSymbol","location":[9,11,9,14],"content":"data","lexeme":"data","info":{"fullRange":[9,11,9,14],"adToks":[],"id":26,"parent":29,"role":"acc","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"operator":"$","access":[{"type":"RArgument","location":[9,16,9,16],"lexeme":"x","value":{"type":"RSymbol","location":[9,16,9,16],"content":"x","lexeme":"x","info":{"fullRange":[9,11,9,16],"adToks":[],"id":27,"parent":28,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[9,16,9,16],"adToks":[],"id":28,"parent":29,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[9,11,9,16],"adToks":[],"id":29,"parent":30,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[9,11,9,16],"adToks":[],"id":30,"parent":31,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[9,6,9,17],"adToks":[],"id":31,"parent":32,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"bin-r"}},"operator":"<-","lexeme":"<-","info":{"fullRange":[9,1,9,17],"adToks":[],"id":32,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":5,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[10,1,10,5],"lexeme":"print","functionName":{"type":"RSymbol","location":[10,1,10,5],"content":"print","lexeme":"print","info":{"fullRange":[10,1,10,8],"adToks":[],"id":33,"parent":36,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[10,7,10,7],"lexeme":"m","value":{"type":"RSymbol","location":[10,7,10,7],"content":"m","lexeme":"m","info":{"fullRange":[10,7,10,7],"adToks":[],"id":34,"parent":35,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[10,7,10,7],"adToks":[],"id":35,"parent":36,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[10,1,10,8],"adToks":[],"id":36,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":6,"role":"el-c"}},{"type":"RBinaryOp","location":[13,35,13,35],"lhs":{"type":"RFunctionCall","named":true,"infixSpecial":true,"lexeme":"data %>%\n\tggplot(aes(x = x, y = y))","location":[12,6,12,8],"functionName":{"type":"RSymbol","location":[12,6,12,8],"lexeme":"%>%","content":"%>%","info":{"id":37,"parent":52,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[12,1,12,4],"value":{"type":"RSymbol","location":[12,1,12,4],"content":"data","lexeme":"data","info":{"fullRange":[12,1,12,4],"adToks":[],"id":38,"parent":39,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"lexeme":"data","info":{"id":39,"parent":52,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}},{"type":"RArgument","location":[13,9,13,14],"value":{"type":"RFunctionCall","named":true,"location":[13,9,13,14],"lexeme":"ggplot","functionName":{"type":"RSymbol","location":[13,9,13,14],"content":"ggplot","lexeme":"ggplot","info":{"fullRange":[13,9,13,33],"adToks":[],"id":40,"parent":50,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[13,16,13,32],"lexeme":"aes(x = x, y = y)","value":{"type":"RFunctionCall","named":true,"location":[13,16,13,18],"lexeme":"aes","functionName":{"type":"RSymbol","location":[13,16,13,18],"content":"aes","lexeme":"aes","info":{"fullRange":[13,16,13,32],"adToks":[],"id":41,"parent":48,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[13,20,13,20],"lexeme":"x","name":{"type":"RSymbol","location":[13,20,13,20],"content":"x","lexeme":"x","info":{"fullRange":[13,20,13,20],"adToks":[],"id":42,"parent":44,"role":"arg-n","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"value":{"type":"RSymbol","location":[13,24,13,24],"content":"x","lexeme":"x","info":{"fullRange":[13,24,13,24],"adToks":[],"id":43,"parent":44,"role":"arg-v","index":1,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[13,20,13,20],"adToks":[],"id":44,"parent":48,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}},{"type":"RArgument","location":[13,27,13,27],"lexeme":"y","name":{"type":"RSymbol","location":[13,27,13,27],"content":"y","lexeme":"y","info":{"fullRange":[13,27,13,27],"adToks":[],"id":45,"parent":47,"role":"arg-n","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"value":{"type":"RSymbol","location":[13,31,13,31],"content":"y","lexeme":"y","info":{"fullRange":[13,31,13,31],"adToks":[],"id":46,"parent":47,"role":"arg-v","index":1,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[13,27,13,27],"adToks":[],"id":47,"parent":48,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":2,"role":"call-arg"}}],"info":{"fullRange":[13,16,13,32],"adToks":[],"id":48,"parent":49,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[13,16,13,32],"adToks":[],"id":49,"parent":50,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[13,9,13,33],"adToks":[],"id":50,"parent":51,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"arg-v"}},"lexeme":"ggplot","info":{"id":51,"parent":52,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":2,"role":"call-arg"}}],"info":{"adToks":[],"id":52,"parent":55,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","role":"bin-l"}},"rhs":{"type":"RFunctionCall","named":true,"location":[14,9,14,18],"lexeme":"geom_point","functionName":{"type":"RSymbol","location":[14,9,14,18],"content":"geom_point","lexeme":"geom_point","info":{"fullRange":[14,9,14,20],"adToks":[],"id":53,"parent":54,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[],"info":{"fullRange":[14,9,14,20],"adToks":[],"id":54,"parent":55,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"bin-r"}},"operator":"+","lexeme":"+","info":{"fullRange":[12,1,14,20],"adToks":[],"id":55,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":7,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[16,1,16,4],"lexeme":"plot","functionName":{"type":"RSymbol","location":[16,1,16,4],"content":"plot","lexeme":"plot","info":{"fullRange":[16,1,16,22],"adToks":[],"id":56,"parent":67,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[16,6,16,12],"lexeme":"data2$x","value":{"type":"RAccess","location":[16,11,16,11],"lexeme":"$","accessed":{"type":"RSymbol","location":[16,6,16,10],"content":"data2","lexeme":"data2","info":{"fullRange":[16,6,16,10],"adToks":[],"id":57,"parent":60,"role":"acc","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"operator":"$","access":[{"type":"RArgument","location":[16,12,16,12],"lexeme":"x","value":{"type":"RSymbol","location":[16,12,16,12],"content":"x","lexeme":"x","info":{"fullRange":[16,6,16,12],"adToks":[],"id":58,"parent":59,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[16,12,16,12],"adToks":[],"id":59,"parent":60,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[16,6,16,12],"adToks":[],"id":60,"parent":61,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[16,6,16,12],"adToks":[],"id":61,"parent":67,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}},{"type":"RArgument","location":[16,15,16,21],"lexeme":"data2$y","value":{"type":"RAccess","location":[16,20,16,20],"lexeme":"$","accessed":{"type":"RSymbol","location":[16,15,16,19],"content":"data2","lexeme":"data2","info":{"fullRange":[16,15,16,19],"adToks":[],"id":62,"parent":65,"role":"acc","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"operator":"$","access":[{"type":"RArgument","location":[16,21,16,21],"lexeme":"y","value":{"type":"RSymbol","location":[16,21,16,21],"content":"y","lexeme":"y","info":{"fullRange":[16,15,16,21],"adToks":[],"id":63,"parent":64,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[16,21,16,21],"adToks":[],"id":64,"parent":65,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[16,15,16,21],"adToks":[],"id":65,"parent":66,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[16,15,16,21],"adToks":[],"id":66,"parent":67,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":2,"role":"call-arg"}}],"info":{"fullRange":[16,1,16,22],"adToks":[],"id":67,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":8,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[17,1,17,6],"lexeme":"points","functionName":{"type":"RSymbol","location":[17,1,17,6],"content":"points","lexeme":"points","info":{"fullRange":[17,1,17,24],"adToks":[],"id":68,"parent":79,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[17,8,17,14],"lexeme":"data2$x","value":{"type":"RAccess","location":[17,13,17,13],"lexeme":"$","accessed":{"type":"RSymbol","location":[17,8,17,12],"content":"data2","lexeme":"data2","info":{"fullRange":[17,8,17,12],"adToks":[],"id":69,"parent":72,"role":"acc","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"operator":"$","access":[{"type":"RArgument","location":[17,14,17,14],"lexeme":"x","value":{"type":"RSymbol","location":[17,14,17,14],"content":"x","lexeme":"x","info":{"fullRange":[17,8,17,14],"adToks":[],"id":70,"parent":71,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[17,14,17,14],"adToks":[],"id":71,"parent":72,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[17,8,17,14],"adToks":[],"id":72,"parent":73,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[17,8,17,14],"adToks":[],"id":73,"parent":79,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}},{"type":"RArgument","location":[17,17,17,23],"lexeme":"data2$y","value":{"type":"RAccess","location":[17,22,17,22],"lexeme":"$","accessed":{"type":"RSymbol","location":[17,17,17,21],"content":"data2","lexeme":"data2","info":{"fullRange":[17,17,17,21],"adToks":[],"id":74,"parent":77,"role":"acc","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"operator":"$","access":[{"type":"RArgument","location":[17,23,17,23],"lexeme":"y","value":{"type":"RSymbol","location":[17,23,17,23],"content":"y","lexeme":"y","info":{"fullRange":[17,17,17,23],"adToks":[],"id":75,"parent":76,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[17,23,17,23],"adToks":[],"id":76,"parent":77,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[17,17,17,23],"adToks":[],"id":77,"parent":78,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[17,17,17,23],"adToks":[],"id":78,"parent":79,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":2,"role":"call-arg"}}],"info":{"fullRange":[17,1,17,24],"adToks":[],"id":79,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":9,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[19,1,19,5],"lexeme":"print","functionName":{"type":"RSymbol","location":[19,1,19,5],"content":"print","lexeme":"print","info":{"fullRange":[19,1,19,20],"adToks":[],"id":80,"parent":89,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[19,7,19,19],"lexeme":"mean(data2$k)","value":{"type":"RFunctionCall","named":true,"location":[19,7,19,10],"lexeme":"mean","functionName":{"type":"RSymbol","location":[19,7,19,10],"content":"mean","lexeme":"mean","info":{"fullRange":[19,7,19,19],"adToks":[],"id":81,"parent":87,"role":"call-name","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"arguments":[{"type":"RArgument","location":[19,12,19,18],"lexeme":"data2$k","value":{"type":"RAccess","location":[19,17,19,17],"lexeme":"$","accessed":{"type":"RSymbol","location":[19,12,19,16],"content":"data2","lexeme":"data2","info":{"fullRange":[19,12,19,16],"adToks":[],"id":82,"parent":85,"role":"acc","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"operator":"$","access":[{"type":"RArgument","location":[19,18,19,18],"lexeme":"k","value":{"type":"RSymbol","location":[19,18,19,18],"content":"k","lexeme":"k","info":{"fullRange":[19,12,19,18],"adToks":[],"id":83,"parent":84,"role":"arg-v","index":0,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}},"info":{"fullRange":[19,18,19,18],"adToks":[],"id":84,"parent":85,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[19,12,19,18],"adToks":[],"id":85,"parent":86,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[19,12,19,18],"adToks":[],"id":86,"parent":87,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[19,7,19,19],"adToks":[],"id":87,"parent":88,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[19,7,19,19],"adToks":[],"id":88,"parent":89,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[19,1,19,20],"adToks":[],"id":89,"parent":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","index":10,"role":"el-c"}}],"info":{"adToks":[],"id":90,"nesting":0,"file":"/tmp/tmp-8880-2Is7MoYW4D9V-.R","role":"root","index":0}},"filePath":"/tmp/tmp-8880-2Is7MoYW4D9V-.R"}],"info":{"id":91}},".meta":{"timing":1}},"dataflow":{"unknownReferences":[],"in":[{"nodeId":3,"name":"library","type":2},{"nodeId":7,"name":"library","type":2},{"nodeId":11,"name":"library","type":2},{"nodeId":17,"name":"<-","type":2},{"nodeId":23,"name":"<-","type":2},{"nodeId":32,"name":"<-","type":2},{"nodeId":16,"name":"read_csv","type":2},{"nodeId":22,"name":"read_csv","type":2},{"nodeId":29,"name":"$","type":2},{"nodeId":60,"name":"$","type":2},{"nodeId":65,"name":"$","type":2},{"nodeId":72,"name":"$","type":2},{"nodeId":77,"name":"$","type":2},{"nodeId":85,"name":"$","type":2},{"nodeId":31,"name":"mean","type":2},{"nodeId":87,"name":"mean","type":2},{"nodeId":36,"name":"print","type":2},{"nodeId":89,"name":"print","type":2},{"nodeId":43,"name":"x","type":1},{"nodeId":46,"name":"y","type":1},{"nodeId":48,"name":"aes","type":2},{"nodeId":50,"name":"ggplot","type":2},{"nodeId":52,"name":"%>%","type":2},{"nodeId":54,"name":"geom_point","type":2},{"nodeId":55,"name":"+","type":2},{"nodeId":67,"name":"plot","type":2},{"nodeId":79,"name":"points","type":2}],"out":[{"nodeId":12,"name":"data","type":1,"definedAt":17,"value":[]},{"nodeId":18,"name":"data2","type":1,"definedAt":23,"value":[]},{"nodeId":24,"name":"m","type":1,"definedAt":32,"value":[31]}],"environment":{"current":{"id":2766,"parent":"","memory":[["data",[{"nodeId":12,"name":"data","type":1,"definedAt":17,"value":[]}]],["data2",[{"nodeId":18,"name":"data2","type":1,"definedAt":23,"value":[]}]],["m",[{"nodeId":24,"name":"m","type":1,"definedAt":32,"value":[31]}]]]},"level":0},"graph":{"rootVertices":[1,3,5,7,9,11,14,16,12,17,20,22,18,23,26,27,29,31,24,32,34,36,38,43,44,46,47,48,50,52,54,55,57,58,60,62,63,65,67,69,70,72,74,75,77,79,82,83,85,87,89],"vertexInformation":[[1,{"tag":"value","id":1}],[3,{"tag":"fcall","id":3,"name":"library","onlyBuiltin":true,"args":[{"nodeId":1,"type":32}],"origin":["builtin:library"]}],[5,{"tag":"value","id":5}],[7,{"tag":"fcall","id":7,"name":"library","onlyBuiltin":true,"args":[{"nodeId":5,"type":32}],"origin":["builtin:library"]}],[9,{"tag":"value","id":9}],[11,{"tag":"fcall","id":11,"name":"library","onlyBuiltin":true,"args":[{"nodeId":9,"type":32}],"origin":["builtin:library"]}],[14,{"tag":"value","id":14}],[16,{"tag":"fcall","id":16,"environment":{"current":{"id":2742,"parent":"","memory":[]},"level":0},"name":"read_csv","onlyBuiltin":false,"args":[{"nodeId":14,"type":32}],"origin":["function"]}],[12,{"tag":"vdef","id":12,"source":[16]}],[17,{"tag":"fcall","id":17,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":12,"type":32},{"nodeId":16,"type":32}],"origin":["builtin:assignment"]}],[20,{"tag":"value","id":20}],[22,{"tag":"fcall","id":22,"environment":{"current":{"id":2750,"parent":"","memory":[["data",[{"nodeId":12,"name":"data","type":1,"definedAt":17,"value":[]}]]]},"level":0},"name":"read_csv","onlyBuiltin":false,"args":[{"nodeId":20,"type":32}],"origin":["function"]}],[18,{"tag":"vdef","id":18,"source":[22]}],[23,{"tag":"fcall","id":23,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":18,"type":32},{"nodeId":22,"type":32}],"origin":["builtin:assignment"]}],[26,{"tag":"use","id":26}],[27,{"tag":"value","id":27}],[29,{"tag":"fcall","id":29,"name":"$","onlyBuiltin":true,"args":[{"nodeId":26,"type":32},{"nodeId":27,"type":32}],"origin":["builtin:access"]}],[31,{"tag":"fcall","id":31,"name":"mean","onlyBuiltin":true,"args":[{"nodeId":29,"type":32}],"origin":["builtin:default"]}],[24,{"tag":"vdef","id":24,"source":[31]}],[32,{"tag":"fcall","id":32,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":24,"type":32},{"nodeId":31,"type":32}],"origin":["builtin:assignment"]}],[34,{"tag":"use","id":34}],[36,{"tag":"fcall","id":36,"name":"print","onlyBuiltin":true,"args":[{"nodeId":34,"type":32}],"origin":["builtin:default"]}],[38,{"tag":"use","id":38}],[43,{"tag":"use","id":43}],[44,{"tag":"use","id":44}],[46,{"tag":"use","id":46}],[47,{"tag":"use","id":47}],[48,{"tag":"fcall","id":48,"environment":{"current":{"id":2783,"parent":"","memory":[["data",[{"nodeId":12,"name":"data","type":1,"definedAt":17,"value":[]}]],["data2",[{"nodeId":18,"name":"data2","type":1,"definedAt":23,"value":[]}]],["m",[{"nodeId":24,"name":"m","type":1,"definedAt":32,"value":[31]}]]]},"level":0},"name":"aes","onlyBuiltin":false,"args":[{"nodeId":44,"valueId":43,"name":"x","type":32},{"nodeId":47,"valueId":46,"name":"y","type":32}],"origin":["function"]}],[50,{"tag":"fcall","id":50,"name":"ggplot","onlyBuiltin":true,"args":[{"nodeId":38,"type":2},{"nodeId":48,"type":32}],"origin":["builtin:default"]}],[52,{"tag":"fcall","id":52,"name":"%>%","onlyBuiltin":true,"args":[{"nodeId":38,"type":32},{"nodeId":50,"type":32}],"origin":["builtin:pipe"]}],[54,{"tag":"fcall","id":54,"name":"geom_point","onlyBuiltin":true,"args":[],"origin":["builtin:default"]}],[55,{"tag":"fcall","id":55,"name":"+","onlyBuiltin":true,"args":[{"nodeId":52,"type":32},{"nodeId":54,"type":32}],"origin":["builtin:default"]}],[57,{"tag":"use","id":57}],[58,{"tag":"value","id":58}],[60,{"tag":"fcall","id":60,"name":"$","onlyBuiltin":true,"args":[{"nodeId":57,"type":32},{"nodeId":58,"type":32}],"origin":["builtin:access"]}],[62,{"tag":"use","id":62}],[63,{"tag":"value","id":63}],[65,{"tag":"fcall","id":65,"name":"$","onlyBuiltin":true,"args":[{"nodeId":62,"type":32},{"nodeId":63,"type":32}],"origin":["builtin:access"]}],[67,{"tag":"fcall","id":67,"name":"plot","onlyBuiltin":true,"args":[{"nodeId":60,"type":32},{"nodeId":65,"type":32}],"origin":["builtin:default"]}],[69,{"tag":"use","id":69}],[70,{"tag":"value","id":70}],[72,{"tag":"fcall","id":72,"name":"$","onlyBuiltin":true,"args":[{"nodeId":69,"type":32},{"nodeId":70,"type":32}],"origin":["builtin:access"]}],[74,{"tag":"use","id":74}],[75,{"tag":"value","id":75}],[77,{"tag":"fcall","id":77,"name":"$","onlyBuiltin":true,"args":[{"nodeId":74,"type":32},{"nodeId":75,"type":32}],"origin":["builtin:access"]}],[79,{"tag":"fcall","id":79,"name":"points","onlyBuiltin":true,"args":[{"nodeId":72,"type":32},{"nodeId":77,"type":32}],"origin":["builtin:default"]}],[82,{"tag":"use","id":82}],[83,{"tag":"value","id":83}],[85,{"tag":"fcall","id":85,"name":"$","onlyBuiltin":true,"args":[{"nodeId":82,"type":32},{"nodeId":83,"type":32}],"origin":["builtin:access"]}],[87,{"tag":"fcall","id":87,"name":"mean","onlyBuiltin":true,"args":[{"nodeId":85,"type":32}],"origin":["builtin:default"]}],[89,{"tag":"fcall","id":89,"name":"print","onlyBuiltin":true,"args":[{"nodeId":87,"type":32}],"origin":["builtin:default"]}]],"edgeInformation":[[3,[[1,{"types":64}],["built-in:library",{"types":5}]]],[7,[[5,{"types":64}],["built-in:library",{"types":5}]]],[11,[[9,{"types":64}],["built-in:library",{"types":5}]]],[16,[[14,{"types":64}]]],[17,[[16,{"types":65}],[12,{"types":72}],["built-in:<-",{"types":5}]]],[12,[[16,{"types":2}],[17,{"types":2}]]],[22,[[20,{"types":64}]]],[23,[[22,{"types":65}],[18,{"types":72}],["built-in:<-",{"types":5}]]],[18,[[22,{"types":2}],[23,{"types":2}]]],[26,[[12,{"types":1}]]],[29,[[26,{"types":73}],[27,{"types":65}],["built-in:$",{"types":5}]]],[31,[[29,{"types":65}],["built-in:mean",{"types":5}]]],[32,[[31,{"types":65}],[24,{"types":72}],["built-in:<-",{"types":5}]]],[24,[[31,{"types":2}],[32,{"types":2}]]],[36,[[34,{"types":73}],["built-in:print",{"types":5}]]],[34,[[24,{"types":1}]]],[38,[[12,{"types":1}]]],[52,[[38,{"types":64}],[50,{"types":72}],["built-in:%>%",{"types":5}]]],[44,[[43,{"types":1}]]],[48,[[43,{"types":1}],[44,{"types":64}],[46,{"types":1}],[47,{"types":64}]]],[47,[[46,{"types":1}]]],[50,[[48,{"types":65}],[38,{"types":65}],["built-in:ggplot",{"types":5}]]],[55,[[52,{"types":65}],[54,{"types":65}],["built-in:+",{"types":5}]]],[54,[["built-in:geom_point",{"types":5}],[50,{"types":1}]]],[57,[[18,{"types":1}]]],[60,[[57,{"types":73}],[58,{"types":65}],["built-in:$",{"types":5}]]],[67,[[60,{"types":65}],[65,{"types":65}],["built-in:plot",{"types":5}]]],[62,[[18,{"types":1}]]],[65,[[62,{"types":73}],[63,{"types":65}],["built-in:$",{"types":5}]]],[69,[[18,{"types":1}]]],[72,[[69,{"types":73}],[70,{"types":65}],["built-in:$",{"types":5}]]],[79,[[72,{"types":65}],[77,{"types":65}],["built-in:points",{"types":5}],[67,{"types":1}]]],[74,[[18,{"types":1}]]],[77,[[74,{"types":73}],[75,{"types":65}],["built-in:$",{"types":5}]]],[82,[[18,{"types":1}]]],[85,[[82,{"types":73}],[83,{"types":65}],["built-in:$",{"types":5}]]],[87,[[85,{"types":65}],["built-in:mean",{"types":5}]]],[89,[[87,{"types":73}],["built-in:print",{"types":5}]]]],"_unknownSideEffects":[3,7,11,{"id":36,"linkTo":{"type":"link-to-last-call","callName":{}}},{"id":50,"linkTo":{"type":"link-to-last-call","callName":{}}},{"id":67,"linkTo":{"type":"link-to-last-call","callName":{}}},{"id":89,"linkTo":{"type":"link-to-last-call","callName":{}}}]},"entryPoint":3,"exitPoints":[{"type":0,"nodeId":89}],"hooks":[],"cfgQuick":{"graph":{"roots":[90,0,3,"3-e",2,1,"2-e",4,7,"7-e",6,5,"6-e",8,11,"11-e",10,9,"10-e",12,13,16,"16-e",15,14,"15-e",17,"17-e",18,19,22,"22-e",21,20,"21-e",23,"23-e",24,25,31,"31-e",30,26,29,28,27,"28-e","29-e","30-e",32,"32-e",33,36,"36-e",35,34,"35-e",37,52,"52-e",39,38,"39-e",51,40,50,"50-e",49,41,48,"48-e",44,42,43,"44-e",47,45,46,"47-e","49-e","51-e",53,54,"54-e",55,"55-e",56,67,"67-e",61,57,60,59,58,"59-e","60-e","61-e",66,62,65,64,63,"64-e","65-e","66-e",68,79,"79-e",73,69,72,71,70,"71-e","72-e","73-e",78,74,77,76,75,"76-e","77-e","78-e",80,89,"89-e",88,81,87,"87-e",86,82,85,84,83,"84-e","85-e","86-e","88-e","90-e"],"vtxInfos":[[90,[2,90,null,["90-e"]]],[0,[2,0]],[3,[1,3,[0],["3-e"]]],["3-e","3-e"],[2,[2,2,[2],["2-e"]]],[1,[2,1]],["2-e","2-e"],[4,[2,4]],[7,[1,7,[4],["7-e"]]],["7-e","7-e"],[6,[2,6,[6],["6-e"]]],[5,[2,5]],["6-e","6-e"],[8,[2,8]],[11,[1,11,[8],["11-e"]]],["11-e","11-e"],[10,[2,10,[10],["10-e"]]],[9,[2,9]],["10-e","10-e"],[12,[2,12]],[13,[2,13]],[16,[2,16,[13],["16-e"]]],["16-e","16-e"],[15,[2,15,[15],["15-e"]]],[14,[2,14]],["15-e","15-e"],[17,[2,17,null,["17-e"]]],["17-e","17-e"],[18,[2,18]],[19,[2,19]],[22,[2,22,[19],["22-e"]]],["22-e","22-e"],[21,[2,21,[21],["21-e"]]],[20,[2,20]],["21-e","21-e"],[23,[2,23,null,["23-e"]]],["23-e","23-e"],[24,[2,24]],[25,[2,25]],[31,[2,31,[25],["31-e"]]],["31-e","31-e"],[30,[2,30,[30],["30-e"]]],[26,[2,26]],[29,[2,29,[26],["29-e"]]],[28,[2,28,[28],["28-e"]]],[27,[2,27]],["28-e","28-e"],["29-e","29-e"],["30-e","30-e"],[32,[2,32,null,["32-e"]]],["32-e","32-e"],[33,[2,33]],[36,[1,36,[33],["36-e"]]],["36-e","36-e"],[35,[2,35,[35],["35-e"]]],[34,[2,34]],["35-e","35-e"],[37,[2,37]],[52,[2,52,[37],["52-e"]]],["52-e","52-e"],[39,[2,39,[39],["39-e"]]],[38,[2,38]],["39-e","39-e"],[51,[2,51,[51],["51-e"]]],[40,[2,40]],[50,[2,50,[40],["50-e"]]],["50-e","50-e"],[49,[2,49,[49],["49-e"]]],[41,[2,41]],[48,[2,48,[41],["48-e"]]],["48-e","48-e"],[44,[2,44,[42],["44-e"]]],[42,[2,42]],[43,[2,43]],["44-e","44-e"],[47,[2,47,[45],["47-e"]]],[45,[2,45]],[46,[2,46]],["47-e","47-e"],["49-e","49-e"],["51-e","51-e"],[53,[2,53]],[54,[2,54,[53],["54-e"]]],["54-e","54-e"],[55,[2,55,null,["55-e"]]],["55-e","55-e"],[56,[2,56]],[67,[1,67,[56],["67-e"]]],["67-e","67-e"],[61,[2,61,[61],["61-e"]]],[57,[2,57]],[60,[2,60,[57],["60-e"]]],[59,[2,59,[59],["59-e"]]],[58,[2,58]],["59-e","59-e"],["60-e","60-e"],["61-e","61-e"],[66,[2,66,[66],["66-e"]]],[62,[2,62]],[65,[2,65,[62],["65-e"]]],[64,[2,64,[64],["64-e"]]],[63,[2,63]],["64-e","64-e"],["65-e","65-e"],["66-e","66-e"],[68,[2,68]],[79,[1,79,[68],["79-e"]]],["79-e","79-e"],[73,[2,73,[73],["73-e"]]],[69,[2,69]],[72,[2,72,[69],["72-e"]]],[71,[2,71,[71],["71-e"]]],[70,[2,70]],["71-e","71-e"],["72-e","72-e"],["73-e","73-e"],[78,[2,78,[78],["78-e"]]],[74,[2,74]],[77,[2,77,[74],["77-e"]]],[76,[2,76,[76],["76-e"]]],[75,[2,75]],["76-e","76-e"],["77-e","77-e"],["78-e","78-e"],[80,[2,80]],[89,[1,89,[80],["89-e"]]],["89-e","89-e"],[88,[2,88,[88],["88-e"]]],[81,[2,81]],[87,[2,87,[81],["87-e"]]],["87-e","87-e"],[86,[2,86,[86],["86-e"]]],[82,[2,82]],[85,[2,85,[82],["85-e"]]],[84,[2,84,[84],["84-e"]]],[83,[2,83]],["84-e","84-e"],["85-e","85-e"],["86-e","86-e"],["88-e","88-e"],["90-e","90-e"]],"bbChildren":[],"edgeInfos":[[3,[[90,0]]],[0,[[3,0]]],[1,[[2,0]]],["2-e",[[1,0]]],[2,[[0,0]]],["3-e",[["2-e",0]]],[7,[["3-e",0]]],[4,[[7,0]]],[5,[[6,0]]],["6-e",[[5,0]]],[6,[[4,0]]],["7-e",[["6-e",0]]],[11,[["7-e",0]]],[8,[[11,0]]],[9,[[10,0]]],["10-e",[[9,0]]],[10,[[8,0]]],["11-e",[["10-e",0]]],[17,[["11-e",0]]],[13,[[16,0]]],[14,[[15,0]]],["15-e",[[14,0]]],[15,[[13,0]]],["16-e",[["15-e",0]]],[16,[[12,0]]],[12,[[17,0]]],["17-e",[["16-e",0]]],[23,[["17-e",0]]],[19,[[22,0]]],[20,[[21,0]]],["21-e",[[20,0]]],[21,[[19,0]]],["22-e",[["21-e",0]]],[22,[[18,0]]],[18,[[23,0]]],["23-e",[["22-e",0]]],[32,[["23-e",0]]],[25,[[31,0]]],[26,[[29,0]]],[27,[[28,0]]],["28-e",[[27,0]]],[28,[[26,0]]],["29-e",[["28-e",0]]],[29,[[30,0]]],["30-e",[["29-e",0]]],[30,[[25,0]]],["31-e",[["30-e",0]]],[31,[[24,0]]],[24,[[32,0]]],["32-e",[["31-e",0]]],[36,[["32-e",0]]],[33,[[36,0]]],[34,[[35,0]]],["35-e",[[34,0]]],[35,[[33,0]]],["36-e",[["35-e",0]]],[55,[["36-e",0]]],[37,[[52,0]]],[38,[[39,0]]],["39-e",[[38,0]]],[39,[[37,0]]],[40,[[50,0]]],[41,[[48,0]]],[42,[[44,0]]],[43,[[42,0]]],["44-e",[[43,0]]],[44,[[41,0]]],[45,[[47,0]]],[46,[[45,0]]],["47-e",[[46,0]]],[47,[["44-e",0]]],["48-e",[["47-e",0]]],[48,[[49,0]]],["49-e",[["48-e",0]]],[49,[[40,0]]],["50-e",[["49-e",0]]],[50,[[51,0]]],["51-e",[["50-e",0]]],[51,[["39-e",0]]],["52-e",[["51-e",0]]],[53,[[54,0]]],["54-e",[[53,0]]],[54,[["52-e",0]]],[52,[[55,0]]],["55-e",[["54-e",0]]],[67,[["55-e",0]]],[56,[[67,0]]],[57,[[60,0]]],[58,[[59,0]]],["59-e",[[58,0]]],[59,[[57,0]]],["60-e",[["59-e",0]]],[60,[[61,0]]],["61-e",[["60-e",0]]],[61,[[56,0]]],[62,[[65,0]]],[63,[[64,0]]],["64-e",[[63,0]]],[64,[[62,0]]],["65-e",[["64-e",0]]],[65,[[66,0]]],["66-e",[["65-e",0]]],[66,[["61-e",0]]],["67-e",[["66-e",0]]],[79,[["67-e",0]]],[68,[[79,0]]],[69,[[72,0]]],[70,[[71,0]]],["71-e",[[70,0]]],[71,[[69,0]]],["72-e",[["71-e",0]]],[72,[[73,0]]],["73-e",[["72-e",0]]],[73,[[68,0]]],[74,[[77,0]]],[75,[[76,0]]],["76-e",[[75,0]]],[76,[[74,0]]],["77-e",[["76-e",0]]],[77,[[78,0]]],["78-e",[["77-e",0]]],[78,[["73-e",0]]],["79-e",[["78-e",0]]],[89,[["79-e",0]]],[80,[[89,0]]],[81,[[87,0]]],[82,[[85,0]]],[83,[[84,0]]],["84-e",[[83,0]]],[84,[[82,0]]],["85-e",[["84-e",0]]],[85,[[86,0]]],["86-e",[["85-e",0]]],[86,[[81,0]]],["87-e",[["86-e",0]]],[87,[[88,0]]],["88-e",[["87-e",0]]],[88,[[80,0]]],["89-e",[["88-e",0]]],["90-e",[["89-e",0]]]],"revEdgeInfos":[[90,[[3,0]]],[3,[[0,0]]],[2,[[1,0]]],[1,[["2-e",0]]],[0,[[2,0]]],["2-e",[["3-e",0]]],["3-e",[[7,0]]],[7,[[4,0]]],[6,[[5,0]]],[5,[["6-e",0]]],[4,[[6,0]]],["6-e",[["7-e",0]]],["7-e",[[11,0]]],[11,[[8,0]]],[10,[[9,0]]],[9,[["10-e",0]]],[8,[[10,0]]],["10-e",[["11-e",0]]],["11-e",[[17,0]]],[16,[[13,0]]],[15,[[14,0]]],[14,[["15-e",0]]],[13,[[15,0]]],["15-e",[["16-e",0]]],[12,[[16,0]]],[17,[[12,0]]],["16-e",[["17-e",0]]],["17-e",[[23,0]]],[22,[[19,0]]],[21,[[20,0]]],[20,[["21-e",0]]],[19,[[21,0]]],["21-e",[["22-e",0]]],[18,[[22,0]]],[23,[[18,0]]],["22-e",[["23-e",0]]],["23-e",[[32,0]]],[31,[[25,0]]],[29,[[26,0]]],[28,[[27,0]]],[27,[["28-e",0]]],[26,[[28,0]]],["28-e",[["29-e",0]]],[30,[[29,0]]],["29-e",[["30-e",0]]],[25,[[30,0]]],["30-e",[["31-e",0]]],[24,[[31,0]]],[32,[[24,0]]],["31-e",[["32-e",0]]],["32-e",[[36,0]]],[36,[[33,0]]],[35,[[34,0]]],[34,[["35-e",0]]],[33,[[35,0]]],["35-e",[["36-e",0]]],["36-e",[[55,0]]],[52,[[37,0]]],[39,[[38,0]]],[38,[["39-e",0]]],[37,[[39,0]]],[50,[[40,0]]],[48,[[41,0]]],[44,[[42,0]]],[42,[[43,0]]],[43,[["44-e",0]]],[41,[[44,0]]],[47,[[45,0]]],[45,[[46,0]]],[46,[["47-e",0]]],["44-e",[[47,0]]],["47-e",[["48-e",0]]],[49,[[48,0]]],["48-e",[["49-e",0]]],[40,[[49,0]]],["49-e",[["50-e",0]]],[51,[[50,0]]],["50-e",[["51-e",0]]],["39-e",[[51,0]]],["51-e",[["52-e",0]]],[54,[[53,0]]],[53,[["54-e",0]]],["52-e",[[54,0]]],[55,[[52,0]]],["54-e",[["55-e",0]]],["55-e",[[67,0]]],[67,[[56,0]]],[60,[[57,0]]],[59,[[58,0]]],[58,[["59-e",0]]],[57,[[59,0]]],["59-e",[["60-e",0]]],[61,[[60,0]]],["60-e",[["61-e",0]]],[56,[[61,0]]],[65,[[62,0]]],[64,[[63,0]]],[63,[["64-e",0]]],[62,[[64,0]]],["64-e",[["65-e",0]]],[66,[[65,0]]],["65-e",[["66-e",0]]],["61-e",[[66,0]]],["66-e",[["67-e",0]]],["67-e",[[79,0]]],[79,[[68,0]]],[72,[[69,0]]],[71,[[70,0]]],[70,[["71-e",0]]],[69,[[71,0]]],["71-e",[["72-e",0]]],[73,[[72,0]]],["72-e",[["73-e",0]]],[68,[[73,0]]],[77,[[74,0]]],[76,[[75,0]]],[75,[["76-e",0]]],[74,[[76,0]]],["76-e",[["77-e",0]]],[78,[[77,0]]],["77-e",[["78-e",0]]],["73-e",[[78,0]]],["78-e",[["79-e",0]]],["79-e",[[89,0]]],[89,[[80,0]]],[87,[[81,0]]],[85,[[82,0]]],[84,[[83,0]]],[83,[["84-e",0]]],[82,[[84,0]]],["84-e",[["85-e",0]]],[86,[[85,0]]],["85-e",[["86-e",0]]],[81,[[86,0]]],["86-e",[["87-e",0]]],[88,[[87,0]]],["87-e",[["88-e",0]]],[80,[[88,0]]],["88-e",[["89-e",0]]],["89-e",[["90-e",0]]]],"_mayBB":false},"breaks":[],"nexts":[],"returns":[],"exitPoints":["90-e"],"entryPoints":[90]},".meta":{"timing":1}}}} +{"type":"response-file-analysis","format":"json","id":"1","results":{"parse":{"files":[{"parsed":"[1,1,1,15,10,0,\"expr\",false,\"library(ggplot)\"],[1,1,1,7,1,3,\"SYMBOL_FUNCTION_CALL\",true,\"library\"],[1,1,1,7,3,10,\"expr\",false,\"library\"],[1,8,1,8,2,10,\"'('\",true,\"(\"],[1,9,1,14,4,6,\"SYMBOL\",true,\"ggplot\"],[1,9,1,14,6,10,\"expr\",false,\"ggplot\"],[1,15,1,15,5,10,\"')'\",true,\")\"],[2,1,2,14,23,0,\"expr\",false,\"library(dplyr)\"],[2,1,2,7,14,16,\"SYMBOL_FUNCTION_CALL\",true,\"library\"],[2,1,2,7,16,23,\"expr\",false,\"library\"],[2,8,2,8,15,23,\"'('\",true,\"(\"],[2,9,2,13,17,19,\"SYMBOL\",true,\"dplyr\"],[2,9,2,13,19,23,\"expr\",false,\"dplyr\"],[2,14,2,14,18,23,\"')'\",true,\")\"],[3,1,3,14,36,0,\"expr\",false,\"library(readr)\"],[3,1,3,7,27,29,\"SYMBOL_FUNCTION_CALL\",true,\"library\"],[3,1,3,7,29,36,\"expr\",false,\"library\"],[3,8,3,8,28,36,\"'('\",true,\"(\"],[3,9,3,13,30,32,\"SYMBOL\",true,\"readr\"],[3,9,3,13,32,36,\"expr\",false,\"readr\"],[3,14,3,14,31,36,\"')'\",true,\")\"],[5,1,5,25,42,-59,\"COMMENT\",true,\"# read data with read_csv\"],[6,1,6,28,59,0,\"expr\",false,\"data <- read_csv('data.csv')\"],[6,1,6,4,45,47,\"SYMBOL\",true,\"data\"],[6,1,6,4,47,59,\"expr\",false,\"data\"],[6,6,6,7,46,59,\"LEFT_ASSIGN\",true,\"<-\"],[6,9,6,28,57,59,\"expr\",false,\"read_csv('data.csv')\"],[6,9,6,16,48,50,\"SYMBOL_FUNCTION_CALL\",true,\"read_csv\"],[6,9,6,16,50,57,\"expr\",false,\"read_csv\"],[6,17,6,17,49,57,\"'('\",true,\"(\"],[6,18,6,27,51,53,\"STR_CONST\",true,\"'data.csv'\"],[6,18,6,27,53,57,\"expr\",false,\"'data.csv'\"],[6,28,6,28,52,57,\"')'\",true,\")\"],[7,1,7,30,76,0,\"expr\",false,\"data2 <- read_csv('data2.csv')\"],[7,1,7,5,62,64,\"SYMBOL\",true,\"data2\"],[7,1,7,5,64,76,\"expr\",false,\"data2\"],[7,7,7,8,63,76,\"LEFT_ASSIGN\",true,\"<-\"],[7,10,7,30,74,76,\"expr\",false,\"read_csv('data2.csv')\"],[7,10,7,17,65,67,\"SYMBOL_FUNCTION_CALL\",true,\"read_csv\"],[7,10,7,17,67,74,\"expr\",false,\"read_csv\"],[7,18,7,18,66,74,\"'('\",true,\"(\"],[7,19,7,29,68,70,\"STR_CONST\",true,\"'data2.csv'\"],[7,19,7,29,70,74,\"expr\",false,\"'data2.csv'\"],[7,30,7,30,69,74,\"')'\",true,\")\"],[9,1,9,17,98,0,\"expr\",false,\"m <- mean(data$x)\"],[9,1,9,1,81,83,\"SYMBOL\",true,\"m\"],[9,1,9,1,83,98,\"expr\",false,\"m\"],[9,3,9,4,82,98,\"LEFT_ASSIGN\",true,\"<-\"],[9,6,9,17,96,98,\"expr\",false,\"mean(data$x)\"],[9,6,9,9,84,86,\"SYMBOL_FUNCTION_CALL\",true,\"mean\"],[9,6,9,9,86,96,\"expr\",false,\"mean\"],[9,10,9,10,85,96,\"'('\",true,\"(\"],[9,11,9,16,91,96,\"expr\",false,\"data$x\"],[9,11,9,14,87,89,\"SYMBOL\",true,\"data\"],[9,11,9,14,89,91,\"expr\",false,\"data\"],[9,15,9,15,88,91,\"'$'\",true,\"$\"],[9,16,9,16,90,91,\"SYMBOL\",true,\"x\"],[9,17,9,17,92,96,\"')'\",true,\")\"],[10,1,10,8,110,0,\"expr\",false,\"print(m)\"],[10,1,10,5,101,103,\"SYMBOL_FUNCTION_CALL\",true,\"print\"],[10,1,10,5,103,110,\"expr\",false,\"print\"],[10,6,10,6,102,110,\"'('\",true,\"(\"],[10,7,10,7,104,106,\"SYMBOL\",true,\"m\"],[10,7,10,7,106,110,\"expr\",false,\"m\"],[10,8,10,8,105,110,\"')'\",true,\")\"],[12,1,14,20,158,0,\"expr\",false,\"data %>%\\n\\tggplot(aes(x = x, y = y)) +\\n\\tgeom_point()\"],[12,1,13,33,149,158,\"expr\",false,\"data %>%\\n\\tggplot(aes(x = x, y = y))\"],[12,1,12,4,116,118,\"SYMBOL\",true,\"data\"],[12,1,12,4,118,149,\"expr\",false,\"data\"],[12,6,12,8,117,149,\"SPECIAL\",true,\"%>%\"],[13,9,13,33,147,149,\"expr\",false,\"ggplot(aes(x = x, y = y))\"],[13,9,13,14,120,122,\"SYMBOL_FUNCTION_CALL\",true,\"ggplot\"],[13,9,13,14,122,147,\"expr\",false,\"ggplot\"],[13,15,13,15,121,147,\"'('\",true,\"(\"],[13,16,13,32,142,147,\"expr\",false,\"aes(x = x, y = y)\"],[13,16,13,18,123,125,\"SYMBOL_FUNCTION_CALL\",true,\"aes\"],[13,16,13,18,125,142,\"expr\",false,\"aes\"],[13,19,13,19,124,142,\"'('\",true,\"(\"],[13,20,13,20,126,142,\"SYMBOL_SUB\",true,\"x\"],[13,22,13,22,127,142,\"EQ_SUB\",true,\"=\"],[13,24,13,24,128,130,\"SYMBOL\",true,\"x\"],[13,24,13,24,130,142,\"expr\",false,\"x\"],[13,25,13,25,129,142,\"','\",true,\",\"],[13,27,13,27,134,142,\"SYMBOL_SUB\",true,\"y\"],[13,29,13,29,135,142,\"EQ_SUB\",true,\"=\"],[13,31,13,31,136,138,\"SYMBOL\",true,\"y\"],[13,31,13,31,138,142,\"expr\",false,\"y\"],[13,32,13,32,137,142,\"')'\",true,\")\"],[13,33,13,33,143,147,\"')'\",true,\")\"],[13,35,13,35,148,158,\"'+'\",true,\"+\"],[14,9,14,20,156,158,\"expr\",false,\"geom_point()\"],[14,9,14,18,151,153,\"SYMBOL_FUNCTION_CALL\",true,\"geom_point\"],[14,9,14,18,153,156,\"expr\",false,\"geom_point\"],[14,19,14,19,152,156,\"'('\",true,\"(\"],[14,20,14,20,154,156,\"')'\",true,\")\"],[16,1,16,22,184,0,\"expr\",false,\"plot(data2$x, data2$y)\"],[16,1,16,4,163,165,\"SYMBOL_FUNCTION_CALL\",true,\"plot\"],[16,1,16,4,165,184,\"expr\",false,\"plot\"],[16,5,16,5,164,184,\"'('\",true,\"(\"],[16,6,16,12,170,184,\"expr\",false,\"data2$x\"],[16,6,16,10,166,168,\"SYMBOL\",true,\"data2\"],[16,6,16,10,168,170,\"expr\",false,\"data2\"],[16,11,16,11,167,170,\"'$'\",true,\"$\"],[16,12,16,12,169,170,\"SYMBOL\",true,\"x\"],[16,13,16,13,171,184,\"','\",true,\",\"],[16,15,16,21,179,184,\"expr\",false,\"data2$y\"],[16,15,16,19,175,177,\"SYMBOL\",true,\"data2\"],[16,15,16,19,177,179,\"expr\",false,\"data2\"],[16,20,16,20,176,179,\"'$'\",true,\"$\"],[16,21,16,21,178,179,\"SYMBOL\",true,\"y\"],[16,22,16,22,180,184,\"')'\",true,\")\"],[17,1,17,24,209,0,\"expr\",false,\"points(data2$x, data2$y)\"],[17,1,17,6,188,190,\"SYMBOL_FUNCTION_CALL\",true,\"points\"],[17,1,17,6,190,209,\"expr\",false,\"points\"],[17,7,17,7,189,209,\"'('\",true,\"(\"],[17,8,17,14,195,209,\"expr\",false,\"data2$x\"],[17,8,17,12,191,193,\"SYMBOL\",true,\"data2\"],[17,8,17,12,193,195,\"expr\",false,\"data2\"],[17,13,17,13,192,195,\"'$'\",true,\"$\"],[17,14,17,14,194,195,\"SYMBOL\",true,\"x\"],[17,15,17,15,196,209,\"','\",true,\",\"],[17,17,17,23,204,209,\"expr\",false,\"data2$y\"],[17,17,17,21,200,202,\"SYMBOL\",true,\"data2\"],[17,17,17,21,202,204,\"expr\",false,\"data2\"],[17,22,17,22,201,204,\"'$'\",true,\"$\"],[17,23,17,23,203,204,\"SYMBOL\",true,\"y\"],[17,24,17,24,205,209,\"')'\",true,\")\"],[19,1,19,20,235,0,\"expr\",false,\"print(mean(data2$k))\"],[19,1,19,5,215,217,\"SYMBOL_FUNCTION_CALL\",true,\"print\"],[19,1,19,5,217,235,\"expr\",false,\"print\"],[19,6,19,6,216,235,\"'('\",true,\"(\"],[19,7,19,19,230,235,\"expr\",false,\"mean(data2$k)\"],[19,7,19,10,218,220,\"SYMBOL_FUNCTION_CALL\",true,\"mean\"],[19,7,19,10,220,230,\"expr\",false,\"mean\"],[19,11,19,11,219,230,\"'('\",true,\"(\"],[19,12,19,18,225,230,\"expr\",false,\"data2$k\"],[19,12,19,16,221,223,\"SYMBOL\",true,\"data2\"],[19,12,19,16,223,225,\"expr\",false,\"data2\"],[19,17,19,17,222,225,\"'$'\",true,\"$\"],[19,18,19,18,224,225,\"SYMBOL\",true,\"k\"],[19,19,19,19,226,230,\"')'\",true,\")\"],[19,20,19,20,231,235,\"')'\",true,\")\"]","filePath":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}],".meta":{"timing":4}},"normalize":{"ast":{"type":"RProject","files":[{"root":{"type":"RExpressionList","children":[{"type":"RFunctionCall","named":true,"location":[1,1,1,7],"lexeme":"library","functionName":{"type":"RSymbol","location":[1,1,1,7],"content":"library","lexeme":"library","info":{"fullRange":[1,1,1,15],"adToks":[],"id":0,"parent":3,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[1,9,1,14],"lexeme":"ggplot","value":{"type":"RSymbol","location":[1,9,1,14],"content":"ggplot","lexeme":"ggplot","info":{"fullRange":[1,9,1,14],"adToks":[],"id":1,"parent":2,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[1,9,1,14],"adToks":[],"id":2,"parent":3,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[1,1,1,15],"adToks":[],"id":3,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[2,1,2,7],"lexeme":"library","functionName":{"type":"RSymbol","location":[2,1,2,7],"content":"library","lexeme":"library","info":{"fullRange":[2,1,2,14],"adToks":[],"id":4,"parent":7,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[2,9,2,13],"lexeme":"dplyr","value":{"type":"RSymbol","location":[2,9,2,13],"content":"dplyr","lexeme":"dplyr","info":{"fullRange":[2,9,2,13],"adToks":[],"id":5,"parent":6,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[2,9,2,13],"adToks":[],"id":6,"parent":7,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[2,1,2,14],"adToks":[],"id":7,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[3,1,3,7],"lexeme":"library","functionName":{"type":"RSymbol","location":[3,1,3,7],"content":"library","lexeme":"library","info":{"fullRange":[3,1,3,14],"adToks":[],"id":8,"parent":11,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[3,9,3,13],"lexeme":"readr","value":{"type":"RSymbol","location":[3,9,3,13],"content":"readr","lexeme":"readr","info":{"fullRange":[3,9,3,13],"adToks":[],"id":9,"parent":10,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[3,9,3,13],"adToks":[],"id":10,"parent":11,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[3,1,3,14],"adToks":[],"id":11,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":2,"role":"el-c"}},{"type":"RBinaryOp","location":[6,6,6,7],"lhs":{"type":"RSymbol","location":[6,1,6,4],"content":"data","lexeme":"data","info":{"fullRange":[6,1,6,4],"adToks":[],"id":12,"parent":17,"role":"bin-l","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"rhs":{"type":"RFunctionCall","named":true,"location":[6,9,6,16],"lexeme":"read_csv","functionName":{"type":"RSymbol","location":[6,9,6,16],"content":"read_csv","lexeme":"read_csv","info":{"fullRange":[6,9,6,28],"adToks":[],"id":13,"parent":16,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[6,18,6,27],"lexeme":"'data.csv'","value":{"type":"RString","location":[6,18,6,27],"content":{"str":"data.csv","quotes":"'"},"lexeme":"'data.csv'","info":{"fullRange":[6,18,6,27],"adToks":[],"id":14,"parent":15,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[6,18,6,27],"adToks":[],"id":15,"parent":16,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[6,9,6,28],"adToks":[],"id":16,"parent":17,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"bin-r"}},"operator":"<-","lexeme":"<-","info":{"fullRange":[6,1,6,28],"adToks":[{"type":"RComment","location":[5,1,5,25],"lexeme":"# read data with read_csv","info":{"fullRange":[6,1,6,28],"adToks":[]}}],"id":17,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":3,"role":"el-c"}},{"type":"RBinaryOp","location":[7,7,7,8],"lhs":{"type":"RSymbol","location":[7,1,7,5],"content":"data2","lexeme":"data2","info":{"fullRange":[7,1,7,5],"adToks":[],"id":18,"parent":23,"role":"bin-l","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"rhs":{"type":"RFunctionCall","named":true,"location":[7,10,7,17],"lexeme":"read_csv","functionName":{"type":"RSymbol","location":[7,10,7,17],"content":"read_csv","lexeme":"read_csv","info":{"fullRange":[7,10,7,30],"adToks":[],"id":19,"parent":22,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[7,19,7,29],"lexeme":"'data2.csv'","value":{"type":"RString","location":[7,19,7,29],"content":{"str":"data2.csv","quotes":"'"},"lexeme":"'data2.csv'","info":{"fullRange":[7,19,7,29],"adToks":[],"id":20,"parent":21,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[7,19,7,29],"adToks":[],"id":21,"parent":22,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[7,10,7,30],"adToks":[],"id":22,"parent":23,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"bin-r"}},"operator":"<-","lexeme":"<-","info":{"fullRange":[7,1,7,30],"adToks":[],"id":23,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":4,"role":"el-c"}},{"type":"RBinaryOp","location":[9,3,9,4],"lhs":{"type":"RSymbol","location":[9,1,9,1],"content":"m","lexeme":"m","info":{"fullRange":[9,1,9,1],"adToks":[],"id":24,"parent":32,"role":"bin-l","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"rhs":{"type":"RFunctionCall","named":true,"location":[9,6,9,9],"lexeme":"mean","functionName":{"type":"RSymbol","location":[9,6,9,9],"content":"mean","lexeme":"mean","info":{"fullRange":[9,6,9,17],"adToks":[],"id":25,"parent":31,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[9,11,9,16],"lexeme":"data$x","value":{"type":"RAccess","location":[9,15,9,15],"lexeme":"$","accessed":{"type":"RSymbol","location":[9,11,9,14],"content":"data","lexeme":"data","info":{"fullRange":[9,11,9,14],"adToks":[],"id":26,"parent":29,"role":"acc","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"operator":"$","access":[{"type":"RArgument","location":[9,16,9,16],"lexeme":"x","value":{"type":"RSymbol","location":[9,16,9,16],"content":"x","lexeme":"x","info":{"fullRange":[9,11,9,16],"adToks":[],"id":27,"parent":28,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[9,16,9,16],"adToks":[],"id":28,"parent":29,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[9,11,9,16],"adToks":[],"id":29,"parent":30,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[9,11,9,16],"adToks":[],"id":30,"parent":31,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[9,6,9,17],"adToks":[],"id":31,"parent":32,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"bin-r"}},"operator":"<-","lexeme":"<-","info":{"fullRange":[9,1,9,17],"adToks":[],"id":32,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":5,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[10,1,10,5],"lexeme":"print","functionName":{"type":"RSymbol","location":[10,1,10,5],"content":"print","lexeme":"print","info":{"fullRange":[10,1,10,8],"adToks":[],"id":33,"parent":36,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[10,7,10,7],"lexeme":"m","value":{"type":"RSymbol","location":[10,7,10,7],"content":"m","lexeme":"m","info":{"fullRange":[10,7,10,7],"adToks":[],"id":34,"parent":35,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[10,7,10,7],"adToks":[],"id":35,"parent":36,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[10,1,10,8],"adToks":[],"id":36,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":6,"role":"el-c"}},{"type":"RBinaryOp","location":[13,35,13,35],"lhs":{"type":"RFunctionCall","named":true,"infixSpecial":true,"lexeme":"data %>%\n\tggplot(aes(x = x, y = y))","location":[12,6,12,8],"functionName":{"type":"RSymbol","location":[12,6,12,8],"lexeme":"%>%","content":"%>%","info":{"id":37,"parent":52,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[12,1,12,4],"value":{"type":"RSymbol","location":[12,1,12,4],"content":"data","lexeme":"data","info":{"fullRange":[12,1,12,4],"adToks":[],"id":38,"parent":39,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"lexeme":"data","info":{"id":39,"parent":52,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}},{"type":"RArgument","location":[13,9,13,14],"value":{"type":"RFunctionCall","named":true,"location":[13,9,13,14],"lexeme":"ggplot","functionName":{"type":"RSymbol","location":[13,9,13,14],"content":"ggplot","lexeme":"ggplot","info":{"fullRange":[13,9,13,33],"adToks":[],"id":40,"parent":50,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[13,16,13,32],"lexeme":"aes(x = x, y = y)","value":{"type":"RFunctionCall","named":true,"location":[13,16,13,18],"lexeme":"aes","functionName":{"type":"RSymbol","location":[13,16,13,18],"content":"aes","lexeme":"aes","info":{"fullRange":[13,16,13,32],"adToks":[],"id":41,"parent":48,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[13,20,13,20],"lexeme":"x","name":{"type":"RSymbol","location":[13,20,13,20],"content":"x","lexeme":"x","info":{"fullRange":[13,20,13,20],"adToks":[],"id":42,"parent":44,"role":"arg-n","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"value":{"type":"RSymbol","location":[13,24,13,24],"content":"x","lexeme":"x","info":{"fullRange":[13,24,13,24],"adToks":[],"id":43,"parent":44,"role":"arg-v","index":1,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[13,20,13,20],"adToks":[],"id":44,"parent":48,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}},{"type":"RArgument","location":[13,27,13,27],"lexeme":"y","name":{"type":"RSymbol","location":[13,27,13,27],"content":"y","lexeme":"y","info":{"fullRange":[13,27,13,27],"adToks":[],"id":45,"parent":47,"role":"arg-n","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"value":{"type":"RSymbol","location":[13,31,13,31],"content":"y","lexeme":"y","info":{"fullRange":[13,31,13,31],"adToks":[],"id":46,"parent":47,"role":"arg-v","index":1,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[13,27,13,27],"adToks":[],"id":47,"parent":48,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":2,"role":"call-arg"}}],"info":{"fullRange":[13,16,13,32],"adToks":[],"id":48,"parent":49,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[13,16,13,32],"adToks":[],"id":49,"parent":50,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[13,9,13,33],"adToks":[],"id":50,"parent":51,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"arg-v"}},"lexeme":"ggplot","info":{"id":51,"parent":52,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":2,"role":"call-arg"}}],"info":{"adToks":[],"id":52,"parent":55,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","role":"bin-l"}},"rhs":{"type":"RFunctionCall","named":true,"location":[14,9,14,18],"lexeme":"geom_point","functionName":{"type":"RSymbol","location":[14,9,14,18],"content":"geom_point","lexeme":"geom_point","info":{"fullRange":[14,9,14,20],"adToks":[],"id":53,"parent":54,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[],"info":{"fullRange":[14,9,14,20],"adToks":[],"id":54,"parent":55,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"bin-r"}},"operator":"+","lexeme":"+","info":{"fullRange":[12,1,14,20],"adToks":[],"id":55,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":7,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[16,1,16,4],"lexeme":"plot","functionName":{"type":"RSymbol","location":[16,1,16,4],"content":"plot","lexeme":"plot","info":{"fullRange":[16,1,16,22],"adToks":[],"id":56,"parent":67,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[16,6,16,12],"lexeme":"data2$x","value":{"type":"RAccess","location":[16,11,16,11],"lexeme":"$","accessed":{"type":"RSymbol","location":[16,6,16,10],"content":"data2","lexeme":"data2","info":{"fullRange":[16,6,16,10],"adToks":[],"id":57,"parent":60,"role":"acc","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"operator":"$","access":[{"type":"RArgument","location":[16,12,16,12],"lexeme":"x","value":{"type":"RSymbol","location":[16,12,16,12],"content":"x","lexeme":"x","info":{"fullRange":[16,6,16,12],"adToks":[],"id":58,"parent":59,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[16,12,16,12],"adToks":[],"id":59,"parent":60,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[16,6,16,12],"adToks":[],"id":60,"parent":61,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[16,6,16,12],"adToks":[],"id":61,"parent":67,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}},{"type":"RArgument","location":[16,15,16,21],"lexeme":"data2$y","value":{"type":"RAccess","location":[16,20,16,20],"lexeme":"$","accessed":{"type":"RSymbol","location":[16,15,16,19],"content":"data2","lexeme":"data2","info":{"fullRange":[16,15,16,19],"adToks":[],"id":62,"parent":65,"role":"acc","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"operator":"$","access":[{"type":"RArgument","location":[16,21,16,21],"lexeme":"y","value":{"type":"RSymbol","location":[16,21,16,21],"content":"y","lexeme":"y","info":{"fullRange":[16,15,16,21],"adToks":[],"id":63,"parent":64,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[16,21,16,21],"adToks":[],"id":64,"parent":65,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[16,15,16,21],"adToks":[],"id":65,"parent":66,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[16,15,16,21],"adToks":[],"id":66,"parent":67,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":2,"role":"call-arg"}}],"info":{"fullRange":[16,1,16,22],"adToks":[],"id":67,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":8,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[17,1,17,6],"lexeme":"points","functionName":{"type":"RSymbol","location":[17,1,17,6],"content":"points","lexeme":"points","info":{"fullRange":[17,1,17,24],"adToks":[],"id":68,"parent":79,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[17,8,17,14],"lexeme":"data2$x","value":{"type":"RAccess","location":[17,13,17,13],"lexeme":"$","accessed":{"type":"RSymbol","location":[17,8,17,12],"content":"data2","lexeme":"data2","info":{"fullRange":[17,8,17,12],"adToks":[],"id":69,"parent":72,"role":"acc","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"operator":"$","access":[{"type":"RArgument","location":[17,14,17,14],"lexeme":"x","value":{"type":"RSymbol","location":[17,14,17,14],"content":"x","lexeme":"x","info":{"fullRange":[17,8,17,14],"adToks":[],"id":70,"parent":71,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[17,14,17,14],"adToks":[],"id":71,"parent":72,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[17,8,17,14],"adToks":[],"id":72,"parent":73,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[17,8,17,14],"adToks":[],"id":73,"parent":79,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}},{"type":"RArgument","location":[17,17,17,23],"lexeme":"data2$y","value":{"type":"RAccess","location":[17,22,17,22],"lexeme":"$","accessed":{"type":"RSymbol","location":[17,17,17,21],"content":"data2","lexeme":"data2","info":{"fullRange":[17,17,17,21],"adToks":[],"id":74,"parent":77,"role":"acc","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"operator":"$","access":[{"type":"RArgument","location":[17,23,17,23],"lexeme":"y","value":{"type":"RSymbol","location":[17,23,17,23],"content":"y","lexeme":"y","info":{"fullRange":[17,17,17,23],"adToks":[],"id":75,"parent":76,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[17,23,17,23],"adToks":[],"id":76,"parent":77,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[17,17,17,23],"adToks":[],"id":77,"parent":78,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[17,17,17,23],"adToks":[],"id":78,"parent":79,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":2,"role":"call-arg"}}],"info":{"fullRange":[17,1,17,24],"adToks":[],"id":79,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":9,"role":"el-c"}},{"type":"RFunctionCall","named":true,"location":[19,1,19,5],"lexeme":"print","functionName":{"type":"RSymbol","location":[19,1,19,5],"content":"print","lexeme":"print","info":{"fullRange":[19,1,19,20],"adToks":[],"id":80,"parent":89,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[19,7,19,19],"lexeme":"mean(data2$k)","value":{"type":"RFunctionCall","named":true,"location":[19,7,19,10],"lexeme":"mean","functionName":{"type":"RSymbol","location":[19,7,19,10],"content":"mean","lexeme":"mean","info":{"fullRange":[19,7,19,19],"adToks":[],"id":81,"parent":87,"role":"call-name","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"arguments":[{"type":"RArgument","location":[19,12,19,18],"lexeme":"data2$k","value":{"type":"RAccess","location":[19,17,19,17],"lexeme":"$","accessed":{"type":"RSymbol","location":[19,12,19,16],"content":"data2","lexeme":"data2","info":{"fullRange":[19,12,19,16],"adToks":[],"id":82,"parent":85,"role":"acc","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"operator":"$","access":[{"type":"RArgument","location":[19,18,19,18],"lexeme":"k","value":{"type":"RSymbol","location":[19,18,19,18],"content":"k","lexeme":"k","info":{"fullRange":[19,12,19,18],"adToks":[],"id":83,"parent":84,"role":"arg-v","index":0,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}},"info":{"fullRange":[19,18,19,18],"adToks":[],"id":84,"parent":85,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"idx-acc"}}],"info":{"fullRange":[19,12,19,18],"adToks":[],"id":85,"parent":86,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[19,12,19,18],"adToks":[],"id":86,"parent":87,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[19,7,19,19],"adToks":[],"id":87,"parent":88,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":0,"role":"arg-v"}},"info":{"fullRange":[19,7,19,19],"adToks":[],"id":88,"parent":89,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":1,"role":"call-arg"}}],"info":{"fullRange":[19,1,19,20],"adToks":[],"id":89,"parent":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","index":10,"role":"el-c"}}],"info":{"adToks":[],"id":90,"nesting":0,"file":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R","role":"root","index":0}},"filePath":"/private/var/folders/93/163001ln55l18fvhkw_5bkk40000gn/T/tmp-16860-xAgz3KPRY4q8-.R"}],"info":{"id":91}},".meta":{"timing":0}},"dataflow":{"unknownReferences":[],"in":[{"nodeId":3,"name":"library","type":2},{"nodeId":7,"name":"library","type":2},{"nodeId":11,"name":"library","type":2},{"nodeId":17,"name":"<-","type":2},{"nodeId":23,"name":"<-","type":2},{"nodeId":32,"name":"<-","type":2},{"nodeId":16,"name":"read_csv","type":2},{"nodeId":22,"name":"read_csv","type":2},{"nodeId":29,"name":"$","type":2},{"nodeId":60,"name":"$","type":2},{"nodeId":65,"name":"$","type":2},{"nodeId":72,"name":"$","type":2},{"nodeId":77,"name":"$","type":2},{"nodeId":85,"name":"$","type":2},{"nodeId":31,"name":"mean","type":2},{"nodeId":87,"name":"mean","type":2},{"nodeId":36,"name":"print","type":2},{"nodeId":89,"name":"print","type":2},{"nodeId":43,"name":"x","type":1},{"nodeId":46,"name":"y","type":1},{"nodeId":48,"name":"aes","type":2},{"nodeId":50,"name":"ggplot","type":2},{"nodeId":52,"name":"%>%","type":2},{"nodeId":54,"name":"geom_point","type":2},{"nodeId":55,"name":"+","type":2},{"nodeId":67,"name":"plot","type":2},{"nodeId":79,"name":"points","type":2}],"out":[{"nodeId":12,"name":"data","type":1,"definedAt":17,"value":[]},{"nodeId":18,"name":"data2","type":1,"definedAt":23,"value":[]},{"nodeId":24,"name":"m","type":1,"definedAt":32,"value":[31]}],"environment":{"current":{"id":2747,"parent":"","memory":[["data",[{"nodeId":12,"name":"data","type":1,"definedAt":17,"value":[]}]],["data2",[{"nodeId":18,"name":"data2","type":1,"definedAt":23,"value":[]}]],["m",[{"nodeId":24,"name":"m","type":1,"definedAt":32,"value":[31]}]]]},"level":0},"graph":{"rootVertices":[1,3,5,7,9,11,14,16,12,17,20,22,18,23,26,27,29,31,24,32,34,36,38,43,44,46,47,48,50,52,54,55,57,58,60,62,63,65,67,69,70,72,74,75,77,79,82,83,85,87,89],"vertexInformation":[[1,{"tag":"value","id":1}],[3,{"tag":"fcall","id":3,"name":"library","onlyBuiltin":true,"args":[{"nodeId":1,"type":32}],"origin":["builtin:library"]}],[5,{"tag":"value","id":5}],[7,{"tag":"fcall","id":7,"name":"library","onlyBuiltin":true,"args":[{"nodeId":5,"type":32}],"origin":["builtin:library"]}],[9,{"tag":"value","id":9}],[11,{"tag":"fcall","id":11,"name":"library","onlyBuiltin":true,"args":[{"nodeId":9,"type":32}],"origin":["builtin:library"]}],[14,{"tag":"value","id":14}],[16,{"tag":"fcall","id":16,"environment":{"current":{"id":2723,"parent":"","memory":[]},"level":0},"name":"read_csv","onlyBuiltin":false,"args":[{"nodeId":14,"type":32}],"origin":["function"]}],[12,{"tag":"vdef","id":12,"source":[16]}],[17,{"tag":"fcall","id":17,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":12,"type":32},{"nodeId":16,"type":32}],"origin":["builtin:assignment"]}],[20,{"tag":"value","id":20}],[22,{"tag":"fcall","id":22,"environment":{"current":{"id":2731,"parent":"","memory":[["data",[{"nodeId":12,"name":"data","type":1,"definedAt":17,"value":[]}]]]},"level":0},"name":"read_csv","onlyBuiltin":false,"args":[{"nodeId":20,"type":32}],"origin":["function"]}],[18,{"tag":"vdef","id":18,"source":[22]}],[23,{"tag":"fcall","id":23,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":18,"type":32},{"nodeId":22,"type":32}],"origin":["builtin:assignment"]}],[26,{"tag":"use","id":26}],[27,{"tag":"value","id":27}],[29,{"tag":"fcall","id":29,"name":"$","onlyBuiltin":true,"args":[{"nodeId":26,"type":32},{"nodeId":27,"type":32}],"origin":["builtin:access"]}],[31,{"tag":"fcall","id":31,"name":"mean","onlyBuiltin":true,"args":[{"nodeId":29,"type":32}],"origin":["builtin:default"]}],[24,{"tag":"vdef","id":24,"source":[31]}],[32,{"tag":"fcall","id":32,"name":"<-","onlyBuiltin":true,"args":[{"nodeId":24,"type":32},{"nodeId":31,"type":32}],"origin":["builtin:assignment"]}],[34,{"tag":"use","id":34}],[36,{"tag":"fcall","id":36,"name":"print","onlyBuiltin":true,"args":[{"nodeId":34,"type":32}],"origin":["builtin:default"]}],[38,{"tag":"use","id":38}],[43,{"tag":"use","id":43}],[44,{"tag":"use","id":44}],[46,{"tag":"use","id":46}],[47,{"tag":"use","id":47}],[48,{"tag":"fcall","id":48,"environment":{"current":{"id":2764,"parent":"","memory":[["data",[{"nodeId":12,"name":"data","type":1,"definedAt":17,"value":[]}]],["data2",[{"nodeId":18,"name":"data2","type":1,"definedAt":23,"value":[]}]],["m",[{"nodeId":24,"name":"m","type":1,"definedAt":32,"value":[31]}]]]},"level":0},"name":"aes","onlyBuiltin":false,"args":[{"nodeId":44,"valueId":43,"name":"x","type":32},{"nodeId":47,"valueId":46,"name":"y","type":32}],"origin":["function"]}],[50,{"tag":"fcall","id":50,"name":"ggplot","onlyBuiltin":true,"args":[{"nodeId":38,"type":2},{"nodeId":48,"type":32}],"origin":["builtin:default"]}],[52,{"tag":"fcall","id":52,"name":"%>%","onlyBuiltin":true,"args":[{"nodeId":38,"type":32},{"nodeId":50,"type":32}],"origin":["builtin:pipe"]}],[54,{"tag":"fcall","id":54,"name":"geom_point","onlyBuiltin":true,"args":[],"origin":["builtin:default"]}],[55,{"tag":"fcall","id":55,"name":"+","onlyBuiltin":true,"args":[{"nodeId":52,"type":32},{"nodeId":54,"type":32}],"origin":["builtin:default"]}],[57,{"tag":"use","id":57}],[58,{"tag":"value","id":58}],[60,{"tag":"fcall","id":60,"name":"$","onlyBuiltin":true,"args":[{"nodeId":57,"type":32},{"nodeId":58,"type":32}],"origin":["builtin:access"]}],[62,{"tag":"use","id":62}],[63,{"tag":"value","id":63}],[65,{"tag":"fcall","id":65,"name":"$","onlyBuiltin":true,"args":[{"nodeId":62,"type":32},{"nodeId":63,"type":32}],"origin":["builtin:access"]}],[67,{"tag":"fcall","id":67,"name":"plot","onlyBuiltin":true,"args":[{"nodeId":60,"type":32},{"nodeId":65,"type":32}],"origin":["builtin:default"]}],[69,{"tag":"use","id":69}],[70,{"tag":"value","id":70}],[72,{"tag":"fcall","id":72,"name":"$","onlyBuiltin":true,"args":[{"nodeId":69,"type":32},{"nodeId":70,"type":32}],"origin":["builtin:access"]}],[74,{"tag":"use","id":74}],[75,{"tag":"value","id":75}],[77,{"tag":"fcall","id":77,"name":"$","onlyBuiltin":true,"args":[{"nodeId":74,"type":32},{"nodeId":75,"type":32}],"origin":["builtin:access"]}],[79,{"tag":"fcall","id":79,"name":"points","onlyBuiltin":true,"args":[{"nodeId":72,"type":32},{"nodeId":77,"type":32}],"origin":["builtin:default"]}],[82,{"tag":"use","id":82}],[83,{"tag":"value","id":83}],[85,{"tag":"fcall","id":85,"name":"$","onlyBuiltin":true,"args":[{"nodeId":82,"type":32},{"nodeId":83,"type":32}],"origin":["builtin:access"]}],[87,{"tag":"fcall","id":87,"name":"mean","onlyBuiltin":true,"args":[{"nodeId":85,"type":32}],"origin":["builtin:default"]}],[89,{"tag":"fcall","id":89,"name":"print","onlyBuiltin":true,"args":[{"nodeId":87,"type":32}],"origin":["builtin:default"]}]],"edgeInformation":[[3,[[1,{"types":64}],["built-in:library",{"types":5}]]],[7,[[5,{"types":64}],["built-in:library",{"types":5}]]],[11,[[9,{"types":64}],["built-in:library",{"types":5}]]],[16,[[14,{"types":64}]]],[17,[[16,{"types":65}],[12,{"types":72}],["built-in:<-",{"types":5}]]],[12,[[16,{"types":2}],[17,{"types":2}]]],[22,[[20,{"types":64}]]],[23,[[22,{"types":65}],[18,{"types":72}],["built-in:<-",{"types":5}]]],[18,[[22,{"types":2}],[23,{"types":2}]]],[26,[[12,{"types":1}]]],[29,[[26,{"types":73}],[27,{"types":65}],["built-in:$",{"types":5}]]],[31,[[29,{"types":65}],["built-in:mean",{"types":5}]]],[32,[[31,{"types":65}],[24,{"types":72}],["built-in:<-",{"types":5}]]],[24,[[31,{"types":2}],[32,{"types":2}]]],[36,[[34,{"types":73}],["built-in:print",{"types":5}]]],[34,[[24,{"types":1}]]],[38,[[12,{"types":1}]]],[52,[[38,{"types":64}],[50,{"types":72}],["built-in:%>%",{"types":5}]]],[44,[[43,{"types":1}]]],[48,[[43,{"types":1}],[44,{"types":64}],[46,{"types":1}],[47,{"types":64}]]],[47,[[46,{"types":1}]]],[50,[[48,{"types":65}],[38,{"types":65}],["built-in:ggplot",{"types":5}]]],[55,[[52,{"types":65}],[54,{"types":65}],["built-in:+",{"types":5}]]],[54,[["built-in:geom_point",{"types":5}],[50,{"types":1}]]],[57,[[18,{"types":1}]]],[60,[[57,{"types":73}],[58,{"types":65}],["built-in:$",{"types":5}]]],[67,[[60,{"types":65}],[65,{"types":65}],["built-in:plot",{"types":5}]]],[62,[[18,{"types":1}]]],[65,[[62,{"types":73}],[63,{"types":65}],["built-in:$",{"types":5}]]],[69,[[18,{"types":1}]]],[72,[[69,{"types":73}],[70,{"types":65}],["built-in:$",{"types":5}]]],[79,[[72,{"types":65}],[77,{"types":65}],["built-in:points",{"types":5}],[67,{"types":1}]]],[74,[[18,{"types":1}]]],[77,[[74,{"types":73}],[75,{"types":65}],["built-in:$",{"types":5}]]],[82,[[18,{"types":1}]]],[85,[[82,{"types":73}],[83,{"types":65}],["built-in:$",{"types":5}]]],[87,[[85,{"types":65}],["built-in:mean",{"types":5}]]],[89,[[87,{"types":73}],["built-in:print",{"types":5}]]]],"_unknownSideEffects":[3,7,11,{"id":36,"linkTo":{"type":"link-to-last-call","callName":{}}},{"id":50,"linkTo":{"type":"link-to-last-call","callName":{}}},{"id":67,"linkTo":{"type":"link-to-last-call","callName":{}}},{"id":89,"linkTo":{"type":"link-to-last-call","callName":{}}}]},"entryPoint":3,"exitPoints":[{"type":0,"nodeId":89}],"hooks":[],"cfgQuick":{"graph":{"roots":[90,0,3,"3-e",2,1,"2-e",4,7,"7-e",6,5,"6-e",8,11,"11-e",10,9,"10-e",12,13,16,"16-e",15,14,"15-e",17,"17-e",18,19,22,"22-e",21,20,"21-e",23,"23-e",24,25,31,"31-e",30,26,29,28,27,"28-e","29-e","30-e",32,"32-e",33,36,"36-e",35,34,"35-e",37,52,"52-e",39,38,"39-e",51,40,50,"50-e",49,41,48,"48-e",44,42,43,"44-e",47,45,46,"47-e","49-e","51-e",53,54,"54-e",55,"55-e",56,67,"67-e",61,57,60,59,58,"59-e","60-e","61-e",66,62,65,64,63,"64-e","65-e","66-e",68,79,"79-e",73,69,72,71,70,"71-e","72-e","73-e",78,74,77,76,75,"76-e","77-e","78-e",80,89,"89-e",88,81,87,"87-e",86,82,85,84,83,"84-e","85-e","86-e","88-e","90-e"],"vtxInfos":[[90,[2,90,null,["90-e"]]],[0,[2,0]],[3,[1,3,[0],["3-e"]]],["3-e","3-e"],[2,[2,2,[2],["2-e"]]],[1,[2,1]],["2-e","2-e"],[4,[2,4]],[7,[1,7,[4],["7-e"]]],["7-e","7-e"],[6,[2,6,[6],["6-e"]]],[5,[2,5]],["6-e","6-e"],[8,[2,8]],[11,[1,11,[8],["11-e"]]],["11-e","11-e"],[10,[2,10,[10],["10-e"]]],[9,[2,9]],["10-e","10-e"],[12,[2,12]],[13,[2,13]],[16,[2,16,[13],["16-e"]]],["16-e","16-e"],[15,[2,15,[15],["15-e"]]],[14,[2,14]],["15-e","15-e"],[17,[2,17,null,["17-e"]]],["17-e","17-e"],[18,[2,18]],[19,[2,19]],[22,[2,22,[19],["22-e"]]],["22-e","22-e"],[21,[2,21,[21],["21-e"]]],[20,[2,20]],["21-e","21-e"],[23,[2,23,null,["23-e"]]],["23-e","23-e"],[24,[2,24]],[25,[2,25]],[31,[2,31,[25],["31-e"]]],["31-e","31-e"],[30,[2,30,[30],["30-e"]]],[26,[2,26]],[29,[2,29,[26],["29-e"]]],[28,[2,28,[28],["28-e"]]],[27,[2,27]],["28-e","28-e"],["29-e","29-e"],["30-e","30-e"],[32,[2,32,null,["32-e"]]],["32-e","32-e"],[33,[2,33]],[36,[1,36,[33],["36-e"]]],["36-e","36-e"],[35,[2,35,[35],["35-e"]]],[34,[2,34]],["35-e","35-e"],[37,[2,37]],[52,[2,52,[37],["52-e"]]],["52-e","52-e"],[39,[2,39,[39],["39-e"]]],[38,[2,38]],["39-e","39-e"],[51,[2,51,[51],["51-e"]]],[40,[2,40]],[50,[2,50,[40],["50-e"]]],["50-e","50-e"],[49,[2,49,[49],["49-e"]]],[41,[2,41]],[48,[2,48,[41],["48-e"]]],["48-e","48-e"],[44,[2,44,[42],["44-e"]]],[42,[2,42]],[43,[2,43]],["44-e","44-e"],[47,[2,47,[45],["47-e"]]],[45,[2,45]],[46,[2,46]],["47-e","47-e"],["49-e","49-e"],["51-e","51-e"],[53,[2,53]],[54,[2,54,[53],["54-e"]]],["54-e","54-e"],[55,[2,55,null,["55-e"]]],["55-e","55-e"],[56,[2,56]],[67,[1,67,[56],["67-e"]]],["67-e","67-e"],[61,[2,61,[61],["61-e"]]],[57,[2,57]],[60,[2,60,[57],["60-e"]]],[59,[2,59,[59],["59-e"]]],[58,[2,58]],["59-e","59-e"],["60-e","60-e"],["61-e","61-e"],[66,[2,66,[66],["66-e"]]],[62,[2,62]],[65,[2,65,[62],["65-e"]]],[64,[2,64,[64],["64-e"]]],[63,[2,63]],["64-e","64-e"],["65-e","65-e"],["66-e","66-e"],[68,[2,68]],[79,[1,79,[68],["79-e"]]],["79-e","79-e"],[73,[2,73,[73],["73-e"]]],[69,[2,69]],[72,[2,72,[69],["72-e"]]],[71,[2,71,[71],["71-e"]]],[70,[2,70]],["71-e","71-e"],["72-e","72-e"],["73-e","73-e"],[78,[2,78,[78],["78-e"]]],[74,[2,74]],[77,[2,77,[74],["77-e"]]],[76,[2,76,[76],["76-e"]]],[75,[2,75]],["76-e","76-e"],["77-e","77-e"],["78-e","78-e"],[80,[2,80]],[89,[1,89,[80],["89-e"]]],["89-e","89-e"],[88,[2,88,[88],["88-e"]]],[81,[2,81]],[87,[2,87,[81],["87-e"]]],["87-e","87-e"],[86,[2,86,[86],["86-e"]]],[82,[2,82]],[85,[2,85,[82],["85-e"]]],[84,[2,84,[84],["84-e"]]],[83,[2,83]],["84-e","84-e"],["85-e","85-e"],["86-e","86-e"],["88-e","88-e"],["90-e","90-e"]],"bbChildren":[],"edgeInfos":[[3,[[90,0]]],[0,[[3,0]]],[1,[[2,0]]],["2-e",[[1,0]]],[2,[[0,0]]],["3-e",[["2-e",0]]],[7,[["3-e",0]]],[4,[[7,0]]],[5,[[6,0]]],["6-e",[[5,0]]],[6,[[4,0]]],["7-e",[["6-e",0]]],[11,[["7-e",0]]],[8,[[11,0]]],[9,[[10,0]]],["10-e",[[9,0]]],[10,[[8,0]]],["11-e",[["10-e",0]]],[17,[["11-e",0]]],[13,[[16,0]]],[14,[[15,0]]],["15-e",[[14,0]]],[15,[[13,0]]],["16-e",[["15-e",0]]],[16,[[12,0]]],[12,[[17,0]]],["17-e",[["16-e",0]]],[23,[["17-e",0]]],[19,[[22,0]]],[20,[[21,0]]],["21-e",[[20,0]]],[21,[[19,0]]],["22-e",[["21-e",0]]],[22,[[18,0]]],[18,[[23,0]]],["23-e",[["22-e",0]]],[32,[["23-e",0]]],[25,[[31,0]]],[26,[[29,0]]],[27,[[28,0]]],["28-e",[[27,0]]],[28,[[26,0]]],["29-e",[["28-e",0]]],[29,[[30,0]]],["30-e",[["29-e",0]]],[30,[[25,0]]],["31-e",[["30-e",0]]],[31,[[24,0]]],[24,[[32,0]]],["32-e",[["31-e",0]]],[36,[["32-e",0]]],[33,[[36,0]]],[34,[[35,0]]],["35-e",[[34,0]]],[35,[[33,0]]],["36-e",[["35-e",0]]],[55,[["36-e",0]]],[37,[[52,0]]],[38,[[39,0]]],["39-e",[[38,0]]],[39,[[37,0]]],[40,[[50,0]]],[41,[[48,0]]],[42,[[44,0]]],[43,[[42,0]]],["44-e",[[43,0]]],[44,[[41,0]]],[45,[[47,0]]],[46,[[45,0]]],["47-e",[[46,0]]],[47,[["44-e",0]]],["48-e",[["47-e",0]]],[48,[[49,0]]],["49-e",[["48-e",0]]],[49,[[40,0]]],["50-e",[["49-e",0]]],[50,[[51,0]]],["51-e",[["50-e",0]]],[51,[["39-e",0]]],["52-e",[["51-e",0]]],[53,[[54,0]]],["54-e",[[53,0]]],[54,[["52-e",0]]],[52,[[55,0]]],["55-e",[["54-e",0]]],[67,[["55-e",0]]],[56,[[67,0]]],[57,[[60,0]]],[58,[[59,0]]],["59-e",[[58,0]]],[59,[[57,0]]],["60-e",[["59-e",0]]],[60,[[61,0]]],["61-e",[["60-e",0]]],[61,[[56,0]]],[62,[[65,0]]],[63,[[64,0]]],["64-e",[[63,0]]],[64,[[62,0]]],["65-e",[["64-e",0]]],[65,[[66,0]]],["66-e",[["65-e",0]]],[66,[["61-e",0]]],["67-e",[["66-e",0]]],[79,[["67-e",0]]],[68,[[79,0]]],[69,[[72,0]]],[70,[[71,0]]],["71-e",[[70,0]]],[71,[[69,0]]],["72-e",[["71-e",0]]],[72,[[73,0]]],["73-e",[["72-e",0]]],[73,[[68,0]]],[74,[[77,0]]],[75,[[76,0]]],["76-e",[[75,0]]],[76,[[74,0]]],["77-e",[["76-e",0]]],[77,[[78,0]]],["78-e",[["77-e",0]]],[78,[["73-e",0]]],["79-e",[["78-e",0]]],[89,[["79-e",0]]],[80,[[89,0]]],[81,[[87,0]]],[82,[[85,0]]],[83,[[84,0]]],["84-e",[[83,0]]],[84,[[82,0]]],["85-e",[["84-e",0]]],[85,[[86,0]]],["86-e",[["85-e",0]]],[86,[[81,0]]],["87-e",[["86-e",0]]],[87,[[88,0]]],["88-e",[["87-e",0]]],[88,[[80,0]]],["89-e",[["88-e",0]]],["90-e",[["89-e",0]]]],"revEdgeInfos":[[90,[[3,0]]],[3,[[0,0]]],[2,[[1,0]]],[1,[["2-e",0]]],[0,[[2,0]]],["2-e",[["3-e",0]]],["3-e",[[7,0]]],[7,[[4,0]]],[6,[[5,0]]],[5,[["6-e",0]]],[4,[[6,0]]],["6-e",[["7-e",0]]],["7-e",[[11,0]]],[11,[[8,0]]],[10,[[9,0]]],[9,[["10-e",0]]],[8,[[10,0]]],["10-e",[["11-e",0]]],["11-e",[[17,0]]],[16,[[13,0]]],[15,[[14,0]]],[14,[["15-e",0]]],[13,[[15,0]]],["15-e",[["16-e",0]]],[12,[[16,0]]],[17,[[12,0]]],["16-e",[["17-e",0]]],["17-e",[[23,0]]],[22,[[19,0]]],[21,[[20,0]]],[20,[["21-e",0]]],[19,[[21,0]]],["21-e",[["22-e",0]]],[18,[[22,0]]],[23,[[18,0]]],["22-e",[["23-e",0]]],["23-e",[[32,0]]],[31,[[25,0]]],[29,[[26,0]]],[28,[[27,0]]],[27,[["28-e",0]]],[26,[[28,0]]],["28-e",[["29-e",0]]],[30,[[29,0]]],["29-e",[["30-e",0]]],[25,[[30,0]]],["30-e",[["31-e",0]]],[24,[[31,0]]],[32,[[24,0]]],["31-e",[["32-e",0]]],["32-e",[[36,0]]],[36,[[33,0]]],[35,[[34,0]]],[34,[["35-e",0]]],[33,[[35,0]]],["35-e",[["36-e",0]]],["36-e",[[55,0]]],[52,[[37,0]]],[39,[[38,0]]],[38,[["39-e",0]]],[37,[[39,0]]],[50,[[40,0]]],[48,[[41,0]]],[44,[[42,0]]],[42,[[43,0]]],[43,[["44-e",0]]],[41,[[44,0]]],[47,[[45,0]]],[45,[[46,0]]],[46,[["47-e",0]]],["44-e",[[47,0]]],["47-e",[["48-e",0]]],[49,[[48,0]]],["48-e",[["49-e",0]]],[40,[[49,0]]],["49-e",[["50-e",0]]],[51,[[50,0]]],["50-e",[["51-e",0]]],["39-e",[[51,0]]],["51-e",[["52-e",0]]],[54,[[53,0]]],[53,[["54-e",0]]],["52-e",[[54,0]]],[55,[[52,0]]],["54-e",[["55-e",0]]],["55-e",[[67,0]]],[67,[[56,0]]],[60,[[57,0]]],[59,[[58,0]]],[58,[["59-e",0]]],[57,[[59,0]]],["59-e",[["60-e",0]]],[61,[[60,0]]],["60-e",[["61-e",0]]],[56,[[61,0]]],[65,[[62,0]]],[64,[[63,0]]],[63,[["64-e",0]]],[62,[[64,0]]],["64-e",[["65-e",0]]],[66,[[65,0]]],["65-e",[["66-e",0]]],["61-e",[[66,0]]],["66-e",[["67-e",0]]],["67-e",[[79,0]]],[79,[[68,0]]],[72,[[69,0]]],[71,[[70,0]]],[70,[["71-e",0]]],[69,[[71,0]]],["71-e",[["72-e",0]]],[73,[[72,0]]],["72-e",[["73-e",0]]],[68,[[73,0]]],[77,[[74,0]]],[76,[[75,0]]],[75,[["76-e",0]]],[74,[[76,0]]],["76-e",[["77-e",0]]],[78,[[77,0]]],["77-e",[["78-e",0]]],["73-e",[[78,0]]],["78-e",[["79-e",0]]],["79-e",[[89,0]]],[89,[[80,0]]],[87,[[81,0]]],[85,[[82,0]]],[84,[[83,0]]],[83,[["84-e",0]]],[82,[[84,0]]],["84-e",[["85-e",0]]],[86,[[85,0]]],["85-e",[["86-e",0]]],[81,[[86,0]]],["86-e",[["87-e",0]]],[88,[[87,0]]],["87-e",[["88-e",0]]],[80,[[88,0]]],["88-e",[["89-e",0]]],["89-e",[["90-e",0]]]],"_mayBB":false},"breaks":[],"nexts":[],"returns":[],"exitPoints":["90-e"],"entryPoints":[90]},".meta":{"timing":2}}}} ``` @@ -2182,7 +2183,7 @@ _As the code is pretty long, we inhibit pretty printing and syntax highlighting -The complete round-trip took 20.7 ms (including time required to validate the messages, start, and stop the internal mock server). +The complete round-trip took 20.4 ms (including time required to validate the messages, start, and stop the internal mock server). From f36ad891757843493a041933ac63ce1319746d77 Mon Sep 17 00:00:00 2001 From: Naomi Panda Date: Sat, 16 May 2026 18:13:15 +0200 Subject: [PATCH 03/10] feat: wip identify name of package --- .../call/built-in/built-in-library.ts | 99 +++++++----- .../main/libraries/link-libraries.test.ts | 151 +++++++++++++++++- 2 files changed, 211 insertions(+), 39 deletions(-) diff --git a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts index 7ec19f5e5cc..3ab3bd701db 100644 --- a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts +++ b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts @@ -15,6 +15,11 @@ import { BuiltInProcName } from '../../../../../environments/built-in-proc-name' import { Environment } from '../../../../../environments/environment'; import { EdgeType } from '../../../../../graph/edge'; import { isUndefined } from '../../../../../../util/assert'; +import type { RArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument'; +import { resolveIdToValue } from '../../../../../eval/resolve/alias-tracking'; +import { valueSetGuard } from '../../../../../eval/values/general'; +import type { Package } from '../../../../../../project/plugins/package-version-plugins/package'; +import { isValue } from '../../../../../eval/values/r-value'; /** * Process a library call like `library` or `require` @@ -26,22 +31,24 @@ export function processLibrary( data: DataflowProcessorInformation ): DataflowInformation { /* we do not really know what loading the library does and what side effects it causes, hence we mark it as an unknown side effect */ - if(args.length !== 1) { + const characterOnlyArg = args.map(v => v as RArgument).find(v => v.lexeme === 'character.only'); + const characterOnly = characterOnlyArg?.value?.type === 'RLogical' && characterOnlyArg?.value?.content === true; + if(args.length > 2 || args.length === 2 && !characterOnly ){ dataflowLogger.warn(`Currently only one-arg library-likes are allows (for ${Identifier.toString(name.content)}), skipping`); return processKnownFunctionCall({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information; } const nameToLoad = unpackNonameArg(args[0]); - if(nameToLoad === undefined || nameToLoad.type !== RType.Symbol) { + if(nameToLoad === undefined || nameToLoad.type !== RType.Symbol && nameToLoad.type !== RType.String){ + //if(nameToLoad === undefined || nameToLoad.type !== RType.Symbol && !characterOnly || characterOnly && nameToLoad.type !== RType.Symbol && nameToLoad.type !== RType.String) { dataflowLogger.warn('No library name provided, skipping'); return processKnownFunctionCall({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information; } - if(Identifier.getNamespace(nameToLoad.content) !== undefined) { + if(Identifier.getNamespace(nameToLoad.type === RType.String ? nameToLoad.content.str : nameToLoad.content) !== undefined) { dataflowLogger.warn('Namespaced library names are not supported, ignoring namespace'); } - // treat as a function call but convert the first argument to a string - const newArg: RString = { + const newArg: RString = nameToLoad.type === RType.String ? nameToLoad : { type: RType.String, info: nameToLoad.info, lexeme: nameToLoad.lexeme, @@ -56,34 +63,69 @@ export function processLibrary( hasUnknownSideEffect: true, origin: BuiltInProcName.Library }).information; - - const dependency = data.ctx.deps.getDependency(nameToLoad.lexeme); - /*if(dependency && dependency.name === 'ggplot2'){ - if(dependency.namespaceInfo?.exportedSymbols.find(v => v === 'ggplot')){ - linkLibraryGlob('ggplot', dependency.name, info, rootId); + let packetName = nameToLoad?.lexeme; + //case: character.only = TRUE + if(characterOnly){ + const resolveArgs = { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx }; + const resolved = valueSetGuard(resolveIdToValue(nameToLoad.info.id, resolveArgs)); + let t = undefined; + if(resolved?.elements.length === 1 && resolved.elements[0].type === 'string') { + const r = resolved.elements[0]; + if(isValue(r.value)){ + t = r.value.str; + } + } + if(t){ + packetName = t; + } else { + dataflowLogger.warn('Package argument must be character only, skipping'); + return processKnownFunctionCall({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information; } - }*/ - if(dependency){ - dependency.namespaceInfo?.exportedSymbols.forEach(v => linkLibraryGlob(v, dependency.name, info, rootId)); } + const dependency = data.ctx.deps.getDependency(packetName); + linkDependency(dependency, info, rootId, data); return info; } +function linkDependency(dependency: Package | undefined, info: DataflowInformation, rootId: NodeId, data: DataflowProcessorInformation){ + if(dependency && dependency.namespaceInfo){ + for(const v of dependency.namespaceInfo.exportedSymbols){ + linkLibraryGlob(v, dependency.name, info, rootId); + } + for(const v of dependency.namespaceInfo.importedPackages){ + //problem! we shouldn't always import everything + const importedDependency = data.ctx.deps.getDependency(v[0]); + //check whether already loaded, problem also applies here + //better?: define set loadedDep? in REnv and add to it whenever defining new env for pack + //const env = info.environment.current; + /*while(env !== null){ + if(env.n === importedDependency){ + continue; + } + env = env.parent; + }*/ + linkDependency(importedDependency, info, rootId, data); + } + } +} + function linkLibraryGlob(func: string, pack: string, info: DataflowInformation, rootId: NodeId): void{ const globalEnv = getGlobalEnv(info); if(isUndefined(globalEnv)){ return; } const oldGlobParent = globalEnv.parent; - let ggplotEnv = new Environment(oldGlobParent); - ggplotEnv.n = pack; - ggplotEnv = ggplotEnv.define({ + let packetEnv = new Environment(oldGlobParent); + packetEnv.n = pack; + console.log('before define', packetEnv); + packetEnv = packetEnv.define({ name: Identifier.make(func, pack), type: ReferenceType.Function, nodeId: NodeId.toBuiltIn(func), definedAt: NodeId.toBuiltIn(pack), }); - globalEnv.parent = ggplotEnv; + console.log('after define', packetEnv); + globalEnv.parent = packetEnv; info.environment = { level: info.environment.level + 1, current: info.environment.current @@ -96,27 +138,8 @@ function getGlobalEnv(info: DataflowInformation){ return undefined; } let env = info.environment.current; - for(let i = 0; i < info.environment.level; i++){ + for(let i = 1; i < info.environment.level; i++){ env = env.parent; } return env; -} -/*function linkLibrary(func: string, pack: string, info: DataflowInformation, rootId: NodeId): void{ - // console.log(nameToLoad?.lexeme);g - // console.log(data.ctx.deps.getDependency(nameToLoad?.lexeme ?? '')) - const oldParent = info.environment.current.parent; - let ggplotEnv = new Environment(oldParent); - ggplotEnv.n = pack; - ggplotEnv = ggplotEnv.define({ - name: Identifier.make(func, pack), - type: ReferenceType.Function, - nodeId: NodeId.toBuiltIn(func), - definedAt: NodeId.toBuiltIn(pack), - }); - info.environment.current.parent = ggplotEnv; - info.environment = { - level: info.environment.level + 1, - current: info.environment.current - }; - info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads); -}*/ +} \ No newline at end of file diff --git a/test/functionality/dataflow/main/libraries/link-libraries.test.ts b/test/functionality/dataflow/main/libraries/link-libraries.test.ts index 420d1c53c5f..c890b7c08c8 100644 --- a/test/functionality/dataflow/main/libraries/link-libraries.test.ts +++ b/test/functionality/dataflow/main/libraries/link-libraries.test.ts @@ -54,6 +54,7 @@ importFrom(stats,setNames)`)).content().current })); analyzer.addRequest('library(ggplot2)\nggplot()\nggplot()'); const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)); expect(df.graph.outgoingEdges(5)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges(7)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); @@ -149,4 +150,152 @@ importFrom(stats,setNames)`)).content().current expect(df.graph.outgoingEdges('built-in:across')?.get(7)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges(7)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); }); -})); \ No newline at end of file +})); + +describe('Linked library imports libraries', withTreeSitter(ts => { + test('Linked library loads imported (unloaded) library', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'dplyr', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(across)\nexport(test)')).content().current + })); + analyzer.addRequest('library(ggplot2)\nlibrary(dplyr)\nggplot(data = NULL, mapping = aes())'); + const df = await analyzer.dataflow(); + //console.log(analyzer.context().env); + console.log(df.environment.current); + + }); +})); + + +describe('Link libraries with character.only', withTreeSitter(ts => { + test('link with variable', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.addRequest('x <- "ggplot2"; library(x, character.only = TRUE)\nggplot()\nggplot()'); + const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)); + //correctly reads character.only + expect(df.graph.outgoingEdges(9)?.get(8)?.types === EdgeType.Argument).toBeTruthy(); + expect(df.graph.outgoingEdges(8)?.get(7)?.types === EdgeType.Reads).toBeTruthy(); + expect(df.graph.idMap?.get(7)?.lexeme).toBeTruthy(); + //ggplot links to library + expect(df.graph.outgoingEdges(11)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges(13)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(6)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + }); + test('link with string value', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.addRequest('library("ggplot2", character.only = TRUE)\nggplot()\nggplot()'); + const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)); + //correctly reads character.only + console.log(df.graph); + expect(df.graph.outgoingEdges(6)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); + expect(df.graph.outgoingEdges(5)?.get(4)?.types === EdgeType.Reads).toBeTruthy(); + expect(df.graph.idMap?.get(4)?.lexeme).toBeTruthy(); + //ggplot2 links to library + expect(df.graph.outgoingEdges(8)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges(10)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(6)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + }); +})); + From 1d29e3baf4fd603e2f08b07e8fa042c4f625f4ee Mon Sep 17 00:00:00 2001 From: Naomi Panda Date: Mon, 18 May 2026 12:04:55 +0200 Subject: [PATCH 04/10] feat: wip namespace imports create new namespace and import environments --- .../call/built-in/built-in-library.ts | 166 +++++++++++++++--- .../main/libraries/link-libraries.test.ts | 12 +- 2 files changed, 147 insertions(+), 31 deletions(-) diff --git a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts index 3ab3bd701db..5c4b2baf0e6 100644 --- a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts +++ b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts @@ -87,50 +87,164 @@ export function processLibrary( return info; } +function linkImport(dependency: Package, info: DataflowInformation, data: DataflowProcessorInformation): Environment | undefined{ + const globalEnv = getGlobalEnv(info); + if(isUndefined(globalEnv) || isUndefined(dependency.namespaceInfo)){ + return; + } + //holds all imports of the namespace file + let importsEnv = new Environment(globalEnv); + importsEnv.n = 'imports:' + dependency.name; + for(const imp of dependency.namespaceInfo.importedPackages){ + //for every dependency imported in the namespacefile + const importedDependency = data.ctx.deps.getDependency(imp[0]); + const funcToImport: string[] |undefined = imp[1] === 'all' ? importedDependency?.namespaceInfo?.exportedSymbols : importedDependency?.namespaceInfo?.exportedSymbols.filter(v => v in (imp[1] as string[])); + if(isUndefined(funcToImport)){ + return; + } + const impNamespaceEnv = createNameSpaceEnv(funcToImport, (importedDependency as Package).name, info, importsEnv.id); + if(isUndefined(impNamespaceEnv)){ + return; + } + /*const successor = linkImport(importedDependency as Package, info, data); + if(isUndefined(successor)){ + return; + }*/ + //we define all imported functions in the imports environment + for(const func of funcToImport){ + importsEnv = importsEnv.define({ + name: Identifier.make(func, (importedDependency as Package).name), + type: ReferenceType.Function, + nodeId: NodeId.toBuiltIn(func), + definedAt: impNamespaceEnv.id + }); + info.graph.addEdge(NodeId.toBuiltIn(func), impNamespaceEnv.id, EdgeType.Reads | EdgeType.Calls); + } + const importOfImpNamespace = linkImport(importedDependency as Package, info, data); + if(isUndefined(importOfImpNamespace)){ + return; + } + impNamespaceEnv.parent = globalEnv; + /*info.environment = { + level: info.environment.level + 1, + current: info.environment.current + };*/ + } + return importsEnv; +} + +function createNameSpaceEnv(functions: string[], pack: string, info: DataflowInformation, rootId: NodeId): Environment |undefined{ + const globalEnv = getGlobalEnv(info); + if(isUndefined(globalEnv)){ + return; + } + let packetEnv = new Environment(globalEnv); + packetEnv.n = 'namespace:' + pack; + for(const func of functions){ + packetEnv = packetEnv.define({ + name: Identifier.make(func, pack), + type: ReferenceType.Function, + nodeId: NodeId.toBuiltIn(func), + definedAt: NodeId.toBuiltIn(pack), + }); + info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); + } + /*info.environment = { + level: info.environment.level + 1, + current: info.environment.current + };*/ + return packetEnv; +} + +/* +function linkNamespaceImport(dependency: Package, info: DataflowInformation, data: DataflowProcessorInformation){ + //add imports and namespace environment as children of global environment + const globalEnv = getGlobalEnv(info); + if(isUndefined(globalEnv)){ + return; + } + if(dependency.namespaceInfo){ + let importsEnv = new Environment(globalEnv); + importsEnv.n = 'imports:' + dependency.name; + for(const imp of dependency.namespaceInfo.importedPackages){ + const impDependency = data.ctx.deps.getDependency(imp[0]); + if(impDependency){ + const toImport: string[] |undefined = imp[1] === 'all' ? impDependency.namespaceInfo?.exportedSymbols : impDependency.namespaceInfo?.exportedSymbols.filter(v => v in (imp[1] as string[])); + if(toImport){ + for(const func of toImport){ + importsEnv = importsEnv.define({ + name: Identifier.make(func, impDependency.name), + type: ReferenceType.Function, + nodeId: NodeId.toBuiltIn(func), + definedAt: NodeId.toBuiltIn(impDependency.name), + }); + info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); + } + linkNamespaceImport(impDependency, info, data); + } + } + } + let namespaceEnv = new Environment(importsEnv); + namespaceEnv.n = 'namespace:' + dependency.name; + info.environment = { + level: info.environment.level + 2, + current: info.environment.current + }; + } +} +*/ function linkDependency(dependency: Package | undefined, info: DataflowInformation, rootId: NodeId, data: DataflowProcessorInformation){ if(dependency && dependency.namespaceInfo){ - for(const v of dependency.namespaceInfo.exportedSymbols){ - linkLibraryGlob(v, dependency.name, info, rootId); + //add package environment as immediate parent of global environment + const p = linkLibraryGlob(dependency.namespaceInfo.exportedSymbols, dependency.name, info, rootId); + //linkNamespaceImport(dependency, info, data); + if(isUndefined(p)){ + return; } - for(const v of dependency.namespaceInfo.importedPackages){ - //problem! we shouldn't always import everything - const importedDependency = data.ctx.deps.getDependency(v[0]); - //check whether already loaded, problem also applies here - //better?: define set loadedDep? in REnv and add to it whenever defining new env for pack - //const env = info.environment.current; - /*while(env !== null){ - if(env.n === importedDependency){ - continue; - } - env = env.parent; - }*/ - linkDependency(importedDependency, info, rootId, data); + const b = createNameSpaceEnv(dependency.namespaceInfo.exportedSymbols, dependency.name, info, p.id); + if(isUndefined(b)){ + return; } + const a = linkImport(dependency, info, data); + if(isUndefined(a)){ + return; + } + b.parent = a; + info.environment = { + level: info.environment.level + 2, + current: info.environment.current + }; } } -function linkLibraryGlob(func: string, pack: string, info: DataflowInformation, rootId: NodeId): void{ + +/** + * Creates an environment with the given package name and sets it as the immediate parent of the global environment. + * Adds the given functions to the environment. + */ +function linkLibraryGlob(functions: string[], pack: string, info: DataflowInformation, rootId: NodeId){ const globalEnv = getGlobalEnv(info); if(isUndefined(globalEnv)){ return; } const oldGlobParent = globalEnv.parent; let packetEnv = new Environment(oldGlobParent); - packetEnv.n = pack; - console.log('before define', packetEnv); - packetEnv = packetEnv.define({ - name: Identifier.make(func, pack), - type: ReferenceType.Function, - nodeId: NodeId.toBuiltIn(func), - definedAt: NodeId.toBuiltIn(pack), - }); - console.log('after define', packetEnv); + packetEnv.n = 'package:' + pack; + for(const func of functions){ + packetEnv = packetEnv.define({ + name: Identifier.make(func, pack), + type: ReferenceType.Function, + nodeId: NodeId.toBuiltIn(func), + definedAt: NodeId.toBuiltIn(pack), + }); + info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); + } globalEnv.parent = packetEnv; info.environment = { level: info.environment.level + 1, current: info.environment.current }; - info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); + return packetEnv; } function getGlobalEnv(info: DataflowInformation){ diff --git a/test/functionality/dataflow/main/libraries/link-libraries.test.ts b/test/functionality/dataflow/main/libraries/link-libraries.test.ts index c890b7c08c8..d2f6599fc82 100644 --- a/test/functionality/dataflow/main/libraries/link-libraries.test.ts +++ b/test/functionality/dataflow/main/libraries/link-libraries.test.ts @@ -186,16 +186,18 @@ exportPattern("^[^\\\\.]\\\\.*$") import(grid) import(rlang) importFrom(scales,alpha) -importFrom(stats,setNames)`)).content().current +importFrom(stats,setNames) +import(random_placeholder)`)).content().current })); analyzer.context().deps.addDependency(new Package({ - name: 'dplyr', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(across)\nexport(test)')).content().current + name: 'random_placeholder', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)')).content().current })); - analyzer.addRequest('library(ggplot2)\nlibrary(dplyr)\nggplot(data = NULL, mapping = aes())'); + analyzer.addRequest('library(ggplot2)\nggplot()'); const df = await analyzer.dataflow(); //console.log(analyzer.context().env); - console.log(df.environment.current); + //console.log(df.environment.current); + console.log(Dataflow.visualize.mermaid.url(df.graph)); }); })); From ffbc7f90f4c7e36fc5c185bd9dc8e610a6ff4db8 Mon Sep 17 00:00:00 2001 From: Naomi Panda Date: Thu, 28 May 2026 08:28:11 +0200 Subject: [PATCH 05/10] feat: correctly rekursive imports, changed packetname identifying logic --- src/dataflow/environments/environment.ts | 3 + .../call/built-in/built-in-library.ts | 261 ++++++++---------- .../main/libraries/link-libraries.test.ts | 216 ++++++++++++++- 3 files changed, 321 insertions(+), 159 deletions(-) diff --git a/src/dataflow/environments/environment.ts b/src/dataflow/environments/environment.ts index cf3073db8d1..16e4bc74146 100644 --- a/src/dataflow/environments/environment.ts +++ b/src/dataflow/environments/environment.ts @@ -49,6 +49,8 @@ export class Environment implements IEnvironment { readonly id: number; /** Optional name for namespaced/non-anonymous environments, please only set if you know what you are doing */ n?: string; + /** to keep track if/whether environment was added as package/namespace/imports environment */ + t?: 'package' |'namespace' |'imports'; /** if created by a closure, the node id of that closure */ private c?: NodeId; parent: Environment; @@ -92,6 +94,7 @@ export class Environment implements IEnvironment { const clone = new Environment(parent, this.builtInEnv); clone.c = this.c; clone.n = this.n; + clone.t = this.t; clone.memory = new Map( this.memory.entries() .map(([k, v]) => [k, diff --git a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts index 5c4b2baf0e6..fc2d713591c 100644 --- a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts +++ b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts @@ -6,7 +6,7 @@ import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang- import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol'; import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id'; import { dataflowLogger } from '../../../../../logger'; -import { unpackNonameArg } from '../argument/unpack-argument'; +import { unpackArg } from '../argument/unpack-argument'; import type { RString } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-string'; import { RType } from '../../../../../../r-bridge/lang-4.x/ast/model/type'; import { wrapArgumentsUnnamed } from '../argument/make-argument'; @@ -15,11 +15,13 @@ import { BuiltInProcName } from '../../../../../environments/built-in-proc-name' import { Environment } from '../../../../../environments/environment'; import { EdgeType } from '../../../../../graph/edge'; import { isUndefined } from '../../../../../../util/assert'; -import type { RArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument'; +import { RArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument'; import { resolveIdToValue } from '../../../../../eval/resolve/alias-tracking'; import { valueSetGuard } from '../../../../../eval/values/general'; import type { Package } from '../../../../../../project/plugins/package-version-plugins/package'; -import { isValue } from '../../../../../eval/values/r-value'; +import type { NamespaceInfo } from '../../../../../../project/plugins/file-plugins/files/flowr-namespace-file'; +import { convertFnArguments } from '../common'; +import { pMatch } from '../../../../linker'; /** * Process a library call like `library` or `require` @@ -31,13 +33,21 @@ export function processLibrary( data: DataflowProcessorInformation ): DataflowInformation { /* we do not really know what loading the library does and what side effects it causes, hence we mark it as an unknown side effect */ - const characterOnlyArg = args.map(v => v as RArgument).find(v => v.lexeme === 'character.only'); - const characterOnly = characterOnlyArg?.value?.type === 'RLogical' && characterOnlyArg?.value?.content === true; - if(args.length > 2 || args.length === 2 && !characterOnly ){ - dataflowLogger.warn(`Currently only one-arg library-likes are allows (for ${Identifier.toString(name.content)}), skipping`); + //const characterOnlyArg = args.map(v => v as RArgument).find(v => v.lexeme === 'character.only'); + //const characterOnly = characterOnlyArg?.value?.type === 'RLogical' && characterOnlyArg?.value?.content === true; + if(args.length === 0){ return processKnownFunctionCall({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information; } - const nameToLoad = unpackNonameArg(args[0]); + const params = { + 'package': 'pkg', + 'character.only': 'char' + }; + const resolveArgs = { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx }; + const argMaps = pMatch(convertFnArguments(args), params); + const packageId = new Set(argMaps.get('pkg')); + const charId = new Set(argMaps.get('char')); + + const nameToLoad = unpackArg(RArgument.getWithId(args, argMaps.get('pkg')?.[0]));//unpackNonameArg(args[0]); if(nameToLoad === undefined || nameToLoad.type !== RType.Symbol && nameToLoad.type !== RType.String){ //if(nameToLoad === undefined || nameToLoad.type !== RType.Symbol && !characterOnly || characterOnly && nameToLoad.type !== RType.Symbol && nameToLoad.type !== RType.String) { @@ -64,8 +74,26 @@ export function processLibrary( origin: BuiltInProcName.Library }).information; let packetName = nameToLoad?.lexeme; + let isCharacterOnly; + if(charId.size === 1){ + const values = valueSetGuard(resolveIdToValue(charId.keys().toArray()[0], resolveArgs)); + if(values?.type === 'set' && values.elements.length !== 0){ + if(values.elements[0].type === 'logical'){ + isCharacterOnly = values.elements[0].value; + } + } + } //case: character.only = TRUE - if(characterOnly){ + if(isCharacterOnly){ + const values = valueSetGuard(resolveIdToValue(packageId.keys().toArray()[0], resolveArgs)); + if(values?.type === 'set' && values.elements.length !== 0){ + if(values.elements[0].type === 'string' && 'str' in values.elements[0].value){ + packetName = values.elements[0].value.str; + } + } + //else fälle? + } + /*if(characterOnly){ const resolveArgs = { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx }; const resolved = valueSetGuard(resolveIdToValue(nameToLoad.info.id, resolveArgs)); let t = undefined; @@ -81,67 +109,38 @@ export function processLibrary( dataflowLogger.warn('Package argument must be character only, skipping'); return processKnownFunctionCall({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information; } - } + }*/ const dependency = data.ctx.deps.getDependency(packetName); - linkDependency(dependency, info, rootId, data); + if(dependency){ + linkLibrary(dependency, info, rootId, data); + } return info; } -function linkImport(dependency: Package, info: DataflowInformation, data: DataflowProcessorInformation): Environment | undefined{ - const globalEnv = getGlobalEnv(info); - if(isUndefined(globalEnv) || isUndefined(dependency.namespaceInfo)){ - return; +function getGlobalEnv(info: DataflowInformation){ + if(info.environment.level < 0){ + return undefined; } - //holds all imports of the namespace file - let importsEnv = new Environment(globalEnv); - importsEnv.n = 'imports:' + dependency.name; - for(const imp of dependency.namespaceInfo.importedPackages){ - //for every dependency imported in the namespacefile - const importedDependency = data.ctx.deps.getDependency(imp[0]); - const funcToImport: string[] |undefined = imp[1] === 'all' ? importedDependency?.namespaceInfo?.exportedSymbols : importedDependency?.namespaceInfo?.exportedSymbols.filter(v => v in (imp[1] as string[])); - if(isUndefined(funcToImport)){ - return; - } - const impNamespaceEnv = createNameSpaceEnv(funcToImport, (importedDependency as Package).name, info, importsEnv.id); - if(isUndefined(impNamespaceEnv)){ - return; - } - /*const successor = linkImport(importedDependency as Package, info, data); - if(isUndefined(successor)){ - return; - }*/ - //we define all imported functions in the imports environment - for(const func of funcToImport){ - importsEnv = importsEnv.define({ - name: Identifier.make(func, (importedDependency as Package).name), - type: ReferenceType.Function, - nodeId: NodeId.toBuiltIn(func), - definedAt: impNamespaceEnv.id - }); - info.graph.addEdge(NodeId.toBuiltIn(func), impNamespaceEnv.id, EdgeType.Reads | EdgeType.Calls); - } - const importOfImpNamespace = linkImport(importedDependency as Package, info, data); - if(isUndefined(importOfImpNamespace)){ - return; - } - impNamespaceEnv.parent = globalEnv; - /*info.environment = { - level: info.environment.level + 1, - current: info.environment.current - };*/ + let env = info.environment.current; + for(let i = 0; i < info.environment.level; i++){ + env = env.parent; } - return importsEnv; + return env; } -function createNameSpaceEnv(functions: string[], pack: string, info: DataflowInformation, rootId: NodeId): Environment |undefined{ +function linkLibrary(dependency: Package, info: DataflowInformation, rootId: NodeId, data: DataflowProcessorInformation) { const globalEnv = getGlobalEnv(info); - if(isUndefined(globalEnv)){ + if(isUndefined(globalEnv) || isUndefined(dependency.namespaceInfo)){ return; } - let packetEnv = new Environment(globalEnv); - packetEnv.n = 'namespace:' + pack; + const pack = dependency.name; + const functions = dependency.namespaceInfo.exportedSymbols; + //add namespace environment + let namespaceEnv = new Environment(globalEnv); + namespaceEnv.n = pack; + namespaceEnv.t = 'namespace'; for(const func of functions){ - packetEnv = packetEnv.define({ + namespaceEnv = namespaceEnv.define({ name: Identifier.make(func, pack), type: ReferenceType.Function, nodeId: NodeId.toBuiltIn(func), @@ -149,111 +148,73 @@ function createNameSpaceEnv(functions: string[], pack: string, info: DataflowInf }); info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); } - /*info.environment = { + info.environment = { level: info.environment.level + 1, - current: info.environment.current - };*/ - return packetEnv; -} - -/* -function linkNamespaceImport(dependency: Package, info: DataflowInformation, data: DataflowProcessorInformation){ - //add imports and namespace environment as children of global environment - const globalEnv = getGlobalEnv(info); - if(isUndefined(globalEnv)){ - return; - } - if(dependency.namespaceInfo){ - let importsEnv = new Environment(globalEnv); - importsEnv.n = 'imports:' + dependency.name; - for(const imp of dependency.namespaceInfo.importedPackages){ - const impDependency = data.ctx.deps.getDependency(imp[0]); - if(impDependency){ - const toImport: string[] |undefined = imp[1] === 'all' ? impDependency.namespaceInfo?.exportedSymbols : impDependency.namespaceInfo?.exportedSymbols.filter(v => v in (imp[1] as string[])); - if(toImport){ - for(const func of toImport){ - importsEnv = importsEnv.define({ - name: Identifier.make(func, impDependency.name), - type: ReferenceType.Function, - nodeId: NodeId.toBuiltIn(func), - definedAt: NodeId.toBuiltIn(impDependency.name), - }); - info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); - } - linkNamespaceImport(impDependency, info, data); - } - } - } - let namespaceEnv = new Environment(importsEnv); - namespaceEnv.n = 'namespace:' + dependency.name; - info.environment = { - level: info.environment.level + 2, - current: info.environment.current - }; - } -} -*/ -function linkDependency(dependency: Package | undefined, info: DataflowInformation, rootId: NodeId, data: DataflowProcessorInformation){ - if(dependency && dependency.namespaceInfo){ - //add package environment as immediate parent of global environment - const p = linkLibraryGlob(dependency.namespaceInfo.exportedSymbols, dependency.name, info, rootId); - //linkNamespaceImport(dependency, info, data); - if(isUndefined(p)){ - return; - } - const b = createNameSpaceEnv(dependency.namespaceInfo.exportedSymbols, dependency.name, info, p.id); - if(isUndefined(b)){ - return; - } - const a = linkImport(dependency, info, data); - if(isUndefined(a)){ - return; - } - b.parent = a; - info.environment = { - level: info.environment.level + 2, - current: info.environment.current - }; - } -} - - -/** - * Creates an environment with the given package name and sets it as the immediate parent of the global environment. - * Adds the given functions to the environment. - */ -function linkLibraryGlob(functions: string[], pack: string, info: DataflowInformation, rootId: NodeId){ - const globalEnv = getGlobalEnv(info); - if(isUndefined(globalEnv)){ - return; - } + current: namespaceEnv + }; + //add package environment const oldGlobParent = globalEnv.parent; - let packetEnv = new Environment(oldGlobParent); - packetEnv.n = 'package:' + pack; + let packageEnv = new Environment(oldGlobParent); + packageEnv.n = pack; + packageEnv.t = 'package'; for(const func of functions){ - packetEnv = packetEnv.define({ + packageEnv = packageEnv.define({ name: Identifier.make(func, pack), type: ReferenceType.Function, nodeId: NodeId.toBuiltIn(func), - definedAt: NodeId.toBuiltIn(pack), + definedAt: namespaceEnv.id, }); - info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); } - globalEnv.parent = packetEnv; + globalEnv.parent = packageEnv; info.environment = { level: info.environment.level + 1, current: info.environment.current }; - return packetEnv; + //add imports environment + let importsEnv: Environment |undefined = new Environment(globalEnv); + importsEnv.n = pack; + importsEnv.t = 'imports'; + importsEnv = recImports(importsEnv, dependency.namespaceInfo, data, new Set()); + if(importsEnv){ + info.environment = { + level: info.environment.level + 1, + current: info.environment.current + }; + namespaceEnv.parent = importsEnv; + } } -function getGlobalEnv(info: DataflowInformation){ - if(info.environment.level < 0){ - return undefined; - } - let env = info.environment.current; - for(let i = 1; i < info.environment.level; i++){ - env = env.parent; +function recImports(importsEnv: Environment, namespaceInfo: NamespaceInfo, data: DataflowProcessorInformation, alreadyImportedAll: Set){ + for(const imp of namespaceInfo.importedPackages){ + const importedDependency = data.ctx.deps.getDependency(imp[0]); + if(isUndefined(importedDependency)){ + continue; + } + const funcToImport: string[] | undefined = imp[1] === 'all' ? importedDependency?.namespaceInfo?.exportedSymbols : importedDependency?.namespaceInfo?.exportedSymbols.filter(v => (imp[1] as string[]).includes(v)); + if(isUndefined(funcToImport)){ + continue; + } + if(alreadyImportedAll.has(importedDependency.name)){ + continue; + } + for(const func of funcToImport){ + if(importsEnv.memory.has(importedDependency.name + ':' + func)){ + continue; + } + importsEnv = importsEnv.define({ + name: Identifier.make(importedDependency.name + ':' + func, importsEnv.n), + type: ReferenceType.Function, + nodeId: NodeId.toBuiltIn(func), + definedAt: NodeId.toBuiltIn(importedDependency.name) + }); + } + if(imp[1] === 'all'){ + alreadyImportedAll.add(importedDependency.name); + } + //info.graph.addEdge(rootId, NodeId.toBuiltIn((importedDependency as Package).name), EdgeType.Reads | EdgeType.Calls); + if(importedDependency?.namespaceInfo){ + importsEnv = recImports(importsEnv, importedDependency.namespaceInfo, data, alreadyImportedAll); + } } - return env; + return importsEnv; } \ No newline at end of file diff --git a/test/functionality/dataflow/main/libraries/link-libraries.test.ts b/test/functionality/dataflow/main/libraries/link-libraries.test.ts index d2f6599fc82..a1a76e88687 100644 --- a/test/functionality/dataflow/main/libraries/link-libraries.test.ts +++ b/test/functionality/dataflow/main/libraries/link-libraries.test.ts @@ -153,6 +153,92 @@ importFrom(stats,setNames)`)).content().current })); describe('Linked library imports libraries', withTreeSitter(ts => { + test('Linked library loads imported (already imported) library', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames) +import(random_placeholder)`)).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nimport(ggplot2)\nimportFrom(random_placeholder3, a)')).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nexport(test3)\nimport(random_placeholder)')).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder3', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(a)\nexport(b)\nimportFrom(random_placeholder2, test3)')).content().current + })); + analyzer.addRequest('library(ggplot2)\nggplot()'); + + const df = await analyzer.dataflow(); + let env = df.environment.current; + console.log(env); + const ggplotSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + const rPSsymbols = ['test1', 'test2']; + const rP2Symbols = ['test1', 'test2', 'test3']; + const rP3Symbols = ['a', 'b']; + //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... + //ggplot namespace + expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot imports + env = env.parent; + const imported = rPSsymbols.map(v => 'random_placeholder:' + v).concat(ggplotSymbols.map(v => 'ggplot2:' + v)).concat(['random_placeholder3:a', 'random_placeholder2:test3']); + expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + /*analyzer.addRequest('library(random_placeholder2)'); + df = await analyzer.dataflow(); + env = df.environment.current; + console.log(env); + expect(env.n === 'random_placeholder2' && env.t === 'namespace' && compare(new Set(r_p2_symbols), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent; + expect(env.n === 'random_placeholder' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + + analyzer.addRequest('library(random_placeholder3)'); + df = await analyzer.dataflow(); + env = df.environment.current; + expect(env.n === 'random_placeholder3' && env.t === 'namespace' && compare(new Set(r_p3_symbols), new Set(env.memory.keys()))).toBeTruthy(); + imported = ['random_placeholder2:test3'].concat(r_p_symbols.map(v => 'random_placeholder:' + v)).concat(ggplotSymbols.map(v => 'ggplot2:' + v)); + expect(env.n === 'random_placeholder3' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot package*/ + env = env.parent.parent;/* + expect(env.n === 'random_placeholder3' && env.t === 'package' && compare(new Set(r_p3_symbols), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent; + expect(env.n === 'random_placeholder2' && env.t === 'package' && compare(new Set(r_p2_symbols), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent;*/ + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + }); test('Linked library loads imported (unloaded) library', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) @@ -195,13 +281,81 @@ import(random_placeholder)`)).content().current })); analyzer.addRequest('library(ggplot2)\nggplot()'); const df = await analyzer.dataflow(); - //console.log(analyzer.context().env); - //console.log(df.environment.current); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - + let env = df.environment.current; + const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... + //ggplot namespace + expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot imports + env = env.parent; + const imported = ['random_placeholder:test1', 'random_placeholder:test2']; + console.log(env); + expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot package + env = env.parent.parent; + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + }); + test('Linked library only partly imports another library', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames) +importFrom(random_placeholder, test1)`)).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)')).content().current + })); + analyzer.addRequest('library(ggplot2)\nggplot()'); + const df = await analyzer.dataflow(); + let env = df.environment.current; + const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... + //ggplot namespace + expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot imports + env = env.parent; + const imported = ['random_placeholder:test1']; + console.log(env); + expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot package + env = env.parent.parent; + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); }); })); +function compare(s1: Set, s2: Set){ + return s1.difference(s2).size === 0 && s2.difference(s1).size === 0; +} describe('Link libraries with character.only', withTreeSitter(ts => { test('link with variable', async() => { @@ -239,16 +393,60 @@ import(rlang) importFrom(scales,alpha) importFrom(stats,setNames)`)).content().current })); - analyzer.addRequest('x <- "ggplot2"; library(x, character.only = TRUE)\nggplot()\nggplot()'); + analyzer.addRequest('x <- "ggplot2"\nlibrary(x, character.only = TRUE)\nggplot()\nggplot()'); const df = await analyzer.dataflow(); console.log(Dataflow.visualize.mermaid.url(df.graph)); //correctly reads character.only - expect(df.graph.outgoingEdges(9)?.get(8)?.types === EdgeType.Argument).toBeTruthy(); + /*expect(df.graph.outgoingEdges(9)?.get(8)?.types === EdgeType.Argument).toBeTruthy(); expect(df.graph.outgoingEdges(8)?.get(7)?.types === EdgeType.Reads).toBeTruthy(); - expect(df.graph.idMap?.get(7)?.lexeme).toBeTruthy(); + expect(df.graph.idMap?.get(7)?.lexeme).toBeTruthy();*/ //ggplot links to library expect(df.graph.outgoingEdges(11)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges(13)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(9)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + }); + test('link usually', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.addRequest('library(ggplot2, character.only = FALSE)\nggplot()\nggplot()'); + const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)); + console.log(df.graph); + //graph has not character.only? + expect(df.graph.outgoingEdges(8)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges(10)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges('built-in:ggplot')?.get(6)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); }); test('link with string value', async() => { @@ -291,9 +489,9 @@ importFrom(stats,setNames)`)).content().current console.log(Dataflow.visualize.mermaid.url(df.graph)); //correctly reads character.only console.log(df.graph); - expect(df.graph.outgoingEdges(6)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); + /*expect(df.graph.outgoingEdges(6)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); expect(df.graph.outgoingEdges(5)?.get(4)?.types === EdgeType.Reads).toBeTruthy(); - expect(df.graph.idMap?.get(4)?.lexeme).toBeTruthy(); + expect(df.graph.idMap?.get(4)?.lexeme).toBeTruthy();*/ //ggplot2 links to library expect(df.graph.outgoingEdges(8)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges(10)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); From cec8203823604df08fd3c549c95ed596550f4b26 Mon Sep 17 00:00:00 2001 From: Naomi Panda Date: Thu, 28 May 2026 08:36:40 +0200 Subject: [PATCH 06/10] lint: commented out --- .../dataflow/main/libraries/link-libraries.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/functionality/dataflow/main/libraries/link-libraries.test.ts b/test/functionality/dataflow/main/libraries/link-libraries.test.ts index a1a76e88687..f531d5b38bd 100644 --- a/test/functionality/dataflow/main/libraries/link-libraries.test.ts +++ b/test/functionality/dataflow/main/libraries/link-libraries.test.ts @@ -202,14 +202,14 @@ import(random_placeholder)`)).content().current namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(a)\nexport(b)\nimportFrom(random_placeholder2, test3)')).content().current })); analyzer.addRequest('library(ggplot2)\nggplot()'); - + const df = await analyzer.dataflow(); let env = df.environment.current; console.log(env); const ggplotSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; const rPSsymbols = ['test1', 'test2']; - const rP2Symbols = ['test1', 'test2', 'test3']; - const rP3Symbols = ['a', 'b']; + //const rP2Symbols = ['test1', 'test2', 'test3']; + //const rP3Symbols = ['a', 'b']; //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... //ggplot namespace expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); From 630d756cc7e837c4dbbb2a8ada8f4b4fbb2312dc Mon Sep 17 00:00:00 2001 From: Florian Sihler Date: Thu, 28 May 2026 09:04:33 +0200 Subject: [PATCH 07/10] feat(wip): fix resolution --- src/dataflow/eval/resolve/alias-tracking.ts | 1 + .../call/built-in/built-in-library.ts | 41 ++--- .../libraries/link-lib-character-only.test.ts | 151 ++++++++++++++++++ .../main/libraries/link-libraries.test.ts | 143 ----------------- 4 files changed, 174 insertions(+), 162 deletions(-) create mode 100644 test/functionality/dataflow/main/libraries/link-lib-character-only.test.ts diff --git a/src/dataflow/eval/resolve/alias-tracking.ts b/src/dataflow/eval/resolve/alias-tracking.ts index 35f3ef91e1e..58ee42f03b9 100644 --- a/src/dataflow/eval/resolve/alias-tracking.ts +++ b/src/dataflow/eval/resolve/alias-tracking.ts @@ -215,6 +215,7 @@ export function trackAliasInEnvironments(identifier: Identifier | undefined, env } const defs = resolveByNameAnyType(identifier, environment); + if(defs === undefined) { return Top; } diff --git a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts index fc2d713591c..28b23ba1097 100644 --- a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts +++ b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts @@ -6,7 +6,6 @@ import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang- import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol'; import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id'; import { dataflowLogger } from '../../../../../logger'; -import { unpackArg } from '../argument/unpack-argument'; import type { RString } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-string'; import { RType } from '../../../../../../r-bridge/lang-4.x/ast/model/type'; import { wrapArgumentsUnnamed } from '../argument/make-argument'; @@ -22,6 +21,7 @@ import type { Package } from '../../../../../../project/plugins/package-version- import type { NamespaceInfo } from '../../../../../../project/plugins/file-plugins/files/flowr-namespace-file'; import { convertFnArguments } from '../common'; import { pMatch } from '../../../../linker'; +import type { Lift, TernaryLogical } from '../../../../../eval/values/r-value'; /** * Process a library call like `library` or `require` @@ -44,10 +44,10 @@ export function processLibrary( }; const resolveArgs = { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx }; const argMaps = pMatch(convertFnArguments(args), params); - const packageId = new Set(argMaps.get('pkg')); - const charId = new Set(argMaps.get('char')); + const packageId = Array.from(new Set(argMaps.get('pkg'))); + const charId = Array.from(new Set(argMaps.get('char'))); - const nameToLoad = unpackArg(RArgument.getWithId(args, argMaps.get('pkg')?.[0]));//unpackNonameArg(args[0]); + const nameToLoad = RArgument.getValue(args, packageId[0]); if(nameToLoad === undefined || nameToLoad.type !== RType.Symbol && nameToLoad.type !== RType.String){ //if(nameToLoad === undefined || nameToLoad.type !== RType.Symbol && !characterOnly || characterOnly && nameToLoad.type !== RType.Symbol && nameToLoad.type !== RType.String) { @@ -68,24 +68,17 @@ export function processLibrary( str: Identifier.getName(nameToLoad.content) } }; - const info = processKnownFunctionCall({ - name, args: wrapArgumentsUnnamed([newArg], data.completeAst.idMap), rootId, data, - hasUnknownSideEffect: true, - origin: BuiltInProcName.Library - }).information; + let packetName = nameToLoad?.lexeme; - let isCharacterOnly; - if(charId.size === 1){ - const values = valueSetGuard(resolveIdToValue(charId.keys().toArray()[0], resolveArgs)); - if(values?.type === 'set' && values.elements.length !== 0){ - if(values.elements[0].type === 'logical'){ - isCharacterOnly = values.elements[0].value; - } + let isCharacterOnly: Lift = false; + if(charId.length >= 1){ + const values = valueSetGuard(resolveIdToValue(charId[0], resolveArgs)); + if(values?.type === 'set' && values.elements.length === 1 && values.elements[0].type === 'logical') { + isCharacterOnly = values.elements[0].value; } } - //case: character.only = TRUE - if(isCharacterOnly){ - const values = valueSetGuard(resolveIdToValue(packageId.keys().toArray()[0], resolveArgs)); + if(isCharacterOnly !== false){ + const values = valueSetGuard(resolveIdToValue(nameToLoad.info.id, resolveArgs)); if(values?.type === 'set' && values.elements.length !== 0){ if(values.elements[0].type === 'string' && 'str' in values.elements[0].value){ packetName = values.elements[0].value.str; @@ -93,6 +86,14 @@ export function processLibrary( } //else fälle? } + // TODO: check whether we know something about the library and if so, do **not** mark it as an unkown side effect + console.log(packetName); + const info = processKnownFunctionCall({ + name, + args: wrapArgumentsUnnamed([newArg, ...args.slice(1)], data.completeAst.idMap), rootId, data, + hasUnknownSideEffect: false, + origin: BuiltInProcName.Library + }).information; /*if(characterOnly){ const resolveArgs = { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx }; const resolved = valueSetGuard(resolveIdToValue(nameToLoad.info.id, resolveArgs)); @@ -113,6 +114,8 @@ export function processLibrary( const dependency = data.ctx.deps.getDependency(packetName); if(dependency){ linkLibrary(dependency, info, rootId, data); + } else { + info.graph.markIdForUnknownSideEffects(rootId); } return info; } diff --git a/test/functionality/dataflow/main/libraries/link-lib-character-only.test.ts b/test/functionality/dataflow/main/libraries/link-lib-character-only.test.ts new file mode 100644 index 00000000000..6a154566df6 --- /dev/null +++ b/test/functionality/dataflow/main/libraries/link-lib-character-only.test.ts @@ -0,0 +1,151 @@ +import { describe, expect, test } from 'vitest'; +import { withTreeSitter } from '../../../_helper/shell'; +import { FlowrAnalyzerBuilder } from '../../../../../src/project/flowr-analyzer-builder'; +import { Package } from '../../../../../src/project/plugins/package-version-plugins/package'; +import { Dataflow } from '../../../../../src/dataflow/graph/df-helper'; +import { EdgeType } from '../../../../../src/dataflow/graph/edge'; +import { FlowrNamespaceFile } from '../../../../../src/project/plugins/file-plugins/files/flowr-namespace-file'; +import { FlowrInlineTextFile } from '../../../../../src/project/context/flowr-file'; + +describe('Link libraries with character.only', withTreeSitter(ts => { + test.only('link with variable', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.addRequest('x <- "ggplot2"\nlibrary(x, character.only = TRUE)\nggplot()\nggplot()'); + const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)); + //correctly reads character.only + /*expect(df.graph.outgoingEdges(9)?.get(8)?.types === EdgeType.Argument).toBeTruthy(); + expect(df.graph.outgoingEdges(8)?.get(7)?.types === EdgeType.Reads).toBeTruthy(); + expect(df.graph.idMap?.get(7)?.lexeme).toBeTruthy();*/ + //ggplot links to library + expect(df.graph.outgoingEdges(11)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges(13)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(9)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + }); + test('link usually', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.addRequest('library(ggplot2, character.only = FALSE)\nggplot()\nggplot()'); + const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)); + console.log(df.graph); + //graph has not character.only? + expect(df.graph.outgoingEdges(8)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges(10)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(6)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + }); + test('link with string value', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames)`)).content().current + })); + analyzer.addRequest('library("ggplot2", character.only = TRUE)\nggplot()\nggplot()'); + const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)); + //correctly reads character.only + console.log(df.graph); + /*expect(df.graph.outgoingEdges(6)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); + expect(df.graph.outgoingEdges(5)?.get(4)?.types === EdgeType.Reads).toBeTruthy(); + expect(df.graph.idMap?.get(4)?.lexeme).toBeTruthy();*/ + //ggplot2 links to library + expect(df.graph.outgoingEdges(8)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges(10)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + expect(df.graph.outgoingEdges('built-in:ggplot')?.get(6)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); + }); +})); + diff --git a/test/functionality/dataflow/main/libraries/link-libraries.test.ts b/test/functionality/dataflow/main/libraries/link-libraries.test.ts index f531d5b38bd..07df8770513 100644 --- a/test/functionality/dataflow/main/libraries/link-libraries.test.ts +++ b/test/functionality/dataflow/main/libraries/link-libraries.test.ts @@ -356,146 +356,3 @@ importFrom(random_placeholder, test1)`)).content().current function compare(s1: Set, s2: Set){ return s1.difference(s2).size === 0 && s2.difference(s1).size === 0; } - -describe('Link libraries with character.only', withTreeSitter(ts => { - test('link with variable', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) -S3method(fortify,lm) -S3method(fortify,default) -S3method(fortify,map) -S3method(scale_type,Date) -S3method(scale_type,POSIXt) -S3method(scale_type,character) -S3method(scale_type,numeric) -S3method(scale_type,factor) -S3method(scale_type,default) -S3method(ggplot,default) -S3method(print,ggproto) -S3method(print,rel) -export("+") -export(ggplot) -export(aes) -export(geom_point) -export(geom_line) -export(theme_bw) -export(coord_cartesian) -export(ggsave) -export(fortify) -export(scale_type) -exportPattern("^[^\\\\.]\\\\.*$") -import(grid) -import(rlang) -importFrom(scales,alpha) -importFrom(stats,setNames)`)).content().current - })); - analyzer.addRequest('x <- "ggplot2"\nlibrary(x, character.only = TRUE)\nggplot()\nggplot()'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - //correctly reads character.only - /*expect(df.graph.outgoingEdges(9)?.get(8)?.types === EdgeType.Argument).toBeTruthy(); - expect(df.graph.outgoingEdges(8)?.get(7)?.types === EdgeType.Reads).toBeTruthy(); - expect(df.graph.idMap?.get(7)?.lexeme).toBeTruthy();*/ - //ggplot links to library - expect(df.graph.outgoingEdges(11)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges(13)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(9)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - }); - test('link usually', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) -S3method(fortify,lm) -S3method(fortify,default) -S3method(fortify,map) -S3method(scale_type,Date) -S3method(scale_type,POSIXt) -S3method(scale_type,character) -S3method(scale_type,numeric) -S3method(scale_type,factor) -S3method(scale_type,default) -S3method(ggplot,default) -S3method(print,ggproto) -S3method(print,rel) -export("+") -export(ggplot) -export(aes) -export(geom_point) -export(geom_line) -export(theme_bw) -export(coord_cartesian) -export(ggsave) -export(fortify) -export(scale_type) -exportPattern("^[^\\\\.]\\\\.*$") -import(grid) -import(rlang) -importFrom(scales,alpha) -importFrom(stats,setNames)`)).content().current - })); - analyzer.addRequest('library(ggplot2, character.only = FALSE)\nggplot()\nggplot()'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - console.log(df.graph); - //graph has not character.only? - expect(df.graph.outgoingEdges(8)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges(10)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(6)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - }); - test('link with string value', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) -S3method(fortify,lm) -S3method(fortify,default) -S3method(fortify,map) -S3method(scale_type,Date) -S3method(scale_type,POSIXt) -S3method(scale_type,character) -S3method(scale_type,numeric) -S3method(scale_type,factor) -S3method(scale_type,default) -S3method(ggplot,default) -S3method(print,ggproto) -S3method(print,rel) -export("+") -export(ggplot) -export(aes) -export(geom_point) -export(geom_line) -export(theme_bw) -export(coord_cartesian) -export(ggsave) -export(fortify) -export(scale_type) -exportPattern("^[^\\\\.]\\\\.*$") -import(grid) -import(rlang) -importFrom(scales,alpha) -importFrom(stats,setNames)`)).content().current - })); - analyzer.addRequest('library("ggplot2", character.only = TRUE)\nggplot()\nggplot()'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - //correctly reads character.only - console.log(df.graph); - /*expect(df.graph.outgoingEdges(6)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); - expect(df.graph.outgoingEdges(5)?.get(4)?.types === EdgeType.Reads).toBeTruthy(); - expect(df.graph.idMap?.get(4)?.lexeme).toBeTruthy();*/ - //ggplot2 links to library - expect(df.graph.outgoingEdges(8)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges(10)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(6)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - }); -})); - From a094ec4083ea8e105d649ff6d8b38956945c71bb Mon Sep 17 00:00:00 2001 From: Naomi Panda Date: Sat, 30 May 2026 22:42:00 +0200 Subject: [PATCH 08/10] feat: vertex added to df graph when function added to namespace env --- .../call/built-in/built-in-library.ts | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts index 28b23ba1097..31663d05815 100644 --- a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts +++ b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts @@ -22,6 +22,8 @@ import type { NamespaceInfo } from '../../../../../../project/plugins/file-plugi import { convertFnArguments } from '../common'; import { pMatch } from '../../../../linker'; import type { Lift, TernaryLogical } from '../../../../../eval/values/r-value'; +import { VertexType } from '../../../../../graph/vertex'; +import type { DataflowFunctionFlowInformation } from '../../../../../graph/graph'; /** * Process a library call like `library` or `require` @@ -87,30 +89,12 @@ export function processLibrary( //else fälle? } // TODO: check whether we know something about the library and if so, do **not** mark it as an unkown side effect - console.log(packetName); const info = processKnownFunctionCall({ name, args: wrapArgumentsUnnamed([newArg, ...args.slice(1)], data.completeAst.idMap), rootId, data, hasUnknownSideEffect: false, origin: BuiltInProcName.Library }).information; - /*if(characterOnly){ - const resolveArgs = { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx }; - const resolved = valueSetGuard(resolveIdToValue(nameToLoad.info.id, resolveArgs)); - let t = undefined; - if(resolved?.elements.length === 1 && resolved.elements[0].type === 'string') { - const r = resolved.elements[0]; - if(isValue(r.value)){ - t = r.value.str; - } - } - if(t){ - packetName = t; - } else { - dataflowLogger.warn('Package argument must be character only, skipping'); - return processKnownFunctionCall({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information; - } - }*/ const dependency = data.ctx.deps.getDependency(packetName); if(dependency){ linkLibrary(dependency, info, rootId, data); @@ -120,6 +104,8 @@ export function processLibrary( return info; } +//todo: muss fixen: wenn zwei libraries importiert über normales 'library' und nicht rekImports, gibt nicht globalEnv sondern das package:library1 zurück +//todo: ggplotEnv hat hier level 3, sollte aber eigentlich level 2 haben, denn globalEnv muss level 0 haben, deswegen funktioniert die ganze logik nicht function getGlobalEnv(info: DataflowInformation){ if(info.environment.level < 0){ return undefined; @@ -149,12 +135,23 @@ function linkLibrary(dependency: Package, info: DataflowInformation, nodeId: NodeId.toBuiltIn(func), definedAt: NodeId.toBuiltIn(pack), }); + info.environment = { + level: info.environment.level + 1, + current: namespaceEnv + }; + const subflow: DataflowFunctionFlowInformation = { graph: new Set(), unknownReferences: [], in: [], out: [], environment: info.environment, entryPoint: NodeId.toBuiltIn(func), hooks: [] }; + info.graph.addVertex({ + tag: VertexType.FunctionDefinition, + id: NodeId.toBuiltIn(func), + environment: info.environment, + cds: data.cds, + params: {}, + subflow: subflow, + exitPoints: [], + }, data.ctx.env.makeCleanEnv()); + //info.graph.addVertex(NodeId.toBuiltIn(func) as string, info.environment); info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); } - info.environment = { - level: info.environment.level + 1, - current: namespaceEnv - }; //add package environment const oldGlobParent = globalEnv.parent; let packageEnv = new Environment(oldGlobParent); @@ -174,6 +171,7 @@ function linkLibrary(dependency: Package, info: DataflowInformation, current: info.environment.current }; //add imports environment + //Todo: change: es gibt immer ein importsEnv auch wenn keine import das heißt die Abfrage ob importsEnv undefined kann raus let importsEnv: Environment |undefined = new Environment(globalEnv); importsEnv.n = pack; importsEnv.t = 'imports'; From c8587a82820ca2dac85a892cba3cf8a85eeaa9a2 Mon Sep 17 00:00:00 2001 From: Naomi Panda Date: Sat, 30 May 2026 22:46:18 +0200 Subject: [PATCH 09/10] test: changed tests to use assertDataflow --- .../libraries/link-lib-character-only.test.ts | 130 +++---- .../main/libraries/link-lib-imports.test.ts | 334 ++++++++++++++++++ .../main/libraries/link-libraries.test.ts | 268 +++++++++----- 3 files changed, 582 insertions(+), 150 deletions(-) create mode 100644 test/functionality/dataflow/main/libraries/link-lib-imports.test.ts diff --git a/test/functionality/dataflow/main/libraries/link-lib-character-only.test.ts b/test/functionality/dataflow/main/libraries/link-lib-character-only.test.ts index 6a154566df6..1decdec9824 100644 --- a/test/functionality/dataflow/main/libraries/link-lib-character-only.test.ts +++ b/test/functionality/dataflow/main/libraries/link-lib-character-only.test.ts @@ -1,20 +1,28 @@ -import { describe, expect, test } from 'vitest'; -import { withTreeSitter } from '../../../_helper/shell'; -import { FlowrAnalyzerBuilder } from '../../../../../src/project/flowr-analyzer-builder'; +import { describe } from 'vitest'; +import { assertDataflow, withTreeSitter } from '../../../_helper/shell'; import { Package } from '../../../../../src/project/plugins/package-version-plugins/package'; -import { Dataflow } from '../../../../../src/dataflow/graph/df-helper'; import { EdgeType } from '../../../../../src/dataflow/graph/edge'; import { FlowrNamespaceFile } from '../../../../../src/project/plugins/file-plugins/files/flowr-namespace-file'; import { FlowrInlineTextFile } from '../../../../../src/project/context/flowr-file'; +import { emptyGraph } from '../../../../../src/dataflow/graph/dataflowgraph-builder'; +import { NodeId } from '../../../../../src/r-bridge/lang-4.x/ast/model/processing/node-id'; +import { label } from '../../../_helper/label'; describe('Link libraries with character.only', withTreeSitter(ts => { - test.only('link with variable', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) + assertDataflow(label('Link with variable'), ts, 'x <- "ggplot2"\nlibrary(x, character.only = TRUE)\nggplot()\nggplot()', + emptyGraph() + //reads character.only + .addEdge(9, 8, EdgeType.Argument) + .addEdge(8, 7, EdgeType.Reads) + //ggplot links to library + .addEdge(11, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(13, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('ggplot'), 9, EdgeType.Reads | EdgeType.Calls), + { + modifyAnalyzer: a => { + a.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) S3method(fortify,lm) S3method(fortify,default) S3method(fortify,map) @@ -42,26 +50,26 @@ import(grid) import(rlang) importFrom(scales,alpha) importFrom(stats,setNames)`)).content().current - })); - analyzer.addRequest('x <- "ggplot2"\nlibrary(x, character.only = TRUE)\nggplot()\nggplot()'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - //correctly reads character.only - /*expect(df.graph.outgoingEdges(9)?.get(8)?.types === EdgeType.Argument).toBeTruthy(); - expect(df.graph.outgoingEdges(8)?.get(7)?.types === EdgeType.Reads).toBeTruthy(); - expect(df.graph.idMap?.get(7)?.lexeme).toBeTruthy();*/ - //ggplot links to library - expect(df.graph.outgoingEdges(11)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges(13)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(9)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - }); - test('link usually', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) + })); + }, + expectIsSubgraph: true, + resolveIdsAsCriterion: true + } + ); + assertDataflow(label('Link usually'), ts, 'library(ggplot2, character.only = FALSE)\nggplot()\nggplot()', + emptyGraph() + //reads character.only + .addEdge(6, 5, EdgeType.Argument) + .addEdge(5, 4, EdgeType.Reads) + //correctly links + .addEdge(8, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(10, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('ggplot'), 6, EdgeType.Reads | EdgeType.Calls), + { + modifyAnalyzer: a => { + a.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) S3method(fortify,lm) S3method(fortify,default) S3method(fortify,map) @@ -89,23 +97,26 @@ import(grid) import(rlang) importFrom(scales,alpha) importFrom(stats,setNames)`)).content().current - })); - analyzer.addRequest('library(ggplot2, character.only = FALSE)\nggplot()\nggplot()'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - console.log(df.graph); - //graph has not character.only? - expect(df.graph.outgoingEdges(8)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges(10)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(6)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - }); - test('link with string value', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) + })); + }, + expectIsSubgraph: true, + resolveIdsAsCriterion: true + } + ); + assertDataflow(label('link with string value'), ts, 'library("ggplot2", character.only = TRUE)\nggplot()\nggplot()', + emptyGraph() + //reads character.only + .addEdge(6, 5, EdgeType.Argument) + .addEdge(5, 4, EdgeType.Reads) + //correctly links + .addEdge(8, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(10, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('ggplot'), 6, EdgeType.Reads | EdgeType.Calls), + { + modifyAnalyzer: a => { + a.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) S3method(fortify,lm) S3method(fortify,default) S3method(fortify,map) @@ -133,19 +144,10 @@ import(grid) import(rlang) importFrom(scales,alpha) importFrom(stats,setNames)`)).content().current - })); - analyzer.addRequest('library("ggplot2", character.only = TRUE)\nggplot()\nggplot()'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - //correctly reads character.only - console.log(df.graph); - /*expect(df.graph.outgoingEdges(6)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); - expect(df.graph.outgoingEdges(5)?.get(4)?.types === EdgeType.Reads).toBeTruthy(); - expect(df.graph.idMap?.get(4)?.lexeme).toBeTruthy();*/ - //ggplot2 links to library - expect(df.graph.outgoingEdges(8)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges(10)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(6)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - }); -})); - + })); + }, + expectIsSubgraph: true, + resolveIdsAsCriterion: true + } + ); +})); \ No newline at end of file diff --git a/test/functionality/dataflow/main/libraries/link-lib-imports.test.ts b/test/functionality/dataflow/main/libraries/link-lib-imports.test.ts new file mode 100644 index 00000000000..ec2d7225e06 --- /dev/null +++ b/test/functionality/dataflow/main/libraries/link-lib-imports.test.ts @@ -0,0 +1,334 @@ +import { describe, expect, test } from 'vitest'; +import { withTreeSitter } from '../../../_helper/shell'; +import { FlowrAnalyzerBuilder } from '../../../../../src/project/flowr-analyzer-builder'; +import { Package } from '../../../../../src/project/plugins/package-version-plugins/package'; +import { FlowrNamespaceFile } from '../../../../../src/project/plugins/file-plugins/files/flowr-namespace-file'; +import { FlowrInlineTextFile } from '../../../../../src/project/context/flowr-file'; + +describe('Linked library imports libraries', withTreeSitter(ts => { + test('Linked library loads imported (already imported) library 1', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames) +import(random_placeholder)`)).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nimport(ggplot2)\nimportFrom(random_placeholder3, a)')).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nexport(test3)\nimport(random_placeholder)')).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder3', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(a)\nexport(b)\nimportFrom(random_placeholder2, test3)')).content().current + })); + analyzer.addRequest('library(ggplot2)\nggplot()'); + + const df = await analyzer.dataflow(); + let env = df.environment.current; + console.log(env); + const ggplotSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + const rPSsymbols = ['test1', 'test2']; + //namespace:ggplot2 -> imports:ggplot2 -> globalEnv -> package:ggplot2 -> ... + //ggplot2 namespace + expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot2 imports + env = env.parent; + const imported = rPSsymbols.map(v => 'random_placeholder:' + v).concat(ggplotSymbols.map(v => 'ggplot2:' + v)).concat(['random_placeholder3:a', 'random_placeholder2:test3']); + expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot2 package*/ + env = env.parent.parent; + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + }); + + test('Linked library loads imported (already imported) library 2', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames) +import(random_placeholder)`)).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nimport(ggplot2)\nimportFrom(random_placeholder3, a)')).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nexport(test3)\nimport(random_placeholder)')).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder3', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(a)\nexport(b)\nimportFrom(random_placeholder2, test3)')).content().current + })); + analyzer.addRequest('library(ggplot2)\nlibrary(random_placeholder2)\nggplot()'); + + const df = await analyzer.dataflow(); + let env = df.environment.current; + const ggplotSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + const rPSsymbols = ['test1', 'test2']; + const rP2Symbols = ['test1', 'test2', 'test3']; + //tested here: namespace:random_placeholder2 -> imports:random_placeholder2 -> globalEnv -> package:random_placeholder2 -> package:ggplot -> ... + //random_placeholder2 namespace + expect(env.n === 'random_placeholder2' && env.t === 'namespace' && compare(new Set(rP2Symbols), new Set(env.memory.keys()))).toBeTruthy(); + //random_placeholder2 imports + env = env.parent; + const imported = rPSsymbols.map(v => 'random_placeholder:' + v).concat(ggplotSymbols.map(v => 'ggplot2:' + v)).concat(['random_placeholder3:a', 'random_placeholder2:test3']); + expect(env.n === 'random_placeholder2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + //packages*/ + env = env.parent.parent; + expect(env.n === 'random_placeholder2' && env.t === 'package' && compare(new Set(rP2Symbols), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent; + console.log(env) + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + }); + + test('Linked library loads imported (already imported) library 3', async() => { +const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames) +import(random_placeholder)`)).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nimport(ggplot2)\nimportFrom(random_placeholder3, a)')).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nexport(test3)\nimport(random_placeholder)')).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder3', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(a)\nexport(b)\nimportFrom(random_placeholder2, test3)')).content().current + })); + analyzer.addRequest('library(ggplot2)\nlibrary(random_placeholder2)\nlibrary(random_placeholder3)\nggplot()'); + + const df = await analyzer.dataflow(); + let env = df.environment.current; + const ggplotSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + const rPSsymbols = ['test1', 'test2']; + const rP2Symbols = ['test1', 'test2', 'test3']; + const rP3Symbols = ['a', 'b']; + //tested here: namespace:random_placeholder3 -> imports:random_placeholder3 -> globalEnv -> package:random_placeholder3 -> package:random_placeholder2 -> package:ggplot -> ... + //random_placeholder3 namespace + expect(env.n === 'random_placeholder3' && env.t === 'namespace' && compare(new Set(rP3Symbols), new Set(env.memory.keys()))).toBeTruthy(); + //random_placeholder3 imports + env = env.parent; + const imported = ['random_placeholder2:test3'].concat(rPSsymbols.map(v => 'random_placeholder:' + v)).concat(ggplotSymbols.map(v => 'ggplot2:' + v)); + expect(env.n === 'random_placeholder3' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + //packages + env = env.parent.parent; + expect(env.n === 'random_placeholder3' && env.t === 'package' && compare(new Set(rP3Symbols), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent; + expect(env.n === 'random_placeholder2' && env.t === 'package' && compare(new Set(rP2Symbols), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent; + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + }); + + test('Linked library loads imported (unloaded) library', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames) +import(random_placeholder)`)).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)')).content().current + })); + analyzer.addRequest('library(ggplot2)\nggplot()'); + const df = await analyzer.dataflow(); + let env = df.environment.current; + const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... + //ggplot namespace + expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot imports + env = env.parent; + const imported = ['random_placeholder:test1', 'random_placeholder:test2']; + console.log(env); + expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot package + env = env.parent.parent; + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + }); + test('Linked library only partly imports another library', async() => { + const analyzer = await new FlowrAnalyzerBuilder() + .setParser(ts) + .build(); + analyzer.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) +S3method(fortify,lm) +S3method(fortify,default) +S3method(fortify,map) +S3method(scale_type,Date) +S3method(scale_type,POSIXt) +S3method(scale_type,character) +S3method(scale_type,numeric) +S3method(scale_type,factor) +S3method(scale_type,default) +S3method(ggplot,default) +S3method(print,ggproto) +S3method(print,rel) +export("+") +export(ggplot) +export(aes) +export(geom_point) +export(geom_line) +export(theme_bw) +export(coord_cartesian) +export(ggsave) +export(fortify) +export(scale_type) +exportPattern("^[^\\\\.]\\\\.*$") +import(grid) +import(rlang) +importFrom(scales,alpha) +importFrom(stats,setNames) +importFrom(random_placeholder, test1)`)).content().current + })); + analyzer.context().deps.addDependency(new Package({ + name: 'random_placeholder', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)')).content().current + })); + analyzer.addRequest('library(ggplot2)\nggplot()'); + const df = await analyzer.dataflow(); + let env = df.environment.current; + const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... + //ggplot namespace + expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot imports + env = env.parent; + const imported = ['random_placeholder:test1']; + console.log(env); + expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot package + env = env.parent.parent; + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + }); +})); + +function compare(s1: Set, s2: Set){ + return s1.difference(s2).size === 0 && s2.difference(s1).size === 0; +} \ No newline at end of file diff --git a/test/functionality/dataflow/main/libraries/link-libraries.test.ts b/test/functionality/dataflow/main/libraries/link-libraries.test.ts index 07df8770513..cccb6855d57 100644 --- a/test/functionality/dataflow/main/libraries/link-libraries.test.ts +++ b/test/functionality/dataflow/main/libraries/link-libraries.test.ts @@ -1,23 +1,79 @@ import { describe, expect, test } from 'vitest'; -import { withTreeSitter } from '../../../_helper/shell'; +import { assertDataflow, withTreeSitter } from '../../../_helper/shell'; import { FlowrAnalyzerBuilder } from '../../../../../src/project/flowr-analyzer-builder'; import { Package } from '../../../../../src/project/plugins/package-version-plugins/package'; import { FlowrNamespaceFile } from '../../../../../src/project/plugins/file-plugins/files/flowr-namespace-file'; import { FlowrInlineTextFile } from '../../../../../src/project/context/flowr-file'; import { Dataflow } from '../../../../../src/dataflow/graph/df-helper'; import { EdgeType } from '../../../../../src/dataflow/graph/edge'; +import { compare } from 'semver'; +import { emptyGraph } from '../../../../../src/dataflow/graph/dataflowgraph-builder'; +import { NodeId } from '../../../../../src/r-bridge/lang-4.x/ast/model/processing/node-id'; +import { label } from '../../../_helper/label'; describe('Link libraries', withTreeSitter(ts => { - test('No dependencies set', async() => { + assertDataflow(label('ggplot links to ggplot2'), ts, 'library(ggplot2)\nggplot()\nggplot()', + emptyGraph() + .addEdge(5, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls) + .addEdge(7, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('ggplot'), 3, EdgeType.Reads | EdgeType.Calls), + { + modifyAnalyzer: a => { + a.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) + S3method(fortify,lm) + S3method(fortify,default) + S3method(fortify,map) + S3method(scale_type,Date) + S3method(scale_type,POSIXt) + S3method(scale_type,character) + S3method(scale_type,numeric) + S3method(scale_type,factor) + S3method(scale_type,default) + S3method(ggplot,default) + S3method(print,ggproto) + S3method(print,rel) + export("+") + export(ggplot) + export(aes) + export(geom_point) + export(geom_line) + export(theme_bw) + export(coord_cartesian) + export(ggsave) + export(fortify) + export(scale_type) + exportPattern("^[^\\\\.]\\\\.*$") + import(grid) + import(rlang) + importFrom(scales,alpha) + importFrom(stats,setNames)`)).content().current + })); + }, + expectIsSubgraph: true, + resolveIdsAsCriterion: true + } + ); + assertDataflow(label('No dependencies set'), ts, 'library(ggplot2)\nggplot()', + emptyGraph() + .addEdge(5, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls), + { + expectIsSubgraph: true, + resolveIdsAsCriterion: true, + mustNotHaveEdges: [[NodeId.toBuiltIn('ggplot'), 3]] + }); + /*test('No dependencies set', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); analyzer.addRequest('library(ggplot2)\nggplot()'); const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)) expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)).toBeUndefined(); expect(df.graph.outgoingEdges(5)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - }); - test('ggplot links to ggplot2', async() => { + });*/ + /*test('ggplot links to ggplot2', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -58,8 +114,52 @@ importFrom(stats,setNames)`)).content().current expect(df.graph.outgoingEdges(5)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges(7)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - }); - test('Several methods of same library', async() => { + });*/ + assertDataflow(label('Several methods of same library'), ts, 'library(ggplot2)\nggplot(data = NULL, mapping = aes())', + emptyGraph() + .addEdge(12, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('ggplot'), 3, EdgeType.Reads | EdgeType.Calls) + .addEdge(10, NodeId.toBuiltIn('aes'), EdgeType.Reads | EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('aes'), 3, EdgeType.Reads | EdgeType.Calls), + { + modifyAnalyzer: a => { + a.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) + S3method(fortify,lm) + S3method(fortify,default) + S3method(fortify,map) + S3method(scale_type,Date) + S3method(scale_type,POSIXt) + S3method(scale_type,character) + S3method(scale_type,numeric) + S3method(scale_type,factor) + S3method(scale_type,default) + S3method(ggplot,default) + S3method(print,ggproto) + S3method(print,rel) + export("+") + export(ggplot) + export(aes) + export(geom_point) + export(geom_line) + export(theme_bw) + export(coord_cartesian) + export(ggsave) + export(fortify) + export(scale_type) + exportPattern("^[^\\\\.]\\\\.*$") + import(grid) + import(rlang) + importFrom(scales,alpha) + importFrom(stats,setNames)`)).content().current + })); + }, + expectIsSubgraph: true, + resolveIdsAsCriterion: true + } + ); + /*test('Several methods of same library', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -96,11 +196,62 @@ importFrom(stats,setNames)`)).content().current })); analyzer.addRequest('library(ggplot2)\nggplot(data = NULL, mapping = aes())'); const df = await analyzer.dataflow(); + console.log(Dataflow.visualize.mermaid.url(df.graph)); expect(df.graph.outgoingEdges(12)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)?.types === EdgeType.Calls + EdgeType.Reads).toBeTruthy(); expect(df.graph.outgoingEdges(10)?.get('built-in:aes')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges('built-in:aes')?.get(3)?.types === EdgeType.Calls + EdgeType.Reads).toBeTruthy(); - }); + });*/ +assertDataflow(label('Links to several libraries'), ts, 'library(ggplot2)\nlibrary(dplyr)\nggplot(data = NULL, mapping = aes())\nacross()', + emptyGraph() + .addEdge(16, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('ggplot'), 3, EdgeType.Reads | EdgeType.Calls) + .addEdge(3, 1, EdgeType.Argument) + .addEdge(18, NodeId.toBuiltIn('across'), EdgeType.Reads | EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('across'), 7, EdgeType.Reads | EdgeType.Calls) + .addEdge(7, 5, EdgeType.Argument), + { + modifyAnalyzer: a => { + a.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) + S3method(fortify,lm) + S3method(fortify,default) + S3method(fortify,map) + S3method(scale_type,Date) + S3method(scale_type,POSIXt) + S3method(scale_type,character) + S3method(scale_type,numeric) + S3method(scale_type,factor) + S3method(scale_type,default) + S3method(ggplot,default) + S3method(print,ggproto) + S3method(print,rel) + export("+") + export(ggplot) + export(aes) + export(geom_point) + export(geom_line) + export(theme_bw) + export(coord_cartesian) + export(ggsave) + export(fortify) + export(scale_type) + exportPattern("^[^\\\\.]\\\\.*$") + import(grid) + import(rlang) + importFrom(scales,alpha) + importFrom(stats,setNames)`)).content().current + })); + a.context().deps.addDependency(new Package({ + name: 'dplyr', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(across)')).content().current + }));; + }, + expectIsSubgraph: true, + resolveIdsAsCriterion: true + } + ); test('Links to several libraries', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) @@ -150,10 +301,7 @@ importFrom(stats,setNames)`)).content().current expect(df.graph.outgoingEdges('built-in:across')?.get(7)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); expect(df.graph.outgoingEdges(7)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); }); -})); - -describe('Linked library imports libraries', withTreeSitter(ts => { - test('Linked library loads imported (already imported) library', async() => { +test('Linked library loads imported (unloaded) library', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -191,55 +339,25 @@ import(random_placeholder)`)).content().current })); analyzer.context().deps.addDependency(new Package({ name: 'random_placeholder', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nimport(ggplot2)\nimportFrom(random_placeholder3, a)')).content().current - })); - analyzer.context().deps.addDependency(new Package({ - name: 'random_placeholder2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nexport(test3)\nimport(random_placeholder)')).content().current - })); - analyzer.context().deps.addDependency(new Package({ - name: 'random_placeholder3', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(a)\nexport(b)\nimportFrom(random_placeholder2, test3)')).content().current + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)')).content().current })); analyzer.addRequest('library(ggplot2)\nggplot()'); - const df = await analyzer.dataflow(); let env = df.environment.current; - console.log(env); - const ggplotSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; - const rPSsymbols = ['test1', 'test2']; - //const rP2Symbols = ['test1', 'test2', 'test3']; - //const rP3Symbols = ['a', 'b']; + const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... //ggplot namespace - expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); //ggplot imports env = env.parent; - const imported = rPSsymbols.map(v => 'random_placeholder:' + v).concat(ggplotSymbols.map(v => 'ggplot2:' + v)).concat(['random_placeholder3:a', 'random_placeholder2:test3']); - expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - /*analyzer.addRequest('library(random_placeholder2)'); - df = await analyzer.dataflow(); - env = df.environment.current; + const imported = ['random_placeholder:test1', 'random_placeholder:test2']; console.log(env); - expect(env.n === 'random_placeholder2' && env.t === 'namespace' && compare(new Set(r_p2_symbols), new Set(env.memory.keys()))).toBeTruthy(); - env = env.parent; - expect(env.n === 'random_placeholder' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - - analyzer.addRequest('library(random_placeholder3)'); - df = await analyzer.dataflow(); - env = df.environment.current; - expect(env.n === 'random_placeholder3' && env.t === 'namespace' && compare(new Set(r_p3_symbols), new Set(env.memory.keys()))).toBeTruthy(); - imported = ['random_placeholder2:test3'].concat(r_p_symbols.map(v => 'random_placeholder:' + v)).concat(ggplotSymbols.map(v => 'ggplot2:' + v)); - expect(env.n === 'random_placeholder3' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot package*/ - env = env.parent.parent;/* - expect(env.n === 'random_placeholder3' && env.t === 'package' && compare(new Set(r_p3_symbols), new Set(env.memory.keys()))).toBeTruthy(); - env = env.parent; - expect(env.n === 'random_placeholder2' && env.t === 'package' && compare(new Set(r_p2_symbols), new Set(env.memory.keys()))).toBeTruthy(); - env = env.parent;*/ - expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot package + env = env.parent.parent; + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); }); - test('Linked library loads imported (unloaded) library', async() => { + test('Simple env structure', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -272,30 +390,18 @@ exportPattern("^[^\\\\.]\\\\.*$") import(grid) import(rlang) importFrom(scales,alpha) -importFrom(stats,setNames) -import(random_placeholder)`)).content().current - })); - analyzer.context().deps.addDependency(new Package({ - name: 'random_placeholder', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)')).content().current +importFrom(stats,setNames)`)).content().current })); analyzer.addRequest('library(ggplot2)\nggplot()'); const df = await analyzer.dataflow(); let env = df.environment.current; - const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; - //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... - //ggplot namespace - expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot imports + expect(env.n === 'ggplot2' && env.t === 'namespace').toBeTruthy(); env = env.parent; - const imported = ['random_placeholder:test1', 'random_placeholder:test2']; - console.log(env); - expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot package + expect(env.n === 'ggplot2' && env.t === 'imports').toBeTruthy(); env = env.parent.parent; - expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + expect(env.n === 'ggplot2' && env.t === 'package').toBeTruthy(); }); - test('Linked library only partly imports another library', async() => { + test('Several libraries structure', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -328,31 +434,21 @@ exportPattern("^[^\\\\.]\\\\.*$") import(grid) import(rlang) importFrom(scales,alpha) -importFrom(stats,setNames) -importFrom(random_placeholder, test1)`)).content().current +importFrom(stats,setNames)`)).content().current })); analyzer.context().deps.addDependency(new Package({ - name: 'random_placeholder', + name: 'random1', namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)')).content().current })); - analyzer.addRequest('library(ggplot2)\nggplot()'); + analyzer.addRequest('library(ggplot2)\nlibrary(random1)'); const df = await analyzer.dataflow(); let env = df.environment.current; - const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; - //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... - //ggplot namespace - expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot imports + expect(env.n === 'random1' && env.t === 'namespace').toBeTruthy(); env = env.parent; - const imported = ['random_placeholder:test1']; - console.log(env); - expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot package + expect(env.n === 'random1' && env.t === 'imports').toBeTruthy(); env = env.parent.parent; - expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + expect(env.n === 'random1' && env.t === 'package').toBeTruthy(); + env = env.parent; + expect(env.n === 'ggplot2' && env.t === 'package').toBeTruthy(); }); -})); - -function compare(s1: Set, s2: Set){ - return s1.difference(s2).size === 0 && s2.difference(s1).size === 0; -} +})); \ No newline at end of file From ea3917e944ab2079d10d9b023182ad8fbb6261d7 Mon Sep 17 00:00:00 2001 From: Naomi Panda Date: Mon, 1 Jun 2026 19:41:58 +0200 Subject: [PATCH 10/10] feat-fix: importFrom, environment structure a call to importFrom does now not lead to adding all imports of the dependency that is imported by this call as well anymore but only adds the specified functions; namespace_env is now not added anymore, instead the imports_env is added as the parent of the package_env --- .../call/built-in/built-in-library.ts | 62 ++- .../main/libraries/link-lib-imports.test.ts | 200 +++---- .../main/libraries/link-libraries.test.ts | 523 ++++++------------ 3 files changed, 268 insertions(+), 517 deletions(-) diff --git a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts index 31663d05815..f5e88220069 100644 --- a/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts +++ b/src/dataflow/internal/process/functions/call/built-in/built-in-library.ts @@ -23,7 +23,6 @@ import { convertFnArguments } from '../common'; import { pMatch } from '../../../../linker'; import type { Lift, TernaryLogical } from '../../../../../eval/values/r-value'; import { VertexType } from '../../../../../graph/vertex'; -import type { DataflowFunctionFlowInformation } from '../../../../../graph/graph'; /** * Process a library call like `library` or `require` @@ -104,8 +103,6 @@ export function processLibrary( return info; } -//todo: muss fixen: wenn zwei libraries importiert über normales 'library' und nicht rekImports, gibt nicht globalEnv sondern das package:library1 zurück -//todo: ggplotEnv hat hier level 3, sollte aber eigentlich level 2 haben, denn globalEnv muss level 0 haben, deswegen funktioniert die ganze logik nicht function getGlobalEnv(info: DataflowInformation){ if(info.environment.level < 0){ return undefined; @@ -124,6 +121,7 @@ function linkLibrary(dependency: Package, info: DataflowInformation, } const pack = dependency.name; const functions = dependency.namespaceInfo.exportedSymbols; + /* //add namespace environment let namespaceEnv = new Environment(globalEnv); namespaceEnv.n = pack; @@ -139,19 +137,8 @@ function linkLibrary(dependency: Package, info: DataflowInformation, level: info.environment.level + 1, current: namespaceEnv }; - const subflow: DataflowFunctionFlowInformation = { graph: new Set(), unknownReferences: [], in: [], out: [], environment: info.environment, entryPoint: NodeId.toBuiltIn(func), hooks: [] }; - info.graph.addVertex({ - tag: VertexType.FunctionDefinition, - id: NodeId.toBuiltIn(func), - environment: info.environment, - cds: data.cds, - params: {}, - subflow: subflow, - exitPoints: [], - }, data.ctx.env.makeCleanEnv()); - //info.graph.addVertex(NodeId.toBuiltIn(func) as string, info.environment); - info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); } + */ //add package environment const oldGlobParent = globalEnv.parent; let packageEnv = new Environment(oldGlobParent); @@ -162,27 +149,45 @@ function linkLibrary(dependency: Package, info: DataflowInformation, name: Identifier.make(func, pack), type: ReferenceType.Function, nodeId: NodeId.toBuiltIn(func), - definedAt: namespaceEnv.id, + definedAt: NodeId.toBuiltIn(pack), }); + info.graph.addVertex({ + tag: VertexType.FunctionDefinition, + id: NodeId.toBuiltIn(func), + environment: info.environment, + cds: data.cds, + params: {}, + subflow: { + graph: new Set(), + unknownReferences: [], + in: [], + out: [], + environment: info.environment, + entryPoint: NodeId.toBuiltIn(func), + hooks: [] + }, + exitPoints: [], + }, data.ctx.env.makeCleanEnv()); + //info.graph.addVertex(NodeId.toBuiltIn(func) as string, info.environment); + info.graph.addEdge(NodeId.toBuiltIn(func), rootId, EdgeType.Reads | EdgeType.Calls); } globalEnv.parent = packageEnv; - info.environment = { + //info environment shouldn't change if we always return globalEnv as current + /*info.environment = { level: info.environment.level + 1, current: info.environment.current - }; + };*/ //add imports environment - //Todo: change: es gibt immer ein importsEnv auch wenn keine import das heißt die Abfrage ob importsEnv undefined kann raus - let importsEnv: Environment |undefined = new Environment(globalEnv); + let importsEnv: Environment = new Environment(oldGlobParent); importsEnv.n = pack; importsEnv.t = 'imports'; importsEnv = recImports(importsEnv, dependency.namespaceInfo, data, new Set()); - if(importsEnv){ - info.environment = { - level: info.environment.level + 1, - current: info.environment.current - }; - namespaceEnv.parent = importsEnv; - } + //info environment shouldn't change if we always return globalEnv as current + /*info.environment = { + level: info.environment.level + 1, + current: info.environment.current + };*/ + packageEnv.parent = importsEnv; } function recImports(importsEnv: Environment, namespaceInfo: NamespaceInfo, data: DataflowProcessorInformation, alreadyImportedAll: Set){ @@ -213,7 +218,8 @@ function recImports(importsEnv: Environment, namespaceInfo: Namespace alreadyImportedAll.add(importedDependency.name); } //info.graph.addEdge(rootId, NodeId.toBuiltIn((importedDependency as Package).name), EdgeType.Reads | EdgeType.Calls); - if(importedDependency?.namespaceInfo){ + //if only importFrom() we don't have to recursively import + if(imp[1] === 'all' && importedDependency?.namespaceInfo){ importsEnv = recImports(importsEnv, importedDependency.namespaceInfo, data, alreadyImportedAll); } } diff --git a/test/functionality/dataflow/main/libraries/link-lib-imports.test.ts b/test/functionality/dataflow/main/libraries/link-lib-imports.test.ts index ec2d7225e06..fbd10aad67f 100644 --- a/test/functionality/dataflow/main/libraries/link-lib-imports.test.ts +++ b/test/functionality/dataflow/main/libraries/link-lib-imports.test.ts @@ -6,7 +6,7 @@ import { FlowrNamespaceFile } from '../../../../../src/project/plugins/file-plug import { FlowrInlineTextFile } from '../../../../../src/project/context/flowr-file'; describe('Linked library imports libraries', withTreeSitter(ts => { - test('Linked library loads imported (already imported) library 1', async() => { + test('Linked library loads circular imports 1', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -57,23 +57,21 @@ import(random_placeholder)`)).content().current analyzer.addRequest('library(ggplot2)\nggplot()'); const df = await analyzer.dataflow(); + //should be global env let env = df.environment.current; - console.log(env); + env = env.parent; const ggplotSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; const rPSsymbols = ['test1', 'test2']; - //namespace:ggplot2 -> imports:ggplot2 -> globalEnv -> package:ggplot2 -> ... - //ggplot2 namespace - expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + //globalEnv -> package:ggplot2 -> imports:ggplot2 -> ... + //ggplot2 package + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); //ggplot2 imports env = env.parent; - const imported = rPSsymbols.map(v => 'random_placeholder:' + v).concat(ggplotSymbols.map(v => 'ggplot2:' + v)).concat(['random_placeholder3:a', 'random_placeholder2:test3']); + const imported = rPSsymbols.map(v => 'random_placeholder:' + v).concat(ggplotSymbols.map(v => 'ggplot2:' + v)).concat(['random_placeholder3:a']); expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot2 package*/ - env = env.parent.parent; - expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); }); - test('Linked library loads imported (already imported) library 2', async() => { + test('Linked library loads circular imports 2', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -107,76 +105,6 @@ import(grid) import(rlang) importFrom(scales,alpha) importFrom(stats,setNames) -import(random_placeholder)`)).content().current - })); - analyzer.context().deps.addDependency(new Package({ - name: 'random_placeholder', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nimport(ggplot2)\nimportFrom(random_placeholder3, a)')).content().current - })); - analyzer.context().deps.addDependency(new Package({ - name: 'random_placeholder2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)\nexport(test3)\nimport(random_placeholder)')).content().current - })); - analyzer.context().deps.addDependency(new Package({ - name: 'random_placeholder3', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(a)\nexport(b)\nimportFrom(random_placeholder2, test3)')).content().current - })); - analyzer.addRequest('library(ggplot2)\nlibrary(random_placeholder2)\nggplot()'); - - const df = await analyzer.dataflow(); - let env = df.environment.current; - const ggplotSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; - const rPSsymbols = ['test1', 'test2']; - const rP2Symbols = ['test1', 'test2', 'test3']; - //tested here: namespace:random_placeholder2 -> imports:random_placeholder2 -> globalEnv -> package:random_placeholder2 -> package:ggplot -> ... - //random_placeholder2 namespace - expect(env.n === 'random_placeholder2' && env.t === 'namespace' && compare(new Set(rP2Symbols), new Set(env.memory.keys()))).toBeTruthy(); - //random_placeholder2 imports - env = env.parent; - const imported = rPSsymbols.map(v => 'random_placeholder:' + v).concat(ggplotSymbols.map(v => 'ggplot2:' + v)).concat(['random_placeholder3:a', 'random_placeholder2:test3']); - expect(env.n === 'random_placeholder2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - //packages*/ - env = env.parent.parent; - expect(env.n === 'random_placeholder2' && env.t === 'package' && compare(new Set(rP2Symbols), new Set(env.memory.keys()))).toBeTruthy(); - env = env.parent; - console.log(env) - expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); - }); - - test('Linked library loads imported (already imported) library 3', async() => { -const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) -S3method(fortify,lm) -S3method(fortify,default) -S3method(fortify,map) -S3method(scale_type,Date) -S3method(scale_type,POSIXt) -S3method(scale_type,character) -S3method(scale_type,numeric) -S3method(scale_type,factor) -S3method(scale_type,default) -S3method(ggplot,default) -S3method(print,ggproto) -S3method(print,rel) -export("+") -export(ggplot) -export(aes) -export(geom_point) -export(geom_line) -export(theme_bw) -export(coord_cartesian) -export(ggsave) -export(fortify) -export(scale_type) -exportPattern("^[^\\\\.]\\\\.*$") -import(grid) -import(rlang) -importFrom(scales,alpha) -importFrom(stats,setNames) import(random_placeholder)`)).content().current })); analyzer.context().deps.addDependency(new Package({ @@ -194,28 +122,31 @@ import(random_placeholder)`)).content().current analyzer.addRequest('library(ggplot2)\nlibrary(random_placeholder2)\nlibrary(random_placeholder3)\nggplot()'); const df = await analyzer.dataflow(); + //should be global env let env = df.environment.current; + env = env.parent; const ggplotSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; - const rPSsymbols = ['test1', 'test2']; + const rP1symbols = ['test1', 'test2']; const rP2Symbols = ['test1', 'test2', 'test3']; const rP3Symbols = ['a', 'b']; - //tested here: namespace:random_placeholder3 -> imports:random_placeholder3 -> globalEnv -> package:random_placeholder3 -> package:random_placeholder2 -> package:ggplot -> ... - //random_placeholder3 namespace - expect(env.n === 'random_placeholder3' && env.t === 'namespace' && compare(new Set(rP3Symbols), new Set(env.memory.keys()))).toBeTruthy(); - //random_placeholder3 imports + //global environment -> random_placeholder3 package -> random_placeholder3 imports -> random_placeholder2 package -> random_placeholder2 imports -> ggplot2 package -> ggplot2 imports + const imp3 = ['random_placeholder2:test3']; + const imp2 = ['random_placeholder3:a'].concat(ggplotSymbols.map(v => 'ggplot2:' + v)).concat(rP1symbols.map(v => 'random_placeholder:' + v)); + const impggplot = rP1symbols.map(v => 'random_placeholder:' + v).concat(ggplotSymbols.map(v => 'ggplot2:' + v)).concat(['random_placeholder3:a']); + expect(env.n === 'random_placeholder3' && env.t === 'package' && compare(new Set(rP3Symbols), new Set(env.memory.keys()))).toBeTruthy(); env = env.parent; - const imported = ['random_placeholder2:test3'].concat(rPSsymbols.map(v => 'random_placeholder:' + v)).concat(ggplotSymbols.map(v => 'ggplot2:' + v)); - expect(env.n === 'random_placeholder3' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - //packages - env = env.parent.parent; - expect(env.n === 'random_placeholder3' && env.t === 'package' && compare(new Set(rP3Symbols), new Set(env.memory.keys()))).toBeTruthy(); + expect(env.n === 'random_placeholder3' && env.t === 'imports' && compare(new Set(imp3), new Set(env.memory.keys()))).toBeTruthy(); env = env.parent; expect(env.n === 'random_placeholder2' && env.t === 'package' && compare(new Set(rP2Symbols), new Set(env.memory.keys()))).toBeTruthy(); env = env.parent; + expect(env.n === 'random_placeholder2' && env.t === 'imports' && compare(new Set(imp2), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent; expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(ggplotSymbols), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent; + expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(impggplot), new Set(env.memory.keys()))).toBeTruthy(); }); - test('Linked library loads imported (unloaded) library', async() => { + test('Linked library only partly imports another library (only importFrom)', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -249,7 +180,7 @@ import(grid) import(rlang) importFrom(scales,alpha) importFrom(stats,setNames) -import(random_placeholder)`)).content().current +importFrom(random_placeholder, test1)`)).content().current })); analyzer.context().deps.addDependency(new Package({ name: 'random_placeholder', @@ -257,55 +188,54 @@ import(random_placeholder)`)).content().current })); analyzer.addRequest('library(ggplot2)\nggplot()'); const df = await analyzer.dataflow(); + //should be globalEnv let env = df.environment.current; + env = env.parent; const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; - //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... - //ggplot namespace - expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + //globalEnv -> package:ggplot2 -> imports: ggplot2... + //ggplot package + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); //ggplot imports env = env.parent; - const imported = ['random_placeholder:test1', 'random_placeholder:test2']; - console.log(env); + const imported = ['random_placeholder:test1']; expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot package - env = env.parent.parent; - expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); }); - test('Linked library only partly imports another library', async() => { + + test('Linked library imports another library', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); analyzer.context().deps.addDependency(new Package({ name: 'ggplot2', namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) -S3method(fortify,lm) -S3method(fortify,default) -S3method(fortify,map) -S3method(scale_type,Date) -S3method(scale_type,POSIXt) -S3method(scale_type,character) -S3method(scale_type,numeric) -S3method(scale_type,factor) -S3method(scale_type,default) -S3method(ggplot,default) -S3method(print,ggproto) -S3method(print,rel) -export("+") -export(ggplot) -export(aes) -export(geom_point) -export(geom_line) -export(theme_bw) -export(coord_cartesian) -export(ggsave) -export(fortify) -export(scale_type) -exportPattern("^[^\\\\.]\\\\.*$") -import(grid) -import(rlang) -importFrom(scales,alpha) -importFrom(stats,setNames) -importFrom(random_placeholder, test1)`)).content().current + S3method(fortify,lm) + S3method(fortify,default) + S3method(fortify,map) + S3method(scale_type,Date) + S3method(scale_type,POSIXt) + S3method(scale_type,character) + S3method(scale_type,numeric) + S3method(scale_type,factor) + S3method(scale_type,default) + S3method(ggplot,default) + S3method(print,ggproto) + S3method(print,rel) + export("+") + export(ggplot) + export(aes) + export(geom_point) + export(geom_line) + export(theme_bw) + export(coord_cartesian) + export(ggsave) + export(fortify) + export(scale_type) + exportPattern("^[^\\\\.]\\\\.*$") + import(grid) + import(rlang) + importFrom(scales,alpha) + importFrom(stats,setNames) + import(random_placeholder)`)).content().current })); analyzer.context().deps.addDependency(new Package({ name: 'random_placeholder', @@ -313,19 +243,17 @@ importFrom(random_placeholder, test1)`)).content().current })); analyzer.addRequest('library(ggplot2)\nggplot()'); const df = await analyzer.dataflow(); + //should be globalEnv let env = df.environment.current; + env = env.parent; const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... - //ggplot namespace - expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + //ggplot package + expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); //ggplot imports env = env.parent; - const imported = ['random_placeholder:test1']; - console.log(env); + const imported = ['random_placeholder:test1', 'random_placeholder:test2']; expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot package - env = env.parent.parent; - expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); }); })); diff --git a/test/functionality/dataflow/main/libraries/link-libraries.test.ts b/test/functionality/dataflow/main/libraries/link-libraries.test.ts index cccb6855d57..652db6b8a68 100644 --- a/test/functionality/dataflow/main/libraries/link-libraries.test.ts +++ b/test/functionality/dataflow/main/libraries/link-libraries.test.ts @@ -4,255 +4,162 @@ import { FlowrAnalyzerBuilder } from '../../../../../src/project/flowr-analyzer- import { Package } from '../../../../../src/project/plugins/package-version-plugins/package'; import { FlowrNamespaceFile } from '../../../../../src/project/plugins/file-plugins/files/flowr-namespace-file'; import { FlowrInlineTextFile } from '../../../../../src/project/context/flowr-file'; -import { Dataflow } from '../../../../../src/dataflow/graph/df-helper'; import { EdgeType } from '../../../../../src/dataflow/graph/edge'; -import { compare } from 'semver'; import { emptyGraph } from '../../../../../src/dataflow/graph/dataflowgraph-builder'; import { NodeId } from '../../../../../src/r-bridge/lang-4.x/ast/model/processing/node-id'; import { label } from '../../../_helper/label'; describe('Link libraries', withTreeSitter(ts => { assertDataflow(label('ggplot links to ggplot2'), ts, 'library(ggplot2)\nggplot()\nggplot()', - emptyGraph() - .addEdge(5, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls) - .addEdge(7, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls) - .addEdge(NodeId.toBuiltIn('ggplot'), 3, EdgeType.Reads | EdgeType.Calls), - { - modifyAnalyzer: a => { - a.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) - S3method(fortify,lm) - S3method(fortify,default) - S3method(fortify,map) - S3method(scale_type,Date) - S3method(scale_type,POSIXt) - S3method(scale_type,character) - S3method(scale_type,numeric) - S3method(scale_type,factor) - S3method(scale_type,default) - S3method(ggplot,default) - S3method(print,ggproto) - S3method(print,rel) - export("+") - export(ggplot) - export(aes) - export(geom_point) - export(geom_line) - export(theme_bw) - export(coord_cartesian) - export(ggsave) - export(fortify) - export(scale_type) - exportPattern("^[^\\\\.]\\\\.*$") - import(grid) - import(rlang) - importFrom(scales,alpha) - importFrom(stats,setNames)`)).content().current - })); - }, - expectIsSubgraph: true, - resolveIdsAsCriterion: true - } - ); - assertDataflow(label('No dependencies set'), ts, 'library(ggplot2)\nggplot()', - emptyGraph() - .addEdge(5, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls), - { - expectIsSubgraph: true, - resolveIdsAsCriterion: true, - mustNotHaveEdges: [[NodeId.toBuiltIn('ggplot'), 3]] - }); - /*test('No dependencies set', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.addRequest('library(ggplot2)\nggplot()'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)) - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)).toBeUndefined(); - expect(df.graph.outgoingEdges(5)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - });*/ - /*test('ggplot links to ggplot2', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) -S3method(fortify,lm) -S3method(fortify,default) -S3method(fortify,map) -S3method(scale_type,Date) -S3method(scale_type,POSIXt) -S3method(scale_type,character) -S3method(scale_type,numeric) -S3method(scale_type,factor) -S3method(scale_type,default) -S3method(ggplot,default) -S3method(print,ggproto) -S3method(print,rel) -export("+") -export(ggplot) -export(aes) -export(geom_point) -export(geom_line) -export(theme_bw) -export(coord_cartesian) -export(ggsave) -export(fortify) -export(scale_type) -exportPattern("^[^\\\\.]\\\\.*$") -import(grid) -import(rlang) -importFrom(scales,alpha) -importFrom(stats,setNames)`)).content().current - })); - analyzer.addRequest('library(ggplot2)\nggplot()\nggplot()'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - expect(df.graph.outgoingEdges(5)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges(7)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - });*/ + emptyGraph() + .addEdge(5, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(7, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('ggplot'), 3, EdgeType.Reads | EdgeType.Calls), + { + modifyAnalyzer: a => { + a.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) + S3method(fortify,lm) + S3method(fortify,default) + S3method(fortify,map) + S3method(scale_type,Date) + S3method(scale_type,POSIXt) + S3method(scale_type,character) + S3method(scale_type,numeric) + S3method(scale_type,factor) + S3method(scale_type,default) + S3method(ggplot,default) + S3method(print,ggproto) + S3method(print,rel) + export("+") + export(ggplot) + export(aes) + export(geom_point) + export(geom_line) + export(theme_bw) + export(coord_cartesian) + export(ggsave) + export(fortify) + export(scale_type) + exportPattern("^[^\\\\.]\\\\.*$") + import(grid) + import(rlang) + importFrom(scales,alpha) + importFrom(stats,setNames)`)).content().current + })); + }, + expectIsSubgraph: true, + resolveIdsAsCriterion: true + } + ); + + assertDataflow(label('No dependencies set'), ts, 'library(ggplot2)\nggplot()', + emptyGraph() + .addEdge(5, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls), + { + expectIsSubgraph: true, + resolveIdsAsCriterion: true, + mustNotHaveEdges: [[NodeId.toBuiltIn('ggplot'), 3]] + }); + assertDataflow(label('Several methods of same library'), ts, 'library(ggplot2)\nggplot(data = NULL, mapping = aes())', - emptyGraph() - .addEdge(12, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls) - .addEdge(NodeId.toBuiltIn('ggplot'), 3, EdgeType.Reads | EdgeType.Calls) - .addEdge(10, NodeId.toBuiltIn('aes'), EdgeType.Reads | EdgeType.Calls) - .addEdge(NodeId.toBuiltIn('aes'), 3, EdgeType.Reads | EdgeType.Calls), - { - modifyAnalyzer: a => { - a.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) - S3method(fortify,lm) - S3method(fortify,default) - S3method(fortify,map) - S3method(scale_type,Date) - S3method(scale_type,POSIXt) - S3method(scale_type,character) - S3method(scale_type,numeric) - S3method(scale_type,factor) - S3method(scale_type,default) - S3method(ggplot,default) - S3method(print,ggproto) - S3method(print,rel) - export("+") - export(ggplot) - export(aes) - export(geom_point) - export(geom_line) - export(theme_bw) - export(coord_cartesian) - export(ggsave) - export(fortify) - export(scale_type) - exportPattern("^[^\\\\.]\\\\.*$") - import(grid) - import(rlang) - importFrom(scales,alpha) - importFrom(stats,setNames)`)).content().current - })); - }, - expectIsSubgraph: true, - resolveIdsAsCriterion: true - } - ); - /*test('Several methods of same library', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) -S3method(fortify,lm) -S3method(fortify,default) -S3method(fortify,map) -S3method(scale_type,Date) -S3method(scale_type,POSIXt) -S3method(scale_type,character) -S3method(scale_type,numeric) -S3method(scale_type,factor) -S3method(scale_type,default) -S3method(ggplot,default) -S3method(print,ggproto) -S3method(print,rel) -export("+") -export(ggplot) -export(aes) -export(geom_point) -export(geom_line) -export(theme_bw) -export(coord_cartesian) -export(ggsave) -export(fortify) -export(scale_type) -exportPattern("^[^\\\\.]\\\\.*$") -import(grid) -import(rlang) -importFrom(scales,alpha) -importFrom(stats,setNames)`)).content().current - })); - analyzer.addRequest('library(ggplot2)\nggplot(data = NULL, mapping = aes())'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - expect(df.graph.outgoingEdges(12)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)?.types === EdgeType.Calls + EdgeType.Reads).toBeTruthy(); - expect(df.graph.outgoingEdges(10)?.get('built-in:aes')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:aes')?.get(3)?.types === EdgeType.Calls + EdgeType.Reads).toBeTruthy(); - });*/ -assertDataflow(label('Links to several libraries'), ts, 'library(ggplot2)\nlibrary(dplyr)\nggplot(data = NULL, mapping = aes())\nacross()', - emptyGraph() - .addEdge(16, NodeId.toBuiltIn('ggplot'), EdgeType.Reads | EdgeType.Calls) - .addEdge(NodeId.toBuiltIn('ggplot'), 3, EdgeType.Reads | EdgeType.Calls) - .addEdge(3, 1, EdgeType.Argument) - .addEdge(18, NodeId.toBuiltIn('across'), EdgeType.Reads | EdgeType.Calls) - .addEdge(NodeId.toBuiltIn('across'), 7, EdgeType.Reads | EdgeType.Calls) - .addEdge(7, 5, EdgeType.Argument), - { - modifyAnalyzer: a => { - a.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) - S3method(fortify,lm) - S3method(fortify,default) - S3method(fortify,map) - S3method(scale_type,Date) - S3method(scale_type,POSIXt) - S3method(scale_type,character) - S3method(scale_type,numeric) - S3method(scale_type,factor) - S3method(scale_type,default) - S3method(ggplot,default) - S3method(print,ggproto) - S3method(print,rel) - export("+") - export(ggplot) - export(aes) - export(geom_point) - export(geom_line) - export(theme_bw) - export(coord_cartesian) - export(ggsave) - export(fortify) - export(scale_type) - exportPattern("^[^\\\\.]\\\\.*$") - import(grid) - import(rlang) - importFrom(scales,alpha) - importFrom(stats,setNames)`)).content().current - })); - a.context().deps.addDependency(new Package({ - name: 'dplyr', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(across)')).content().current - }));; - }, - expectIsSubgraph: true, - resolveIdsAsCriterion: true - } - ); - test('Links to several libraries', async() => { + emptyGraph() + .addEdge(12, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('ggplot'), 3, EdgeType.Reads |EdgeType.Calls) + .addEdge(10, NodeId.toBuiltIn('aes'), EdgeType.Reads |EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('aes'), 3, EdgeType.Reads | EdgeType.Calls), + { + modifyAnalyzer: a => { + a.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) + S3method(fortify,lm) + S3method(fortify,default) + S3method(fortify,map) + S3method(scale_type,Date) + S3method(scale_type,POSIXt) + S3method(scale_type,character) + S3method(scale_type,numeric) + S3method(scale_type,factor) + S3method(scale_type,default) + S3method(ggplot,default) + S3method(print,ggproto) + S3method(print,rel) + export("+") + export(ggplot) + export(aes) + export(geom_point) + export(geom_line) + export(theme_bw) + export(coord_cartesian) + export(ggsave) + export(fortify) + export(scale_type) + exportPattern("^[^\\\\.]\\\\.*$") + import(grid) + import(rlang) + importFrom(scales,alpha) + importFrom(stats,setNames)`)).content().current + })); + }, + expectIsSubgraph: true, + resolveIdsAsCriterion: true + } + ); + + assertDataflow(label('Links to several libraries'), ts, 'library(ggplot2)\nlibrary(dplyr)\nggplot(data = NULL, mapping = aes())\nacross()', + emptyGraph() + .addEdge(16, NodeId.toBuiltIn('ggplot'), EdgeType.Reads |EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('ggplot'), 3, EdgeType.Reads |EdgeType.Calls) + .addEdge(3, 1, EdgeType.Argument) + .addEdge(18, NodeId.toBuiltIn('across'), EdgeType.Reads |EdgeType.Calls) + .addEdge(NodeId.toBuiltIn('across'), 7, EdgeType.Reads | EdgeType.Calls) + .addEdge(7, 5, EdgeType.Argument), + { + modifyAnalyzer: a => { + a.context().deps.addDependency(new Package({ + name: 'ggplot2', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) + S3method(fortify,lm) + S3method(fortify,default) + S3method(fortify,map) + S3method(scale_type,Date) + S3method(scale_type,POSIXt) + S3method(scale_type,character) + S3method(scale_type,numeric) + S3method(scale_type,factor) + S3method(scale_type,default) + S3method(ggplot,default) + S3method(print,ggproto) + S3method(print,rel) + export("+") + export(ggplot) + export(aes) + export(geom_point) + export(geom_line) + export(theme_bw) + export(coord_cartesian) + export(ggsave) + export(fortify) + export(scale_type) + exportPattern("^[^\\\\.]\\\\.*$") + import(grid) + import(rlang) + importFrom(scales,alpha) + importFrom(stats,setNames)`)).content().current + })); + a.context().deps.addDependency(new Package({ + name: 'dplyr', + namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(across)')).content().current + }));; + }, + expectIsSubgraph: true, + resolveIdsAsCriterion: true + } + ); + + test('Simple import, check env structure', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -287,121 +194,20 @@ import(rlang) importFrom(scales,alpha) importFrom(stats,setNames)`)).content().current })); - analyzer.context().deps.addDependency(new Package({ - name: 'dplyr', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(across)')).content().current - })); - analyzer.addRequest('library(ggplot2)\nlibrary(dplyr)\nggplot(data = NULL, mapping = aes())\nacross()'); - const df = await analyzer.dataflow(); - console.log(Dataflow.visualize.mermaid.url(df.graph)); - expect(df.graph.outgoingEdges(16)?.get('built-in:ggplot')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:ggplot')?.get(3)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges(3)?.get(1)?.types === EdgeType.Argument).toBeTruthy(); - expect(df.graph.outgoingEdges(18)?.get('built-in:across')?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges('built-in:across')?.get(7)?.types === EdgeType.Reads + EdgeType.Calls).toBeTruthy(); - expect(df.graph.outgoingEdges(7)?.get(5)?.types === EdgeType.Argument).toBeTruthy(); - }); -test('Linked library loads imported (unloaded) library', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) -S3method(fortify,lm) -S3method(fortify,default) -S3method(fortify,map) -S3method(scale_type,Date) -S3method(scale_type,POSIXt) -S3method(scale_type,character) -S3method(scale_type,numeric) -S3method(scale_type,factor) -S3method(scale_type,default) -S3method(ggplot,default) -S3method(print,ggproto) -S3method(print,rel) -export("+") -export(ggplot) -export(aes) -export(geom_point) -export(geom_line) -export(theme_bw) -export(coord_cartesian) -export(ggsave) -export(fortify) -export(scale_type) -exportPattern("^[^\\\\.]\\\\.*$") -import(grid) -import(rlang) -importFrom(scales,alpha) -importFrom(stats,setNames) -import(random_placeholder)`)).content().current - })); - analyzer.context().deps.addDependency(new Package({ - name: 'random_placeholder', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', 'export(test1)\nexport(test2)')).content().current - })); analyzer.addRequest('library(ggplot2)\nggplot()'); const df = await analyzer.dataflow(); + //should be globalEnv let env = df.environment.current; - const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; - //namespace:ggplot -> imports:ggplot -> globalEnv -> package:ggplot -> ... - //ggplot namespace - expect(env.n === 'ggplot2' && env.t === 'namespace' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot imports env = env.parent; - const imported = ['random_placeholder:test1', 'random_placeholder:test2']; - console.log(env); - expect(env.n === 'ggplot2' && env.t === 'imports' && compare(new Set(imported), new Set(env.memory.keys()))).toBeTruthy(); - //ggplot package - env = env.parent.parent; - expect(env.n === 'ggplot2' && env.t === 'package' && compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); - }); - test('Simple env structure', async() => { - const analyzer = await new FlowrAnalyzerBuilder() - .setParser(ts) - .build(); - analyzer.context().deps.addDependency(new Package({ - name: 'ggplot2', - namespaceInfo: FlowrNamespaceFile.from(new FlowrInlineTextFile('NAMESPACE', `S3method(fortify,data.frame) -S3method(fortify,lm) -S3method(fortify,default) -S3method(fortify,map) -S3method(scale_type,Date) -S3method(scale_type,POSIXt) -S3method(scale_type,character) -S3method(scale_type,numeric) -S3method(scale_type,factor) -S3method(scale_type,default) -S3method(ggplot,default) -S3method(print,ggproto) -S3method(print,rel) -export("+") -export(ggplot) -export(aes) -export(geom_point) -export(geom_line) -export(theme_bw) -export(coord_cartesian) -export(ggsave) -export(fortify) -export(scale_type) -exportPattern("^[^\\\\.]\\\\.*$") -import(grid) -import(rlang) -importFrom(scales,alpha) -importFrom(stats,setNames)`)).content().current - })); - analyzer.addRequest('library(ggplot2)\nggplot()'); - const df = await analyzer.dataflow(); - let env = df.environment.current; - expect(env.n === 'ggplot2' && env.t === 'namespace').toBeTruthy(); + expect(env.n === 'ggplot2' && env.t === 'package').toBeTruthy(); + const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + expect(compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); env = env.parent; expect(env.n === 'ggplot2' && env.t === 'imports').toBeTruthy(); - env = env.parent.parent; - expect(env.n === 'ggplot2' && env.t === 'package').toBeTruthy(); + expect(new Set(env.memory.keys()).size === 0).toBeTruthy(); }); - test('Several libraries structure', async() => { + + test('Several libraries, check env structure', async() => { const analyzer = await new FlowrAnalyzerBuilder() .setParser(ts) .build(); @@ -442,13 +248,24 @@ importFrom(stats,setNames)`)).content().current })); analyzer.addRequest('library(ggplot2)\nlibrary(random1)'); const df = await analyzer.dataflow(); + //should be globalEnv let env = df.environment.current; - expect(env.n === 'random1' && env.t === 'namespace').toBeTruthy(); env = env.parent; - expect(env.n === 'random1' && env.t === 'imports').toBeTruthy(); - env = env.parent.parent; expect(env.n === 'random1' && env.t === 'package').toBeTruthy(); + expect(compare(new Set(['test1', 'test2']), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent; + expect(env.n === 'random1' && env.t === 'imports').toBeTruthy(); + expect(new Set(env.memory.keys()).size === 0).toBeTruthy(); env = env.parent; expect(env.n === 'ggplot2' && env.t === 'package').toBeTruthy(); + const exportedSymbols = ['+', 'ggplot', 'aes', 'geom_point', 'geom_line', 'theme_bw', 'coord_cartesian', 'ggsave', 'fortify', 'scale_type']; + expect(compare(new Set(exportedSymbols), new Set(env.memory.keys()))).toBeTruthy(); + env = env.parent; + expect(env.n === 'ggplot2' && env.t === 'imports').toBeTruthy(); + expect(new Set(env.memory.keys()).size === 0).toBeTruthy(); }); -})); \ No newline at end of file +})); + +function compare(s1: Set, s2: Set){ + return s1.difference(s2).size === 0 && s2.difference(s1).size === 0; +} \ No newline at end of file