diff --git a/language-configuration.json b/language-configuration.json index 2d0dd7986..8050f5581 100644 --- a/language-configuration.json +++ b/language-configuration.json @@ -7,7 +7,6 @@ ["(", ")"], ["{", "}"], ["[", "]"], - ["<", ">"], ["»", "«"] ], "autoClosingPairs": [ diff --git a/package-lock.json b/package-lock.json index 29fdb980d..07738bff9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "safe-ds", "version": "0.1.0", + "license": "MIT", "dependencies": { "chalk": "^5.3.0", "chevrotain": "^11.0.3", diff --git a/src/language/typing/safe-ds-type-computer.ts b/src/language/typing/safe-ds-type-computer.ts index f3ce50c76..cb854922a 100644 --- a/src/language/typing/safe-ds-type-computer.ts +++ b/src/language/typing/safe-ds-type-computer.ts @@ -88,9 +88,9 @@ export class SafeDsTypeComputer { private readonly coreClasses: SafeDsClasses; private readonly nodeMapper: SafeDsNodeMapper; - readonly typeCache: WorkspaceCache; + private readonly typeCache: WorkspaceCache; - constructor(readonly services: SafeDsServices) { + constructor(services: SafeDsServices) { this.astNodeLocator = services.workspace.AstNodeLocator; this.coreClasses = services.builtins.Classes; this.nodeMapper = services.helpers.NodeMapper; diff --git a/src/language/validation/other/expressions/references.ts b/src/language/validation/other/expressions/references.ts index d88b80f98..26f260d7a 100644 --- a/src/language/validation/other/expressions/references.ts +++ b/src/language/validation/other/expressions/references.ts @@ -19,7 +19,6 @@ export const referenceMustNotBeFunctionPointer = (node: SdsReference, accept: Va return; } - // let container: AstNode | undefined = node.$container; if (isSdsMemberAccess(container) && node.$containerProperty === 'member') { container = container.$container; diff --git a/src/language/validation/other/statements/assignments.ts b/src/language/validation/other/statements/assignments.ts index 1ca08db0a..88fc75a23 100644 --- a/src/language/validation/other/statements/assignments.ts +++ b/src/language/validation/other/statements/assignments.ts @@ -1,8 +1,24 @@ -import { isSdsPipeline, SdsYield } from '../../../generated/ast.js'; +import { isSdsPipeline, SdsAssignment, SdsYield } from '../../../generated/ast.js'; import { getContainerOfType, ValidationAcceptor } from 'langium'; +import { SafeDsServices } from '../../../safe-ds-module.js'; +import { assigneesOrEmpty } from '../../../helpers/nodeProperties.js'; +export const CODE_ASSIGMENT_NOTHING_ASSIGNED = 'assignment/nothing-assigned'; export const CODE_ASSIGMENT_YIELD_FORBIDDEN_IN_PIPELINE = 'assignment/yield-forbidden-in-pipeline'; +export const assignmentAssigneeMustGetValue = + (services: SafeDsServices) => + (node: SdsAssignment, accept: ValidationAcceptor): void => { + for (const assignee of assigneesOrEmpty(node)) { + if (!services.helpers.NodeMapper.assigneeToAssignedObjectOrUndefined(assignee)) { + accept('error', 'No value is assigned to this assignee.', { + node: assignee, + code: CODE_ASSIGMENT_NOTHING_ASSIGNED, + }); + } + } + }; + export const yieldMustNotBeUsedInPipeline = (node: SdsYield, accept: ValidationAcceptor): void => { const containingPipeline = getContainerOfType(node, isSdsPipeline); diff --git a/src/language/validation/safe-ds-validator.ts b/src/language/validation/safe-ds-validator.ts index 41e38f8c8..b4d527410 100644 --- a/src/language/validation/safe-ds-validator.ts +++ b/src/language/validation/safe-ds-validator.ts @@ -33,7 +33,7 @@ import { unionTypeShouldNotHaveASingularTypeArgument, } from './style.js'; import { templateStringMustHaveExpressionBetweenTwoStringParts } from './other/expressions/templateStrings.js'; -import { yieldMustNotBeUsedInPipeline } from './other/statements/assignments.js'; +import { assignmentAssigneeMustGetValue, yieldMustNotBeUsedInPipeline } from './other/statements/assignments.js'; import { attributeMustHaveTypeHint, parameterMustHaveTypeHint, resultMustHaveTypeHint } from './types.js'; import { moduleDeclarationsMustMatchFileKind, moduleWithDeclarationsMustStatePackage } from './other/modules.js'; import { typeParameterConstraintLeftOperandMustBeOwnTypeParameter } from './other/declarations/typeParameterConstraints.js'; @@ -87,7 +87,7 @@ export const registerValidationChecks = function (services: SafeDsServices) { assigneeAssignedResultShouldNotBeDeprecated(services), assigneeAssignedResultShouldNotBeExperimental(services), ], - SdsAssignment: [assignmentShouldHaveMoreThanWildcardsAsAssignees], + SdsAssignment: [assignmentAssigneeMustGetValue(services), assignmentShouldHaveMoreThanWildcardsAsAssignees], SdsAnnotation: [ annotationMustContainUniqueNames, annotationParameterListShouldNotBeEmpty, diff --git a/tests/resources/validation/other/statements/assignments/nothing assigned/main.sdstest b/tests/resources/validation/other/statements/assignments/nothing assigned/main.sdstest new file mode 100644 index 000000000..dcd48f85f --- /dev/null +++ b/tests/resources/validation/other/statements/assignments/nothing assigned/main.sdstest @@ -0,0 +1,83 @@ +package tests.validation.other.statements.assignments.nothingAssigned + +fun noResults() +fun oneResult() -> first: Int +fun twoResults() -> (first: Int, second: Int) + +segment mySegment() -> ( + r1: Any?, + r2: Any?, + r3: Any?, + r4: Any?, + r5: Any?, + r6: Any?, + r7: Any?, + r8: Any?, + r9: Any?, + r10: Any?, + r11: Any?, + r12: Any?, + r13: Any?, + r14: Any?, +) { + // $TEST$ error "No value is assigned to this assignee." + »_« = noResults(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »_«, »_« = oneResult(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »_«, »_«, »_« = twoResults(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »_«, »_« = 1; + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »_«, »_« = unresolved; + // $TEST$ error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »_«, »_« = unresolved(); + + // $TEST$ error "No value is assigned to this assignee." + »val a« = noResults(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »val b«, »val c« = oneResult(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »val d«, »val e«, »val f« = twoResults(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »val g«, »val h« = 1; + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »val i«, »val j« = unresolved; + // $TEST$ error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »val k«, »val l« = unresolved(); + + // $TEST$ error "No value is assigned to this assignee." + »yield r1« = noResults(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »yield r2«, »yield r3« = oneResult(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »yield r4«, »yield r5«, »yield r6« = twoResults(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »yield r7«, »yield r8« = 1; + // $TEST$ no error "No value is assigned to this assignee." + »yield r9« = oneResult(); + // $TEST$ no error "No value is assigned to this assignee." + »yield r10« = twoResults(); + // $TEST$ no error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »yield r11«, »yield r12« = unresolved; + // $TEST$ error "No value is assigned to this assignee." + // $TEST$ error "No value is assigned to this assignee." + »yield r13«, »yield r14« = unresolved(); +}