Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
178 commits
Select commit Hold shift + click to select a range
337ed96
feat: infer types for constant expressions
loki259 Apr 5, 2025
4ef9811
style: make stylistic changes to satisfy ESLint
loki259 Apr 6, 2025
746596b
test(typing): streamline the type inferencer tests using `describe.each`
loki259 Apr 7, 2025
e53e003
feat(typing): add preliminary support for expression lists and `NULL`
loki259 Apr 7, 2025
8072fe6
test(typing): add tests for unsupported expression types
loki259 Apr 7, 2025
ce1fc8c
test: add a test for empty expression lists
loki259 Apr 7, 2025
53fe22f
feat(typing): add support for complex number literals
loki259 Apr 7, 2025
18ec199
test(types): refactor tests to use tree-sitter
loki259 Apr 7, 2025
bb514bf
refactor: refactor the type representation of R data types
loki259 May 3, 2025
2eccfcd
Merge branch 'main' into 174-add-type-inference
loki259 May 4, 2025
67f9204
Merge branch 'main' into 174-add-type-inference
loki259 May 8, 2025
ebcff1e
feat(ast): add `mapAstInfo` for transforming metadata attached to nodes
loki259 May 10, 2025
9c8c4c1
Merge branch '1637-map-attached-ast-info' into 174-add-type-inference
loki259 May 10, 2025
e8f02a2
wip(typing): rework type inference to use type variables and constraints
loki259 May 10, 2025
c74a1cb
Merge branch 'main' into 174-add-type-inference
loki259 May 11, 2025
9b7e136
refactor(typing): replace '<>' with `EmptyArgument` constant
loki259 May 11, 2025
d936697
refactor(typing): rename string representation of `RDataTypeTag.Any`
loki259 May 11, 2025
ac3b105
feat-fix(typing): fix erroneous property access of `inferredType`
loki259 May 11, 2025
9710138
feat-fix(semantic-cfg): explicit onProgram visitor
EagleoutIce May 11, 2025
14913c4
refactor(ast): rework `mapAstInfo` to mutate the AST nodes in place
loki259 May 12, 2025
5339c1a
refactor(ast): define default for `downUpdater` argument of `mapAstInfo`
loki259 May 12, 2025
d00cced
feat(ast): add wrapper of `mapAstInfo` for normalized ASTs
loki259 May 12, 2025
c966fe9
Merge branch '1637-map-attached-ast-info' into 174-add-type-inference
loki259 May 12, 2025
b1b5963
refactor(typing): infer types directly on the normalized AST
loki259 May 12, 2025
a9bbff0
test(typing): add test helper for asserting types of queried subnodes
loki259 May 14, 2025
d65e243
meta(typing): rename test file to better reflect its testing domain
loki259 May 15, 2025
2427695
feat(typing): add support for variables
loki259 May 15, 2025
45a417d
refactor(typing): handle expression lists more robustly via return edges
loki259 May 19, 2025
5d631fc
refactor(typing): handle variables more robustly
loki259 May 19, 2025
76c5c1b
feat(typing): add preliminary support for functions
loki259 May 19, 2025
fa736e2
refactor(typing): handle program expression lists more robustly
loki259 May 19, 2025
919172d
feat(typing): split role of `Any` into `Any`, `Never` and `Error` types
loki259 May 21, 2025
4e230f1
Merge branch 'main' into 174-add-type-inference
loki259 May 21, 2025
31bb506
refactor(typing): remove `Special` and `Builtin` and add `Language` type
loki259 May 24, 2025
58e1bb4
feat(typing): infer types for `get` and `rm` calls
loki259 May 24, 2025
7303d55
feat(typing): infer types for loops
loki259 May 24, 2025
31616e1
feat(typing): infer types for if-then-else calls
loki259 May 24, 2025
09bd3f9
feat(typing): infer types for list and vector constructors
loki259 May 24, 2025
a3d6f4e
feat(typing): infer types for `quote` and `eval` calls
loki259 May 24, 2025
5b1734d
test(typing): split up tests into multiple test files
loki259 May 24, 2025
3c88cfa
refactor(typing): refactor counting of vertices flowing into loop exits
loki259 May 24, 2025
c36973e
feat-fix(cfg): correct spelling of origin id for repeat loops
loki259 May 24, 2025
9cd59e9
feat-fix(cfg): link for loop cfg exits using `end` instead of `exit`
loki259 May 24, 2025
393080f
Merge branch '1676-misspelled-origin-identifier-for-repeat-loops' int…
loki259 May 24, 2025
fa54a37
Merge branch '1677-loop-cfg-vertices-use-exit-instead-of-end-field' i…
loki259 May 24, 2025
38238af
build-fix(typing): fix merge issues
loki259 May 24, 2025
5aad303
test(typing): test type inference for loops
loki259 May 24, 2025
afccc29
Merge remote-tracking branch 'origin/main' into 174-add-type-inference
loki259 May 26, 2025
3222f31
refactor(typing): refactor `onDefaultFunctionCall`
loki259 May 26, 2025
c8bbeca
Merge remote-tracking branch 'origin/main' into 174-add-type-inference
loki259 May 26, 2025
41b166c
feat(typing): add support for NULL constants
loki259 May 26, 2025
24a4e33
test(typing): add tests for currently inferrable builtin functions
loki259 May 26, 2025
8720315
feat-fix(typing): fix type inference for `quote` calls
loki259 May 26, 2025
0c21cda
Merge remote-tracking branch 'origin/main' into 174-add-type-inference
loki259 May 29, 2025
0b15bdd
feat-fix(typing): fix merge issues
loki259 May 29, 2025
40e47cf
refactor(typing): handle missing arguments in `if` calls more robustly
loki259 May 29, 2025
526ffe3
test(typing): add tests for typing of `if` calls
loki259 May 29, 2025
fa66032
feat(typing): add support for function argument and return types
loki259 May 29, 2025
a07b142
Merge remote-tracking branch 'origin/main' into 174-add-type-inference
loki259 Jun 1, 2025
7fcd64f
build-fix(typing): resolve merge issues
loki259 Jun 1, 2025
b660b7b
test(typing): update test cases for loops and conditionals
loki259 Jun 1, 2025
92f3f71
Add A Query Type For Querying Data Types (#1707)
loki259 Jun 1, 2025
9693b40
feat(typing): include dead code analysis passes when extracting the cfg
loki259 Jun 1, 2025
473ee21
Merge branch '174-add-type-inference' of github.com:flowr-analysis/fl…
loki259 Jun 1, 2025
dae9dca
Merge remote-tracking branch 'origin/main' into 174-add-type-inference
loki259 Jun 5, 2025
6dab576
test(typing): edit tests
loki259 Jun 5, 2025
a676aad
feat(typing): properly track conflicting types within `RErrorType`
loki259 Jun 5, 2025
6f65c7e
refactor(typing): refactor typing of if-then-else calls
loki259 Jun 6, 2025
f7bb39d
refactor(typing): remove `Any` and `Never` and introduce `Unknown` type
loki259 Jun 8, 2025
8565e11
feat-fix(typing): fix typing of `get` calls
loki259 Jun 8, 2025
d21fe03
feat(typing): make list datatypes more sophisticated
loki259 Jun 12, 2025
ef3e14d
feat(typing): infer types for list elements
loki259 Jun 12, 2025
03f2551
feat(typing): make function and list type inference more sophisticated
loki259 Jun 12, 2025
fe95551
test-fix(typing): fix list typing test
loki259 Jun 12, 2025
5e57e4c
feat-fix(typing): ignore positional parameters occuring after `...`
loki259 Jun 12, 2025
2d6ad1c
feat(typing): pretty-print list types
loki259 Jun 13, 2025
920f754
feat(typing): add discriminator functions for vector and compound types
loki259 Jun 13, 2025
6098201
feat(typing): implement preliminary inference for access calls
loki259 Jun 13, 2025
ae89b42
refactor(typing): only infer `RIntegerType` for marked number constants
loki259 Jun 13, 2025
f474473
refactor(typing): refactor test files
loki259 Jun 13, 2025
aa7208d
Merge remote-tracking branch 'origin/main' into 174-add-type-inference
loki259 Jun 15, 2025
263309d
refactor(typing): simplify list types due to constraints of unification
loki259 Jun 17, 2025
7768229
refactor(typing): refactor handling of argument nodes
loki259 Jun 19, 2025
9e2cff4
refactor(typing): change traversal order to visit call arguments first
loki259 Jun 19, 2025
3b1519e
refactor(typing): use sets to track conflicting types in error types
loki259 Jun 19, 2025
d2c1ea5
wip(typing): add an enumeration of R's base types
loki259 Jun 19, 2025
9ca8dea
feat-fix(typing): remove failing guard disallowing calls without targets
loki259 Jun 19, 2025
730fa56
refactor(ast): refactor mapNormalizedAstInfo to use NormalizedAst.idMap
loki259 Jun 19, 2025
7e44d62
Merge branch '1637-map-attached-ast-info' into 174-add-type-inference
loki259 Jun 19, 2025
1a75999
feat-fix(typing): fix merge issues
loki259 Jun 19, 2025
ccfc943
Merge remote-tracking branch 'origin/main' into 174-add-type-inference
loki259 Jun 19, 2025
83b3169
feat-fix(ast-map): do not map virtual nodes
EagleoutIce Jun 19, 2025
0f394cb
refactor: add test that i commented out
EagleoutIce Jun 19, 2025
c0ca7b7
Merge branch '174-add-type-inference' of github.com:flowr-analysis/fl…
loki259 Jun 19, 2025
b58071c
test-fix(typing): fix expected type due to dead code elimination updates
loki259 Jun 19, 2025
38af6c5
Merge remote-tracking branch 'origin/main' into 174-add-type-inference
loki259 Jun 19, 2025
340d203
refactor(datatype-query): reuse typed AST for all criteria
loki259 Jun 19, 2025
be5e30d
lint-fix(datatype-query): remove redundant space
loki259 Jun 19, 2025
63177c9
test-fix(typing): remove `only` specifier from test
loki259 Jun 19, 2025
a6a369c
Merge branch '1765-optimize-datatype-query' of github.com:flowr-analy…
loki259 Jun 19, 2025
90b774b
refactor(datatype-query): reuse typed AST for all criteria (#1766)
loki259 Jun 19, 2025
d19bcc1
feat-fix(typing): remove invalid inference rule for undefined variables
loki259 Jun 24, 2025
114263c
refactor(typing): refactor representation of types
loki259 Jul 4, 2025
af1fb14
feat-fix(typing): remove invalid inference rule for `get` calls
loki259 Jul 4, 2025
6e749e6
feat(typing): add basic subtyping support :sparkles:
loki259 Jul 5, 2025
2f18820
wip(typing): distinguish scalars from vectors of arbitrary length
loki259 Jul 8, 2025
b98b3ec
wip(typing): introduce `RVectorType` as join of list and atomic vector
loki259 Jul 8, 2025
8b81258
feat(typing): fix errors and add subsetting support for vector types
loki259 Jul 10, 2025
626266c
feat(typing): implement support for type unions and intersections
loki259 Jul 12, 2025
1c6e0b8
test(typing): add tests for constraint handling
loki259 Jul 12, 2025
97e5a39
refactor(typing): remove unnecessary cfg traversal modification
loki259 Jul 12, 2025
eaf2d07
test-fix(typing): remove `only` modifier from test suites
loki259 Jul 14, 2025
98f557d
feat-fix(typing): also match unresolved datatypes in `subsumes` function
loki259 Jul 14, 2025
c5a3acd
test(typing): add test for function overloading (it works! :D)
loki259 Jul 14, 2025
232fc61
feat(typing): infer types for indexed elements of lists
loki259 Jul 14, 2025
e229b78
refactor(typing): change project structure
loki259 Jul 15, 2025
f6fbdf4
refactor(typing): change test file organization
loki259 Jul 15, 2025
63937ee
refactor(typing): unify error handling between unification and suptyping
loki259 Jul 15, 2025
4d5a320
refactor(typing): share types between unification and subtyping
loki259 Jul 15, 2025
ddeaf32
feat(typing): add support for using subtyping in datatype queries
loki259 Jul 16, 2025
2327a7c
feat-fix(typing): add constraint caching to prevent infinite recursion
loki259 Jul 18, 2025
53a98c5
feat-fix(typing): improve handling of `c` function calls with flattening
loki259 Jul 18, 2025
a24bab3
feat: #hopetomakerohdehappy
EagleoutIce Jul 25, 2025
25117d3
feat: change parser and pretty-printer to #makerohdehappy
loki259 Jul 25, 2025
5b94771
feat: rohde types are chonky
EagleoutIce Jul 26, 2025
548c2bc
refactor(typing): refactor constraint handling functions
loki259 Jul 26, 2025
792474e
Let's favor the Rohde Type System (#1828)
loki259 Jul 26, 2025
d8873e2
feat-fix(typing): fix merge conflicts
loki259 Jul 26, 2025
70bd745
refactor(typing): move turcotte-types.csv and refactor turcotte-types.ts
loki259 Jul 26, 2025
8a6c962
feat(typing): integrate turcotte types into the inference strategy
loki259 Jul 26, 2025
3dd31e2
feat(typing): add query configuration option for usage of turcotte types
loki259 Jul 26, 2025
9cf22c5
feat-fix(typing): fix stack overflows due to large types and add tests
loki259 Jul 28, 2025
7585d54
feat-fix(typing): fix `subsumes` function
loki259 Jul 31, 2025
4b2946c
feat-fix(typing): fix overloading and upper bound unions by pruning
loki259 Jul 31, 2025
0289612
refactor(typing): move tests
loki259 Jul 31, 2025
2edd831
feat-fix(typing): fix resolving of recursive types and meets/joins
loki259 Jul 31, 2025
c99d307
test-fix(typing): update tests
loki259 Jul 31, 2025
7494555
feat-fix(typing): fix subsumption checks in `meet`, `join` and `combine`
loki259 Jul 31, 2025
8f6c770
test(typing): add test and rename suite
loki259 Jul 31, 2025
e28a3bc
feat(typing): support replacement and infer upper bounds for variables
loki259 Aug 1, 2025
02e0ec4
feat(typing): add subtyping relation between NULL and atomic vectors
loki259 Aug 1, 2025
7135d5d
feat-fix(typing): fix explosion of recursive calls in `prune`
loki259 Aug 2, 2025
4f4b210
refactor(typing): aggressively simplify `prune` and avoid repeated work
loki259 Aug 2, 2025
1c73180
refactor(typing): refactor the datatype query format and its execution
loki259 Aug 4, 2025
446d3c5
feat(typing): add compression for json results of datatype queries
loki259 Aug 4, 2025
997c74e
feat(typing): add improved support for loading contextual types
loki259 Aug 5, 2025
d021183
refactor(typing): change compression format for json datatype queries
loki259 Aug 5, 2025
8a3fec5
Merge remote-tracking branch 'origin/main' into level-up-type-inferen…
loki259 Aug 5, 2025
776cdb3
build-fix(merge): fix merge conflicts
loki259 Aug 6, 2025
df13f4a
feat(typing): load dynamically traced types for datatype queries
loki259 Aug 6, 2025
61150f5
feat-fix(typing): fix loading of contextual types
loki259 Aug 6, 2025
7b8d5d8
Merge branch 'level-up-type-inference-with-base-function-types' into …
loki259 Aug 6, 2025
3279fa0
feat-fix(typing): fix type error in datatype query executor
loki259 Aug 6, 2025
5f4e635
feat(typing): improve pretty printing of datatypes
loki259 Aug 6, 2025
d6999e1
feat-fix(typing): fix bug with virtual node ids in mapNormalizedAstInfo
loki259 Aug 6, 2025
2ea13cb
feat-fix(typing): fix contextual type inference
loki259 Aug 6, 2025
dd3f689
feat(typing): refine type extraction from traced data
loki259 Aug 6, 2025
8c442f6
build-fix(typing): fix inclusion and resolution of csv data files
loki259 Aug 7, 2025
8c9a669
feat-fix(typing): fix constraints of loaded function signatures
loki259 Aug 7, 2025
bbbd51d
feat(typing): add limited support for S4 and improve subsetting rules
loki259 Aug 8, 2025
308f85f
feat(typing): make inference rules for number literals more precise
loki259 Aug 10, 2025
30bc9e8
feat(typing): rework rules for NULL, vectors, and subsetting/replacement
loki259 Aug 10, 2025
128469a
feat-fix(typing): fix default values for datatype query parameters
loki259 Aug 11, 2025
898859c
feat-fix(typing): fix major oversight in handling overloading
loki259 Aug 11, 2025
ddfaa64
feat(typing): improve typing of function definitions
loki259 Aug 11, 2025
8cbd2fb
feat(typing): add override for apply functions
loki259 Aug 11, 2025
352e6fb
refactor(typing): remove builtin support for `quote`, `eval`, and `rm`
loki259 Aug 11, 2025
bfc85a1
refactor(typing): simplify typing of function calls
loki259 Aug 11, 2025
08b3771
refactor(typing): remove compression for datatype query results
loki259 Aug 12, 2025
695c00e
wip(typing): add test code file and log statements for debugging
loki259 Aug 12, 2025
e708d22
refactor(typing): disambiguate `inferDataTypes` for unification
loki259 Aug 12, 2025
3724176
refactor(typing): make subtyping the default in queries
loki259 Aug 12, 2025
11ac68c
feat(typing): add option for writing datatype query output to a file
loki259 Aug 12, 2025
113822e
feat-fix(typing): fix writing of output files in datatype queries
loki259 Aug 12, 2025
bf67bc5
feat(typing): improve caching for `subsumes` check
loki259 Aug 12, 2025
d3eeba3
refactor(typing): remove r code file previously used for testing
loki259 Aug 12, 2025
44cdaeb
test(typing): add test for null subtyping anomaly
loki259 Sep 3, 2025
d51cba5
Merge branch 'main' into 174-add-type-inference
loki259 Sep 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions package-lock.json

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

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@
"gen:linter-issue": "ts-node src/documentation/print-linter-issue.ts",
"build": "tsc --project .",
"build-dev": "npm run build && npm run build:copy-wasm",
"build:bundle-flowr": "npm run build && esbuild --bundle dist/src/cli/flowr.js --platform=node --tree-shaking=true --bundle --minify --external:clipboardy --target=node22 --outfile=dist/src/cli/flowr.min.js && npm run build:copy-wasm",
"build:bundle-flowr": "npm run build && esbuild --bundle dist/src/cli/flowr.js --platform=node --tree-shaking=true --bundle --minify --external:clipboardy --target=node22 --outfile=dist/src/cli/flowr.min.js && npm run build:copy-wasm && npm run build:copy-csvs",
"build:copy-wasm": "mkdir -p dist/node_modules/@eagleoutice/tree-sitter-r/ && mkdir -p dist/node_modules/web-tree-sitter && cp node_modules/@eagleoutice/tree-sitter-r/tree-sitter-r.wasm dist/node_modules/@eagleoutice/tree-sitter-r/ && cp node_modules/web-tree-sitter/tree-sitter.wasm dist/node_modules/web-tree-sitter/",
"build:copy-csvs": "cp src/typing/adapter/traced-function-types.csv dist/src/typing/adapter/traced-function-types.csv && cp src/typing/adapter/turcotte-types.csv dist/src/typing/adapter/turcotte-types.csv",
"lint-local": "npx eslint --version && npx eslint src/ test/ --rule \"no-warning-comments: off\"",
"lint": "npm run license-compat -- --summary && npx eslint --version && npx eslint src/ test/",
"license-compat": "license-checker --onlyAllow 'MIT;MIT OR X11;GPLv2;LGPL;GNUGPL;ISC;Apache-2.0;FreeBSD;BSD-2-Clause;clearbsd;ModifiedBSD;BSD-3-Clause;Python-2.0;Unlicense;WTFPL;BlueOak-1.0.0;CC-BY-4.0;CC-BY-3.0;CC0-1.0;0BSD'",
Expand Down Expand Up @@ -212,6 +213,7 @@
"clipboardy": "^4.0.0",
"command-line-args": "^6.0.1",
"command-line-usage": "^7.0.3",
"csv-parser": "^3.2.0",
"joi": "^18.0.1",
"lz-string": "^1.5.0",
"n-readlines": "^1.0.1",
Expand Down
38 changes: 20 additions & 18 deletions src/cli/repl/commands/repl-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { guard } from '../../../util/assert';
import { scripts } from '../../common/scripts-info';
import { lineageCommand } from './repl-lineage';
import { queryCommand, queryStarCommand } from './repl-query';
import { replTurcotteTypeParseCommand } from './repl-turcotte-type-parse';

function printHelpForScript(script: [string, ReplCommand], f: OutputFormatter, starredVersion?: ReplCommand): string {
let base = ` ${bold(padCmd(':' + script[0] + (starredVersion ? '[*]' : '')), f)}${script[1].description}`;
Expand Down Expand Up @@ -80,24 +81,25 @@ You can combine commands by separating them with a semicolon ${bold(';',output.f
* All commands that should be available in the REPL.
*/
const _commands: Record<string, ReplCommand> = {
'help': helpCommand,
'quit': quitCommand,
'version': versionCommand,
'execute': executeCommand,
'parse': parseCommand,
'normalize': normalizeCommand,
'normalize*': normalizeStarCommand,
'dataflow': dataflowCommand,
'dataflow*': dataflowStarCommand,
'dataflowsimple': dataflowSimplifiedCommand,
'dataflowsimple*': dataflowSimpleStarCommand,
'controlflow': controlflowCommand,
'controlflow*': controlflowStarCommand,
'controlflowbb': controlflowBbCommand,
'controlflowbb*': controlflowBbStarCommand,
'lineage': lineageCommand,
'query': queryCommand,
'query*': queryStarCommand
'help': helpCommand,
'quit': quitCommand,
'version': versionCommand,
'turcotte-type-parse': replTurcotteTypeParseCommand,
'execute': executeCommand,
'parse': parseCommand,
'normalize': normalizeCommand,
'normalize*': normalizeStarCommand,
'dataflow': dataflowCommand,
'dataflow*': dataflowStarCommand,
'dataflowsimple': dataflowSimplifiedCommand,
'dataflowsimple*': dataflowSimpleStarCommand,
'controlflow': controlflowCommand,
'controlflow*': controlflowStarCommand,
'controlflowbb': controlflowBbCommand,
'controlflowbb*': controlflowBbStarCommand,
'lineage': lineageCommand,
'query': queryCommand,
'query*': queryStarCommand
};
let commandsInitialized = false;

Expand Down
69 changes: 69 additions & 0 deletions src/cli/repl/commands/repl-turcotte-type-parse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import type { ReplCommand } from './repl-main';
import { findSource } from '../../../dataflow/internal/process/functions/call/built-in/built-in-source';
import fs from 'fs';
import csvParser from 'csv-parser';
import type { TurcotteCsvRow } from '../../../typing/adapter/turcotte-types';
import {
dumpRohdeTypesFromTurcotte,
recoverRohdeTypesFromTurcotteFromDump,
turcotte2RohdeTypes
} from '../../../typing/adapter/turcotte-types';
import { splitAtEscapeSensitive } from '../../../util/text/args';
import { compressToUTF16, decompressFromUTF16 } from 'lz-string';
import type { RohdeTypes } from '../../../typing/adapter/interface';


export const replTurcotteTypeParseCommand: ReplCommand = {
description: 'Give me a file to read from and I will happily print you the types in the Rohde System!',
usageExample: ':turcotte-type-parse foo.csv out.data',
aliases: [ 'ttp',],
script: false,
fn: async(info) => {
const now = new Date();
if(!info.remainingLine.trim()) {
info.output.stderr('Please provide a file to read from. You do not need a prefix, just the file path.');
return;
}
const args = splitAtEscapeSensitive(info.remainingLine.trim());
if(args.length < 1 || args.length > 2) {
info.output.stderr(`Expected a single file to read from and and optional one to write to, got: ${JSON.stringify(args)}`);
return;
}
const [readFilePath, writeFilePath] = args as [string, string | undefined];
const readFile = findSource(undefined, readFilePath.trim(), { referenceChain: [] });
if(readFile?.length !== 1) {
info.output.stderr(`Could not find a single file to read from. Got: ${JSON.stringify(readFile)}`);
return;
}
const writeFile = writeFilePath ? findSource(undefined, writeFilePath.trim(), { referenceChain: [] }) : undefined;
if(writeFilePath && writeFile && writeFile.length > 0) {
info.output.stderr(`The output file already exists, will not overwrite: ${writeFilePath}`);
return;
}


const data: TurcotteCsvRow[] = [];
await new Promise(resolve => {
fs.createReadStream(readFile[0], { encoding: 'utf-8' })
.pipe(csvParser({ separator: ',' }))
.on('data', (row: TurcotteCsvRow) => {
data.push(row);
})
.on('end', () => resolve(null));
});
const rohdeTypes: RohdeTypes = turcotte2RohdeTypes(data);

info.output.stdout(`Parsed ${rohdeTypes.info.length} functions from ${readFile[0]} in ${Date.now() - now.getTime()}ms.`);

if(writeFilePath) {
const startWrite = Date.now();
fs.writeFileSync(writeFilePath, compressToUTF16(dumpRohdeTypesFromTurcotte(rohdeTypes)), { encoding: 'utf-16le' });
info.output.stdout(`Wrote ${rohdeTypes.info.length} functions to ${writeFilePath} in ${Date.now() - startWrite}ms.`);
const startRead = Date.now();
const loadCheck = decompressFromUTF16(fs.readFileSync(writeFilePath, { encoding: 'utf-16le' }));
const recovered = recoverRohdeTypesFromTurcotteFromDump(loadCheck);
info.output.stdout(`[Test] Recovered ${recovered.info.length} functions from ${writeFilePath} in ${Date.now() - startRead}ms.`);
}
}
};

25 changes: 25 additions & 0 deletions src/documentation/print-query-wiki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { Q } from '../search/flowr-search-builder';
import { VertexType } from '../dataflow/graph/vertex';
import { getTypesFromFolder, shortLink } from './doc-util/doc-types';
import path from 'path';
import { executeDatatypeQuery } from '../queries/catalog/datatype-query/datatype-query-executor';
import { executeControlFlowQuery } from '../queries/catalog/control-flow-query/control-flow-query-executor';
import { printCfgCode } from './doc-util/doc-cfg';
import { executeDfShapeQuery } from '../queries/catalog/df-shape-query/df-shape-query-executor';
Expand Down Expand Up @@ -536,6 +537,30 @@ This query replaces the old [\`request-slice\`](${FlowrWikiBaseRef}/Interface#me
}
});


registerQueryDocumentation('datatype', {
name: 'Datatype Query',
type: 'active',
shortDescription: 'Returns all datatypes for syntactic elements (or the type for a criterion).',
functionName: executeDatatypeQuery.name,
functionFile: '../queries/catalog/datatype-query/datatype-query-executor.ts',
buildExplanation: async(shell: RShell) => {
const exampleCode = 'x <- 1\ny <- 2\nx';
return `
This query returns the datatypes of syntactic elements in the code.
To exemplify the capabilities, consider the following code:
${codeBlock('r', exampleCode)}
To see the type of the variable \`x\`, you can use the following query:
${
await showQuery(shell, exampleCode, [{
type: 'datatype',
criteria: ['3@x']
}], { showCode: false })
}
`;
}
});

registerQueryDocumentation('dependencies', {
name: 'Dependencies Query',
type: 'active',
Expand Down
66 changes: 66 additions & 0 deletions src/queries/catalog/datatype-query/datatype-query-executor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import type { DatatypeQuery, DatatypeQueryResult } from './datatype-query-format';
import { log } from '../../../util/log';
import type { BasicQueryData } from '../../base-query-format';
import type { NormalizedAst, ParentInformation } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
import type { SingleSlicingCriterion } from '../../../slicing/criterion/parse';
import { slicingCriterionToId } from '../../../slicing/criterion/parse';
import { inferDataTypesWithUnification } from '../../../typing/unification/infer';
import { inferDataTypes } from '../../../typing/subtyping/infer';
import type { UnresolvedDataType } from '../../../typing/subtyping/types';
import { loadTracedTypes, loadTurcotteTypes } from '../../../typing/adapter/load-type-signatures';
import fs from 'fs';
import { superBigJsonStringify } from '../../../util/json';

export async function executeDatatypeQuery({ dataflow, ast }: BasicQueryData, queries: readonly DatatypeQuery[]): Promise<DatatypeQueryResult> {
const start = Date.now();

const result: DatatypeQueryResult['inferredTypes'] = {};
for(const query of queries) {
const knownTypes = new Map<string, Set<UnresolvedDataType>>();
if(query.useTurcotteTypes ?? true) {
await loadTurcotteTypes(knownTypes);
}
if(query.useTracedTypes ?? true) {
await loadTracedTypes(knownTypes);
}

const typedAst = query.useSubtyping ?? true
? inferDataTypes(ast as NormalizedAst<ParentInformation & { typeVariable?: undefined }>, dataflow, knownTypes)
: inferDataTypesWithUnification(ast as NormalizedAst<ParentInformation & { typeVariable?: undefined }>, dataflow);
for(const criterion of query.criteria ?? typedAst.idMap.keys().map(id => `$${id}` as SingleSlicingCriterion)) {
if(result[criterion] !== undefined) {
log.warn('Duplicate criterion in datatype query:', criterion);
continue;
}

const node = criterion !== undefined ? typedAst.idMap.get(slicingCriterionToId(criterion, typedAst.idMap)) : typedAst.ast;
if(node === undefined) {
log.warn('Criterion not found in normalized AST:', criterion);
continue;
}

result[criterion] = node.info.inferredType;
}
}

const output = {
'.meta': { timing: Date.now() - start },
inferredTypes: result
};

for(const filePath of queries.map(query => query.outputFile).filter(filePath => filePath !== undefined)) {
if(fs.existsSync(filePath)) {
const stream = fs.createWriteStream(filePath, { flags: 'w' });
superBigJsonStringify(output, '', str => stream.write(str));
await new Promise<void>((resolve, reject) => {
stream.end();
stream.on('error', reject);
stream.on('finish', resolve);
});
} else {
log.warn('Output file does not exist:', filePath);
}
}

return output;
}
49 changes: 49 additions & 0 deletions src/queries/catalog/datatype-query/datatype-query-format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
import type { SingleSlicingCriterion } from '../../../slicing/criterion/parse';
import type { QueryResults, SupportedQuery } from '../../query';
import { bold } from '../../../util/text/ansi';
import { printAsMs } from '../../../util/text/time';
import Joi from 'joi';
import { executeDatatypeQuery } from './datatype-query-executor';
import type { DataType } from '../../../typing/types';
import { prettyPrintDataType } from '../../../typing/pretty-print';

/**
* Calculates the inferred data type for the given criterion.
*/
export interface DatatypeQuery extends BaseQueryFormat {
readonly type: 'datatype';
readonly criteria?: SingleSlicingCriterion[];
readonly useSubtyping?: boolean;
readonly useTurcotteTypes?: boolean;
readonly useTracedTypes?: boolean;
readonly outputFile?: string;
}

export interface DatatypeQueryResult extends BaseQueryResult {
/** Maps each criterion to the inferred data type, duplicates are ignored. */
readonly inferredTypes: Record<SingleSlicingCriterion, DataType>;
}

export const DatatypeQueryDefinition = {
executor: executeDatatypeQuery,
asciiSummarizer: (formatter, _processed, queryResults, result) => {
const out = queryResults as QueryResults<'datatype'>['datatype'];
result.push(`Query: ${bold('datatype', formatter)} (${printAsMs(out['.meta'].timing, 0)})`);
for(const [criterion, inferredType] of Object.entries(out.inferredTypes)) {
result.push(` ╰ ${criterion}: {${prettyPrintDataType(inferredType)}}`);
}
return true;
},
flattenInvolvedNodes: () => {
return [];
},
schema: Joi.object({
type: Joi.string().valid('datatype').required().description('The type of the query.'),
criteria: Joi.array().items(Joi.string()).optional().description('The slicing criteria of the node to get the inferred data type for.'),
useSubtyping: Joi.boolean().optional().default(true).description('Whether to use subtyping to infer the data type.'),
useTurcotteTypes: Joi.boolean().optional().default(true).description('Whether to use Turcotte types for inference.'),
useTracedTypes: Joi.boolean().optional().default(true).description('Whether to use our manually traced types for inference.'),
outputFile: Joi.string().optional().description('The output file to write the inferred types to.')
}).description('Datatype query used to extract the inferred data type for a node in the normalized AST')
} as const satisfies SupportedQuery<'datatype'>;
3 changes: 3 additions & 0 deletions src/queries/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { OriginQueryDefinition } from './catalog/origin-query/origin-query-forma
import type { LinterQuery } from './catalog/linter-query/linter-query-format';
import { LinterQueryDefinition } from './catalog/linter-query/linter-query-format';
import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
import { DatatypeQueryDefinition, type DatatypeQuery } from './catalog/datatype-query/datatype-query-format';
import type { ControlFlowQuery } from './catalog/control-flow-query/control-flow-query-format';
import { ControlFlowQueryDefinition } from './catalog/control-flow-query/control-flow-query-format';
import type { DfShapeQuery } from './catalog/df-shape-query/df-shape-query-format';
Expand All @@ -65,6 +66,7 @@ export type Query = CallContextQuery
| DataflowClusterQuery
| StaticSliceQuery
| LineageQuery
| DatatypeQuery
| DependenciesQuery
| LocationMapQuery
| HappensBeforeQuery
Expand Down Expand Up @@ -114,6 +116,7 @@ export const SupportedQueries = {
'dataflow-cluster': ClusterQueryDefinition,
'static-slice': StaticSliceQueryDefinition,
'lineage': LineageQueryDefinition,
'datatype': DatatypeQueryDefinition,
'dependencies': DependenciesQueryDefinition,
'location-map': LocationMapQueryDefinition,
'search': SearchQueryDefinition,
Expand Down
2 changes: 1 addition & 1 deletion src/r-bridge/lang-4.x/ast/model/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export type NoInfo = object;
* Will be used to reconstruct the source of the given element in the R-ast.
* This will not be part of most comparisons as it is mainly of interest to the reconstruction of R code.
*/
interface Source {
export interface Source {
/**
* The range is different from the assigned {@link Location} as it refers to the complete source range covered by the given
* element.
Expand Down
Loading
Loading