diff --git a/src/language/helpers/safe-ds-node-mapper.ts b/src/language/helpers/safe-ds-node-mapper.ts index 2ef2a0151..98cf7a8a2 100644 --- a/src/language/helpers/safe-ds-node-mapper.ts +++ b/src/language/helpers/safe-ds-node-mapper.ts @@ -29,15 +29,15 @@ import { SdsYield, } from '../generated/ast.js'; import { CallableType, StaticType } from '../typing/model.js'; -import { findLocalReferences, getContainerOfType, Stream, stream } from 'langium'; +import { EMPTY_STREAM, findLocalReferences, getContainerOfType, Stream } from 'langium'; import { getAbstractResults, getArguments, - isNamedArgument, - isNamedTypeArgument, getParameters, getTypeArguments, getTypeParameters, + isNamedArgument, + isNamedTypeArgument, } from './nodeProperties.js'; export class SafeDsNodeMapper { @@ -155,13 +155,13 @@ export class SafeDsNodeMapper { */ parameterToReferences(node: SdsParameter | undefined): Stream { if (!node) { - return stream(); + return EMPTY_STREAM; } const containingCallable = getContainerOfType(node, isSdsCallable); /* c8 ignore start */ if (!containingCallable) { - return stream(); + return EMPTY_STREAM; } /* c8 ignore stop */ @@ -175,13 +175,13 @@ export class SafeDsNodeMapper { */ placeholderToReferences(node: SdsPlaceholder | undefined): Stream { if (!node) { - return stream(); + return EMPTY_STREAM; } const containingBlock = getContainerOfType(node, isSdsBlock); /* c8 ignore start */ if (!containingBlock) { - return stream(); + return EMPTY_STREAM; } /* c8 ignore stop */ @@ -195,12 +195,12 @@ export class SafeDsNodeMapper { */ resultToYields(node: SdsResult | undefined): Stream { if (!node) { - return stream(); + return EMPTY_STREAM; } const containingSegment = getContainerOfType(node, isSdsSegment); if (!containingSegment) { - return stream(); + return EMPTY_STREAM; } return findLocalReferences(node, containingSegment) diff --git a/src/language/safe-ds-module.ts b/src/language/safe-ds-module.ts index 17c493b74..31912ff63 100644 --- a/src/language/safe-ds-module.ts +++ b/src/language/safe-ds-module.ts @@ -28,6 +28,7 @@ import { SafeDsTypeChecker } from './typing/safe-ds-type-checker.js'; import { SafeDsCoreTypes } from './typing/safe-ds-core-types.js'; import { SafeDsNodeKindProvider } from './lsp/safe-ds-node-kind-provider.js'; import { SafeDsDocumentSymbolProvider } from './lsp/safe-ds-document-symbol-provider.js'; +import { SafeDsDocumentBuilder } from './workspace/safe-ds-document-builder.js'; /** * Declaration of custom services - add your own service classes here. @@ -106,6 +107,7 @@ export const SafeDsSharedModule: Module new SafeDsNodeKindProvider(), }, workspace: { + DocumentBuilder: (services) => new SafeDsDocumentBuilder(services), WorkspaceManager: (services) => new SafeDsWorkspaceManager(services), }, }; diff --git a/src/language/typing/safe-ds-class-hierarchy.ts b/src/language/typing/safe-ds-class-hierarchy.ts index 479af0752..1bc6c7a87 100644 --- a/src/language/typing/safe-ds-class-hierarchy.ts +++ b/src/language/typing/safe-ds-class-hierarchy.ts @@ -1,7 +1,7 @@ import { SafeDsServices } from '../safe-ds-module.js'; import { SafeDsClasses } from '../builtins/safe-ds-classes.js'; import { SdsClass } from '../generated/ast.js'; -import { stream, Stream } from 'langium'; +import { EMPTY_STREAM, stream, Stream } from 'langium'; import { getParentTypes } from '../helpers/nodeProperties.js'; import { SafeDsTypeComputer } from './safe-ds-type-computer.js'; import { ClassType } from './model.js'; @@ -39,7 +39,7 @@ export class SafeDsClassHierarchy { */ streamSuperclasses(node: SdsClass | undefined): Stream { if (!node) { - return stream(); + return EMPTY_STREAM; } return stream(this.superclassesGenerator(node)); diff --git a/src/language/workspace/safe-ds-document-builder.ts b/src/language/workspace/safe-ds-document-builder.ts new file mode 100644 index 000000000..ddef9fb9e --- /dev/null +++ b/src/language/workspace/safe-ds-document-builder.ts @@ -0,0 +1,11 @@ +import { BuildOptions, DefaultDocumentBuilder } from 'langium'; + +export class SafeDsDocumentBuilder extends DefaultDocumentBuilder { + override updateBuildOptions: BuildOptions = { + validation: { + categories: ['built-in', 'fast'], + stopAfterLexingErrors: true, + stopAfterParsingErrors: true, + }, + }; +} diff --git a/tests/language/builtins/builtinFilesCorrectness.test.ts b/tests/language/builtins/builtinFilesCorrectness.test.ts index 6a9d59371..81e434905 100644 --- a/tests/language/builtins/builtinFilesCorrectness.test.ts +++ b/tests/language/builtins/builtinFilesCorrectness.test.ts @@ -8,14 +8,14 @@ import { URI } from 'langium'; import { locationToString } from '../../helpers/location.js'; import { AssertionError } from 'assert'; import { isEmpty } from '../../../src/helpers/collectionUtils.js'; +import { loadDocuments } from '../../helpers/testResources.js'; -const workspace = createSafeDsServices(NodeFileSystem).SafeDs.shared.workspace; +const services = createSafeDsServices(NodeFileSystem).SafeDs; const builtinFiles = listBuiltinFiles(); describe('builtin files', () => { beforeAll(async () => { - const documents = builtinFiles.map((uri) => workspace.LangiumDocuments.getOrCreateDocument(uri)); - await workspace.DocumentBuilder.build(documents, { validation: true }); + await loadDocuments(services, builtinFiles, { validation: true }); }); const testCases = builtinFiles.map((uri) => ({ @@ -23,7 +23,7 @@ describe('builtin files', () => { shortenedResourceName: uriToShortenedResourceName(uri, 'builtins'), })); it.each(testCases)('[$shortenedResourceName] should have no errors or warnings', async ({ uri }) => { - const document = workspace.LangiumDocuments.getOrCreateDocument(uri); + const document = services.shared.workspace.LangiumDocuments.getOrCreateDocument(uri); const errorsOrWarnings = document.diagnostics?.filter(