Skip to content

Commit

Permalink
Handle enums and other type definitios differently
Browse files Browse the repository at this point in the history
  • Loading branch information
daogrady committed Jan 30, 2024
1 parent 1abce09 commit 435f4dd
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 7 deletions.
10 changes: 9 additions & 1 deletion lib/components/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,15 @@ class Resolver {
if (isInlineEnumType(element, this.csn)) {
// element.parent is only set if the enum is attached to an entity's property.
// If it is missing then we are dealing with an inline parameter type of an action.
if (element.parent) {
// Edge case: element.parent is set, but no .name property is attached. This happens
// for inline enums inside types:
// ```cds
// type T {
// x : String enum { ... }; // no element.name for x
// }
// ```
// In that case, we currently resolve to the more general type (cds.String, here)
if (element.parent?.name) {
result.isInlineDeclaration = true
// we use the singular as the initial declaration of these enums takes place
// while defining the singular class. Which therefore uses the singular over the plural name.
Expand Down
13 changes: 10 additions & 3 deletions lib/visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,12 +446,19 @@ class Visitor {
case 'function':
this.#printAction(name, entity)
break
case 'type':
this.#printType(name, entity)
break
case 'aspect':
this.#printAspect(name, entity)
break
case 'type':
// types like inline definitions can be used very similarly to entities.
// They can be extended, contain inline enums, etc., so we treat them as entities.
// Enums seem to be the only actual "type".
if (entity.enum) {
this.#printType(name, entity)
} else {
this.#printEntity(name, entity)
}
break
case 'event':
this.#printEvent(name, entity)
break
Expand Down
File renamed without changes.
8 changes: 8 additions & 0 deletions test/unit/enum.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ describe('Enum Types', () => {
})

describe('Anonymous', () => {
describe('Within type Definition', () => {
// FIXME: this is for now the expected behaviour, but it should be possible to
// resolve the type to the actual enum definition
test('Coalesces to cds.String', () => {
astw.tree
})
})

describe('String Enum', () => {
test('Definition Present', async () =>
expect(astw.tree.find(n => n.name === 'InlineEnum_gender'
Expand Down
5 changes: 5 additions & 0 deletions test/unit/files/enums/model.cds
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ type Status : Integer enum {
unknown = 0;
cancelled = -1;
}
type SomeType {
inlineEnum: String enum {
foo; bar
}
}

entity InlineEnums {
gender: String enum {
Expand Down
6 changes: 3 additions & 3 deletions test/unit/type.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ describe('type Definitions', () => {
})

test('All Definitions Present', async () => {
expect(ast.tree.find(({name, nodeType}) => name === 'IntAlias' && nodeType === 'typeAliasDeclaration')).toBeTruthy()
expect(ast.tree.find(({name, nodeType}) => name === 'Points' && nodeType === 'typeAliasDeclaration')).toBeTruthy()
expect(ast.tree.find(({name, nodeType}) => name === 'Lines' && nodeType === 'typeAliasDeclaration')).toBeTruthy()
expect(ast.tree.find(({name, nodeType}) => name === 'IntAlias' && nodeType === 'classDeclaration')).toBeTruthy()
expect(ast.tree.find(({name, nodeType}) => name === 'Points' && nodeType === 'classDeclaration')).toBeTruthy()
expect(ast.tree.find(({name, nodeType}) => name === 'Lines' && nodeType === 'classDeclaration')).toBeTruthy()
})

test('Types as Properties', async () => {
Expand Down

0 comments on commit 435f4dd

Please sign in to comment.