Skip to content

Commit cff57bd

Browse files
committed
feat-fix(*): fix most of compile errors - #1496
1 parent e631bb6 commit cff57bd

File tree

8 files changed

+58
-38
lines changed

8 files changed

+58
-38
lines changed

src/dataflow/environments/resolve-by-name.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ import { RType } from '../../r-bridge/lang-4.x/ast/model/type';
1616
import { VisitingQueue } from '../../slicing/static/visiting-queue';
1717
import { envFingerprint } from '../../slicing/static/fingerprint';
1818
import { EdgeType } from '../graph/edge';
19-
import type { Value, ValueSet } from '../eval/values/r-value';
20-
import { Bottom, Top } from '../eval/values/r-value';
19+
import { Bottom, Top, type Lift, type Value, type ValueSet } from '../eval/values/r-value';
2120
import { valueFromTsValue } from '../eval/values/general';
2221
import { setFrom } from '../eval/values/sets/set-constants';
2322

23+
export type ResolveResult = Lift<ValueSet<Value[]>>;
2424

2525
const FunctionTargetTypes = ReferenceType.Function | ReferenceType.BuiltInFunction | ReferenceType.Unknown | ReferenceType.Argument | ReferenceType.Parameter;
2626
const VariableTargetTypes = ReferenceType.Variable | ReferenceType.Parameter | ReferenceType.Argument | ReferenceType.Unknown;
@@ -103,7 +103,7 @@ export function resolvesToBuiltInConstant(name: Identifier | undefined, environm
103103
}
104104

