@abapify/acds 0.0.0 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -1
- package/package.json +38 -3
package/README.md
CHANGED
|
@@ -1,3 +1,220 @@
|
|
|
1
1
|
# @abapify/acds
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**ABAP CDS source parser** — tokenizer, parser, and typed AST for DDL-based ABAP source types.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Parses `.acds` (ABAP CDS DDL) source code into a fully typed Abstract Syntax Tree. Built on [Chevrotain](https://chevrotain.io/) for fast, error-recovering parsing.
|
|
8
|
+
|
|
9
|
+
### Supported Definitions
|
|
10
|
+
|
|
11
|
+
| CDS Construct | AST Node | Example |
|
|
12
|
+
| ------------- | ---------------------- | ------------------------------------ |
|
|
13
|
+
| Table | `TableDefinition` | `define table ztable { ... }` |
|
|
14
|
+
| Structure | `StructureDefinition` | `define structure zstruct { ... }` |
|
|
15
|
+
| Simple type | `SimpleTypeDefinition` | `define type ztype : abap.char(10);` |
|
|
16
|
+
| Service | `ServiceDefinition` | `define service zsvc { ... }` |
|
|
17
|
+
| Metadata ext. | `MetadataExtension` | `annotate entity ZView with { ... }` |
|
|
18
|
+
|
|
19
|
+
### Parser Features
|
|
20
|
+
|
|
21
|
+
- **Error recovery** — returns partial AST + structured errors on invalid input
|
|
22
|
+
- **Full annotation support** — strings, enums, booleans, numbers, arrays, objects
|
|
23
|
+
- **Built-in types** — `abap.char(10)`, `abap.dec(11,2)`, `abap.dats`, etc.
|
|
24
|
+
- **Named types** — data element and qualified name references
|
|
25
|
+
- **Include directives** — `include <structure>` with optional suffix
|
|
26
|
+
- **Comments** — line (`//`) and block (`/* */`) comments are skipped
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bun add @abapify/acds
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { parse } from '@abapify/acds';
|
|
38
|
+
|
|
39
|
+
const result = parse(`
|
|
40
|
+
@AbapCatalog.tableCategory : #TRANSPARENT
|
|
41
|
+
@AbapCatalog.deliveryClass : #A
|
|
42
|
+
define table ztable {
|
|
43
|
+
key mandt : abap.clnt not null;
|
|
44
|
+
key field1 : abap.char(10) not null;
|
|
45
|
+
field2 : some_data_element;
|
|
46
|
+
}
|
|
47
|
+
`);
|
|
48
|
+
|
|
49
|
+
if (result.errors.length === 0) {
|
|
50
|
+
const table = result.ast.definitions[0]; // TableDefinition
|
|
51
|
+
console.log(table.kind); // 'table'
|
|
52
|
+
console.log(table.name); // 'ztable'
|
|
53
|
+
console.log(table.members); // [FieldDefinition, FieldDefinition, ...]
|
|
54
|
+
console.log(table.annotations); // [Annotation, Annotation]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## API
|
|
59
|
+
|
|
60
|
+
### `parse(source: string): ParseResult`
|
|
61
|
+
|
|
62
|
+
Parses a CDS source string through the full pipeline: tokenize → parse → visit.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
interface ParseResult {
|
|
66
|
+
/** The parsed AST (may be partial if there are errors) */
|
|
67
|
+
ast: CdsSourceFile;
|
|
68
|
+
/** Lexing and parsing errors */
|
|
69
|
+
errors: CdsParseError[];
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### AST Types
|
|
74
|
+
|
|
75
|
+
#### Root
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
interface CdsSourceFile {
|
|
79
|
+
definitions: CdsDefinition[];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type CdsDefinition =
|
|
83
|
+
| TableDefinition
|
|
84
|
+
| StructureDefinition
|
|
85
|
+
| SimpleTypeDefinition
|
|
86
|
+
| ServiceDefinition
|
|
87
|
+
| MetadataExtension
|
|
88
|
+
| RoleDefinition // Phase 2 placeholder
|
|
89
|
+
| ViewEntityDefinition; // Phase 3 placeholder
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Definitions
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
interface TableDefinition {
|
|
96
|
+
kind: 'table';
|
|
97
|
+
name: string;
|
|
98
|
+
annotations: Annotation[];
|
|
99
|
+
members: TableMember[]; // FieldDefinition | IncludeDirective
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
interface StructureDefinition {
|
|
103
|
+
kind: 'structure';
|
|
104
|
+
name: string;
|
|
105
|
+
annotations: Annotation[];
|
|
106
|
+
members: TableMember[];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface SimpleTypeDefinition {
|
|
110
|
+
kind: 'simpleType';
|
|
111
|
+
name: string;
|
|
112
|
+
annotations: Annotation[];
|
|
113
|
+
type: TypeRef;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
interface ServiceDefinition {
|
|
117
|
+
kind: 'service';
|
|
118
|
+
name: string;
|
|
119
|
+
annotations: Annotation[];
|
|
120
|
+
exposes: ExposeStatement[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
interface MetadataExtension {
|
|
124
|
+
kind: 'metadataExtension';
|
|
125
|
+
entity: string;
|
|
126
|
+
annotations: Annotation[];
|
|
127
|
+
elements: AnnotatedElement[];
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Fields & Types
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
interface FieldDefinition {
|
|
135
|
+
annotations: Annotation[];
|
|
136
|
+
name: string;
|
|
137
|
+
type: TypeRef;
|
|
138
|
+
isKey: boolean;
|
|
139
|
+
notNull: boolean;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
type TypeRef = BuiltinTypeRef | NamedTypeRef;
|
|
143
|
+
|
|
144
|
+
// abap.char(10), abap.dec(11,2)
|
|
145
|
+
interface BuiltinTypeRef {
|
|
146
|
+
kind: 'builtin';
|
|
147
|
+
name: string;
|
|
148
|
+
length?: number;
|
|
149
|
+
decimals?: number;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Data element or qualified name
|
|
153
|
+
interface NamedTypeRef {
|
|
154
|
+
kind: 'named';
|
|
155
|
+
name: string;
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### Annotations
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
interface Annotation {
|
|
163
|
+
key: string;
|
|
164
|
+
value: AnnotationValue;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
type AnnotationValue =
|
|
168
|
+
| { kind: 'string'; value: string }
|
|
169
|
+
| { kind: 'enum'; value: string } // #TRANSPARENT → 'TRANSPARENT'
|
|
170
|
+
| { kind: 'boolean'; value: boolean }
|
|
171
|
+
| { kind: 'number'; value: number }
|
|
172
|
+
| { kind: 'array'; items: AnnotationValue[] }
|
|
173
|
+
| { kind: 'object'; properties: AnnotationProperty[] };
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### Errors
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
interface CdsParseError {
|
|
180
|
+
message: string;
|
|
181
|
+
line: number;
|
|
182
|
+
column: number;
|
|
183
|
+
offset: number;
|
|
184
|
+
length: number;
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Architecture
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
Source string
|
|
192
|
+
→ CdsLexer (Chevrotain Lexer) tokens.ts
|
|
193
|
+
→ CdsParser (Chevrotain CstParser) parser.ts
|
|
194
|
+
→ CdsVisitor (CST → AST) visitor.ts
|
|
195
|
+
→ CdsSourceFile ast.ts
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
| Module | Responsibility |
|
|
199
|
+
| ------------ | ----------------------------------------------- |
|
|
200
|
+
| `tokens.ts` | Token definitions (keywords, symbols, literals) |
|
|
201
|
+
| `parser.ts` | Grammar rules (CST production) |
|
|
202
|
+
| `visitor.ts` | CST → typed AST transformation |
|
|
203
|
+
| `ast.ts` | AST node type definitions |
|
|
204
|
+
| `errors.ts` | Error normalization (lex + parse) |
|
|
205
|
+
| `index.ts` | `parse()` entry point + re-exports |
|
|
206
|
+
|
|
207
|
+
## Roadmap
|
|
208
|
+
|
|
209
|
+
- ✅ **DDL**: tables, structures, simple types, view entities, projection views, abstract/custom entities, services (SRVD), metadata extensions (DDLX), parameters, associations, compositions
|
|
210
|
+
- ✅ **DCL**: role definitions with grant-select + where clauses
|
|
211
|
+
- ✅ **Annotations**: full value grammar (strings, enums, booleans, numbers, arrays, objects, dotted keys)
|
|
212
|
+
- ✅ **Tooling**: AST walker helpers, semantic validators (`SemanticDiagnostic`), grammar coverage metadata
|
|
213
|
+
- 🔜 **Expression grammar** (structured `on`/`where` trees — currently opaque `{ source, tokens }`)
|
|
214
|
+
- 🔜 **Joins** (`inner join`, `left outer join …`), CASE/CAST, aggregates, GROUP BY, UNION
|
|
215
|
+
- 🔜 **`define aspect` (DRAS), `define hierarchy`, cache definitions (DTDC/DTSC), scalar functions (DSFD)**
|
|
216
|
+
- 🔜 **BDEF / behavior definitions** (owned by epic E10)
|
|
217
|
+
|
|
218
|
+
## Dependencies
|
|
219
|
+
|
|
220
|
+
- [`chevrotain`](https://chevrotain.io/) — Parser toolkit (lexer + CstParser + visitor)
|
package/package.json
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abapify/acds",
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
}
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.3.4",
|
|
7
|
+
"description": "ABAP CDS source parser — tokenizer, parser, and AST for all DDL-based ABAP source types",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"types": "./dist/index.d.mts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": "./dist/index.mjs",
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"chevrotain": "^11.0.0"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"abap",
|
|
23
|
+
"cds",
|
|
24
|
+
"parser",
|
|
25
|
+
"ddl",
|
|
26
|
+
"sap",
|
|
27
|
+
"adt"
|
|
28
|
+
],
|
|
29
|
+
"author": "abapify",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/abapify/adt-cli.git",
|
|
34
|
+
"directory": "packages/acds"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/abapify/adt-cli/tree/main/packages/acds#readme",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/abapify/adt-cli/issues"
|
|
39
|
+
}
|
|
40
|
+
}
|