Skip to content

Commit 01933b9

Browse files
feat: error if function pointers are used (#629)
Closes #565 Closes partially #543 ### Summary of Changes To provide a cleaner graphical view, this PR makes the use of function pointers (to functions/segments) an error. Lambdas can be used instead. --------- Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com>
1 parent b99ab25 commit 01933b9

File tree

3 files changed

+109
-3
lines changed

3 files changed

+109
-3
lines changed

src/language/validation/other/expressions/references.ts

+36-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,42 @@
1-
import { isSdsAnnotation, isSdsPipeline, isSdsSchema, SdsReference } from '../../../generated/ast.js';
2-
import { ValidationAcceptor } from 'langium';
1+
import {
2+
isSdsAnnotation,
3+
isSdsCall,
4+
isSdsFunction,
5+
isSdsMemberAccess,
6+
isSdsPipeline,
7+
isSdsSchema,
8+
isSdsSegment,
9+
SdsReference,
10+
} from '../../../generated/ast.js';
11+
import { AstNode, ValidationAcceptor } from 'langium';
312

13+
export const CODE_REFERENCE_FUNCTION_POINTER = 'reference/function-pointer';
414
export const CODE_REFERENCE_TARGET = 'reference/target';
515

16+
export const referenceMustNotBeFunctionPointer = (node: SdsReference, accept: ValidationAcceptor): void => {
17+
const target = node.target?.ref;
18+
if (!isSdsFunction(target) && !isSdsSegment(target)) {
19+
return;
20+
}
21+
22+
//
23+
let container: AstNode | undefined = node.$container;
24+
if (isSdsMemberAccess(container) && node.$containerProperty === 'member') {
25+
container = container.$container;
26+
}
27+
28+
if (!isSdsCall(container)) {
29+
accept(
30+
'error',
31+
'Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead.',
32+
{
33+
node,
34+
code: CODE_REFERENCE_FUNCTION_POINTER,
35+
},
36+
);
37+
}
38+
};
39+
640
export const referenceTargetMustNotBeAnnotationPipelineOrSchema = (
741
node: SdsReference,
842
accept: ValidationAcceptor,

src/language/validation/safe-ds-validator.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ import {
4545
} from './other/types/callableTypes.js';
4646
import { typeArgumentListMustNotHavePositionalArgumentsAfterNamedArguments } from './other/types/typeArgumentLists.js';
4747
import { argumentListMustNotHavePositionalArgumentsAfterNamedArguments } from './other/argumentLists.js';
48-
import { referenceTargetMustNotBeAnnotationPipelineOrSchema } from './other/expressions/references.js';
48+
import {
49+
referenceMustNotBeFunctionPointer,
50+
referenceTargetMustNotBeAnnotationPipelineOrSchema,
51+
} from './other/expressions/references.js';
4952
import {
5053
annotationCallAnnotationShouldNotBeDeprecated,
5154
argumentCorrespondingParameterShouldNotBeDeprecated,
@@ -141,6 +144,7 @@ export const registerValidationChecks = function (services: SafeDsServices) {
141144
SdsPipeline: [pipelineMustContainUniqueNames],
142145
SdsPlaceholder: [placeholdersMustNotBeAnAlias, placeholderShouldBeUsed(services)],
143146
SdsReference: [
147+
referenceMustNotBeFunctionPointer,
144148
referenceTargetMustNotBeAnnotationPipelineOrSchema,
145149
referenceTargetShouldNotBeDeprecated(services),
146150
referenceTargetShouldNotExperimental(services),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package tests.validation.other.expressions.references.target
2+
3+
class MyClass {
4+
fun myInstanceMethod()
5+
static fun myStaticMethod()
6+
}
7+
8+
fun myFunction1()
9+
fun myFunction2(p: Any)
10+
11+
segment mySegment1() {}
12+
13+
segment mySegment2() {
14+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
15+
MyClass().»myInstanceMethod«;
16+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
17+
MyClass().»myInstanceMethod«.a;
18+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
19+
MyClass().»myInstanceMethod«.a();
20+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
21+
myFunction2(MyClass().»myInstanceMethod«);
22+
// $TEST$ no error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
23+
MyClass().»myInstanceMethod«();
24+
25+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
26+
MyClass.»myStaticMethod«;
27+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
28+
MyClass.»myStaticMethod«.a;
29+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
30+
MyClass.»myStaticMethod«.a();
31+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
32+
myFunction2(MyClass.»myStaticMethod«);
33+
// $TEST$ no error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
34+
MyClass.»myStaticMethod«();
35+
36+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
37+
»myFunction1«;
38+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
39+
»myFunction1«.a;
40+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
41+
»myFunction1«.a();
42+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
43+
myFunction2(»myFunction1«);
44+
// $TEST$ no error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
45+
»myFunction1«();
46+
47+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
48+
»mySegment1«;
49+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
50+
»mySegment1«.a;
51+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
52+
»mySegment1«.a();
53+
// $TEST$ error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
54+
myFunction2(»mySegment1«);
55+
// $TEST$ no error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
56+
»mySegment1«();
57+
58+
// $TEST$ no error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
59+
»unresolved«;
60+
// $TEST$ no error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
61+
»unresolved«.a;
62+
// $TEST$ no error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
63+
»unresolved«.a();
64+
// $TEST$ no error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
65+
myFunction2(»unresolved«);
66+
// $TEST$ no error "Function pointers are not allowed to provide a cleaner graphical view. Use a lambda instead."
67+
»unresolved«();
68+
}

0 commit comments

Comments
 (0)