105105
/** Please use {@link resolveValueOfVariable} */
106-
export function resolveToConstants(name: Identifier | undefined, environment: REnvironmentInformation): ValueSet | typeof Top {
106+
export function resolveToConstants(name: Identifier | undefined, environment: REnvironmentInformation): ResolveResult {
107107
if(name === undefined) {
108108
return Top;
109109
}
@@ -179,7 +179,7 @@ export function getAliases(sourceIds: readonly NodeId[], dataflow: DataflowGraph
179179
}
180180

181181
/** Please use {@link resolveValueOfVariable} */
182-
export function trackAliasInEnvironments(identifier: Identifier | undefined, use: REnvironmentInformation, idMap?: AstIdMap): ValueSet | typeof Top {
182+
export function trackAliasInEnvironments(identifier: Identifier | undefined, use: REnvironmentInformation, idMap?: AstIdMap): ResolveResult {
183183
if(identifier === undefined) {
184184
return Top;
185185
}
@@ -235,7 +235,7 @@ function isNestedInLoop(node: RNodeWithParent | undefined, ast: AstIdMap): boole
235235
return isNestedInLoop(parentNode, ast);
236236
}
237237

238-
export function trackAliasesInGraph(id: NodeId, graph: DataflowGraph, idMap?: AstIdMap): ValueSet | typeof Top | typeof Bottom {
238+
export function trackAliasesInGraph(id: NodeId, graph: DataflowGraph, idMap?: AstIdMap): ResolveResult {
239239
idMap ??= graph.idMap;
240240
guard(idMap !== undefined, 'The ID map is required to get the lineage of a node');
241241
const start = graph.getVertex(id);
@@ -304,7 +304,7 @@ export function trackAliasesInGraph(id: NodeId, graph: DataflowGraph, idMap?: As
304304
*
305305
* @see {@link resolveIdToValue} - for a more general approach which "evaluates" a node based on value resolve
306306
*/
307-
export function resolveValueOfVariable(identifier: Identifier | undefined, environment: REnvironmentInformation, idMap?: AstIdMap): ValueSet | typeof Top | typeof Bottom {
307+
export function resolveValueOfVariable(identifier: Identifier | undefined, environment: REnvironmentInformation, idMap?: AstIdMap): ResolveResult {
308308
const resolve = getConfig().solver.variables;
309309

310310
switch(resolve) {
@@ -335,7 +335,7 @@ export interface ResolveInfo {
335335
* @param idMap - The id map to resolve the node if given as an id
336336
* @param full - Whether to track variables
337337
*/
338-
export function resolveIdToValue(id: NodeId | RNodeWithParent, { environment, graph, idMap, full } : ResolveInfo): ValueSet | typeof Top | typeof Bottom {
338+
export function resolveIdToValue(id: NodeId | RNodeWithParent, { environment, graph, idMap, full } : ResolveInfo): ResolveResult {
339339
idMap ??= graph?.idMap;
340340
const node = typeof id === 'object' ? id : idMap?.get(id);
341341
if(node === undefined) {

src/dataflow/eval/values/general.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { intervalFrom } from './intervals/interval-constants';
22
import { ValueLogicalFalse, ValueLogicalTrue } from './logical/logical-constants';
3-
import type { Lift, Value } from './r-value';
3+
import type { Lift, Unlift, Value, ValueSet } from './r-value';
44
import { Bottom, isBottom, isTop, Top } from './r-value';
55
import { stringFrom } from './string/string-constants';
66

@@ -15,6 +15,10 @@ export function bottomTopGuard(...a: Lift<unknown>[]): typeof Top | typeof Botto
1515
}
1616
}
1717

18+
export function valueSetGuard(a: Lift<ValueSet<Value[]>>): ValueSet<Value[]> | undefined {
19+
return (isBottom(a) || isTop(a)) ? undefined : a;
20+
}
21+
1822
export function valueFromTsValue(a: unknown): Value {
1923
if(a === undefined) {
2024
return Bottom;
Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { bottomTopGuard } from '../general';
22
import type { Lift, Value, ValueSet } from '../r-value';
3+
import { Top } from '../r-value';
34

45
function flattenSetElements(s: Lift<Value[]>): Lift<Value[]> {
56
return bottomTopGuard(s) ?? (s as Value[]).flatMap(e => {
67
return e.type === 'set' ? flattenSetElements(e.elements) : e;
78
});
89
}
910

10-
export function setFrom<V extends Value[]>(...elements: V): ValueSet {
11+
export function setFrom<V extends Value[]>(...elements: V): ValueSet<Value[]> {
1112
return {
1213
type: 'set',
1314
elements: elements.flatMap(e => {
@@ -16,3 +17,16 @@ export function setFrom<V extends Value[]>(...elements: V): ValueSet {
1617
};
1718
}
1819

20+
export function isSet<V extends Value>(element: V): boolean {
21+
return element.type === 'set';
22+
}
23+
24+
export const ValueEmptySet = setFrom();
25+
export const ValueSetTop: ValueSet<typeof Top> = {
26+
type: 'set',
27+
elements: Top
28+
};
29+
export const ValueSetBottom: ValueSet<typeof Top> = {
30+
type: 'set',
31+
elements: Top
32+
};

src/dataflow/internal/process/functions/call/built-in/built-in-apply.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { EdgeType } from '../../../../../graph/edge';
1515
import { ReferenceType } from '../../../../../environments/identifier';
1616
import { resolveValueOfVariable } from '../../../../../environments/resolve-by-name';
1717
import { UnnamedFunctionCallPrefix } from '../unnamed-call-handling';
18+
import { valueSetGuard } from '../../../../../eval/values/general';
19+
import { isValue } from '../../../../../eval/values/r-value';
1820

1921
export interface BuiltInApplyConfiguration extends MergeableRecord {
2022
/** the 0-based index of the argument which is the actual function passed, defaults to 1 */
@@ -83,9 +85,9 @@ export function processApply<OtherInfo>(
8385
} else if(val.type === RType.Symbol) {
8486
functionId = val.info.id;
8587
if(resolveValue) {
86-
const resolved = resolveValueOfVariable(val.content, data.environment);
87-
if(resolved?.length === 1 && typeof resolved[0] === 'string') {
88-
functionName = resolved[0];
88+
const resolved = valueSetGuard(resolveValueOfVariable(val.content, data.environment));
89+
if(resolved?.elements.length === 1 && resolved.elements[0].type === 'string') {
90+
functionName = isValue(resolved.elements[0].value) ? resolved.elements[0].value.str : undefined;
8991
}
9092
} else {
9193
functionName = val.content;

src/dataflow/internal/process/functions/call/built-in/built-in-eval.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import { RType } from '../../../../../../r-bridge/lang-4.x/ast/model/type';
2222
import { resolveValueOfVariable } from '../../../../../environments/resolve-by-name';
2323
import { appendEnvironment } from '../../../../../environments/append';
2424
import type { RArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument';
25-
import { isUndefined } from '../../../../../../util/assert';
25+
import { isNotUndefined, isUndefined } from '../../../../../../util/assert';
2626
import { cartesianProduct } from '../../../../../../util/arrays';
27+
import { valueSetGuard } from '../../../../../eval/values/general';
28+
import { isValue } from '../../../../../eval/values/r-value';
2729

2830
export function processEvalCall<OtherInfo>(
2931
name: RSymbol<OtherInfo & ParentInformation>,
@@ -110,10 +112,11 @@ function resolveEvalToCode<OtherInfo>(evalArgument: RNode<OtherInfo & ParentInfo
110112
if(arg.value?.type === RType.String) {
111113
return [arg.value.content.str];
112114
} else if(arg.value?.type === RType.Symbol) {
113-
const resolve = resolveValueOfVariable(arg.value.content, env, idMap);
114-
if(resolve && resolve.every(r => typeof r === 'object' && r !== null && 'str' in r)) {
115-
return resolve.map(r => r.str as string);
116-
}
115+
const resolve = valueSetGuard(resolveValueOfVariable(arg.value.content, env, idMap));
116+
return resolve?.elements.map(r => r.type === 'string' && isValue(r.value)
117+
? r.value.str
118+
: undefined
119+
).filter(isNotUndefined);
117120
} else if(arg.value?.type === RType.FunctionCall && arg.value.named && ['paste', 'paste0'].includes(arg.value.functionName.content)) {
118121
return handlePaste(arg.value.arguments, env, idMap, arg.value.functionName.content === 'paste' ? [' '] : ['']);
119122
}

src/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type { IdentifierReference } from '../../../../../environments/identifier
1717
import { ReferenceType } from '../../../../../environments/identifier';
1818
import type { REnvironmentInformation } from '../../../../../environments/environment';
1919
import { makeAllMaybe } from '../../../../../environments/environment';
20+
import { valueSetGuard } from '../../../../../eval/values/general';
2021

2122
export function processIfThenElse<OtherInfo>(
2223
name: RSymbol<OtherInfo & ParentInformation>,
@@ -51,10 +52,9 @@ export function processIfThenElse<OtherInfo>(
5152
let makeThenMaybe = false;
5253

5354
// we should defer this to the abstract interpretation
54-
5555
const values = resolveValueOfVariable(condArg?.lexeme, data.environment, data.completeAst.idMap);
56-
const conditionIsAlwaysFalse = values?.every(d => d === false) ?? false;
57-
const conditionIsAlwaysTrue = values?.every(d => d === true) ?? false;
56+
const conditionIsAlwaysFalse = valueSetGuard(values)?.elements.every(d => d.type === 'logical' && d.value === false) ?? false;
57+
const conditionIsAlwaysTrue = valueSetGuard(values)?.elements.every(d => d.type === 'logical' && d.value === true) ?? false;
5858

5959
if(!conditionIsAlwaysFalse) {
6060
then = processDataflowFor(thenArg, data);

src/dataflow/internal/process/functions/call/built-in/built-in-source.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import { RShellExecutor } from '../../../../../../r-bridge/shell-executor';
2929
import { resolveValueOfVariable } from '../../../../../environments/resolve-by-name';
3030
import { isNotUndefined } from '../../../../../../util/assert';
3131
import path from 'path';
32+
import { valueSetGuard } from '../../../../../eval/values/general';
33+
import { isValue } from '../../../../../eval/values/r-value';
3234

3335
let sourceProvider = requestProviderFromFile();
3436

@@ -153,13 +155,8 @@ export function processSourceCall<OtherInfo>(
153155
if(sourceFileArgument !== EmptyArgument && sourceFileArgument?.value?.type === RType.String) {
154156
sourceFile = [removeRQuotes(sourceFileArgument.lexeme)];
155157
} else if(sourceFileArgument !== EmptyArgument) {
156-
sourceFile = resolveValueOfVariable(sourceFileArgument.value?.lexeme, data.environment, data.completeAst.idMap)?.map(x => {
157-
if(typeof x === 'object' && x && 'str' in x) {
158-
return x.str as string;
159-
} else {
160-
return undefined;
161-
}
162-
}).filter(isNotUndefined);
158+
const resolved = valueSetGuard(resolveValueOfVariable(sourceFileArgument.value?.lexeme, data.environment, data.completeAst.idMap));
159+
sourceFile = resolved?.elements.map(r => r.type === 'string' && isValue(r.value) ? r.value.str : undefined).filter(isNotUndefined);
163160
}
164161

165162
if(sourceFile && sourceFile.length === 1) {

test/functionality/dataflow/environments/resolve.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ import { resolveByName, resolveToConstants, resolveValueOfVariable, resolvesToBu
55
import { ReferenceType } from '../../../../src/dataflow/environments/identifier';
66
import { Ternary } from '../../../../src/util/logic';
77
import { describe, assert, test, expect } from 'vitest';
8-
import { DEFAULT_DATAFLOW_PIPELINE } from '../../../../src/core/steps/pipeline/default-pipelines';
9-
import { PipelineExecutor } from '../../../../src/core/pipeline-executor';
10-
import { RShell } from '../../../../src/r-bridge/shell';
11-
import { requestFromInput } from '../../../../src/r-bridge/retriever';
8+
// import { DEFAULT_DATAFLOW_PIPELINE } from '../../../../src/core/steps/pipeline/default-pipelines';
9+
// import { PipelineExecutor } from '../../../../src/core/pipeline-executor';
10+
// import { RShell } from '../../../../src/r-bridge/shell';
11+
// import { requestFromInput } from '../../../../src/r-bridge/retriever';
1212

13-
async function get(code: string) {
14-
const result = await new PipelineExecutor(DEFAULT_DATAFLOW_PIPELINE, {
15-
parser: new RShell(),
16-
request: requestFromInput(code.trim())
17-
}).allRemainingSteps();
18-
return result;
19-
}
13+
// async function get(code: string) {
14+
// const result = await new PipelineExecutor(DEFAULT_DATAFLOW_PIPELINE, {
15+
// parser: new RShell(),
16+
// request: requestFromInput(code.trim())
17+
// }).allRemainingSteps();
18+
// return result;
19+
// }
2020

2121
describe('Resolve', () => {
2222
describe('ByName', () => {

0 commit comments

Comments
 (0)