Skip to content

Commit 608e470

Browse files
feat: handle backticks surrounding IDs (#622)
Closes #579 ### Summary of Changes Backticks allow using keywords as IDs. This now removes them properly from IDs. --------- Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com>
1 parent a51a644 commit 608e470

20 files changed

+137
-4
lines changed

src/language/grammar/safe-ds-value-converter.ts

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { convertString, CstNode, DefaultValueConverter, GrammarAST, ValueType }
33
export class SafeDsValueConverter extends DefaultValueConverter {
44
protected override runConverter(rule: GrammarAST.AbstractRule, input: string, cstNode: CstNode): ValueType {
55
switch (rule.name.toUpperCase()) {
6+
case 'ID':
7+
return input.replaceAll('`', '');
68
case 'TEMPLATE_STRING_START':
79
return convertString(input.substring(0, input.length - 1));
810
case 'TEMPLATE_STRING_INNER':

tests/helpers/nodeFinder.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,12 @@ describe('getNodeOfType', () => {
8585

8686
it('should return the nth matching node if an index is set', async () => {
8787
const code = `
88+
package p
89+
8890
class C
8991
enum D
9092
`;
91-
const node = await getNodeOfType(services, code, isSdsDeclaration, 1);
93+
const node = await getNodeOfType(services, code, isSdsDeclaration, 2);
9294
expect(node).to.satisfy(isSdsEnum);
9395
});
9496
});

tests/helpers/nodeFinder.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Location, Range } from 'vscode-languageserver';
22
import { isRangeEqual, parseHelper } from 'langium/test';
33
import { SafeDsServices } from '../../src/language/safe-ds-module.js';
4-
import { AstNode, streamAllContents, URI } from 'langium';
4+
import { AstNode, streamAllContents, streamAst, URI } from 'langium';
55
import { SdsModule } from '../../src/language/generated/ast.js';
66
import { AssertionError } from 'assert';
77
import { locationToString } from './location.js';
@@ -67,7 +67,7 @@ export const getNodeOfType = async <T extends AstNode>(
6767
): Promise<T> => {
6868
const document = await parseHelper(services)(code);
6969
const module = document.parseResult.value as SdsModule;
70-
const candidates = streamAllContents(module).filter(predicate).toArray();
70+
const candidates = streamAst(module).filter(predicate).toArray();
7171

7272
if (candidates.length === 0) {
7373
throw new AssertionError({ message: `Expected to find a matching node but found none.` });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { createSafeDsServices } from '../../../src/language/safe-ds-module.js';
3+
import { EmptyFileSystem } from 'langium';
4+
import { getNodeOfType } from '../../helpers/nodeFinder.js';
5+
import {
6+
isSdsClass,
7+
isSdsModule,
8+
isSdsTemplateStringEnd,
9+
isSdsTemplateStringInner,
10+
isSdsTemplateStringStart,
11+
} from '../../../src/language/generated/ast.js';
12+
13+
const services = createSafeDsServices(EmptyFileSystem).SafeDs;
14+
15+
describe('runConverter', () => {
16+
it('should remove backticks from IDs (package)', async () => {
17+
const code = `
18+
package \`foo\`.bar
19+
`;
20+
21+
const module = await getNodeOfType(services, code, isSdsModule);
22+
expect(module.name).toBe('foo.bar');
23+
});
24+
25+
it('should remove backticks from IDs (declaration)', async () => {
26+
const code = `
27+
class \`MyClass\`
28+
`;
29+
30+
const firstClass = await getNodeOfType(services, code, isSdsClass);
31+
expect(firstClass.name).toBe('MyClass');
32+
});
33+
34+
it('should remove delimiters from TEMPLATE_STRING_STARTs', async () => {
35+
const code = `
36+
pipeline myPipeline {
37+
"start{{ 1 }}inner{{ 2 }}end";
38+
}
39+
`;
40+
41+
const firstTemplateStringStart = await getNodeOfType(services, code, isSdsTemplateStringStart);
42+
expect(firstTemplateStringStart.value).toBe('start');
43+
});
44+
45+
it('should handle escape sequences in TEMPLATE_STRING_STARTs', async () => {
46+
const code = `
47+
pipeline myPipeline {
48+
"\\tstart{{ 1 }}inner{{ 2 }}end";
49+
}
50+
`;
51+
52+
const firstTemplateStringStart = await getNodeOfType(services, code, isSdsTemplateStringStart);
53+
expect(firstTemplateStringStart.value).toBe('\tstart');
54+
});
55+
56+
it('should remove delimiters from TEMPLATE_STRING_INNERs', async () => {
57+
const code = `
58+
pipeline myPipeline {
59+
"start{{ 1 }}inner{{ 2 }}end";
60+
}
61+
`;
62+
63+
const firstTemplateStringInner = await getNodeOfType(services, code, isSdsTemplateStringInner);
64+
expect(firstTemplateStringInner.value).toBe('inner');
65+
});
66+
67+
it('should handle escape sequences in TEMPLATE_STRING_INNERs', async () => {
68+
const code = `
69+
pipeline myPipeline {
70+
"start{{ 1 }}\\tinner{{ 2 }}end";
71+
}
72+
`;
73+
74+
const firstTemplateStringInner = await getNodeOfType(services, code, isSdsTemplateStringInner);
75+
expect(firstTemplateStringInner.value).toBe('\tinner');
76+
});
77+
78+
it('should remove delimiters from TEMPLATE_STRING_ENDs', async () => {
79+
const code = `
80+
pipeline myPipeline {
81+
"start{{ 1 }}inner{{ 2 }}end";
82+
}
83+
`;
84+
85+
const firstTemplateStringEnd = await getNodeOfType(services, code, isSdsTemplateStringEnd);
86+
expect(firstTemplateStringEnd.value).toBe('end');
87+
});
88+
89+
it('should handle escape sequences in TEMPLATE_STRING_ENDs', async () => {
90+
const code = `
91+
pipeline myPipeline {
92+
"start{{ 1 }}inner{{ 2 }}\\tend";
93+
}
94+
`;
95+
96+
const firstTemplateStringEnd = await getNodeOfType(services, code, isSdsTemplateStringEnd);
97+
expect(firstTemplateStringEnd.value).toBe('\tend');
98+
});
99+
});

tests/resources/validation/names/casing/annotations.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package tests.validation.names.casing
22

33
// $TEST$ no warning "Names of annotations should be UpperCamelCase."
44
annotation »AnnotationUppercase1«
5+
// $TEST$ no warning "Names of annotations should be UpperCamelCase."
6+
annotation »`AnnotationUppercase2`«
57
// $TEST$ warning "Names of annotations should be UpperCamelCase."
68
annotation »annotationLowercase«
79
// $TEST$ warning "Names of annotations should be UpperCamelCase."

tests/resources/validation/names/casing/attributes.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ class MyClass {
55
attr »AttributeUppercase«: Int
66
// $TEST$ no warning "Names of attributes should be lowerCamelCase."
77
attr »attributeLowercase1«: Int
8+
// $TEST$ no warning "Names of attributes should be lowerCamelCase."
9+
attr »`attributeLowercase2`«: Int
810
// $TEST$ warning "Names of attributes should be lowerCamelCase."
911
attr »_attributeUnderscore«: Int
1012
// $TEST$ warning "Names of attributes should be lowerCamelCase."

tests/resources/validation/names/casing/block lambda results.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ pipeline myPipeline1 {
66
yield »LambdaResultUppercase« = 1;
77
// $TEST$ no warning "Names of block lambda results should be lowerCamelCase."
88
yield »lambdaResultLowercase1« = 1;
9+
// $TEST$ no warning "Names of block lambda results should be lowerCamelCase."
10+
yield »`lambdaResultLowercase2`« = 1;
911
// $TEST$ warning "Names of block lambda results should be lowerCamelCase."
1012
yield »_lambdaResultUnderscore« = 1;
1113
// $TEST$ warning "Names of block lambda results should be lowerCamelCase."

tests/resources/validation/names/casing/classes.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package tests.validation.names.casing
22

33
// $TEST$ no warning "Names of classes should be UpperCamelCase."
44
class »ClassUppercase1«
5+
// $TEST$ no warning "Names of classes should be UpperCamelCase."
6+
class »`ClassUppercase2`«
57
// $TEST$ warning "Names of classes should be UpperCamelCase."
68
class »classLowercase«
79
// $TEST$ warning "Names of classes should be UpperCamelCase."

tests/resources/validation/names/casing/enum variants.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package tests.validation.names.casing
33
enum MyEnum {
44
// $TEST$ no warning "Names of enum variants should be UpperCamelCase."
55
»EnumVariantUppercase1«
6+
// $TEST$ no warning "Names of enum variants should be UpperCamelCase."
7+
»`EnumVariantUppercase2`«
68
// $TEST$ warning "Names of enum variants should be UpperCamelCase."
79
»enumVariantLowercase«
810
// $TEST$ warning "Names of enum variants should be UpperCamelCase."

tests/resources/validation/names/casing/enums.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package tests.validation.names.casing
22

33
// $TEST$ no warning "Names of enums should be UpperCamelCase."
44
enum »EnumUppercase1«
5+
// $TEST$ no warning "Names of enums should be UpperCamelCase."
6+
enum »`EnumUppercase2`«
57
// $TEST$ warning "Names of enums should be UpperCamelCase."
68
enum »enumLowercase«
79
// $TEST$ warning "Names of enums should be UpperCamelCase."

tests/resources/validation/names/casing/functions.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package tests.validation.names.casing
44
fun »FunctionUppercase«()
55
// $TEST$ no warning "Names of functions should be lowerCamelCase."
66
fun »functionLowercase1«()
7+
// $TEST$ no warning "Names of functions should be lowerCamelCase."
8+
fun »`functionLowercase2`«()
79
// $TEST$ warning "Names of functions should be lowerCamelCase."
810
fun »_functionUnderscore«()
911
// $TEST$ warning "Names of functions should be lowerCamelCase."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// $TEST$ no warning "All segments of the qualified name of a package should be lowerCamelCase."
2+
package »tests.validation.declarations.`lowercase1`«

tests/resources/validation/names/casing/parameters.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ fun myFunction1(
55
»ParameterUppercase«: Int,
66
// $TEST$ no warning "Names of parameters should be lowerCamelCase."
77
»parameterLowercase1«: Int,
8+
// $TEST$ no warning "Names of parameters should be lowerCamelCase."
9+
»`parameterLowercase2`«: Int,
810
// $TEST$ warning "Names of parameters should be lowerCamelCase."
911
»_parameterUnderscore«: Int,
1012
// $TEST$ warning "Names of parameters should be lowerCamelCase."

tests/resources/validation/names/casing/pipelines.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package tests.validation.names.casing
44
pipeline »PipelineUppercase« {}
55
// $TEST$ no warning "Names of pipelines should be lowerCamelCase."
66
pipeline »pipelineLowercase1« {}
7+
// $TEST$ no warning "Names of pipelines should be lowerCamelCase."
8+
pipeline »`pipelineLowercase2`« {}
79
// $TEST$ warning "Names of pipelines should be lowerCamelCase."
810
pipeline »_pipelineUnderscore« {}
911
// $TEST$ warning "Names of pipelines should be lowerCamelCase."

tests/resources/validation/names/casing/placeholders.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ pipeline myPipeline2 {
55
val »PlaceholderUppercase« = 1;
66
// $TEST$ no warning "Names of placeholders should be lowerCamelCase."
77
val »placeholderLowercase1« = 1;
8+
// $TEST$ no warning "Names of placeholders should be lowerCamelCase."
9+
val »`placeholderLowercase2`« = 1;
810
// $TEST$ warning "Names of placeholders should be lowerCamelCase."
911
val »_placeholderUnderscore« = 1;
1012
// $TEST$ warning "Names of placeholders should be lowerCamelCase."

tests/resources/validation/names/casing/results.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ fun myFunction2() -> (
55
»ResultUppercase«: Int,
66
// $TEST$ no warning "Names of results should be lowerCamelCase."
77
»resultLowercase1«: Int,
8+
// $TEST$ no warning "Names of results should be lowerCamelCase."
9+
»`resultLowercase2`«: Int,
810
// $TEST$ warning "Names of results should be lowerCamelCase."
911
»_resultUnderscore«: Int,
1012
// $TEST$ warning "Names of results should be lowerCamelCase."

tests/resources/validation/names/casing/schemas.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package tests.validation.names.casing
22

33
// $TEST$ no warning "Names of schemas should be UpperCamelCase."
44
schema »SchemaUppercase1« {}
5+
// $TEST$ no warning "Names of schemas should be UpperCamelCase."
6+
schema »`SchemaUppercase2`« {}
57
// $TEST$ warning "Names of schemas should be UpperCamelCase."
68
schema »schemaLowercase« {}
79
// $TEST$ warning "Names of schemas should be UpperCamelCase."

tests/resources/validation/names/casing/segments.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package tests.validation.names.casing
44
segment »SegmentUppercase«() {}
55
// $TEST$ no warning "Names of segments should be lowerCamelCase."
66
segment »segmentLowercase1«() {}
7+
// $TEST$ no warning "Names of segments should be lowerCamelCase."
8+
segment »`segmentLowercase2`«() {}
79
// $TEST$ warning "Names of segments should be lowerCamelCase."
810
segment »_segmentUnderscore«() {}
911
// $TEST$ warning "Names of segments should be lowerCamelCase."

tests/resources/validation/names/casing/type parameters.sdstest

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package tests.validation.names.casing
33
fun myFunction3<
44
// $TEST$ no warning "Names of type parameters should be UpperCamelCase."
55
»TypeParameterUppercase1«,
6+
// $TEST$ no warning "Names of type parameters should be UpperCamelCase."
7+
»`TypeParameterUppercase2`«,
68
// $TEST$ warning "Names of type parameters should be UpperCamelCase."
79
»typeParameterLowercase«,
810
// $TEST$ warning "Names of type parameters should be UpperCamelCase."

vitest.config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { defineConfig } from 'vitest/config';
33
export default defineConfig({
44
test: {
55
chaiConfig: {
6-
truncateThreshold: 0,
6+
truncateThreshold: 200,
77
},
88
coverage: {
99
provider: 'v8',

0 commit comments

Comments
 (0)