Skip to content

Commit

Permalink
feat: filter statements without effect for code generation (#786)
Browse files Browse the repository at this point in the history
Closes #542

### Summary of Changes

- filter statements without effect for code generation
- enable test "statements/statement without effect"
- change purity to impure in functions of various tests to have effect

---------

Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com>
  • Loading branch information
WinPlay02 and megalinter-bot authored Nov 21, 2023
1 parent 9ed1c08 commit cd4f2c1
Show file tree
Hide file tree
Showing 31 changed files with 56 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import {
} from '../partialEvaluation/model.js';
import { SafeDsPartialEvaluator } from '../partialEvaluation/safe-ds-partial-evaluator.js';
import { SafeDsServices } from '../safe-ds-module.js';
import { SafeDsPurityComputer } from '../purity/safe-ds-purity-computer.js';

export const CODEGEN_PREFIX = '__gen_';
const BLOCK_LAMBDA_PREFIX = `${CODEGEN_PREFIX}block_lambda_`;
Expand All @@ -104,11 +105,13 @@ export class SafeDsPythonGenerator {
private readonly builtinAnnotations: SafeDsAnnotations;
private readonly nodeMapper: SafeDsNodeMapper;
private readonly partialEvaluator: SafeDsPartialEvaluator;
private readonly purityComputer: SafeDsPurityComputer;

constructor(services: SafeDsServices) {
this.builtinAnnotations = services.builtins.Annotations;
this.nodeMapper = services.helpers.NodeMapper;
this.partialEvaluator = services.evaluation.PartialEvaluator;
this.purityComputer = services.purity.PurityComputer;
}

generate(document: LangiumDocument, generateOptions: GenerateOptions): TextDocument[] {
Expand Down Expand Up @@ -356,8 +359,7 @@ export class SafeDsPythonGenerator {
}

private generateBlock(block: SdsBlock, frame: GenerationInfoFrame): CompositeGeneratorNode {
// TODO filter withEffect
let statements = getStatements(block);
let statements = getStatements(block).filter((stmt) => this.hasStatementEffect(stmt));
if (statements.length === 0) {
return traceToNode(block)('pass');
}
Expand All @@ -366,6 +368,21 @@ export class SafeDsPythonGenerator {
})!;
}

private hasStatementEffect(statement: SdsStatement): boolean {
if (isSdsAssignment(statement)) {
const assignees = getAssignees(statement);
return (
assignees.some((value) => !isSdsWildcard(value)) ||
(statement.expression !== undefined &&
this.purityComputer.expressionHasSideEffects(statement.expression))
);
} else if (isSdsExpressionStatement(statement)) {
return this.purityComputer.expressionHasSideEffects(statement.expression);
}
/* c8 ignore next */
return false;
}

private generateStatement(statement: SdsStatement, frame: GenerationInfoFrame): CompositeGeneratorNode {
if (isSdsAssignment(statement)) {
return traceToNode(statement)(this.generateAssignment(statement, frame));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package tests.generator.parameterWithPythonName

@Pure fun f1(param: (a: Int, b: Int, c: Int) -> r: Int)
@Pure fun f2(param: (a: Int, b: Int, c: Int) -> ())
@Impure([ImpurityReason.Other]) fun f1(param: (a: Int, b: Int, c: Int) -> r: Int)
@Impure([ImpurityReason.Other]) fun f2(param: (a: Int, b: Int, c: Int) -> ())

segment test(param1: Int, @PythonName("param_2") param2: Int, @PythonName("param_3") param3: Int = 0) {
f1((a: Int, b: Int, c: Int = 0) -> 1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.pipelineWithPythonName

@Pure fun f()
@Impure([ImpurityReason.Other]) fun f()

@PythonName("test_pipeline")
pipeline testPipeline {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.segmentWithPythonName

@Pure fun f()
@Impure([ImpurityReason.Other]) fun f()

@PythonName("test_segment")
segment testSegment() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.twoPipelines

@Pure fun f()
@Impure([ImpurityReason.Other]) fun f()

pipeline test1 {
f();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.twoSegments

@Pure fun f()
@Impure([ImpurityReason.Other]) fun f()

segment test1(a: Int, b: Int = 0) {
f();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package tests.generator.blockLambdaResult

@Pure fun g() -> a: Int

@Pure fun h(a: Int)
@Impure([ImpurityReason.Other]) fun h(a: Int)

segment f1(l: (a: Int, b: Int) -> d: Int) {
h(l(1, 2).d);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package tests.generator.blockLambda

@Pure fun f1(param: (a: Int, b: Int) -> r: Int)
@Pure fun f2(param: () -> ())
@Impure([ImpurityReason.Other]) fun f1(param: (a: Int, b: Int) -> r: Int)
@Impure([ImpurityReason.Other]) fun f2(param: () -> ())

@Pure fun g() -> a: Int

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.call

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

@Pure fun g(
param1: Int,
Expand All @@ -12,15 +12,15 @@ package tests.generator.call
@PythonName("param_2") param2: Int = 0
) -> result: Boolean

@Pure
@Impure([ImpurityReason.Other])
@PythonCall("$param.i()")
fun i(param: Any?)

@Pure
@Impure([ImpurityReason.Other])
@PythonCall("$param.j($param2)")
fun j(param: Any?, param2: Any?)

@Pure
@Impure([ImpurityReason.Other])
@PythonCall("k($param2, $param)")
fun k(param: Any?, param2: Any?)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.constant

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

pipeline test {
f(1 < 2);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.enumVariantCall

@Pure fun f(p: Any)
@Impure([ImpurityReason.Other]) fun f(p: Any)

enum MyEnum {
Variant1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.expressionLambda

@Pure fun f(param: (a: Int, b: Int) -> r: Int)
@Impure([ImpurityReason.Other]) fun f(param: (a: Int, b: Int) -> r: Int)

pipeline test {
f((a, b = 2) -> 1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.indexedAccess

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

segment test(params: List<Int>) {
f(params[0]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.infixOperation

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

@Pure fun g() -> result: Boolean

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.lists

@Pure fun f(param: List<Int>)
@Impure([ImpurityReason.Other]) fun f(param: List<Int>)

@Pure fun h() -> result: Int

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.literals

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

pipeline test {
f(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package tests.generator.maps

@Pure fun g1(param: Map<String, Float>)
@Impure([ImpurityReason.Other]) fun g1(param: Map<String, Float>)

@Pure fun g2(param: Map<Float, String>)
@Impure([ImpurityReason.Other]) fun g2(param: Map<Float, String>)

@Pure fun h1() -> result: Float

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.memberAccess

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

@Pure fun g() -> result: Boolean

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.parenthesizedExpression

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

@Pure fun g() -> result: Boolean

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.prefixOperation

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

@Pure fun g() -> result: Boolean

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.reference

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

@Pure
@PythonName("explain_model")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.templateString

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

@Pure fun g() -> result: Int

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ from tests.generator.differentPackage import function2InDifferentPackage as g
from tests.generator.withPythonModule import function1InCompilationUnitWithPythonModule
from tests.generator.withPythonModule import function2InCompilationUnitWithPythonModule as h

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

pipeline test {
f(segment1InSamePackage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package tests.generator.wildcard
from tests.generator.differentPackageWildcard import *
from tests.generator.withPythonModuleWildcard import *

@Pure fun f(param: Any?)
@Impure([ImpurityReason.Other]) fun f(param: Any?)

pipeline test {
f(function1InDifferentPackage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package tests.generator.pythonModule

@Pure fun f()
@Impure([ImpurityReason.Other]) fun f()

segment test() {
f();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package tests.generator.assignment

@Pure fun f1(param: Any?)
@Pure fun f2(param: () -> r: Int?)
@Impure([ImpurityReason.Other]) fun f1(param: Any?)
@Impure([ImpurityReason.Other]) fun f2(param: () -> r: Int?)

@Pure fun g() -> (a: Int, b: Int, c: Int)
@Impure([ImpurityReason.Other]) fun g() -> (a: Int, b: Int, c: Int)

pipeline testPipeline {
_, _ ,_ = g();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package tests.generator.expressionStatement

@Pure fun f(param: () -> ())
@Impure([ImpurityReason.Other]) fun f(param: () -> ())

@Pure fun g() -> result: Int
@Impure([ImpurityReason.Other]) fun g() -> result: Int

pipeline testPipeline {
g();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tests.generator.statementWithoutEffect

fun f(param: () -> ())
@Impure([ImpurityReason.Other]) fun f(param: () -> ())

pipeline testPipeline {
1;
Expand Down

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

0 comments on commit cd4f2c1

Please sign in to comment.