Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow schemas in pipeline files #1080

Merged
merged 1 commit into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import {
getQualifiedName,
getResults,
getTypeParameters,
isImplementedDeclaration,
isInternal,
isPrivate,
isStatic,
Expand All @@ -54,6 +53,7 @@ import { expandToStringLF } from 'langium/generate';
import { SafeDsClassHierarchy } from '../typing/safe-ds-class-hierarchy.js';
import { SafeDsClasses } from '../builtins/safe-ds-classes.js';
import { SafeDsPackageManager } from '../workspace/safe-ds-package-manager.js';
import { isInPipelineFile } from '../helpers/fileExtensions.js';

const INDENTATION = ' ';
const LIB = path.join('packages', 'safe-ds-lang', 'lib', 'resources');
Expand Down Expand Up @@ -695,7 +695,7 @@ export class SafeDsMarkdownGenerator {

const text = removeLinePrefix(cstNode.text, firstLineIndent);
const fileName = AstUtils.getDocument(node).uri.path.split('/').pop();
const kind = isImplementedDeclaration(node) ? 'Implementation' : 'Stub';
const kind = isInPipelineFile(node) ? 'Implementation' : 'Stub';

let result = `??? quote "${kind} code in \`${fileName}\`"\n\n`;
result += indent(`\`\`\`sds linenums="${startLine + 1}"\n${text}\n\`\`\``);
Expand Down
13 changes: 7 additions & 6 deletions packages/safe-ds-lang/src/language/helpers/nodeProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
isSdsPipeline,
isSdsPlaceholder,
isSdsQualifiedImport,
isSdsSchema,
isSdsSegment,
isSdsTypeArgumentList,
isSdsTypeParameter,
Expand Down Expand Up @@ -196,17 +197,17 @@ export namespace TypeParameter {
}

/**
* Checks whether the declaration has an implementation.
* Checks whether the declaration is valid in a pipeline file.
*/
export const isImplementedDeclaration = (declaration: SdsDeclaration): boolean => {
return isSdsPipeline(declaration) || isSdsSegment(declaration);
export const isValidPipelineDeclaration = (node: SdsDeclaration): boolean => {
return isSdsPipeline(node) || isSdsSchema(node) || isSdsSegment(node);
};

/**
* Checks whether the declaration is just a stub.
* Checks whether the declaration is valid in a stub file.
*/
export const isStubDeclaration = (declaration: SdsDeclaration): boolean => {
return !isSdsPipeline(declaration) && !isSdsSegment(declaration);
export const isValidStubDeclaration = (node: SdsDeclaration): boolean => {
return isSdsAnnotation(node) || isSdsClass(node) || isSdsEnum(node) || isSdsFunction(node) || isSdsSchema(node);
};

// -------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class SafeDsCompletionProvider extends DefaultCompletionProvider {
return true;
}

private illegalKeywordsInPipelineFile = new Set(['annotation', 'class', 'enum', 'fun', 'schema']);
private illegalKeywordsInPipelineFile = new Set(['annotation', 'class', 'enum', 'fun']);
private illegalKeywordsInStubFile = new Set(['pipeline', 'internal', 'private', 'segment']);

protected override filterKeyword(context: CompletionContext, keyword: Keyword): boolean {
Expand Down
8 changes: 4 additions & 4 deletions packages/safe-ds-lang/src/language/validation/names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ import {
getParameters,
getResults,
getTypeParameters,
isImplementedDeclaration,
isStatic,
isStubDeclaration,
isValidPipelineDeclaration,
isValidStubDeclaration,
streamBlockLambdaResults,
streamPlaceholders,
} from '../helpers/nodeProperties.js';
Expand Down Expand Up @@ -341,14 +341,14 @@ export const moduleMustContainUniqueNames = (node: SdsModule, accept: Validation
getModuleMembers(node),
(name) => `A declaration with name '${name}' exists already in this file.`,
accept,
isImplementedDeclaration,
isValidPipelineDeclaration,
);
} else if (isInStubFile(node)) {
namesMustBeUnique(
getModuleMembers(node),
(name) => `A declaration with name '${name}' exists already in this file.`,
accept,
isStubDeclaration,
isValidStubDeclaration,
);
} else if (isInDevFile(node)) {
namesMustBeUnique(
Expand Down
14 changes: 6 additions & 8 deletions packages/safe-ds-lang/src/language/validation/other/modules.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ValidationAcceptor } from 'langium';
import { isSdsDeclaration, SdsModule } from '../../generated/ast.js';
import { SdsModule } from '../../generated/ast.js';
import { isInPipelineFile, isInStubFile } from '../../helpers/fileExtensions.js';
import { getModuleMembers, isImplementedDeclaration, isStubDeclaration } from '../../helpers/nodeProperties.js';
import { getModuleMembers, isValidPipelineDeclaration, isValidStubDeclaration } from '../../helpers/nodeProperties.js';
import { BUILTINS_ROOT_PACKAGE } from '../../builtins/packageNames.js';

export const CODE_MODULE_FORBIDDEN_IN_PIPELINE_FILE = 'module/forbidden-in-pipeline-file';
Expand All @@ -10,11 +10,9 @@ export const CODE_MODULE_MISSING_PACKAGE = 'module/missing-package';
export const CODE_MODULE_PIPELINE_FILE_IN_BUILTIN_PACKAGE = 'module/pipeline-file-in-builtin-package';

export const moduleDeclarationsMustMatchFileKind = (node: SdsModule, accept: ValidationAcceptor): void => {
const declarations = node.members.filter(isSdsDeclaration);

if (isInPipelineFile(node)) {
for (const declaration of declarations) {
if (!isImplementedDeclaration(declaration)) {
for (const declaration of getModuleMembers(node)) {
if (!isValidPipelineDeclaration(declaration)) {
accept('error', 'A pipeline file must only declare pipelines and segments.', {
node: declaration,
property: 'name',
Expand All @@ -23,8 +21,8 @@ export const moduleDeclarationsMustMatchFileKind = (node: SdsModule, accept: Val
}
}
} else if (isInStubFile(node)) {
for (const declaration of declarations) {
if (!isStubDeclaration(declaration)) {
for (const declaration of getModuleMembers(node)) {
if (!isValidStubDeclaration(declaration)) {
accept('error', 'A stub file must not declare pipelines or segments.', {
node: declaration,
property: 'name',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('SafeDsCompletionProvider', async () => {
`,
uri: `file:///test1.sds`,
expectedLabels: {
shouldEqual: ['from', 'pipeline', 'internal', 'private', 'segment'],
shouldEqual: ['from', 'schema', 'pipeline', 'internal', 'private', 'segment'],
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fun »duplicateFunction«()
schema »UniqueSchema« {}
// $TEST$ no error r"A declaration with name '\w*' exists already in this file\."
schema »DuplicateSchema« {}
// $TEST$ no error r"A declaration with name '\w*' exists already in this file\."
// $TEST$ error r"A declaration with name '\w*' exists already in this file\."
schema »DuplicateSchema« {}


Expand All @@ -77,9 +77,9 @@ class »DuplicateDeclaration«
enum »DuplicateDeclaration«
// $TEST$ no error r"A declaration with name '\w*' exists already in this file\."
fun »DuplicateDeclaration«()
// $TEST$ no error r"A declaration with name '\w*' exists already in this file\."
schema »DuplicateDeclaration« {}
// $TEST$ error r"A declaration with name '\w*' exists already in this file\."
pipeline »DuplicateDeclaration« {}
// $TEST$ error r"A declaration with name '\w*' exists already in this file\."
schema »DuplicateDeclaration« {}
// $TEST$ error "A declaration with name 'DuplicateDeclaration' exists already in this file."
segment »DuplicateDeclaration«() {}
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ enum »MyEnum« {
}
// $TEST$ error "A pipeline file must only declare pipelines and segments."
fun »myFunction«()
// $TEST$ error "A pipeline file must only declare pipelines and segments."
schema »MySchema« {}

// $TEST$ no error "A pipeline file must only declare pipelines and segments."
pipeline »myPipeline« {}
// $TEST$ no error "A pipeline file must only declare pipelines and segments."
schema »MySchema« {}
// $TEST$ no error "A pipeline file must only declare pipelines and segments."
segment »mySegment«() {}
10 changes: 5 additions & 5 deletions packages/safe-ds-vscode/snippets/safe-ds-dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@
],
"description": "A method."
},
"Schema": {
"prefix": ["schema"],
"body": ["schema ${1:MySchema} {", " $0", "}"],
"description": "A schema."
},
"Pipeline": {
"prefix": ["pipeline"],
"body": ["pipeline ${1:myPipeline} {", " $0", "}"],
"description": "A pipeline."
},
"Schema": {
"prefix": ["schema"],
"body": ["schema ${1:MySchema} {", " $0", "}"],
"description": "A schema."
},
"Segment": {
"prefix": ["segment"],
"body": ["${1|internal ,private |}segment ${2:mySegment}($3) ${4:-> ($5)} ${6:where {$7\\}} {", " $0", "}"],
Expand Down
5 changes: 5 additions & 0 deletions packages/safe-ds-vscode/snippets/safe-ds.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
"body": ["pipeline ${1:myPipeline} {", " $0", "}"],
"description": "A pipeline."
},
"Schema": {
"prefix": ["schema"],
"body": ["schema ${1:MySchema} {", " $0", "}"],
"description": "A schema."
},
"Segment": {
"prefix": ["segment"],
"body": ["${1|internal ,private |}segment ${2:mySegment}($3) ${4:-> ($5)} ${6:where {$7\\}} {", " $0", "}"],
Expand Down
2 changes: 1 addition & 1 deletion packages/safe-ds-vscode/syntaxes/safe-ds.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

{
"name": "storage.type.safe-ds",
"match": "\\b(package|pipeline|segment|val)\\b"
"match": "\\b(package|pipeline|schema|segment|val)\\b"
},
{
"name": "storage.modifier.safe-ds",
Expand Down