Skip to content

Commit

Permalink
fix: generation of memoized class member calls (#982)
Browse files Browse the repository at this point in the history
- fix: generating memoized class member calls (on non-static members)
should still use the class for python code generation
- added testcase
------------------
Fixes the (last) issue in #954

---------

Co-authored-by: megalinter-bot <[email protected]>
  • Loading branch information
WinPlay02 and megalinter-bot authored Apr 3, 2024
1 parent f69d836 commit ed06aef
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
SdsBlock,
SdsBlockLambda,
SdsCall,
SdsClassMember,
SdsDeclaration,
SdsExpression,
SdsModule,
Expand Down Expand Up @@ -1018,6 +1019,10 @@ export class SafeDsPythonGenerator {
Parameter.isOptional(this.nodeMapper.argumentToParameter(arg)),
);
const fullyQualifiedTargetName = this.generateFullyQualifiedFunctionName(expression);
if (!containsOptionalArgs && isSdsMemberAccess(expression.receiver)) {
const referenceImport = this.createImportDataForReference(expression.receiver.member!);
frame.addImport(referenceImport);
}
return expandTracedToNode(expression)`${RUNNER_PACKAGE}.memoized_call("${fullyQualifiedTargetName}", ${
containsOptionalArgs ? 'lambda *_ : ' : ''
}${
Expand All @@ -1028,7 +1033,9 @@ export class SafeDsPythonGenerator {
expression.receiver.receiver.receiver,
frame,
)}.${this.generateExpression(expression.receiver.member!, frame)}`
: this.generateExpression(expression.receiver, frame)
: isSdsMemberAccess(expression.receiver)
? this.getClassQualifiedNameForMember(<SdsClassMember>callable)
: this.generateExpression(expression.receiver, frame)
}, [${generateThisParam ? thisParam : ''}${
generateThisParam && memoizedArgs.length > 0 ? ', ' : ''
}${joinTracedToNode(expression.argumentList, 'arguments')(
Expand Down Expand Up @@ -1083,6 +1090,16 @@ export class SafeDsPythonGenerator {
throw new Error('Callable of provided call does not exist or is not a declaration.');
}

private getClassQualifiedNameForMember(node: SdsClassMember): string {
const classMemberPath = [];
let enclosingClass: SdsDeclaration | undefined = node;
while (enclosingClass) {
classMemberPath.unshift(this.getPythonNameOrDefault(enclosingClass));
enclosingClass = AstUtils.getContainerOfType(enclosingClass.$container, isSdsClass);
}
return classMemberPath.join('.');
}

private getArgumentsMap(
argumentList: SdsArgument[],
frame: GenerationInfoFrame,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Imports ----------------------------------------------------------------------

import safeds_runner
from tests.generator.memberAccessWithRunnerIntegration import C, f, factory, g, h
from safeds.data.tabular.containers import Table
from tests.generator.memberAccessWithRunnerIntegration import C, f, factory, factoryNested, g, h, Outer
from typing import Any, TypeVar

# Type variables ---------------------------------------------------------------
Expand All @@ -27,3 +28,14 @@ def test():
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C.j", C.j, [safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []), 123], []))
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C.k2", C.k2, [safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []), 'abc'], []))
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C.from_csv_file", C.from_csv_file, ['abc.csv'], [safeds_runner.file_mtime('abc.csv')]))
a = safeds_runner.memoized_call("safeds.data.tabular.containers.Table.from_csv_file", Table.from_csv_file, ['abc.csv'], [safeds_runner.file_mtime('abc.csv')])
safeds_runner.save_placeholder('a', a)
v = safeds_runner.memoized_call("safeds.data.tabular.containers.Table.get_column", Table.get_column, [a, 'b'], [])
safeds_runner.save_placeholder('v', v)
f(v)
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.Outer.Nested.f", Outer.Nested.f, [], []))
nestedInstance = safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.factoryNested", factoryNested, [], [])
safeds_runner.save_placeholder('nestedInstance', nestedInstance)
nestedResult = safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.Outer.Nested.g", Outer.Nested.g, [nestedInstance], [])
safeds_runner.save_placeholder('nestedResult', nestedResult)
f(nestedResult)

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

Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,20 @@ class C() {
static fun from_csv_file(name: String) -> c: C
}

class Outer() {
class Nested() {
@Pure
static fun f() -> result: Boolean

@Pure
fun g() -> result: Boolean
}
}

@Pure fun factory() -> instance: C?

@Pure fun factoryNested() -> instance: Outer.Nested

pipeline test {
f(g().result);
f(h().result1);
Expand All @@ -38,4 +50,11 @@ pipeline test {
f(C().j(123));
f(C().k("abc"));
f(C.from_csv_file("abc.csv"));
val a = Table.fromCsvFile("abc.csv");
val v = a.getColumn("b");
f(v);
f(Outer.Nested.f());
val nestedInstance = factoryNested();
val nestedResult = nestedInstance.g();
f(nestedResult);
}

0 comments on commit ed06aef

Please sign in to comment.