@sap/cds-dk 10.1.2 → 10.2.1
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/CHANGELOG.md +54 -0
- package/bin/add.js +7 -2
- package/bin/bind.js +5 -6
- package/bin/bindings.js +35 -0
- package/bin/build.js +11 -6
- package/bin/compile/index.js +1 -0
- package/bin/completion/index.js +10 -448
- package/bin/completion/scripts/cds.fish +28 -19
- package/bin/completion/scripts/cds.ps1 +30 -29
- package/bin/completion/scripts/cds.sh +26 -23
- package/bin/completion/scripts/cds.zsh +26 -23
- package/bin/debug.js +3 -3
- package/bin/deploy/index.js +3 -3
- package/bin/deploy/to-hana/hana.js +6 -5
- package/bin/deploy/to-hana/hdiDeployUtil.js +25 -14
- package/bin/env.js +0 -1
- package/bin/eval.js +9 -5
- package/bin/export.js +6 -4
- package/bin/help/export.md +28 -4
- package/bin/import.js +6 -5
- package/bin/inspect.js +0 -1
- package/bin/login.js +28 -3
- package/bin/repl.js +82 -26
- package/bin/run.js +6 -7
- package/bin/serve.js +6 -7
- package/bin/up.js +10 -5
- package/bin/upgrade/steps/install.js +6 -6
- package/bin/version.js +1 -1
- package/bin/watch/index.js +1 -0
- package/bin/watch/vite-watch.js +12 -6
- package/lib/bind/shared.js +1 -1
- package/lib/build/index.js +11 -7
- package/lib/build/plugins/featureToggles.js +2 -2
- package/lib/build/plugins/hana/index.js +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/_helpers.tpl +7 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/api-rule.yaml +1 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/templates/service-binding.yaml +4 -4
- package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +13 -0
- package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +7 -1
- package/lib/build/plugins/java/index.js +5 -1
- package/lib/build/plugins/nodejs/index.js +5 -1
- package/lib/build/util.js +4 -5
- package/lib/env/schemas/cds-rc.js +5 -0
- package/lib/import/importapi.js +2 -3
- package/lib/init/constants.js +1 -1
- package/lib/init/index.js +9 -3
- package/lib/init/plugin.js +1 -1
- package/lib/init/projectReader.js +16 -12
- package/lib/init/registries/mta.js +0 -6
- package/lib/init/template/ai/index.js +4 -4
- package/lib/init/template/ams/files/extensionDeveloper.dcl +6 -0
- package/lib/init/template/ams/files/mta.yaml.hbs +6 -0
- package/lib/init/template/ams/files/sidecar.package.json.hbs +5 -0
- package/lib/init/template/ams/index.js +42 -40
- package/lib/init/template/app-frontend/files/mta.yaml.hbs +2 -0
- package/lib/init/template/app-frontend/files/ui5.yaml.hbs +0 -4
- package/lib/init/template/app-frontend/index.js +29 -24
- package/lib/init/template/application-logging/index.js +6 -6
- package/lib/init/template/approuter/files/values.yaml.hbs +0 -9
- package/lib/init/template/approuter/index.js +19 -13
- package/lib/init/template/attachments/index.js +3 -3
- package/lib/init/template/audit-logging/index.js +4 -4
- package/lib/init/template/cloud-logging/index.js +12 -6
- package/lib/init/template/completion/completionSetup.js +19 -6
- package/lib/init/template/connectivity/index.js +3 -3
- package/lib/init/template/data/as-csv.js +7 -4
- package/lib/init/template/data/as-json.js +77 -20
- package/lib/init/template/destination/index.js +12 -9
- package/lib/init/template/dynatrace/index.js +5 -5
- package/lib/init/template/enterprise-messaging/index.js +6 -6
- package/lib/init/template/enterprise-messaging-shared/index.js +4 -4
- package/lib/init/template/extensibility/index.js +2 -2
- package/lib/init/template/extension/index.js +26 -0
- package/lib/init/template/github-actions/index.js +3 -3
- package/lib/init/template/hana/files/package.json.hbs +3 -2
- package/lib/init/template/hana/index.js +5 -5
- package/lib/init/template/hana-serverless/index.js +3 -3
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +2 -0
- package/lib/init/template/html5-repo/files/ui5.yaml.hbs +0 -4
- package/lib/init/template/html5-repo/index.js +80 -40
- package/lib/init/template/http/index.js +1 -1
- package/lib/init/template/ias/index.js +7 -7
- package/lib/init/template/initial/files/.gitignore.hbs +1 -0
- package/lib/init/template/kafka/index.js +3 -3
- package/lib/init/template/kyma/index.js +7 -9
- package/lib/init/template/malware-scanner/index.js +3 -3
- package/lib/init/template/mta/index.js +6 -3
- package/lib/init/template/multitenancy/index.js +6 -7
- package/lib/init/template/notifications/index.js +2 -2
- package/lib/init/template/portal/index.js +16 -10
- package/lib/init/template/postgres/index.js +5 -5
- package/lib/init/template/react/files/index.html.hbs +1 -1
- package/lib/init/template/react/files/package.json.hbs +3 -2
- package/lib/init/template/react/files/src/{App.jsx.hbs → App.{{jsxExtension}}.hbs} +8 -2
- package/lib/init/template/react/files/src/{main.jsx → main.{{jsxExtension}}.hbs} +2 -2
- package/lib/init/template/react/files/{vite.config.js.hbs → vite.config.{{extension}}.hbs} +2 -3
- package/lib/init/template/react/index.js +22 -5
- package/lib/init/template/react/typescript/src/vite-env.d.ts +1 -0
- package/lib/init/template/react/typescript/tsconfig.json.hbs +16 -0
- package/lib/init/template/redis/index.js +2 -2
- package/lib/init/template/sample/files/app/index.html.hbs +18 -0
- package/lib/init/template/sample/index.js +1 -0
- package/lib/init/template/side-by-side-extensibility/index.js +6 -3
- package/lib/init/template/typescript/files/tsconfig.json +3 -1
- package/lib/init/template/vue/files/index.html.hbs +1 -1
- package/lib/init/template/vue/files/package.json.hbs +2 -1
- package/lib/init/template/vue/files/src/App.vue.hbs +8 -2
- package/lib/init/template/vue/files/{vite.config.js.hbs → vite.config.{{extension}}.hbs} +2 -3
- package/lib/init/template/vue/index.js +19 -5
- package/lib/init/template/vue/typescript/tsconfig.json +11 -0
- package/lib/init/template/workzone-standard/files/mta.yaml.hbs +2 -2
- package/lib/init/template/workzone-standard/index.js +29 -27
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +1 -1
- package/lib/init/template/xsuaa/files/values.yaml.hbs +1 -1
- package/lib/init/template/xsuaa/index.js +34 -22
- package/lib/mtx/auth_manager.js +8 -2
- package/lib/mtx/browser_login.js +181 -0
- package/lib/mtx/params.js +6 -0
- package/lib/mtx/push.js +7 -1
- package/lib/mtx/settings_manager.js +29 -4
- package/lib/util/cf.js +44 -8
- package/lib/util/fs.js +2 -2
- package/node_modules/@cap-js/asyncapi/README.md +4 -14
- package/node_modules/@cap-js/asyncapi/cds-plugin.js +12 -0
- package/node_modules/@cap-js/asyncapi/index.js +3 -2
- package/node_modules/@cap-js/asyncapi/lib/compile/components/messages/index.js +4 -2
- package/node_modules/@cap-js/asyncapi/lib/compile/components/schemas/definition.js +11 -1
- package/node_modules/@cap-js/asyncapi/lib/compile/components/schemas/utils.js +16 -0
- package/node_modules/@cap-js/asyncapi/lib/compile/utils.js +4 -3
- package/node_modules/@cap-js/asyncapi/lib/import/importAsyncAPI.js +34 -0
- package/node_modules/@cap-js/asyncapi/lib/import/index.js +18 -0
- package/node_modules/@cap-js/asyncapi/lib/import/message.js +9 -0
- package/node_modules/@cap-js/asyncapi/lib/import/parserContext.js +368 -0
- package/node_modules/@cap-js/asyncapi/lib/import/utils.js +85 -0
- package/node_modules/@cap-js/asyncapi/package.json +89 -1
- package/node_modules/@cap-js/db-service/CHANGELOG.md +10 -0
- package/node_modules/@cap-js/db-service/lib/cqn2pql.js +4 -0
- package/node_modules/@cap-js/db-service/lib/cqn2sql.js +3 -0
- package/node_modules/@cap-js/db-service/lib/cqn4sql.js +8 -23
- package/node_modules/@cap-js/db-service/lib/infer/index.js +20 -27
- package/node_modules/@cap-js/db-service/package.json +1 -1
- package/node_modules/@cap-js/openapi/cds-plugin.js +12 -0
- package/node_modules/@cap-js/openapi/index.js +3 -1
- package/node_modules/@cap-js/openapi/lib/compile/csdl2openapi.js +652 -413
- package/node_modules/@cap-js/openapi/lib/compile/diagram.js +16 -13
- package/node_modules/@cap-js/openapi/lib/compile/index.js +10 -7
- package/node_modules/@cap-js/openapi/lib/compile/property-util.js +51 -0
- package/{lib/import/openapi → node_modules/@cap-js/openapi/lib/import}/importOpenAPI.js +12 -9
- package/{lib/import/openapi → node_modules/@cap-js/openapi/lib/import}/index.js +4 -3
- package/node_modules/@cap-js/openapi/package.json +71 -3
- package/node_modules/@cap-js/sqlite/CHANGELOG.md +9 -0
- package/node_modules/@cap-js/sqlite/package.json +3 -3
- package/node_modules/@isaacs/fs-minipass/LICENSE +15 -0
- package/node_modules/@isaacs/fs-minipass/README.md +71 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.d.ts +118 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.js +430 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.js.map +1 -0
- package/node_modules/@isaacs/fs-minipass/dist/commonjs/package.json +3 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/index.d.ts +118 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/index.d.ts.map +1 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/index.js +420 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/index.js.map +1 -0
- package/node_modules/@isaacs/fs-minipass/dist/esm/package.json +3 -0
- package/node_modules/@isaacs/fs-minipass/package.json +72 -0
- package/node_modules/@sap/cds/CHANGELOG.md +62 -1
- package/node_modules/@sap/cds/_i18n/messages_ar.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_bg.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_cs.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_da.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_de.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_el.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_en.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_es.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_es_MX.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_fi.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_fr.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_he.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_hr.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_hu.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_it.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ja.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_kk.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ko.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ms.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_nl.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_no.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_pl.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_pt.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ro.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_ru.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_sh.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_sk.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_sl.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_sv.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_th.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_tr.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_uk.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_vi.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_zh_CN.properties +1 -0
- package/node_modules/@sap/cds/_i18n/messages_zh_TW.properties +1 -0
- package/node_modules/@sap/cds/app/index-client.js +164 -0
- package/node_modules/@sap/cds/app/index.css +598 -87
- package/node_modules/@sap/cds/app/index.html +54 -30
- package/node_modules/@sap/cds/app/index.js +311 -67
- package/node_modules/@sap/cds/app/table.html +226 -0
- package/node_modules/@sap/cds/app/table.js +302 -0
- package/node_modules/@sap/cds/bin/serve.js +3 -2
- package/node_modules/@sap/cds/eslint.config.mjs +2 -0
- package/node_modules/@sap/cds/lib/compile/cdsc.js +7 -0
- package/node_modules/@sap/cds/lib/compile/for/embeddings.js +27 -0
- package/node_modules/@sap/cds/lib/compile/load.js +2 -2
- package/node_modules/@sap/cds/lib/compile/minify.js +17 -4
- package/node_modules/@sap/cds/lib/compile/parse.js +3 -0
- package/node_modules/@sap/cds/lib/compile/resolve.js +16 -14
- package/node_modules/@sap/cds/lib/core/classes.js +1 -0
- package/node_modules/@sap/cds/lib/dbs/cds-deploy.js +4 -5
- package/node_modules/@sap/cds/lib/env/cds-env.js +132 -70
- package/node_modules/@sap/cds/lib/env/cds-requires/auth-strategies.js +62 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/databases.js +49 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/embeddings.js +8 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/index.js +27 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/messaging.js +82 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/platform.js +23 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/queues.js +34 -0
- package/node_modules/@sap/cds/lib/env/cds-requires/services.js +32 -0
- package/node_modules/@sap/cds/lib/env/defaults.js +9 -1
- package/node_modules/@sap/cds/lib/env/schemas/cds-package.js +0 -2
- package/node_modules/@sap/cds/lib/env/schemas/cds-rc.js +3 -3
- package/node_modules/@sap/cds/lib/env/schemas/index.js +4 -4
- package/node_modules/@sap/cds/lib/i18n/files.js +4 -4
- package/node_modules/@sap/cds/lib/i18n/locale.js +1 -1
- package/node_modules/@sap/cds/lib/index.js +9 -9
- package/node_modules/@sap/cds/lib/log/cds-log.js +3 -3
- package/node_modules/@sap/cds/lib/ql/SELECT.js +2 -0
- package/node_modules/@sap/cds/lib/ql/UPDATE.js +1 -1
- package/node_modules/@sap/cds/lib/ql/cds.ql-Query.js +4 -1
- package/node_modules/@sap/cds/lib/ql/core/@types/cqn.d.ts +146 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/exprs.d.ts +51 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/index.d.ts +29 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/package.json +7 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/ql/delete.d.ts +8 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/ql/insert.d.ts +19 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/ql/select.d.ts +24 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/ql/update.d.ts +10 -0
- package/node_modules/@sap/cds/lib/ql/core/@types/query.d.ts +18 -0
- package/node_modules/@sap/cds/lib/ql/core/cql/parser.min.js +1 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/index.js +69 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/cache.js +34 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/call-action.js +6 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/delete.js +8 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/insert.js +26 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/select.js +22 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/ql/update.js +26 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/query.js +85 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/xl/fluent.js +47 -0
- package/node_modules/@sap/cds/lib/ql/core/lib/xl/ttl.js +24 -0
- package/node_modules/@sap/cds/lib/ql/core/license +201 -0
- package/node_modules/@sap/cds/lib/ql/core/package.json +24 -0
- package/node_modules/@sap/cds/lib/ql/core/readme.md +99 -0
- package/node_modules/@sap/cds/lib/ql/core/upstream.json +5 -0
- package/node_modules/@sap/cds/lib/req/spawn.js +1 -1
- package/node_modules/@sap/cds/lib/srv/bindings.js +111 -115
- package/node_modules/@sap/cds/lib/srv/cds-connect.js +11 -10
- package/node_modules/@sap/cds/lib/srv/cds-serve.js +16 -7
- package/node_modules/@sap/cds/lib/srv/cds.Service.js +13 -7
- package/node_modules/@sap/cds/lib/srv/factory.js +8 -10
- package/node_modules/@sap/cds/lib/srv/middlewares/auth/ias-auth.js +35 -32
- package/node_modules/@sap/cds/lib/srv/middlewares/auth/jwt-auth.js +5 -1
- package/node_modules/@sap/cds/lib/srv/middlewares/auth/mocked-users.js +1 -1
- package/node_modules/@sap/cds/lib/srv/protocols/hcql.js +230 -79
- package/node_modules/@sap/cds/lib/srv/protocols/http.js +7 -3
- package/node_modules/@sap/cds/lib/srv/protocols/index.js +7 -2
- package/node_modules/@sap/cds/lib/srv/srv-dispatch.js +2 -2
- package/node_modules/@sap/cds/lib/utils/cds-utils.js +50 -0
- package/node_modules/@sap/cds/lib/utils/csv-reader.js +2 -2
- package/node_modules/@sap/cds/libx/_runtime/common/generic/assert.js +18 -27
- package/node_modules/@sap/cds/libx/_runtime/common/generic/crud.js +1 -1
- package/node_modules/@sap/cds/libx/_runtime/common/utils/rewriteAsterisks.js +1 -1
- package/node_modules/@sap/cds/libx/_runtime/fiori/lean-draft.js +121 -84
- package/node_modules/@sap/cds/libx/_runtime/messaging/common-utils/authorizedRequest.js +24 -1
- package/node_modules/@sap/cds/libx/_runtime/messaging/common-utils/connections.js +45 -39
- package/node_modules/@sap/cds/libx/_runtime/remote/Service.js +2 -2
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/client.js +3 -2
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/query.js +11 -6
- package/node_modules/@sap/cds/libx/odata/ODataAdapter.js +1 -1
- package/node_modules/@sap/cds/libx/odata/middleware/create.js +4 -0
- package/node_modules/@sap/cds/libx/odata/middleware/metadata.js +1 -1
- package/node_modules/@sap/cds/libx/odata/middleware/operation.js +3 -0
- package/node_modules/@sap/cds/libx/odata/middleware/parse.js +9 -0
- package/node_modules/@sap/cds/libx/odata/middleware/read.js +6 -0
- package/node_modules/@sap/cds/libx/odata/middleware/update.js +5 -1
- package/node_modules/@sap/cds/libx/odata/parse/afterburner.js +3 -3
- package/node_modules/@sap/cds/libx/odata/parse/multipartToJson.js +1 -1
- package/node_modules/@sap/cds/libx/odata/utils/ieee754.js +20 -0
- package/node_modules/@sap/cds/libx/queue/TaskRunner.js +22 -5
- package/node_modules/@sap/cds/libx/queue/api.js +1 -1
- package/node_modules/@sap/cds/libx/queue/index.js +3 -1
- package/node_modules/@sap/cds/libx/queue/processing.js +5 -0
- package/node_modules/@sap/cds/libx/rest/RestAdapter.js +1 -0
- package/node_modules/@sap/cds/package.json +2 -2
- package/node_modules/@sap/cds/server.js +1 -0
- package/node_modules/@sap/cds/srv/ucl-service.cds +1 -0
- package/node_modules/@sap/cds-compiler/CHANGELOG.md +83 -0
- package/node_modules/@sap/cds-compiler/bin/cdsse.js +1 -1
- package/node_modules/@sap/cds-compiler/doc/EffectiveCSN.md +3314 -0
- package/node_modules/@sap/cds-compiler/lib/api/main.js +9 -6
- package/node_modules/@sap/cds-compiler/lib/api/options.js +3 -3
- package/node_modules/@sap/cds-compiler/lib/{model → base}/csnUtils.js +5 -5
- package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +54 -6
- package/node_modules/@sap/cds-compiler/lib/base/optionProcessor.js +4 -4
- package/node_modules/@sap/cds-compiler/lib/{model → base}/sortViews.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/assocOutsideService.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/checkForTypes.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/checkPathsInStoredCalcElement.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/elements.js +37 -3
- package/node_modules/@sap/cds-compiler/lib/checks/enricher.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/existsInForbiddenPlaces.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/hasPersistedElements.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/manyExpand.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/manyNavigations.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/onConditions.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/parameters.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/queryNoDbArtifacts.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/selectItems.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/structuredAnnoExpressions.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/typeParameters.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/types.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/checks/validator.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/compiler/assert-consistency.js +20 -12
- package/node_modules/@sap/cds-compiler/lib/compiler/builtins.js +9 -4
- package/node_modules/@sap/cds-compiler/lib/compiler/checks.js +50 -0
- package/node_modules/@sap/cds-compiler/lib/compiler/define.js +303 -323
- package/node_modules/@sap/cds-compiler/lib/compiler/dictionaries.js +5 -0
- package/node_modules/@sap/cds-compiler/lib/compiler/extend.js +1015 -1177
- package/node_modules/@sap/cds-compiler/lib/compiler/generate.js +55 -42
- package/node_modules/@sap/cds-compiler/lib/compiler/populate.js +74 -45
- package/node_modules/@sap/cds-compiler/lib/compiler/propagator.js +1 -0
- package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +6 -4
- package/node_modules/@sap/cds-compiler/lib/compiler/shared.js +30 -49
- package/node_modules/@sap/cds-compiler/lib/compiler/utils.js +32 -18
- package/node_modules/@sap/cds-compiler/lib/edm/annotations/edmJson.js +3 -3
- package/node_modules/@sap/cds-compiler/lib/edm/annotations/genericTranslation.js +2 -2
- package/node_modules/@sap/cds-compiler/lib/edm/annotations/preprocessAnnotations.js +2 -3
- package/node_modules/@sap/cds-compiler/lib/edm/csn2edm.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/edm/edm.js +6 -7
- package/node_modules/@sap/cds-compiler/lib/edm/edmAnnoPreprocessor.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/edm/edmInboundChecks.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/edm/edmPreprocessor.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/edm/edmUtils.js +12 -7
- package/node_modules/@sap/cds-compiler/lib/gen/CdlGrammar.checksum +1 -1
- package/node_modules/@sap/cds-compiler/lib/gen/CdlParser.js +15 -15
- package/node_modules/@sap/cds-compiler/lib/gen/Dictionary.json +7 -0
- package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +30 -30
- package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +2 -1
- package/node_modules/@sap/cds-compiler/lib/main.js +4 -1
- package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +42 -15
- package/node_modules/@sap/cds-compiler/lib/render/DuplicateChecker.js +37 -11
- package/node_modules/@sap/cds-compiler/lib/render/manageConstraints.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/render/toCdl.js +11 -6
- package/node_modules/@sap/cds-compiler/lib/render/toRename.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/render/toSql.js +74 -24
- package/node_modules/@sap/cds-compiler/lib/render/utils/common.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/render/utils/operators.js +81 -0
- package/node_modules/@sap/cds-compiler/lib/render/utils/sql.js +17 -10
- package/node_modules/@sap/cds-compiler/lib/transform/db/assertUnique.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/associations.js +3 -4
- package/node_modules/@sap/cds-compiler/lib/transform/db/assocsToQueries/transformExists.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/backlinks.js +2 -2
- package/node_modules/@sap/cds-compiler/lib/transform/db/cdsPersistence.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/constraints.js +6 -5
- package/node_modules/@sap/cds-compiler/lib/transform/db/expansion.js +7 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/flattening.js +2 -2
- package/node_modules/@sap/cds-compiler/lib/{modelCompare/compare.js → transform/db/migration/diffModels.js} +5 -5
- package/node_modules/@sap/cds-compiler/lib/{modelCompare/utils/filter.js → transform/db/migration/filterDiff.js} +2 -2
- package/node_modules/@sap/cds-compiler/lib/transform/db/processSqlServices.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/rewriteCalculatedElements.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/temporal.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/views.js +2 -6
- package/node_modules/@sap/cds-compiler/lib/transform/draft/db.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/draft/odata.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/annotations.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/associations.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/flattening.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/main.js +3 -2
- package/node_modules/@sap/cds-compiler/lib/transform/effective/misc.js +2 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/queries.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/types.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/forOdata.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/forRelationalDB.js +9 -4
- package/node_modules/@sap/cds-compiler/lib/transform/localized.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/odata/adaptAnnotationRefs.js +5 -11
- package/node_modules/@sap/cds-compiler/lib/transform/odata/createForeignKeys.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/odata/flattening.js +4 -4
- package/node_modules/@sap/cds-compiler/lib/transform/odata/foreignKeyRefsInXprAnnos.js +5 -3
- package/node_modules/@sap/cds-compiler/lib/transform/odata/toFinalBaseType.js +29 -5
- package/node_modules/@sap/cds-compiler/lib/transform/odata/typesExposure.js +13 -3
- package/node_modules/@sap/cds-compiler/lib/transform/odata/utils.js +9 -0
- package/node_modules/@sap/cds-compiler/lib/transform/transformUtils.js +2 -2
- package/node_modules/@sap/cds-compiler/lib/transform/translateAssocsToJoins.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/tupleExpansion.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/universalCsn/coreComputed.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/universalCsn/universalCsnEnricher.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/universalCsn/utils.js +1 -1
- package/node_modules/@sap/cds-compiler/package.json +1 -1
- package/node_modules/@sap/cds-mtxs/CHANGELOG.md +55 -0
- package/node_modules/@sap/cds-mtxs/bin/cds-mtx-migrate.js +4 -6
- package/node_modules/@sap/cds-mtxs/bin/cds-mtx.js +5 -4
- package/node_modules/@sap/cds-mtxs/cds-plugin.js +38 -2
- package/node_modules/@sap/cds-mtxs/db/t0.cds +7 -0
- package/node_modules/@sap/cds-mtxs/lib/utils.js +129 -20
- package/node_modules/@sap/cds-mtxs/package.json +15 -14
- package/node_modules/@sap/cds-mtxs/srv/cf/abstract-provisioning-service.js +13 -12
- package/node_modules/@sap/cds-mtxs/srv/cf/saas-provisioning-service.cds +1 -0
- package/node_modules/@sap/cds-mtxs/srv/cf/sms-provisioning-service.cds +1 -0
- package/node_modules/@sap/cds-mtxs/srv/extensibility/compat/update.js +5 -2
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/config.js +1 -2
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/csv-allowlist.js +64 -0
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/index.js +4 -2
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/protected-namespace.js +67 -5
- package/node_modules/@sap/cds-mtxs/srv/extensibility-service.js +199 -19
- package/node_modules/@sap/cds-mtxs/srv/jobs-service.js +39 -15
- package/node_modules/@sap/cds-mtxs/srv/plugins/common.js +33 -12
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/ctnr-mgr-base.js +24 -6
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi-ctnr-mgr.js +3 -1
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi-native.js +752 -0
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/serverless.js +17 -20
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/srv-mgr-v2.js +511 -0
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/srv-mgr.js +11 -4
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/tms.js +8 -0
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana.js +58 -43
- package/node_modules/@sap/cds-mtxs/srv/worker/job-worker-pool.js +1 -1
- package/node_modules/@sap/cds-mtxs/srv/worker/job-worker.js +1 -1
- package/node_modules/body-parser/README.md +17 -13
- package/node_modules/body-parser/lib/read.js +74 -57
- package/node_modules/body-parser/lib/types/json.js +11 -11
- package/node_modules/body-parser/lib/types/urlencoded.js +5 -5
- package/node_modules/body-parser/lib/utils.js +0 -15
- package/node_modules/body-parser/package.json +7 -12
- package/node_modules/chownr/LICENSE.md +63 -0
- package/node_modules/chownr/README.md +3 -0
- package/node_modules/chownr/dist/commonjs/index.d.ts +3 -0
- package/node_modules/chownr/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/chownr/dist/commonjs/index.js +93 -0
- package/node_modules/chownr/dist/commonjs/index.js.map +1 -0
- package/node_modules/chownr/dist/commonjs/package.json +3 -0
- package/node_modules/chownr/dist/esm/index.d.ts +3 -0
- package/node_modules/chownr/dist/esm/index.d.ts.map +1 -0
- package/node_modules/chownr/dist/esm/index.js +85 -0
- package/node_modules/chownr/dist/esm/index.js.map +1 -0
- package/node_modules/chownr/dist/esm/package.json +3 -0
- package/node_modules/chownr/package.json +69 -0
- package/node_modules/content-disposition/README.md +105 -35
- package/node_modules/content-disposition/dist/index.d.ts +72 -0
- package/node_modules/content-disposition/dist/index.js +388 -0
- package/node_modules/content-disposition/dist/index.js.map +1 -0
- package/node_modules/content-disposition/package.json +31 -19
- package/node_modules/content-type/README.md +34 -57
- package/node_modules/content-type/package.json +35 -25
- package/node_modules/encodeurl/README.md +14 -0
- package/node_modules/encodeurl/index.js +5 -10
- package/node_modules/encodeurl/package.json +10 -6
- package/node_modules/express/Readme.md +15 -9
- package/node_modules/express/lib/application.js +2 -2
- package/node_modules/express/lib/request.js +32 -19
- package/node_modules/express/lib/response.js +27 -30
- package/node_modules/express/package.json +10 -10
- package/node_modules/handlebars/bin/handlebars +1 -1
- package/node_modules/handlebars/dist/amd/handlebars/base.js +2 -2
- package/node_modules/handlebars/dist/amd/handlebars/compiler/base.js +2 -59
- package/node_modules/handlebars/dist/amd/handlebars/compiler/code-gen.js +68 -5
- package/node_modules/handlebars/dist/amd/handlebars/compiler/compiler.js +160 -19
- package/node_modules/handlebars/dist/amd/handlebars/compiler/javascript-compiler.js +23 -7
- package/node_modules/handlebars/dist/amd/handlebars/compiler/node-types.js +12 -0
- package/node_modules/handlebars/dist/amd/handlebars/compiler/visitor.js +26 -7
- package/node_modules/handlebars/dist/amd/handlebars/compiler/whitespace-control.js +9 -4
- package/node_modules/handlebars/dist/amd/handlebars/exception.js +8 -4
- package/node_modules/handlebars/dist/amd/handlebars/helpers/each.js +40 -14
- package/node_modules/handlebars/dist/amd/handlebars/internal/proto-access.js +21 -1
- package/node_modules/handlebars/dist/amd/handlebars/runtime.js +24 -4
- package/node_modules/handlebars/dist/amd/handlebars/utils.js +4 -3
- package/node_modules/handlebars/dist/amd/precompiler.js +13 -7
- package/node_modules/handlebars/dist/cjs/handlebars/base.js +2 -2
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/base.js +1 -60
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/code-gen.js +64 -4
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js +161 -18
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js +23 -7
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/node-types.js +10 -0
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/visitor.js +29 -6
- package/node_modules/handlebars/dist/cjs/handlebars/compiler/whitespace-control.js +9 -4
- package/node_modules/handlebars/dist/cjs/handlebars/exception.js +8 -4
- package/node_modules/handlebars/dist/cjs/handlebars/helpers/each.js +40 -14
- package/node_modules/handlebars/dist/cjs/handlebars/internal/proto-access.js +21 -1
- package/node_modules/handlebars/dist/cjs/handlebars/runtime.js +24 -4
- package/node_modules/handlebars/dist/cjs/handlebars/utils.js +4 -3
- package/node_modules/handlebars/dist/cjs/precompiler.js +14 -6
- package/node_modules/handlebars/dist/handlebars.amd.js +401 -130
- package/node_modules/handlebars/dist/handlebars.amd.min.js +4 -4
- package/node_modules/handlebars/dist/handlebars.js +396 -125
- package/node_modules/handlebars/dist/handlebars.min.js +4 -4
- package/node_modules/handlebars/dist/handlebars.runtime.amd.js +100 -29
- package/node_modules/handlebars/dist/handlebars.runtime.amd.min.js +2 -2
- package/node_modules/handlebars/dist/handlebars.runtime.js +94 -23
- package/node_modules/handlebars/dist/handlebars.runtime.min.js +2 -2
- package/node_modules/handlebars/lib/handlebars/base.js +1 -1
- package/node_modules/handlebars/lib/handlebars/compiler/base.js +0 -67
- package/node_modules/handlebars/lib/handlebars/compiler/code-gen.js +65 -11
- package/node_modules/handlebars/lib/handlebars/compiler/compiler.js +164 -23
- package/node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js +23 -7
- package/node_modules/handlebars/lib/handlebars/compiler/node-types.js +24 -0
- package/node_modules/handlebars/lib/handlebars/compiler/visitor.js +29 -5
- package/node_modules/handlebars/lib/handlebars/compiler/whitespace-control.js +16 -5
- package/node_modules/handlebars/lib/handlebars/exception.js +7 -3
- package/node_modules/handlebars/lib/handlebars/helpers/each.js +39 -16
- package/node_modules/handlebars/lib/handlebars/internal/proto-access.js +22 -0
- package/node_modules/handlebars/lib/handlebars/runtime.js +36 -4
- package/node_modules/handlebars/lib/handlebars/utils.js +3 -2
- package/node_modules/handlebars/lib/precompiler.js +14 -5
- package/node_modules/handlebars/package.json +2 -2
- package/node_modules/handlebars/release-notes.md +20 -1
- package/node_modules/handlebars/types/index.d.ts +8 -0
- package/node_modules/hdb/cfg/VERSION +1 -1
- package/node_modules/hdb/lib/Client.js +6 -2
- package/node_modules/hdb/lib/protocol/ClientInfo.js +28 -15
- package/node_modules/hdb/lib/protocol/Connection.js +30 -3
- package/node_modules/hdb/lib/protocol/Writer.js +2 -2
- package/node_modules/hdb/lib/protocol/common/ConnectOption.js +2 -0
- package/node_modules/hdb/lib/protocol/common/ConnectOptionFlagSet1.js +18 -0
- package/node_modules/hdb/lib/protocol/common/ConnectOptionType.js +2 -0
- package/node_modules/hdb/lib/protocol/common/Constants.js +1 -0
- package/node_modules/hdb/lib/protocol/common/MessageType.js +3 -2
- package/node_modules/hdb/lib/protocol/common/PartKind.js +2 -1
- package/node_modules/hdb/lib/protocol/common/index.js +1 -0
- package/node_modules/hdb/lib/protocol/data/TextList.js +25 -17
- package/node_modules/hdb/lib/protocol/data/index.js +1 -0
- package/node_modules/hdb/lib/protocol/part/ConnectOptions.js +7 -0
- package/node_modules/hdb/lib/protocol/request/index.js +7 -0
- package/node_modules/hdb/package.json +1 -2
- package/node_modules/livereload-js/.github/workflows/main.yml +4 -4
- package/node_modules/livereload-js/README.md +3 -3
- package/node_modules/livereload-js/dist/livereload.js +839 -2742
- package/node_modules/livereload-js/dist/livereload.min.js +1 -1
- package/node_modules/livereload-js/package.json +11 -11
- package/node_modules/minipass/LICENSE.md +55 -0
- package/node_modules/minipass/README.md +825 -0
- package/node_modules/minipass/dist/commonjs/index.d.ts +545 -0
- package/node_modules/minipass/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/minipass/dist/commonjs/index.js +1038 -0
- package/node_modules/minipass/dist/commonjs/index.js.map +1 -0
- package/node_modules/minipass/dist/commonjs/package.json +3 -0
- package/node_modules/minipass/dist/esm/index.d.ts +545 -0
- package/node_modules/minipass/dist/esm/index.d.ts.map +1 -0
- package/node_modules/minipass/dist/esm/index.js +1020 -0
- package/node_modules/minipass/dist/esm/index.js.map +1 -0
- package/node_modules/minipass/dist/esm/package.json +3 -0
- package/node_modules/minipass/package.json +77 -0
- package/node_modules/minizlib/LICENSE +26 -0
- package/node_modules/minizlib/README.md +64 -0
- package/node_modules/minizlib/dist/commonjs/constants.d.ts +2 -0
- package/node_modules/minizlib/dist/commonjs/constants.d.ts.map +1 -0
- package/node_modules/minizlib/dist/commonjs/constants.js +123 -0
- package/node_modules/minizlib/dist/commonjs/constants.js.map +1 -0
- package/node_modules/minizlib/dist/commonjs/index.d.ts +99 -0
- package/node_modules/minizlib/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/minizlib/dist/commonjs/index.js +416 -0
- package/node_modules/minizlib/dist/commonjs/index.js.map +1 -0
- package/node_modules/minizlib/dist/commonjs/package.json +3 -0
- package/node_modules/minizlib/dist/esm/constants.d.ts +2 -0
- package/node_modules/minizlib/dist/esm/constants.d.ts.map +1 -0
- package/node_modules/minizlib/dist/esm/constants.js +117 -0
- package/node_modules/minizlib/dist/esm/constants.js.map +1 -0
- package/node_modules/minizlib/dist/esm/index.d.ts +99 -0
- package/node_modules/minizlib/dist/esm/index.d.ts.map +1 -0
- package/node_modules/minizlib/dist/esm/index.js +363 -0
- package/node_modules/minizlib/dist/esm/index.js.map +1 -0
- package/node_modules/minizlib/dist/esm/package.json +3 -0
- package/node_modules/minizlib/package.json +80 -0
- package/node_modules/on-finished/index.js +14 -2
- package/node_modules/on-finished/package.json +11 -7
- package/node_modules/qs/.editorconfig +1 -1
- package/node_modules/qs/.github/THREAT_MODEL.md +4 -2
- package/node_modules/qs/CHANGELOG.md +103 -14
- package/node_modules/qs/README.md +90 -9
- package/node_modules/qs/dist/qs.js +19 -19
- package/node_modules/qs/eslint.config.mjs +61 -50
- package/node_modules/qs/lib/formats.js +7 -2
- package/node_modules/qs/lib/parse.js +121 -12
- package/node_modules/qs/lib/stringify.js +9 -7
- package/node_modules/qs/lib/utils.js +158 -15
- package/node_modules/qs/package.json +8 -8
- package/node_modules/qs/test/parse.js +509 -2
- package/node_modules/qs/test/stringify.js +485 -33
- package/node_modules/qs/test/utils.js +245 -3
- package/node_modules/semver/classes/range.js +2 -2
- package/node_modules/semver/internal/constants.js +30 -0
- package/node_modules/semver/internal/trim-comparator-whitespace.js +438 -0
- package/node_modules/semver/package.json +1 -1
- package/node_modules/tar/LICENSE.md +55 -0
- package/node_modules/tar/README.md +1233 -0
- package/node_modules/tar/dist/commonjs/create.d.ts +3 -0
- package/node_modules/tar/dist/commonjs/create.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/create.js +82 -0
- package/node_modules/tar/dist/commonjs/create.js.map +1 -0
- package/node_modules/tar/dist/commonjs/cwd-error.d.ts +8 -0
- package/node_modules/tar/dist/commonjs/cwd-error.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/cwd-error.js +18 -0
- package/node_modules/tar/dist/commonjs/cwd-error.js.map +1 -0
- package/node_modules/tar/dist/commonjs/extract.d.ts +3 -0
- package/node_modules/tar/dist/commonjs/extract.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/extract.js +88 -0
- package/node_modules/tar/dist/commonjs/extract.js.map +1 -0
- package/node_modules/tar/dist/commonjs/get-write-flag.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/get-write-flag.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/get-write-flag.js +32 -0
- package/node_modules/tar/dist/commonjs/get-write-flag.js.map +1 -0
- package/node_modules/tar/dist/commonjs/header.d.ts +53 -0
- package/node_modules/tar/dist/commonjs/header.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/header.js +348 -0
- package/node_modules/tar/dist/commonjs/header.js.map +1 -0
- package/node_modules/tar/dist/commonjs/index.d.ts +20 -0
- package/node_modules/tar/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/index.js +64 -0
- package/node_modules/tar/dist/commonjs/index.js.map +1 -0
- package/node_modules/tar/dist/commonjs/index.min.js +4 -0
- package/node_modules/tar/dist/commonjs/index.min.js.map +7 -0
- package/node_modules/tar/dist/commonjs/large-numbers.d.ts +3 -0
- package/node_modules/tar/dist/commonjs/large-numbers.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/large-numbers.js +99 -0
- package/node_modules/tar/dist/commonjs/large-numbers.js.map +1 -0
- package/node_modules/tar/dist/commonjs/list.d.ts +7 -0
- package/node_modules/tar/dist/commonjs/list.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/list.js +153 -0
- package/node_modules/tar/dist/commonjs/list.js.map +1 -0
- package/node_modules/tar/dist/commonjs/make-command.d.ts +49 -0
- package/node_modules/tar/dist/commonjs/make-command.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/make-command.js +52 -0
- package/node_modules/tar/dist/commonjs/make-command.js.map +1 -0
- package/node_modules/tar/dist/commonjs/mkdir.d.ts +25 -0
- package/node_modules/tar/dist/commonjs/mkdir.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/mkdir.js +187 -0
- package/node_modules/tar/dist/commonjs/mkdir.js.map +1 -0
- package/node_modules/tar/dist/commonjs/mode-fix.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/mode-fix.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/mode-fix.js +29 -0
- package/node_modules/tar/dist/commonjs/mode-fix.js.map +1 -0
- package/node_modules/tar/dist/commonjs/normalize-unicode.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/normalize-unicode.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/normalize-unicode.js +38 -0
- package/node_modules/tar/dist/commonjs/normalize-unicode.js.map +1 -0
- package/node_modules/tar/dist/commonjs/normalize-windows-path.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/normalize-windows-path.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/normalize-windows-path.js +12 -0
- package/node_modules/tar/dist/commonjs/normalize-windows-path.js.map +1 -0
- package/node_modules/tar/dist/commonjs/options.d.ts +604 -0
- package/node_modules/tar/dist/commonjs/options.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/options.js +66 -0
- package/node_modules/tar/dist/commonjs/options.js.map +1 -0
- package/node_modules/tar/dist/commonjs/pack.d.ts +105 -0
- package/node_modules/tar/dist/commonjs/pack.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/pack.js +544 -0
- package/node_modules/tar/dist/commonjs/pack.js.map +1 -0
- package/node_modules/tar/dist/commonjs/package.json +3 -0
- package/node_modules/tar/dist/commonjs/parse.d.ts +92 -0
- package/node_modules/tar/dist/commonjs/parse.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/parse.js +655 -0
- package/node_modules/tar/dist/commonjs/parse.js.map +1 -0
- package/node_modules/tar/dist/commonjs/path-reservations.d.ts +11 -0
- package/node_modules/tar/dist/commonjs/path-reservations.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/path-reservations.js +170 -0
- package/node_modules/tar/dist/commonjs/path-reservations.js.map +1 -0
- package/node_modules/tar/dist/commonjs/pax.d.ts +26 -0
- package/node_modules/tar/dist/commonjs/pax.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/pax.js +182 -0
- package/node_modules/tar/dist/commonjs/pax.js.map +1 -0
- package/node_modules/tar/dist/commonjs/process-umask.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/process-umask.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/process-umask.js +7 -0
- package/node_modules/tar/dist/commonjs/process-umask.js.map +1 -0
- package/node_modules/tar/dist/commonjs/read-entry.d.ts +36 -0
- package/node_modules/tar/dist/commonjs/read-entry.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/read-entry.js +136 -0
- package/node_modules/tar/dist/commonjs/read-entry.js.map +1 -0
- package/node_modules/tar/dist/commonjs/replace.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/replace.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/replace.js +227 -0
- package/node_modules/tar/dist/commonjs/replace.js.map +1 -0
- package/node_modules/tar/dist/commonjs/strip-absolute-path.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/strip-absolute-path.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/strip-absolute-path.js +29 -0
- package/node_modules/tar/dist/commonjs/strip-absolute-path.js.map +1 -0
- package/node_modules/tar/dist/commonjs/strip-trailing-slashes.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/strip-trailing-slashes.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/strip-trailing-slashes.js +18 -0
- package/node_modules/tar/dist/commonjs/strip-trailing-slashes.js.map +1 -0
- package/node_modules/tar/dist/commonjs/symlink-error.d.ts +9 -0
- package/node_modules/tar/dist/commonjs/symlink-error.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/symlink-error.js +19 -0
- package/node_modules/tar/dist/commonjs/symlink-error.js.map +1 -0
- package/node_modules/tar/dist/commonjs/types.d.ts +16 -0
- package/node_modules/tar/dist/commonjs/types.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/types.js +70 -0
- package/node_modules/tar/dist/commonjs/types.js.map +1 -0
- package/node_modules/tar/dist/commonjs/unpack.d.ts +101 -0
- package/node_modules/tar/dist/commonjs/unpack.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/unpack.js +932 -0
- package/node_modules/tar/dist/commonjs/unpack.js.map +1 -0
- package/node_modules/tar/dist/commonjs/update.d.ts +2 -0
- package/node_modules/tar/dist/commonjs/update.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/update.js +33 -0
- package/node_modules/tar/dist/commonjs/update.js.map +1 -0
- package/node_modules/tar/dist/commonjs/warn-method.d.ts +24 -0
- package/node_modules/tar/dist/commonjs/warn-method.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/warn-method.js +31 -0
- package/node_modules/tar/dist/commonjs/warn-method.js.map +1 -0
- package/node_modules/tar/dist/commonjs/winchars.d.ts +3 -0
- package/node_modules/tar/dist/commonjs/winchars.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/winchars.js +14 -0
- package/node_modules/tar/dist/commonjs/winchars.js.map +1 -0
- package/node_modules/tar/dist/commonjs/write-entry.d.ts +129 -0
- package/node_modules/tar/dist/commonjs/write-entry.d.ts.map +1 -0
- package/node_modules/tar/dist/commonjs/write-entry.js +698 -0
- package/node_modules/tar/dist/commonjs/write-entry.js.map +1 -0
- package/node_modules/tar/dist/esm/create.d.ts +3 -0
- package/node_modules/tar/dist/esm/create.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/create.js +76 -0
- package/node_modules/tar/dist/esm/create.js.map +1 -0
- package/node_modules/tar/dist/esm/cwd-error.d.ts +8 -0
- package/node_modules/tar/dist/esm/cwd-error.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/cwd-error.js +14 -0
- package/node_modules/tar/dist/esm/cwd-error.js.map +1 -0
- package/node_modules/tar/dist/esm/extract.d.ts +3 -0
- package/node_modules/tar/dist/esm/extract.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/extract.js +49 -0
- package/node_modules/tar/dist/esm/extract.js.map +1 -0
- package/node_modules/tar/dist/esm/get-write-flag.d.ts +2 -0
- package/node_modules/tar/dist/esm/get-write-flag.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/get-write-flag.js +26 -0
- package/node_modules/tar/dist/esm/get-write-flag.js.map +1 -0
- package/node_modules/tar/dist/esm/header.d.ts +53 -0
- package/node_modules/tar/dist/esm/header.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/header.js +311 -0
- package/node_modules/tar/dist/esm/header.js.map +1 -0
- package/node_modules/tar/dist/esm/index.d.ts +20 -0
- package/node_modules/tar/dist/esm/index.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/index.js +20 -0
- package/node_modules/tar/dist/esm/index.js.map +1 -0
- package/node_modules/tar/dist/esm/index.min.js +4 -0
- package/node_modules/tar/dist/esm/index.min.js.map +7 -0
- package/node_modules/tar/dist/esm/large-numbers.d.ts +3 -0
- package/node_modules/tar/dist/esm/large-numbers.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/large-numbers.js +94 -0
- package/node_modules/tar/dist/esm/large-numbers.js.map +1 -0
- package/node_modules/tar/dist/esm/list.d.ts +7 -0
- package/node_modules/tar/dist/esm/list.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/list.js +113 -0
- package/node_modules/tar/dist/esm/list.js.map +1 -0
- package/node_modules/tar/dist/esm/make-command.d.ts +49 -0
- package/node_modules/tar/dist/esm/make-command.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/make-command.js +48 -0
- package/node_modules/tar/dist/esm/make-command.js.map +1 -0
- package/node_modules/tar/dist/esm/mkdir.d.ts +25 -0
- package/node_modules/tar/dist/esm/mkdir.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/mkdir.js +179 -0
- package/node_modules/tar/dist/esm/mkdir.js.map +1 -0
- package/node_modules/tar/dist/esm/mode-fix.d.ts +2 -0
- package/node_modules/tar/dist/esm/mode-fix.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/mode-fix.js +25 -0
- package/node_modules/tar/dist/esm/mode-fix.js.map +1 -0
- package/node_modules/tar/dist/esm/normalize-unicode.d.ts +2 -0
- package/node_modules/tar/dist/esm/normalize-unicode.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/normalize-unicode.js +34 -0
- package/node_modules/tar/dist/esm/normalize-unicode.js.map +1 -0
- package/node_modules/tar/dist/esm/normalize-windows-path.d.ts +2 -0
- package/node_modules/tar/dist/esm/normalize-windows-path.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/normalize-windows-path.js +9 -0
- package/node_modules/tar/dist/esm/normalize-windows-path.js.map +1 -0
- package/node_modules/tar/dist/esm/options.d.ts +604 -0
- package/node_modules/tar/dist/esm/options.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/options.js +54 -0
- package/node_modules/tar/dist/esm/options.js.map +1 -0
- package/node_modules/tar/dist/esm/pack.d.ts +105 -0
- package/node_modules/tar/dist/esm/pack.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/pack.js +502 -0
- package/node_modules/tar/dist/esm/pack.js.map +1 -0
- package/node_modules/tar/dist/esm/package.json +3 -0
- package/node_modules/tar/dist/esm/parse.d.ts +92 -0
- package/node_modules/tar/dist/esm/parse.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/parse.js +651 -0
- package/node_modules/tar/dist/esm/parse.js.map +1 -0
- package/node_modules/tar/dist/esm/path-reservations.d.ts +11 -0
- package/node_modules/tar/dist/esm/path-reservations.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/path-reservations.js +166 -0
- package/node_modules/tar/dist/esm/path-reservations.js.map +1 -0
- package/node_modules/tar/dist/esm/pax.d.ts +26 -0
- package/node_modules/tar/dist/esm/pax.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/pax.js +178 -0
- package/node_modules/tar/dist/esm/pax.js.map +1 -0
- package/node_modules/tar/dist/esm/process-umask.d.ts +2 -0
- package/node_modules/tar/dist/esm/process-umask.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/process-umask.js +3 -0
- package/node_modules/tar/dist/esm/process-umask.js.map +1 -0
- package/node_modules/tar/dist/esm/read-entry.d.ts +36 -0
- package/node_modules/tar/dist/esm/read-entry.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/read-entry.js +132 -0
- package/node_modules/tar/dist/esm/read-entry.js.map +1 -0
- package/node_modules/tar/dist/esm/replace.d.ts +2 -0
- package/node_modules/tar/dist/esm/replace.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/replace.js +221 -0
- package/node_modules/tar/dist/esm/replace.js.map +1 -0
- package/node_modules/tar/dist/esm/strip-absolute-path.d.ts +2 -0
- package/node_modules/tar/dist/esm/strip-absolute-path.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/strip-absolute-path.js +25 -0
- package/node_modules/tar/dist/esm/strip-absolute-path.js.map +1 -0
- package/node_modules/tar/dist/esm/strip-trailing-slashes.d.ts +2 -0
- package/node_modules/tar/dist/esm/strip-trailing-slashes.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/strip-trailing-slashes.js +14 -0
- package/node_modules/tar/dist/esm/strip-trailing-slashes.js.map +1 -0
- package/node_modules/tar/dist/esm/symlink-error.d.ts +9 -0
- package/node_modules/tar/dist/esm/symlink-error.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/symlink-error.js +15 -0
- package/node_modules/tar/dist/esm/symlink-error.js.map +1 -0
- package/node_modules/tar/dist/esm/types.d.ts +16 -0
- package/node_modules/tar/dist/esm/types.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/types.js +65 -0
- package/node_modules/tar/dist/esm/types.js.map +1 -0
- package/node_modules/tar/dist/esm/unpack.d.ts +101 -0
- package/node_modules/tar/dist/esm/unpack.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/unpack.js +891 -0
- package/node_modules/tar/dist/esm/unpack.js.map +1 -0
- package/node_modules/tar/dist/esm/update.d.ts +2 -0
- package/node_modules/tar/dist/esm/update.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/update.js +30 -0
- package/node_modules/tar/dist/esm/update.js.map +1 -0
- package/node_modules/tar/dist/esm/warn-method.d.ts +24 -0
- package/node_modules/tar/dist/esm/warn-method.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/warn-method.js +27 -0
- package/node_modules/tar/dist/esm/warn-method.js.map +1 -0
- package/node_modules/tar/dist/esm/winchars.d.ts +3 -0
- package/node_modules/tar/dist/esm/winchars.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/winchars.js +9 -0
- package/node_modules/tar/dist/esm/winchars.js.map +1 -0
- package/node_modules/tar/dist/esm/write-entry.d.ts +129 -0
- package/node_modules/tar/dist/esm/write-entry.d.ts.map +1 -0
- package/node_modules/tar/dist/esm/write-entry.js +656 -0
- package/node_modules/tar/dist/esm/write-entry.js.map +1 -0
- package/node_modules/tar/package.json +298 -0
- package/node_modules/ws/README.md +21 -29
- package/node_modules/ws/lib/buffer-util.js +13 -2
- package/node_modules/ws/lib/sender.js +4 -1
- package/node_modules/ws/lib/websocket.js +25 -6
- package/node_modules/ws/package.json +1 -1
- package/node_modules/yallist/LICENSE.md +63 -0
- package/node_modules/yallist/README.md +205 -0
- package/node_modules/yallist/dist/commonjs/index.d.ts +39 -0
- package/node_modules/yallist/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/yallist/dist/commonjs/index.js +384 -0
- package/node_modules/yallist/dist/commonjs/index.js.map +1 -0
- package/node_modules/yallist/dist/commonjs/package.json +3 -0
- package/node_modules/yallist/dist/esm/index.d.ts +39 -0
- package/node_modules/yallist/dist/esm/index.d.ts.map +1 -0
- package/node_modules/yallist/dist/esm/index.js +379 -0
- package/node_modules/yallist/dist/esm/index.js.map +1 -0
- package/node_modules/yallist/dist/esm/package.json +3 -0
- package/node_modules/yallist/package.json +68 -0
- package/package.json +7 -1
- package/bin/completion/templates/cds-tmpl.fish +0 -65
- package/bin/completion/templates/cds-tmpl.ps1 +0 -217
- package/bin/completion/templates/cds-tmpl.sh +0 -93
- package/bin/completion/templates/cds-tmpl.zsh +0 -74
- package/node_modules/@cap-js/db-service/lib/recursion-guard.js +0 -40
- package/node_modules/@sap/cds/lib/env/cds-requires.js +0 -327
- package/node_modules/@sap/cds-mtxs/srv/bootstrap.cds +0 -2
- package/node_modules/@sap/cds-mtxs/srv/bootstrap.js +0 -33
- package/node_modules/body-parser/node_modules/content-type/LICENSE +0 -22
- package/node_modules/body-parser/node_modules/content-type/README.md +0 -71
- package/node_modules/body-parser/node_modules/content-type/package.json +0 -52
- package/node_modules/content-disposition/index.js +0 -536
- package/node_modules/content-type/HISTORY.md +0 -29
- package/node_modules/content-type/index.js +0 -225
- package/node_modules/negotiator/node_modules/content-type/LICENSE +0 -22
- package/node_modules/negotiator/node_modules/content-type/README.md +0 -71
- package/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +0 -46
- package/node_modules/negotiator/node_modules/content-type/dist/index.js +0 -176
- package/node_modules/negotiator/node_modules/content-type/dist/index.js.map +0 -1
- package/node_modules/negotiator/node_modules/content-type/package.json +0 -52
- package/node_modules/on-finished/HISTORY.md +0 -98
- package/node_modules/type-is/node_modules/content-type/LICENSE +0 -22
- package/node_modules/type-is/node_modules/content-type/README.md +0 -71
- package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +0 -46
- package/node_modules/type-is/node_modules/content-type/dist/index.js +0 -176
- package/node_modules/type-is/node_modules/content-type/dist/index.js.map +0 -1
- package/node_modules/type-is/node_modules/content-type/package.json +0 -52
- /package/lib/init/template/vue/files/src/{main.js → main.{{extension}}.hbs} +0 -0
- /package/{lib/import/openapi → node_modules/@cap-js/openapi/lib/import}/utilities.js +0 -0
- /package/node_modules/{body-parser/node_modules/content-type → content-type}/dist/index.d.ts +0 -0
- /package/node_modules/{body-parser/node_modules/content-type → content-type}/dist/index.js +0 -0
- /package/node_modules/{body-parser/node_modules/content-type → content-type}/dist/index.js.map +0 -0
|
@@ -1,11 +1,51 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Provide functions for extensions and includes
|
|
2
|
+
|
|
3
|
+
// The main functions are the following, the first three are called on-demand in
|
|
4
|
+
// the "origin chain loop", i.e. in dependency order:
|
|
5
|
+
//
|
|
6
|
+
// extendArtifactBefore(), called at the start of the loop body:
|
|
7
|
+
// - traverses collected extensions for the given artifact, and for each property,
|
|
8
|
+
// select one (or sort them, e.g. for `includes`) if multiple extensions exist
|
|
9
|
+
// - _also called_ by main function of this file for all user-defined main artifacts,
|
|
10
|
+
// because we need some annotations rather early → the "origin" is not necessarily
|
|
11
|
+
// processed → this fn can't inspect the "origin" or derived props of includes
|
|
12
|
+
//
|
|
13
|
+
// … in between: populateGeneratedEntity(), resolveInclude(), populateArtifact()
|
|
14
|
+
//
|
|
15
|
+
// extendArtifactAdd(), called in the middle of the loop body:
|
|
16
|
+
// - add elements, enums and actions to artifact via includes and/or extension
|
|
17
|
+
//
|
|
18
|
+
// … in between: set _effectiveType, mergeSpecifiedElementsOrEnum(), generateForEntity()
|
|
19
|
+
//
|
|
20
|
+
// extendArtifactAfter(), called at the end of the loop body:
|
|
21
|
+
// - pushes down member extensions to members
|
|
22
|
+
// - handles type property extensions (TODO: move to extendArtifactAdd)
|
|
23
|
+
//
|
|
24
|
+
// createRemainingAnnotateStatements(), called near end of compilation
|
|
25
|
+
// - creates `annotate` statements for non-applied extensions
|
|
26
|
+
|
|
27
|
+
// Sections in this file: -------------------------------------------------------
|
|
28
|
+
// - Pushdown and transform extensions
|
|
29
|
+
// - Sort sources, select/sort extension
|
|
30
|
+
// - Array annotations with `...`, same anno values
|
|
31
|
+
// - Special properties: query clauses, type properties
|
|
32
|
+
// - Add new members
|
|
33
|
+
// - Create “super” ANNOTATE statements
|
|
34
|
+
// - TODO TMP: initMembers()
|
|
35
|
+
// - TODO TMP: includes
|
|
36
|
+
// - Foreign key extensions (currently postponed)
|
|
37
|
+
// - Utility functions
|
|
2
38
|
|
|
3
39
|
'use strict';
|
|
4
40
|
|
|
5
41
|
const { weakRefLocation } = require('../base/location');
|
|
6
|
-
const {
|
|
7
|
-
|
|
8
|
-
|
|
42
|
+
const {
|
|
43
|
+
dictAdd,
|
|
44
|
+
pushToDict,
|
|
45
|
+
dictNonEmpty,
|
|
46
|
+
dictFirst,
|
|
47
|
+
} = require('./dictionaries');
|
|
48
|
+
const { kindProperties } = require('./base');
|
|
9
49
|
const {
|
|
10
50
|
setLink,
|
|
11
51
|
setArtifactLink,
|
|
@@ -13,9 +53,8 @@ const {
|
|
|
13
53
|
setExpandStatus,
|
|
14
54
|
linkToOrigin,
|
|
15
55
|
initItemsLinks,
|
|
16
|
-
|
|
56
|
+
outerArtifact,
|
|
17
57
|
createAndLinkCalcDepElement,
|
|
18
|
-
initExprAnnoBlock,
|
|
19
58
|
initBoundSelfParam,
|
|
20
59
|
dependsOnSilent,
|
|
21
60
|
hasSecurityAnno,
|
|
@@ -26,13 +65,12 @@ const {
|
|
|
26
65
|
forEachDefinition,
|
|
27
66
|
forEachMember,
|
|
28
67
|
forEachGeneric,
|
|
29
|
-
isDirectComposition,
|
|
30
|
-
targetCantBeAspect,
|
|
31
68
|
} = require('./utils');
|
|
32
69
|
const layers = require('./moduleLayers');
|
|
33
70
|
const { CompilerAssertion } = require('../base/error');
|
|
34
71
|
const { Location } = require('../base/location');
|
|
35
72
|
const { typeParameters } = require('./builtins');
|
|
73
|
+
const { XsnArtifact, XsnName } = require('./xsn-model');
|
|
36
74
|
|
|
37
75
|
const $location = Symbol.for( 'cds.$location' );
|
|
38
76
|
const $inferred = Symbol.for( 'cds.$inferred' ); // TODO: no $inferred yet?
|
|
@@ -53,10 +91,6 @@ const draftBoundActions = [
|
|
|
53
91
|
'draftEdit',
|
|
54
92
|
];
|
|
55
93
|
|
|
56
|
-
function canBeDraftMember( name, parent, draftMembers ) {
|
|
57
|
-
return parent?.kind === 'entity' && parent._service && draftMembers.includes( name );
|
|
58
|
-
}
|
|
59
|
-
|
|
60
94
|
function extend( model ) {
|
|
61
95
|
// Get simplified "resolve" functionality and the message function:
|
|
62
96
|
const {
|
|
@@ -68,7 +102,6 @@ function extend( model ) {
|
|
|
68
102
|
resolveTypeArgumentsUnchecked,
|
|
69
103
|
resolveDefinitionName,
|
|
70
104
|
attachAndEmitValidNames,
|
|
71
|
-
checkRedefinition,
|
|
72
105
|
} = model.$functions;
|
|
73
106
|
|
|
74
107
|
Object.assign( model.$functions, {
|
|
@@ -78,117 +111,15 @@ function extend( model ) {
|
|
|
78
111
|
extendArtifactAdd,
|
|
79
112
|
extendForeignKeys,
|
|
80
113
|
withLocalizedData,
|
|
81
|
-
applyIncludes, // TODO: re-check
|
|
82
114
|
} );
|
|
83
115
|
|
|
84
|
-
const includeCollisions = [];
|
|
85
|
-
|
|
86
|
-
forEachGeneric( model, 'definitions', tagCompositionTargets );
|
|
87
|
-
dictForEach( model.$collectedExtensions, e => e._extensions.forEach( tagCompositionTargets ) );
|
|
88
|
-
// remark: tagging on extensions works _before_ running extendArtifactBefore() on each artifact
|
|
89
116
|
sortModelSources();
|
|
90
|
-
|
|
91
117
|
// Set annotations on user-provided artifacts, but they are not propagated yet!
|
|
92
|
-
// Use them in the main compiler phase (and before) with extra care:
|
|
93
118
|
forEachDefinition( model, extendArtifactBefore );
|
|
94
119
|
return;
|
|
95
120
|
|
|
96
|
-
// Tag composition targets: ---------------------------------------------------
|
|
97
|
-
|
|
98
|
-
function tagCompositionTargets( elem ) {
|
|
99
|
-
if (elem.$inferred) // TODO: probably no $inferred yet
|
|
100
|
-
return;
|
|
101
|
-
if (elem.targetAspect?.elements)
|
|
102
|
-
elem = elem.targetAspect;
|
|
103
|
-
if (elem.elements) {
|
|
104
|
-
forEachGeneric( elem, 'elements', tagCompositionTargets );
|
|
105
|
-
}
|
|
106
|
-
else if (elem.columns) { // `elem` is query or extension
|
|
107
|
-
elem.columns.forEach( tagCompositionTargets );
|
|
108
|
-
}
|
|
109
|
-
else if (elem.$queries) {
|
|
110
|
-
for (const query of elem.$queries) {
|
|
111
|
-
if (query.mixin)
|
|
112
|
-
forEachGeneric( query, 'mixin', tagCompositionTargets );
|
|
113
|
-
if (query.columns)
|
|
114
|
-
query.columns.forEach( tagCompositionTargets );
|
|
115
|
-
// Remark: no directly published expand/inline column yet
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
else if (elem.target && isDirectComposition( elem )) {
|
|
119
|
-
const name = resolveUncheckedPath( elem.target, 'target', elem );
|
|
120
|
-
if (!name)
|
|
121
|
-
return;
|
|
122
|
-
const target = model.definitions[name];
|
|
123
|
-
// move target aspect in `target` to `targetAspect` (in define.js, we only
|
|
124
|
-
// do it with anonymous aspect)
|
|
125
|
-
if (target?.kind in { aspect: 1, type: 1 } && // type is sloppy
|
|
126
|
-
target.elements && !target.elements[$inferred] &&
|
|
127
|
-
!targetCantBeAspect( elem, false, model.definitions )) { // tests `!elem.targetAspect`
|
|
128
|
-
elem.targetAspect = elem.target;
|
|
129
|
-
delete elem.target;
|
|
130
|
-
}
|
|
131
|
-
model.$compositionTargets[name] = true; // does not hurt if set on aspect
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
//-----------------------------------------------------------------------------
|
|
137
|
-
// Extensions: general algorithm
|
|
138
|
-
//-----------------------------------------------------------------------------
|
|
139
|
-
// extendArtifactBefore, extendArtifactAfter, createRemainingAnnotateStatements,
|
|
140
|
-
// extendForeignKeys
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Goes through all (applied) annotations in the given artifact and chooses one
|
|
144
|
-
* if multiple exist according to the module layer.
|
|
145
|
-
* TODO: update comment if extension algorithm is finished
|
|
146
|
-
*
|
|
147
|
-
* Called at the beginning for each main artifact, and must not call
|
|
148
|
-
* resolvePath() then. It is later called via effectiveType().
|
|
149
|
-
*
|
|
150
|
-
* @param {XSN.Artifact} art
|
|
151
|
-
*/
|
|
152
|
-
function extendArtifactBefore( art ) {
|
|
153
|
-
// for main artifacts, move extensions from `$collectedExtensions` model dictionary:
|
|
154
|
-
if (!art._main && !art._outer && art._extensions === undefined &&
|
|
155
|
-
art.name && // TODO: probably just a workaround, check with TODO in getOriginRaw()
|
|
156
|
-
art.kind !== 'namespace') {
|
|
157
|
-
const { id } = art.name;
|
|
158
|
-
setLink( art, '_extensions', model.$collectedExtensions[id]?._extensions || null );
|
|
159
|
-
if (art._extensions && !art.builtin) { // keep extensions for builtin in $collectedExtensions
|
|
160
|
-
delete model.$collectedExtensions[id];
|
|
161
|
-
// TODO: if the extension mechanism has been completed, we could uncomment:
|
|
162
|
-
// art._extensions.forEach( ext => resolvePath( ext.name, ext.kind, ext )); // for LSP
|
|
163
|
-
// for now, we do that at the end of createRemainingAnnotateStatements()
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
if (art.kind === 'entity' && art.includes && !art._entityIncludes)
|
|
167
|
-
setEntityIncludes( art, art );
|
|
168
121
|
|
|
169
|
-
|
|
170
|
-
// TODO: the following function can now be simplified
|
|
171
|
-
// if (art.$inferred) console.log('CAI:', art.name, art.$inferred,art._extensions)
|
|
172
|
-
// With extensions, member appears in CSN, affects directly the rendering of
|
|
173
|
-
// elements etc. TODO: do that more specifically on the dicts (via symbol)
|
|
174
|
-
// Probably better: we could use the _extensions dict prop directly in to-csn
|
|
175
|
-
if (art.$inferred)
|
|
176
|
-
setExpandStatus( art, 'annotate' );
|
|
177
|
-
if (Array.isArray( art._extensions )) {
|
|
178
|
-
checkExtensionsKind( art._extensions, art );
|
|
179
|
-
transformArtifactExtensions( art );
|
|
180
|
-
}
|
|
181
|
-
// console.log('EA:',require('../model/revealInternalProperties')
|
|
182
|
-
// .ref(art),Object.keys(art._extensions))
|
|
183
|
-
for (const prop in art._extensions) {
|
|
184
|
-
if (Object.hasOwn( art._extensions, prop ) &&
|
|
185
|
-
// remark: if we change the array, consider whether to delete the artifact
|
|
186
|
-
// TODO: what is the `$gen`? `$add` is handled...
|
|
187
|
-
![ 'elements', 'actions', 'params', '$gen' ].includes( prop ))
|
|
188
|
-
applyPropertyExtensions( art, prop );
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
122
|
+
// Pushdown and transform extensions ------------------------------------------
|
|
192
123
|
|
|
193
124
|
/**
|
|
194
125
|
* Push down extensions on member properties like `elements` to the individual
|
|
@@ -240,14 +171,17 @@ function extend( model ) {
|
|
|
240
171
|
annotateFor( art, 'params', '' ); // create anno for non-existing returns
|
|
241
172
|
for (const ext of extensionsMap.elements) {
|
|
242
173
|
if (!ext.returns) {
|
|
174
|
+
if (artProp === 'returns') {
|
|
175
|
+
reportMissingReturns( ext, art );
|
|
176
|
+
if (ext.kind === 'extend')
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
243
179
|
pushToDict( returnsDict || art[artProp], '_extensions', ext );
|
|
244
|
-
if (artProp === 'returns')
|
|
245
|
-
extendHandleReturns( ext, art );
|
|
246
180
|
}
|
|
247
181
|
else {
|
|
248
182
|
pushToDict( returnsDict || art[artProp], '_extensions', ext.returns );
|
|
249
183
|
if (!art.returns)
|
|
250
|
-
|
|
184
|
+
reportUnexpectedReturns( ext, art );
|
|
251
185
|
}
|
|
252
186
|
}
|
|
253
187
|
// TODO: what about `many many Type` (via CSN)?
|
|
@@ -255,7 +189,7 @@ function extend( model ) {
|
|
|
255
189
|
else if (!art.target) { // TODO: foreign keys currently handled specially
|
|
256
190
|
for (const ext of extensionsMap.elements) {
|
|
257
191
|
if (ext.returns)
|
|
258
|
-
|
|
192
|
+
reportUnexpectedReturns( ext, art ); // TODO: ???
|
|
259
193
|
}
|
|
260
194
|
// if (art.elements || art.enum || art.kind === 'annotate')
|
|
261
195
|
moveDictExtensions( art, extensionsMap,
|
|
@@ -263,114 +197,26 @@ function extend( model ) {
|
|
|
263
197
|
}
|
|
264
198
|
}
|
|
265
199
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
* Instead, we postpone applying them until all foreign keys were generated.
|
|
270
|
-
*
|
|
271
|
-
* @param art
|
|
272
|
-
*/
|
|
273
|
-
function extendForeignKeys( art ) {
|
|
274
|
-
// See extendArtifactAfter() for targetAspect/items handling.
|
|
275
|
-
if (!art._extensions || art.items || art.targetAspect?.elements)
|
|
276
|
-
return;
|
|
277
|
-
|
|
278
|
-
// push down foreign keys
|
|
279
|
-
moveDictExtensions( art, art._extensions, 'foreignKeys', 'elements' );
|
|
280
|
-
if (!art.foreignKeys)
|
|
281
|
-
return;
|
|
282
|
-
|
|
283
|
-
forEachGeneric(art, 'foreignKeys', (key) => {
|
|
284
|
-
if (!key._effectiveType)
|
|
285
|
-
throw new CompilerAssertion('foreign key should have been processed');
|
|
286
|
-
extendArtifactBefore( key );
|
|
287
|
-
extendArtifactAfter( key );
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Applying extensions is handled in extendArtifactAfter(). And only afterward,
|
|
293
|
-
* an effective sequence number is set. Meaning that if a sub artifact already
|
|
294
|
-
* has a sequence number, then extensions would be lost.
|
|
295
|
-
*
|
|
296
|
-
* A special case are foreign keys, see extendForeignKeys().
|
|
297
|
-
*/
|
|
298
|
-
function ensureArtifactNotProcessed( art ) {
|
|
299
|
-
if (!model.options.testMode)
|
|
300
|
-
return;
|
|
301
|
-
|
|
302
|
-
if (art.kind !== 'key' && art.$effectiveSeqNo !== 0 && art.$effectiveSeqNo !== undefined) {
|
|
303
|
-
// if the artifact already has a sequence number, then
|
|
304
|
-
// extendArtifactAfter() was already called -> annotations would be lost.
|
|
305
|
-
throw new CompilerAssertion('artifact already processed; extensions would be lost');
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Create super annotate statements for remaining extensions
|
|
311
|
-
*/
|
|
312
|
-
function createRemainingAnnotateStatements() {
|
|
313
|
-
model.extensions = Object.values( model.$collectedExtensions );
|
|
314
|
-
// TODO: testMode sort?
|
|
315
|
-
model.extensions.forEach( createSuperAnnotate );
|
|
316
|
-
// set _artifact links for “main extensions” late as it would disturb the
|
|
317
|
-
// still existing old extend mechanism, see extendArtifactBefore(),
|
|
318
|
-
// needed for LSP and friends:
|
|
319
|
-
Object.values( model.sources ).forEach( setArtifactLinkForExtensions );
|
|
320
|
-
Object.values( model.definitions ).forEach( setArtifactLinkForExtensions );
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// TODO: delete again - if not, what about extensions in contexts/services?
|
|
324
|
-
// Check test.lsp-api.js! Links in extensions are needed.
|
|
325
|
-
function setArtifactLinkForExtensions( source ) {
|
|
326
|
-
if (!source.extensions)
|
|
200
|
+
function moveDictExtensions( art, extensionsMap, artProp, extProp = artProp ) {
|
|
201
|
+
const extensions = extensionsMap[extProp || 'elements'];
|
|
202
|
+
if (!extensions)
|
|
327
203
|
return;
|
|
328
|
-
for (const ext of source.extensions) {
|
|
329
|
-
if (!ext.name?.id)
|
|
330
|
-
continue;
|
|
331
|
-
|
|
332
|
-
const { name } = ext;
|
|
333
|
-
const { path } = name;
|
|
334
|
-
if (name._artifact === undefined) {
|
|
335
|
-
resolvePath( name, ext.kind, ext ); // induce error & for LSP
|
|
336
|
-
}
|
|
337
|
-
else if (model.options.lspMode && path?.[0]._artifact === undefined) {
|
|
338
|
-
// we don't use resolvePath(…,'extend'), as that would add a dependency
|
|
339
|
-
resolveDefinitionName( ext );
|
|
340
|
-
setArtifactLink( path[path.length - 1], name._artifact );
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// For extendArtifactBefore(): ------------------------------------------------
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Complain about invalid `extend service` and `extend context`.
|
|
349
|
-
*/
|
|
350
|
-
function checkExtensionsKind( extensions, art ) {
|
|
351
204
|
for (const ext of extensions) {
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
annotate: 'There is no artifact $(ART), use $(CODE) instead',
|
|
368
|
-
// do not mention 'extend context', that is not in CAPire
|
|
369
|
-
service: 'Artifact $(ART) is not of kind $(KIND), use $(CODE) or $(KEYWORD) instead',
|
|
370
|
-
} );
|
|
371
|
-
}
|
|
372
|
-
// TODO: Use similar checks for EXTEND ENTITY etc - 'ext-ignoring-kind'
|
|
373
|
-
}
|
|
205
|
+
const members = art[artProp];
|
|
206
|
+
const realExtProp = extProp || (ext.enum ? 'enum' : 'elements');
|
|
207
|
+
if (!members && !checkExtensionDictionary( ext, art, artProp, realExtProp ))
|
|
208
|
+
continue;
|
|
209
|
+
forEachGeneric( ext, realExtProp, ( elemExt, name ) => {
|
|
210
|
+
if (elemExt.kind !== 'annotate' && elemExt.kind !== 'extend')
|
|
211
|
+
return; // definitions inside extend, already handled
|
|
212
|
+
// Remark: don't test elemExt.$duplicates, `annotate A (@Foo P, @Bar P)` should work
|
|
213
|
+
reportUnexpectedMemberExtensions( art, elemExt, artProp, name );
|
|
214
|
+
const elem = members?.[name] || annotateFor( art, extProp || 'elements', name );
|
|
215
|
+
setLink( elemExt.name, '_artifact', (elem.kind !== 'annotate' ? elem : null ) );
|
|
216
|
+
// null, because the element is not really there, just in a "super annotate"
|
|
217
|
+
if (elem.$duplicates !== true) // TODO: re-check, or just !elem.$duplicates
|
|
218
|
+
pushToDict( elem, '_extensions', elemExt );
|
|
219
|
+
});
|
|
374
220
|
}
|
|
375
221
|
}
|
|
376
222
|
|
|
@@ -379,8 +225,12 @@ function extend( model ) {
|
|
|
379
225
|
* `{ prop: relevantExtensions, … }` where `relevantExtensions` are the extensions
|
|
380
226
|
* which are relevant for the value of `art[prop]` after the application of extensions.
|
|
381
227
|
*
|
|
382
|
-
*
|
|
383
|
-
* `
|
|
228
|
+
* A special property is `$add`: it collects extensions for both `elements` (+
|
|
229
|
+
* `enum`) extensions and `includes` (also without elements, because the order
|
|
230
|
+
* of includes might influences which inludes wins for inherited annotations).
|
|
231
|
+
*
|
|
232
|
+
* Called in extendArtifactBefore(), where it is not necessarily clear whether
|
|
233
|
+
* `art` has `elements`, `enums`, `items`, etc.
|
|
384
234
|
*/
|
|
385
235
|
function transformArtifactExtensions( art ) {
|
|
386
236
|
// TODO: if extensions has more than one of returns,items,elements,enum, delete all those props
|
|
@@ -403,7 +253,7 @@ function extend( model ) {
|
|
|
403
253
|
prop === 'groupBy' || prop === 'where' || prop === 'having' ||
|
|
404
254
|
prop === 'orderBy' || prop === 'limit' || prop === 'length' ||
|
|
405
255
|
prop === 'scale' || prop === 'precision' || prop === 'srid') {
|
|
406
|
-
if (!isAutoItemsOrReturns)
|
|
256
|
+
if (!isAutoItemsOrReturns) // these props are ignored inside items/returns
|
|
407
257
|
pushToDict( dict, prop, ext );
|
|
408
258
|
}
|
|
409
259
|
else if (prop === 'elements' || prop === 'enum') {
|
|
@@ -417,14 +267,19 @@ function extend( model ) {
|
|
|
417
267
|
}
|
|
418
268
|
else {
|
|
419
269
|
pushToDict( dict, 'elements', ext ); // yes, enum → elements here
|
|
420
|
-
if
|
|
270
|
+
// if at least one elem/enum (TODO):
|
|
271
|
+
// && Object.keys( ext.elements ).some( elem => elem.kind !== 'extend' ))
|
|
272
|
+
// Add to $add if not already for includes:
|
|
273
|
+
if (ext.kind === 'extend' && !ext.includes)
|
|
421
274
|
pushTo$add( dict, ext );
|
|
275
|
+
// TODO: issue error for ext on art having returns/items if ext has both
|
|
276
|
+
// include/actions/params and elements/enum (or handle that properly)
|
|
422
277
|
}
|
|
423
278
|
}
|
|
424
279
|
else if (prop === 'returns') {
|
|
425
280
|
pushToDict( dict, 'elements', ext );
|
|
426
281
|
if (hasSecurityAnno( ext.returns ))
|
|
427
|
-
|
|
282
|
+
reportUnexpectedReturns( ext, ext );
|
|
428
283
|
// create 'returns' for the super annotate, store in elements anyway
|
|
429
284
|
if (!art.returns && art.kind === 'annotate')
|
|
430
285
|
annotateCreate( art, '', art, 'returns' );
|
|
@@ -433,14 +288,14 @@ function extend( model ) {
|
|
|
433
288
|
}
|
|
434
289
|
else if (prop === 'actions' || prop === 'params') {
|
|
435
290
|
pushToDict( dict, prop, ext );
|
|
436
|
-
if (ext.kind === 'extend' && prop === 'actions' && !isAutoItemsOrReturns)
|
|
437
|
-
pushTo$add( dict, ext );
|
|
438
291
|
}
|
|
439
292
|
}
|
|
440
293
|
}
|
|
441
294
|
art._extensions = dict;
|
|
442
295
|
}
|
|
443
296
|
|
|
297
|
+
// Sort sources, select/sort extensions ---------------------------------------
|
|
298
|
+
|
|
444
299
|
/**
|
|
445
300
|
* Sort sources according to the reversed layered extension order without
|
|
446
301
|
* reporting any messages.
|
|
@@ -467,12 +322,84 @@ function extend( model ) {
|
|
|
467
322
|
setLink( model, '_sortedSources', scheduled );
|
|
468
323
|
}
|
|
469
324
|
|
|
325
|
+
/**
|
|
326
|
+
* Traverses collected extensions for the given artifact, and for each property,
|
|
327
|
+
* select one (or sort them, e.g. for `includes`) if multiple extensions exist.
|
|
328
|
+
*
|
|
329
|
+
* Consider the module layer for the selection/sorting, and issue messages.
|
|
330
|
+
*
|
|
331
|
+
* Called at the beginning for each main artifact, and must not call
|
|
332
|
+
* resolvePath() then.
|
|
333
|
+
*
|
|
334
|
+
* @param {XSN.Artifact} art
|
|
335
|
+
*/
|
|
336
|
+
function extendArtifactBefore( art ) {
|
|
337
|
+
// for main artifacts, move extensions from `$collectedExtensions` model dictionary:
|
|
338
|
+
if (!art._main && !art._outer && art._extensions === undefined &&
|
|
339
|
+
art.name && // TODO: probably just a workaround, check with TODO in getOriginRaw()
|
|
340
|
+
art.kind !== 'namespace') {
|
|
341
|
+
const { id } = art.name;
|
|
342
|
+
setLink( art, '_extensions', model.$collectedExtensions[id]?._extensions || null );
|
|
343
|
+
if (art._extensions && !art.builtin) { // keep extensions for builtin in $collectedExtensions
|
|
344
|
+
delete model.$collectedExtensions[id];
|
|
345
|
+
// TODO: if the extension mechanism has been completed, we could uncomment:
|
|
346
|
+
// art._extensions.forEach( ext => resolvePath( ext.name, ext.kind, ext )); // for LSP
|
|
347
|
+
// for now, we do that at the end of createRemainingAnnotateStatements()
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (art.kind === 'entity' && art.includes && !art._entityIncludes)
|
|
351
|
+
setEntityIncludes( art, art );
|
|
352
|
+
|
|
353
|
+
if (Array.isArray( art._extensions )) {
|
|
354
|
+
// TODO: the following function can now be simplified
|
|
355
|
+
// if (art.$inferred) console.log('CAI:', art.name, art.$inferred,art._extensions)
|
|
356
|
+
// With extensions, member appears in CSN, affects directly the rendering of
|
|
357
|
+
// elements etc. TODO: do that more specifically on the dicts (via symbol)
|
|
358
|
+
// Probably better: we could use the _extensions dict prop directly in to-csn
|
|
359
|
+
if (art.$inferred)
|
|
360
|
+
setExpandStatus( art, 'annotate' );
|
|
361
|
+
if (Array.isArray( art._extensions )) {
|
|
362
|
+
reportInvalidExtensionKind( art._extensions, art );
|
|
363
|
+
transformArtifactExtensions( art );
|
|
364
|
+
}
|
|
365
|
+
// console.log('EA:',require('../model/revealInternalProperties')
|
|
366
|
+
// .ref(art),Object.keys(art._extensions))
|
|
367
|
+
for (const prop in art._extensions) {
|
|
368
|
+
if (Object.hasOwn( art._extensions, prop ))
|
|
369
|
+
applyPropertyExtensions( art, prop );
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Collect all includes which are entities in property `_entityIncludes`.
|
|
376
|
+
* This information is needed to kick-start the auto-redirection mechanism,
|
|
377
|
+
* i.e. must be called in extendArtifactBefore().
|
|
378
|
+
*
|
|
379
|
+
* A consequence is that a compiler-generated entity must never include an
|
|
380
|
+
* entity; the generated entity could be an auto-redirection target otherwise
|
|
381
|
+
* → an on-demand generated could change the auto-redirection behavior.
|
|
382
|
+
*/
|
|
383
|
+
function setEntityIncludes( ext, art ) {
|
|
384
|
+
// TODO: better to call this once at the end of extendArtifactBefore()
|
|
385
|
+
setLink( art, '_entityIncludes', [] );
|
|
386
|
+
for (const ref of ext.includes) {
|
|
387
|
+
const name = resolveUncheckedPath( ref, 'include', ext );
|
|
388
|
+
const template = name && model.definitions[name];
|
|
389
|
+
if (template?.kind === 'entity')
|
|
390
|
+
art._entityIncludes.push( template );
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
470
394
|
/**
|
|
471
395
|
* For all `prop → extensions` in `art._extensions`, apply the extensions.
|
|
472
396
|
* Currently only for annotations, the `doc` property, `columns` and type properties,
|
|
473
397
|
* not for `elements` and other members.
|
|
474
398
|
*/
|
|
475
399
|
function applyPropertyExtensions( art, prop ) {
|
|
400
|
+
if (prop === 'params' || prop === 'returns' || prop === 'elements')
|
|
401
|
+
return; // only for push-down
|
|
402
|
+
|
|
476
403
|
const extensions = art._extensions;
|
|
477
404
|
// annotations, `doc`, `includes`, `columns`, `length`, ...
|
|
478
405
|
const scheduled = [];
|
|
@@ -498,20 +425,19 @@ function extend( model ) {
|
|
|
498
425
|
}
|
|
499
426
|
// Now apply the relevant extensions
|
|
500
427
|
scheduled.reverse();
|
|
501
|
-
art.$postponeInclude ??= 0; // add elems of includes before direct ones
|
|
502
428
|
if (prop === 'includes' && !art.includes?.$original) {
|
|
503
429
|
const $original = art.includes ?? [];
|
|
504
430
|
art.includes = [ ...$original ];
|
|
505
431
|
art.includes.$original = $original;
|
|
432
|
+
// extensions[prop] = scheduled;
|
|
506
433
|
// console.log('APE:',art.name.id,art.includes.map( r => r._artifact?.name.id ))
|
|
507
434
|
}
|
|
508
|
-
if (prop === '$add') {
|
|
435
|
+
if (prop === '$add' || prop === 'actions') {
|
|
509
436
|
extensions[prop] = scheduled;
|
|
510
|
-
return; //
|
|
437
|
+
return; // $add and actions are applied in extendArtifactAdd()
|
|
511
438
|
}
|
|
512
439
|
for (const ext of scheduled)
|
|
513
440
|
applySingleExtension( art, ext, prop );
|
|
514
|
-
delete extensions[prop];
|
|
515
441
|
}
|
|
516
442
|
|
|
517
443
|
function extensionOverwrites( ext, prop ) {
|
|
@@ -520,80 +446,20 @@ function extend( model ) {
|
|
|
520
446
|
: !annotationHasEllipsis( ext[prop] );
|
|
521
447
|
}
|
|
522
448
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
const clause = ext[prop];
|
|
538
|
-
if (clause) {
|
|
539
|
-
message( 'ext-unstable-order', [ clause[0]?.location || ext.location, ext ],
|
|
540
|
-
{ keyword: prop },
|
|
541
|
-
// eslint-disable-next-line @stylistic/max-len
|
|
542
|
-
'Unstable order of entries in the $(KEYWORD) clause due to another extension in unrelated layer' );
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
547
|
-
// eslint-disable-next-line no-nested-ternary
|
|
548
|
-
let msg = (index < 0)
|
|
549
|
-
? 'anno-unstable-array'
|
|
550
|
-
: (issue === true)
|
|
551
|
-
? 'anno-duplicate'
|
|
552
|
-
: 'anno-duplicate-unrelated-layer';
|
|
553
|
-
if (!isAnnoOrDoc) {
|
|
554
|
-
msg = (issue === true)
|
|
555
|
-
? 'ext-duplicate-extend-type'
|
|
556
|
-
: 'ext-duplicate-extend-type-unrelated-layer';
|
|
557
|
-
// not sure whether to repeat the extended artifact in the message (we
|
|
558
|
-
// have the semantic location, after all)
|
|
559
|
-
// extend-repeated-intralayer / extend-unrelated-layer
|
|
560
|
-
}
|
|
561
|
-
const variant = prop === 'doc' ? 'doc' : 'std';
|
|
562
|
-
for (const ext of extensions) {
|
|
563
|
-
const anno = ext[prop];
|
|
564
|
-
if (anno && !anno.$errorReported) {
|
|
565
|
-
message( msg, [ anno.name?.location || anno.location, ext ],
|
|
566
|
-
{ '#': variant, anno: prop, type: art } );
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
else if (index > 0) { // more than one set (not just ...)
|
|
571
|
-
const variant = prop === 'doc' ? 'doc' : 'std';
|
|
572
|
-
const msgid = (isAnnoOrDoc)
|
|
573
|
-
? 'anno-duplicate-same-file' // TODO: always ext-duplicate-…
|
|
574
|
-
: 'ext-duplicate-same-file';
|
|
575
|
-
while (index >= 0) { // do not report for trailing [...]
|
|
576
|
-
const ext = extensions[index--];
|
|
577
|
-
const anno = ext[prop];
|
|
578
|
-
warning( msgid, [ anno.name?.location || anno.location, ext ],
|
|
579
|
-
{ '#': variant, prop, anno: prop } );
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
function applySingleExtension( art, ext, prop ) {
|
|
585
|
-
if (prop === 'includes') {
|
|
586
|
-
if (art.kind !== 'annotate' && !art._outer) { // TODO: why this check?
|
|
587
|
-
// not with elem extension in targetAspect
|
|
588
|
-
art.includes.push( ...ext.includes );
|
|
589
|
-
// head of ref in in ext.includes must be set in _block of ext; for
|
|
590
|
-
// remaining path items, effectiveType() has `art` as user
|
|
591
|
-
// (alternatively, we could set some _user on `includes` items):
|
|
592
|
-
for (const ref of ext.includes)
|
|
593
|
-
resolveUncheckedPath( ref, 'include', ext );
|
|
594
|
-
if (art.kind === 'entity')
|
|
595
|
-
setEntityIncludes( ext, art );
|
|
596
|
-
// console.log( 'ASI:',prop,art.name,ext,extensionsDict[id])
|
|
449
|
+
function applySingleExtension( art, ext, prop ) {
|
|
450
|
+
if (prop === 'includes') {
|
|
451
|
+
if (art.kind !== 'annotate' && !art._outer) { // TODO: why this check?
|
|
452
|
+
// not with elem extension in targetAspect
|
|
453
|
+
art.includes.push( ...ext.includes );
|
|
454
|
+
// head of ref in in ext.includes must be set in _block of ext; for
|
|
455
|
+
// remaining path items, effectiveType() has `art` as user
|
|
456
|
+
// (alternatively, we could set some _user on `includes` items):
|
|
457
|
+
for (const ref of ext.includes)
|
|
458
|
+
resolveUncheckedPath( ref, 'include', ext );
|
|
459
|
+
// TODO: some warning if duplicate ref
|
|
460
|
+
if (art.kind === 'entity')
|
|
461
|
+
setEntityIncludes( ext, art );
|
|
462
|
+
// console.log( 'ASI:',prop,art.name,ext,extensionsDict[id])
|
|
597
463
|
}
|
|
598
464
|
// art[prop] = (art[prop]) ? art[prop].concat( ext[prop] ) : ext[prop];
|
|
599
465
|
}
|
|
@@ -610,10 +476,14 @@ function extend( model ) {
|
|
|
610
476
|
error( 'extend-columns', [ ext.columns[$location], ext ], { '#': variant, art } );
|
|
611
477
|
return;
|
|
612
478
|
}
|
|
613
|
-
if (!query.columns)
|
|
614
|
-
query.columns = [ {
|
|
615
|
-
|
|
479
|
+
if (!query.columns) {
|
|
480
|
+
query.columns = [ {
|
|
481
|
+
__proto__: XsnArtifact.prototype, location: query.from.location, val: '*',
|
|
482
|
+
}, ...ext.columns ];
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
616
485
|
query.columns.push( ...ext.columns );
|
|
486
|
+
}
|
|
617
487
|
ext.columns.forEach( col => changeParentLinks( col, query ) );
|
|
618
488
|
}
|
|
619
489
|
else if (prop === 'groupBy' || prop === 'where' || prop === 'having' ||
|
|
@@ -626,76 +496,12 @@ function extend( model ) {
|
|
|
626
496
|
}
|
|
627
497
|
else {
|
|
628
498
|
const result = applyAssignment( art[prop], ext[prop], ext, prop );
|
|
499
|
+
// Remark: result is ext[prop] if without [...]
|
|
629
500
|
art[prop] = (result.name) ? result : Object.assign( {}, art[prop], result );
|
|
630
501
|
}
|
|
631
502
|
}
|
|
632
503
|
|
|
633
|
-
|
|
634
|
-
const { query } = art;
|
|
635
|
-
const clause = ext[prop];
|
|
636
|
-
const isArray = Array.isArray( clause );
|
|
637
|
-
|
|
638
|
-
if (prop !== 'limit') {
|
|
639
|
-
const items = isArray ? clause : [ clause ];
|
|
640
|
-
for (const item of items) {
|
|
641
|
-
item.$extended = prop;
|
|
642
|
-
setLink( item, '_block', ext._block );
|
|
643
|
-
setLink( item, '_outer', query );
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
if (!query?.from?.path) {
|
|
647
|
-
const variant = (query?.from || query)?.op?.val || 'std';
|
|
648
|
-
const loc = isArray ? clause[$location] : clause.location;
|
|
649
|
-
error( `extend-${ prop.toLowerCase() }`, [ loc, ext ], { '#': variant, art } );
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
if (isArray) {
|
|
653
|
-
if (!query[prop])
|
|
654
|
-
query[prop] = [];
|
|
655
|
-
query[prop].push( ...clause );
|
|
656
|
-
}
|
|
657
|
-
else if (prop === 'where' || prop === 'having') {
|
|
658
|
-
const existing = query[prop];
|
|
659
|
-
if (!existing) {
|
|
660
|
-
query[prop] = clause;
|
|
661
|
-
}
|
|
662
|
-
else if (existing.op?.val === 'and' &&
|
|
663
|
-
existing.args.some( a => a.$extended === prop )) {
|
|
664
|
-
existing.args.push( clause );
|
|
665
|
-
}
|
|
666
|
-
else {
|
|
667
|
-
query[prop] = {
|
|
668
|
-
op: { val: 'and', location: art.name.location },
|
|
669
|
-
args: [ existing, clause ],
|
|
670
|
-
location: clause.location,
|
|
671
|
-
};
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
else if (query[prop]) {
|
|
675
|
-
error( 'ext-unexpected-sql-clause', [ clause.location, ext ], { art, keyword: prop } );
|
|
676
|
-
}
|
|
677
|
-
else {
|
|
678
|
-
query[prop] = clause;
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
function changeParentLinks( art, queryOrMain ) {
|
|
683
|
-
// TODO: we might also change the implicit name (if name.id is a number,
|
|
684
|
-
// adding the previous column lenght - 1) for better error messages
|
|
685
|
-
const parent = art._parent;
|
|
686
|
-
if (!art._parent)
|
|
687
|
-
return;
|
|
688
|
-
if (parent.kind === 'extend')
|
|
689
|
-
art._parent = queryOrMain;
|
|
690
|
-
if (art._main.kind === 'extend') // TODO: probably always
|
|
691
|
-
art._main = queryOrMain._main;
|
|
692
|
-
if (art._columnParent?.kind === 'extend')
|
|
693
|
-
art._columnParent = queryOrMain;
|
|
694
|
-
const subColumns = art.expand || art.inline;
|
|
695
|
-
if (subColumns)
|
|
696
|
-
subColumns.forEach( a => changeParentLinks( a, queryOrMain ) );
|
|
697
|
-
forEachMember( art, a => changeParentLinks( a, queryOrMain ) );
|
|
698
|
-
}
|
|
504
|
+
// Array annotations with `...`: ----------------------------------------------
|
|
699
505
|
|
|
700
506
|
function applyAssignment( previousAnno, anno, art, annoName ) {
|
|
701
507
|
const firstEllipsis = annotationHasEllipsis( anno );
|
|
@@ -738,6 +544,7 @@ function extend( model ) {
|
|
|
738
544
|
}
|
|
739
545
|
else {
|
|
740
546
|
let upToSpec = !item.$errorReported && item.upTo;
|
|
547
|
+
// $errorReported: no anno-unexpected-upto-value with anno-invalid-upto-value
|
|
741
548
|
while (prevPos < previousValue.length) {
|
|
742
549
|
const prevItem = previousValue[prevPos++];
|
|
743
550
|
result.push( prevItem );
|
|
@@ -748,7 +555,8 @@ function extend( model ) {
|
|
|
748
555
|
}
|
|
749
556
|
if (upToSpec && hasBase) {
|
|
750
557
|
// non-matched UP TO; if there is no base to apply to, there is already an error.
|
|
751
|
-
warning(
|
|
558
|
+
warning( 'anno-unexpected-upto-value', [ item.upTo.location, art ],
|
|
559
|
+
{ anno: annoName, code: '... up to' },
|
|
752
560
|
'The $(CODE) value does not match any item in the base annotation $(ANNO)' );
|
|
753
561
|
}
|
|
754
562
|
}
|
|
@@ -764,7 +572,6 @@ function extend( model ) {
|
|
|
764
572
|
}
|
|
765
573
|
|
|
766
574
|
// For the `up to` specification, see ../../test3/Annotations/EllipsisUpTo/
|
|
767
|
-
|
|
768
575
|
function equalUpTo( previousItem, upToSpec ) {
|
|
769
576
|
if (!previousItem)
|
|
770
577
|
return false;
|
|
@@ -816,11 +623,60 @@ function extend( model ) {
|
|
|
816
623
|
|
|
817
624
|
function normalizeRef( node ) { // see to-csn.js
|
|
818
625
|
const ref = pathName( node.path );
|
|
819
|
-
// TODO XSN 7.
|
|
626
|
+
// TODO XSN 7.2: get rid of name.variant (induces a wrong structure anyway)
|
|
820
627
|
return node.variant ? `${ ref }#${ pathName( node.variant.path ) }` : ref;
|
|
821
628
|
}
|
|
822
629
|
|
|
823
|
-
//
|
|
630
|
+
// Special properties: query clauses, type properties -------------------------
|
|
631
|
+
|
|
632
|
+
function applyQueryClause( prop, ext, art ) {
|
|
633
|
+
const { query } = art;
|
|
634
|
+
const clause = ext[prop];
|
|
635
|
+
const isArray = Array.isArray( clause );
|
|
636
|
+
|
|
637
|
+
if (prop !== 'limit') {
|
|
638
|
+
const items = isArray ? clause : [ clause ];
|
|
639
|
+
for (const item of items) {
|
|
640
|
+
item.$extended = prop;
|
|
641
|
+
setLink( item, '_block', ext._block );
|
|
642
|
+
setLink( item, '_outer', query );
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (!query?.from?.path) {
|
|
646
|
+
const variant = (query?.from || query)?.op?.val || 'std';
|
|
647
|
+
const loc = isArray ? clause[$location] : clause.location;
|
|
648
|
+
error( `extend-${ prop.toLowerCase() }`, [ loc, ext ], { '#': variant, art } );
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
if (isArray) {
|
|
652
|
+
if (!query[prop])
|
|
653
|
+
query[prop] = [];
|
|
654
|
+
query[prop].push( ...clause );
|
|
655
|
+
}
|
|
656
|
+
else if (prop === 'where' || prop === 'having') {
|
|
657
|
+
const existing = query[prop];
|
|
658
|
+
if (!existing) {
|
|
659
|
+
query[prop] = clause;
|
|
660
|
+
}
|
|
661
|
+
else if (existing.op?.val === 'and' &&
|
|
662
|
+
existing.args.some( a => a.$extended === prop )) {
|
|
663
|
+
existing.args.push( clause );
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
query[prop] = {
|
|
667
|
+
op: { val: 'and', location: art.name.location },
|
|
668
|
+
args: [ existing, clause ],
|
|
669
|
+
location: clause.location,
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
else if (query[prop]) {
|
|
674
|
+
error( 'ext-unexpected-sql-clause', [ clause.location, ext ], { art, keyword: prop } );
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
query[prop] = clause;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
824
680
|
|
|
825
681
|
// Remarks on messages: we allow the type extensions only if the artifact
|
|
826
682
|
// originally had that property → any check of the kind “type prop can only be
|
|
@@ -833,7 +689,7 @@ function extend( model ) {
|
|
|
833
689
|
// - 'ext-unexpected-type-argument' (TODO) if the artifact does not have the prop
|
|
834
690
|
// - 'ext-invalid-type-argument' if the value is wrong for extend (no overwrite)
|
|
835
691
|
//
|
|
836
|
-
// TODO
|
|
692
|
+
// TODO v8: do not allow `extend … with (precision: …)` alone if original def also has `scale`
|
|
837
693
|
function applyTypeExtensions( art, ext, prop, scaleDiff ) {
|
|
838
694
|
// console.log('ATE:',art?.[prop],ext?.[prop],scaleDiff)
|
|
839
695
|
if (!ext?.[prop])
|
|
@@ -901,194 +757,332 @@ function extend( model ) {
|
|
|
901
757
|
return parameters.includes( prop ) || parameters[0]?.name === prop;
|
|
902
758
|
}
|
|
903
759
|
|
|
904
|
-
|
|
905
|
-
// TODO: setExpandStatus
|
|
906
|
-
const extensions = extensionsMap[extProp || 'elements'];
|
|
907
|
-
if (!extensions)
|
|
908
|
-
return;
|
|
760
|
+
// Add new members ------------------------------------------------------------
|
|
909
761
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
762
|
+
/**
|
|
763
|
+
* Extend artifact with additional elements and actions: via includes and/or
|
|
764
|
+
* extensions. This happens _after_ `populateArtifact`, i.e. after eventually
|
|
765
|
+
* having inferred the elements/... from an "origin".
|
|
766
|
+
*
|
|
767
|
+
* `art` can also be a pseudo artifact in `items`.
|
|
768
|
+
*/
|
|
769
|
+
function extendArtifactAdd( art ) {
|
|
770
|
+
const { includes, _extensions: extensions } = art;
|
|
771
|
+
if (includes) {
|
|
772
|
+
// propagation of core-compiler relevant annotation assignments:
|
|
773
|
+
propagateEarly( art, '@cds.autoexpose' );
|
|
774
|
+
propagateEarly( art, '@fiori.draft.enabled' );
|
|
775
|
+
reportInvalidIncludes( art );
|
|
922
776
|
}
|
|
923
|
-
|
|
777
|
+
else if (!extensions) { // semantically unnecessary, just for speed-up
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
if (art.items || art.targetAspect || art.returns)
|
|
781
|
+
return; // adding enums/elements is pushed down
|
|
924
782
|
|
|
925
|
-
|
|
926
|
-
const base = annotateBase( art );
|
|
927
|
-
if (name === '' && prop === 'params')
|
|
928
|
-
return base.returns || annotateCreate( base, name, base, 'returns' );
|
|
929
|
-
const dict = base[prop] || (base[prop] = Object.create( null ));
|
|
930
|
-
if (name == null)
|
|
931
|
-
return dict;
|
|
932
|
-
return dict[name] || annotateCreate( dict, name, base );
|
|
933
|
-
}
|
|
783
|
+
const realArt = outerArtifact( art ); // e.g. if `art = realArt.items`
|
|
934
784
|
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
785
|
+
// params: no new params can be added via extend yet (annotation is ok)
|
|
786
|
+
if (!art.params && extensions?.params &&
|
|
787
|
+
(art.kind === 'action' || art.kind === 'function' ||
|
|
788
|
+
art.kind === 'entity' && art.query))
|
|
789
|
+
art.params = Object.create(null); // for moveDictExtensions()
|
|
940
790
|
|
|
941
|
-
//
|
|
942
|
-
if (art.kind === 'select')
|
|
943
|
-
art = art._parent;
|
|
944
|
-
if (art._main)
|
|
945
|
-
return annotateFor( art._parent, kindProperties[art.kind].dict, art.name.id );
|
|
791
|
+
// foreign keys: TODO - do something here?
|
|
946
792
|
|
|
947
|
-
const {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
793
|
+
const { elements } = art;
|
|
794
|
+
if (extensions?.$add) {
|
|
795
|
+
for (const ext of extensions.$add)
|
|
796
|
+
addExtensionEnum( ext, realArt, art );
|
|
797
|
+
}
|
|
951
798
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
799
|
+
if (!elements) // elements and actions can only added to defs with elements
|
|
800
|
+
return;
|
|
801
|
+
// elements: direct includes + elements → extended includes + elements
|
|
802
|
+
if (includes?.some( i => i._artifact?.elements ) ||
|
|
803
|
+
extensions?.$add?.some( e => e.elements || e.enum )) {
|
|
804
|
+
// TODO: calculate $add here, not in extendArtifactBefore(), consider
|
|
805
|
+
// unreleated layer messages (elements + includes with elements)
|
|
806
|
+
art.elements = Object.create( null );
|
|
807
|
+
art.elements[$location] = elements[$location];
|
|
808
|
+
if (elements[$inferred])
|
|
809
|
+
art.elements[$inferred] = elements[$inferred];
|
|
810
|
+
const def = { elements, includes: includes?.$original || includes };
|
|
811
|
+
const postponeFirst = postponeFirstInclude( def.includes, elements );
|
|
812
|
+
let addedLast = addExtensionMembers( def, realArt, art, 'elements', postponeFirst );
|
|
813
|
+
for (const ext of extensions?.$add || []) {
|
|
814
|
+
const extInclude = ext.includes?.[0];
|
|
815
|
+
if (extInclude) {
|
|
816
|
+
const postpone = extInclude.$postponeInclude ?? 0;
|
|
817
|
+
extInclude.$postponeInclude = postpone + addedLast;
|
|
818
|
+
addedLast = addExtensionMembers( ext, realArt, art, 'elements', postpone );
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
addedLast += addExtensionMembers( ext, realArt, art, 'elements', -1 );
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
if (includes)
|
|
825
|
+
reportRedefinitionThroughIncludes( art, 'elements' );
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// actions: via includes (also extended ones) → direct actions → extended actions
|
|
829
|
+
if (art.kind === 'type') { // TODO: what about event ?
|
|
830
|
+
if (includes)
|
|
831
|
+
reportTypeIncludesWithActions( art );
|
|
832
|
+
}
|
|
833
|
+
else if ((art.kind === 'entity' || art.kind === 'aspect') &&
|
|
834
|
+
(extensions?.actions || includes?.some( ref => ref._artifact?.actions ))) {
|
|
835
|
+
const { actions } = art;
|
|
836
|
+
art.actions = Object.create( null );
|
|
837
|
+
if (actions)
|
|
838
|
+
art.actions[$location] = actions[$location];
|
|
839
|
+
for (const ref of includes || [])
|
|
840
|
+
applyInclude( ref, null, art, 'actions' );
|
|
841
|
+
if (actions)
|
|
842
|
+
addExtensionMembers( { actions }, art, art, 'actions' );
|
|
843
|
+
for (const ext of extensions?.actions || [])
|
|
844
|
+
addExtensionMembers( ext, art, art, 'actions' );
|
|
845
|
+
if (includes)
|
|
846
|
+
reportRedefinitionThroughIncludes( art, 'actions' );
|
|
962
847
|
}
|
|
963
|
-
dict[prop || id] = annotate;
|
|
964
|
-
return annotate;
|
|
965
848
|
}
|
|
966
849
|
|
|
967
|
-
function
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
850
|
+
function addExtensionMembers( ext, art, obj, prop, postpone = -1 ) {
|
|
851
|
+
if (ext.kind)
|
|
852
|
+
dependsOnSilent( art, ext ); // TODO: really do that here?
|
|
853
|
+
if (ext.kind === 'annotate') // is also used for extensions.actions
|
|
854
|
+
return 0;
|
|
855
|
+
// art depends silently on ext (inverse to normal dep!), still necessary?
|
|
856
|
+
const { includes } = ext;
|
|
857
|
+
const extDict = ext[prop];
|
|
858
|
+
if (!extDict && !includes?.some( i => i._artifact?.[prop] ))
|
|
859
|
+
return 0;
|
|
977
860
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
861
|
+
const artDict = obj[prop];
|
|
862
|
+
if (ext.kind &&
|
|
863
|
+
(obj.$inferred || artDict?.[$inferred] || art.query && prop === 'elements') &&
|
|
864
|
+
(extDict || ext.includes))
|
|
865
|
+
reportExtensionOnGenerated( ext, art, prop, extDict );
|
|
866
|
+
let index = 0;
|
|
867
|
+
for (const name in extDict || {}) { // remark: `|| {}` not really necessary
|
|
868
|
+
const adding = extDict[name];
|
|
869
|
+
if (adding.kind === 'annotate' || adding.kind === 'extend')
|
|
870
|
+
continue;
|
|
871
|
+
while (postpone === 0)
|
|
872
|
+
postpone = applyInclude( includes[index++], includes[index], art, prop );
|
|
873
|
+
const existing = artDict[name];
|
|
874
|
+
if (!existing || existing.$inferred === 'include')
|
|
875
|
+
artDict[name] = adding;
|
|
876
|
+
else
|
|
877
|
+
dictAdd( artDict, name, adding, reportDuplicate );
|
|
878
|
+
initMember( adding, art, prop );
|
|
879
|
+
if (!adding.$inferred) // not for derived members (with aspect include)
|
|
880
|
+
--postpone; // also when members shadows included one
|
|
881
|
+
}
|
|
882
|
+
if (prop !== 'elements' || !includes?.[index])
|
|
883
|
+
return -1 - postpone; // number of elements added last (after includes)
|
|
884
|
+
while (index < includes.length)
|
|
885
|
+
applyInclude( includes[index++], null, art, prop );
|
|
886
|
+
return 0;
|
|
988
887
|
}
|
|
989
888
|
|
|
990
|
-
function
|
|
991
|
-
//
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
// if we consider this an error or such sub annotates are then ignored
|
|
998
|
-
// (i.e. not put into the "super annotate").
|
|
999
|
-
const dict = parent[prop];
|
|
1000
|
-
const securityRelevant = hasSecurityAnno( ext ) ? '-sec' : '';
|
|
1001
|
-
const inSuperAnnotate = (parent.kind === 'annotate');
|
|
1002
|
-
if (!dict && !securityRelevant) {
|
|
1003
|
-
if (inSuperAnnotate) // no check in super annotate statement
|
|
1004
|
-
return;
|
|
1005
|
-
// TODO: check - for each name? - better locations
|
|
1006
|
-
const location = ext._parent?.[prop]?.[$location] || ext.name.location;
|
|
1007
|
-
// Remark: no `elements` dict location with `annotate Main:elem`
|
|
1008
|
-
switch (prop) {
|
|
1009
|
-
// TODO: change texts, somehow similar to checkDefinitions() ?
|
|
1010
|
-
case 'foreignKeys':
|
|
1011
|
-
case 'elements':
|
|
1012
|
-
case 'enum': // TODO: extra?
|
|
1013
|
-
warning( 'anno-unexpected-elements', [ location, ext._parent ],
|
|
1014
|
-
{ '#': (parent._effectiveType?.kind === 'entity') ? 'entity' : 'std' }, {
|
|
1015
|
-
std: 'Elements only exist in entities, types or typed constructs',
|
|
1016
|
-
entity: 'Elements of entity types can\'t be annotated',
|
|
1017
|
-
// TODO: extra msg for 'entity'? → this is some other
|
|
1018
|
-
// situation, somehow similar when trying to annotate elements
|
|
1019
|
-
// of target entity
|
|
1020
|
-
} );
|
|
1021
|
-
break;
|
|
1022
|
-
case 'params':
|
|
1023
|
-
warning( 'anno-unexpected-params', [ location, ext._parent ], {},
|
|
1024
|
-
'Parameters only exist for actions or functions' );
|
|
1025
|
-
break;
|
|
1026
|
-
case 'actions':
|
|
1027
|
-
if (canBeDraftMember( name, parent, draftBoundActions ))
|
|
1028
|
-
return;
|
|
1029
|
-
// TODO: use extra text variant and location of dictionary - no
|
|
1030
|
-
notFound( 'ext-undefined-action', ext.name.location, ext,
|
|
1031
|
-
{ '#': 'action', art: parent, name } );
|
|
1032
|
-
break;
|
|
1033
|
-
default:
|
|
1034
|
-
if (model.options.testMode)
|
|
1035
|
-
throw new CompilerAssertion(`Missing case for prop: ${ prop }`);
|
|
1036
|
-
}
|
|
889
|
+
function addExtensionEnum( ext, art, obj ) {
|
|
890
|
+
// TODO: test `extend Enum with Include;
|
|
891
|
+
const artDict = obj.enum;
|
|
892
|
+
if (!artDict) {
|
|
893
|
+
if (ext.enum)
|
|
894
|
+
error( 'def-unexpected-enum', [ ext.enum[$location] || ext.name.location, ext ], {} );
|
|
895
|
+
return;
|
|
1037
896
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
break;
|
|
1060
|
-
case 'params':
|
|
1061
|
-
notFound( `ext-undefined-param${ securityRelevant }`, ext.name.location, ext,
|
|
1062
|
-
{ '#': 'param', name },
|
|
1063
|
-
parent.params );
|
|
1064
|
-
break;
|
|
1065
|
-
case 'actions':
|
|
1066
|
-
if (canBeDraftMember( name, parent, draftBoundActions ))
|
|
1067
|
-
break;
|
|
1068
|
-
notFound( `ext-undefined-action${ securityRelevant }`, ext.name.location, ext,
|
|
1069
|
-
{ '#': 'action', name },
|
|
1070
|
-
parent.actions );
|
|
1071
|
-
break;
|
|
1072
|
-
default:
|
|
1073
|
-
if (model.options.testMode)
|
|
1074
|
-
throw new CompilerAssertion(`Missing case for prop: ${ prop }`);
|
|
897
|
+
if (ext.kind)
|
|
898
|
+
dependsOnSilent( art, ext ); // TODO: really do that here?
|
|
899
|
+
// art depends silently on ext (inverse to normal dep!), still necessary?
|
|
900
|
+
const extDict = ext.enum || ext.elements;
|
|
901
|
+
if (!extDict) // i.e. includes-only extension
|
|
902
|
+
return;
|
|
903
|
+
const notEnum = [];
|
|
904
|
+
if (ext.kind && (art.$inferred || art.query))
|
|
905
|
+
reportExtensionOnGenerated( ext, art, 'enum', extDict );
|
|
906
|
+
for (const name in extDict) {
|
|
907
|
+
const adding = extDict[name];
|
|
908
|
+
if (adding.kind === 'annotate' || adding.kind === 'extend')
|
|
909
|
+
continue;
|
|
910
|
+
if (adding.kind === 'enum' || adding.$syntax === 'or-enum') {
|
|
911
|
+
notEnum.addedAnyway = true;
|
|
912
|
+
adding.kind = 'enum';
|
|
913
|
+
initMember( adding, art, 'enum' );
|
|
914
|
+
dictAdd( artDict, name, adding, reportDuplicate );
|
|
915
|
+
}
|
|
916
|
+
else {
|
|
917
|
+
notEnum.push( name ); // not added to enum dict!
|
|
1075
918
|
}
|
|
1076
919
|
}
|
|
920
|
+
if (notEnum.length) {
|
|
921
|
+
error( 'ext-unexpected-element', [ extDict[$location], ext ],
|
|
922
|
+
{ code: 'extend … with enum', names: notEnum } );
|
|
923
|
+
}
|
|
924
|
+
else if (notEnum.addedAnyway &&
|
|
925
|
+
(!obj.type || obj.type.$inferred || (art._main || art).query)) {
|
|
926
|
+
// TODO: really improve msg id and text
|
|
927
|
+
error( 'extend-type', [ extDict[$location], ext ], {},
|
|
928
|
+
'Only structures or enum types can be extended with elements/enums' );
|
|
929
|
+
}
|
|
930
|
+
else if (!ext.enum) {
|
|
931
|
+
warning( 'ext-expecting-enum', [ extDict[$location], ext ],
|
|
932
|
+
{ code: 'extend … with enum' }, 'Use $(CODE) when extending enums' );
|
|
933
|
+
}
|
|
1077
934
|
}
|
|
1078
935
|
|
|
1079
|
-
function
|
|
1080
|
-
|
|
1081
|
-
|
|
936
|
+
function postponeFirstInclude( includes, members ) {
|
|
937
|
+
if (!includes?.length)
|
|
938
|
+
return -1;
|
|
939
|
+
const postpone = includes[0].$postponeInclude;
|
|
940
|
+
if (postpone != null || !members) // TODO v8: `(postpone !== -1)`
|
|
941
|
+
return postpone ?? 0;
|
|
942
|
+
// compatibility: includes in definition - if elements cover all elements from
|
|
943
|
+
// includes, use provided order - TODO v8: only for CSN input
|
|
944
|
+
for (const ref of includes) {
|
|
945
|
+
const elements = ref._artifact?.elements;
|
|
946
|
+
if (elements && Object.keys( elements ).some( name => !members[name] ))
|
|
947
|
+
return 0; // some element in some include not covered → normal order
|
|
948
|
+
}
|
|
949
|
+
return -1; // includes last = use provided element order
|
|
1082
950
|
}
|
|
1083
951
|
|
|
1084
|
-
|
|
952
|
+
function applyInclude( ref, nextRef, art, prop ) {
|
|
953
|
+
const include = ref._artifact; // already resolved
|
|
954
|
+
const members = include?.[prop];
|
|
955
|
+
if (!members)
|
|
956
|
+
return nextRef ? nextRef.$postponeInclude ?? 0 : -1;
|
|
1085
957
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
958
|
+
// If elements `texts` and `localized` from an included entity are (likely)
|
|
959
|
+
// compiler-generated, users won't expect them to be included:
|
|
960
|
+
const checkForLocalized = prop === 'elements' && include.kind === 'entity' &&
|
|
961
|
+
!include.query && withLocalizedData( include );
|
|
962
|
+
const propagateKeys = art.kind !== 'type' || model.options.v6KeyPropagation;
|
|
963
|
+
|
|
964
|
+
for (const name in members) {
|
|
965
|
+
const existing = art[prop][name];
|
|
966
|
+
if (existing && existing.$inferred !== 'include' ||
|
|
967
|
+
checkForLocalized && (name === 'texts' || name === 'localized'))
|
|
968
|
+
continue; // shadowed by directly defined/extended element, or localized
|
|
969
|
+
const origin = members[name];
|
|
970
|
+
if (origin.$duplicates) // duplicates are not included
|
|
971
|
+
continue;
|
|
972
|
+
const location = weakRefLocation( ref );
|
|
973
|
+
const proxy = linkToOrigin( origin, name, null, null, location );
|
|
974
|
+
setLink( proxy, '_block', origin._block ); // TODO: why is this necessary?
|
|
975
|
+
proxy.$inferred = 'include';
|
|
976
|
+
if (origin.key && propagateKeys)
|
|
977
|
+
proxy.key = Object.assign( { $inferred: 'include' }, origin.key );
|
|
978
|
+
// TODO: origin.$syntax === 'calc' test?
|
|
979
|
+
if (origin.value && origin.$syntax === 'calc') {
|
|
980
|
+
// TODO: If paths become invalid in the new artifact, should we mark
|
|
981
|
+
// all usages in the expressions? Possibly just the first one?
|
|
982
|
+
proxy.value = { $inferred: 'include', ...copyExpr( origin.value, location, true ) };
|
|
983
|
+
proxy.$syntax = 'calc';
|
|
984
|
+
createAndLinkCalcDepElement( proxy );
|
|
985
|
+
setLink( proxy, '_calcOrigin', origin._calcOrigin || origin );
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
setLink( proxy, '_parent', art );
|
|
989
|
+
setLink( proxy, '_main', art );
|
|
990
|
+
initMember( proxy, art );
|
|
991
|
+
dictAdd( art[prop], name, proxy );
|
|
992
|
+
// delayed reporting of duplicates via reportRedefinitionThroughIncludes()
|
|
993
|
+
}
|
|
994
|
+
return nextRef ? nextRef.$postponeInclude ?? 0 : -1;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
/**
|
|
998
|
+
* Return true if include (with `name` and `elements`) in `ext` highly likely
|
|
999
|
+
* contain elements `texts` and `localized` which are compiler-generated for
|
|
1000
|
+
* localized data. Due to recompilation, we cannot just check the `$inferred`
|
|
1001
|
+
* property in the XSN, but need to apply an heuristics.
|
|
1002
|
+
* (We could still use $inferred as speed-up if run without `testMode`.)
|
|
1003
|
+
*
|
|
1004
|
+
* It is as follows: the elements `texts` and `localized` in entity `‹E›` and
|
|
1005
|
+
* the entity `‹E›.texts` are considered compiler-generated for Localized Data if
|
|
1006
|
+
*
|
|
1007
|
+
* - `‹E›.texts` has a key element `locale`
|
|
1008
|
+
* (TODO: currently weakend to “entity exists”)
|
|
1009
|
+
* - `texts` of `‹E›` is an unmanaged composition to `‹E›.texts`
|
|
1010
|
+
* - `localized` of `‹E›` is an unmanaged association to `‹E›.texts`
|
|
1011
|
+
*/
|
|
1012
|
+
function withLocalizedData( { name, elements } ) { // TODO: use it again
|
|
1013
|
+
const textsEntityName = `${ name.id }.texts`;
|
|
1014
|
+
// if we test (again) for element `locale` - it might come from an extend or
|
|
1015
|
+
// TextsAspect include, which might not have yet applied
|
|
1016
|
+
if (!model.definitions[textsEntityName])
|
|
1017
|
+
return false;
|
|
1018
|
+
const { texts, localized } = elements ?? {};
|
|
1019
|
+
return texts?.target && localized?.target && texts.on && localized.on &&
|
|
1020
|
+
resolveUncheckedPath( texts.target, 'target', texts ) === textsEntityName &&
|
|
1021
|
+
resolveUncheckedPath( localized.target, 'target', localized ) === textsEntityName &&
|
|
1022
|
+
resolveUncheckedPath( texts.type, 'type', texts ) === 'cds.Composition' &&
|
|
1023
|
+
resolveUncheckedPath( localized.type, 'type', localized ) === 'cds.Association';
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
function initMember( member, parent, prop = 'elements' ) {
|
|
1027
|
+
if (member._parent === parent) // origin element → nothing to do
|
|
1028
|
+
return;
|
|
1029
|
+
changeParentLinks( member, parent );
|
|
1030
|
+
if (member.targetAspect?.elements)
|
|
1031
|
+
setLink( member.targetAspect, '_parent', member._parent );
|
|
1032
|
+
|
|
1033
|
+
if (member.kind === 'action' || member.kind === 'function')
|
|
1034
|
+
initBoundSelfParam( member.params, member._main );
|
|
1035
|
+
|
|
1036
|
+
if (parent[prop]?.[$inferred])
|
|
1037
|
+
setExpandStatus( parent, 'extend' );
|
|
1038
|
+
|
|
1039
|
+
if (member.$syntax === 'or-enum' && member.value && member.kind === 'element') {
|
|
1040
|
+
member.$syntax = 'calc';
|
|
1041
|
+
createAndLinkCalcDepElement( member );
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
function changeParentLinks( art, parentOrMain ) { // or just `parentOrMain`?
|
|
1046
|
+
// TODO: we might also change the implicit name (if name.id is a number,
|
|
1047
|
+
// adding the previous column lenght - 1) for better error messages
|
|
1048
|
+
if (art._parent?.kind === 'extend')
|
|
1049
|
+
setLink( art, '_parent', parentOrMain );
|
|
1050
|
+
if (art._outer?.kind === 'extend')
|
|
1051
|
+
setLink( art, '_outer', parentOrMain );
|
|
1052
|
+
if (art._main?.kind === 'extend')
|
|
1053
|
+
setLink( art, '_main', parentOrMain._main || parentOrMain );
|
|
1054
|
+
if (art._columnParent?.kind === 'extend')
|
|
1055
|
+
art._columnParent = parentOrMain;
|
|
1056
|
+
const subColumns = art.expand || art.inline;
|
|
1057
|
+
if (subColumns)
|
|
1058
|
+
subColumns.forEach( a => changeParentLinks( a, parentOrMain ) );
|
|
1059
|
+
forEachMember( initItemsLinks( art, art._block ),
|
|
1060
|
+
a => changeParentLinks( a, parentOrMain ) );
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
// Create “super” ANNOTATE statements -----------------------------------------
|
|
1064
|
+
|
|
1065
|
+
/**
|
|
1066
|
+
* Create super annotate statements for remaining extensions.
|
|
1067
|
+
* Called near the end of the compilation.
|
|
1068
|
+
*/
|
|
1069
|
+
function createRemainingAnnotateStatements() {
|
|
1070
|
+
model.extensions = Object.values( model.$collectedExtensions );
|
|
1071
|
+
// TODO: testMode sort?
|
|
1072
|
+
model.extensions.forEach( createSuperAnnotate );
|
|
1073
|
+
// set _artifact links for “main extensions” late as it would disturb the
|
|
1074
|
+
// still existing old extend mechanism, see extendArtifactBefore(),
|
|
1075
|
+
// needed for LSP and friends:
|
|
1076
|
+
Object.values( model.sources ).forEach( setArtifactLinkForExtensions );
|
|
1077
|
+
Object.values( model.definitions ).forEach( setArtifactLinkForExtensions );
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
function createSuperAnnotate( annotate ) {
|
|
1081
|
+
const extensions = annotate._extensions;
|
|
1082
|
+
if (extensions && !annotate._main) {
|
|
1089
1083
|
const art = model.definitions[annotate.name.id];
|
|
1090
1084
|
for (const ext of extensions)
|
|
1091
|
-
|
|
1085
|
+
reportExtensionOnBuiltin( art, ext ); // induce messages for extension path
|
|
1092
1086
|
if (art?.builtin && art.kind !== 'namespace') { // TODO: do not set `builtin` on cds, cds.hana
|
|
1093
1087
|
setLink( annotate, '_extensions', art._extensions ); // for messages and member extensions
|
|
1094
1088
|
// direct annotations on builtins or on the builtins for propagation, and
|
|
@@ -1108,716 +1102,559 @@ function extend( model ) {
|
|
|
1108
1102
|
forEachMember( annotate, createSuperAnnotate );
|
|
1109
1103
|
}
|
|
1110
1104
|
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
if (typeProp) {
|
|
1120
|
-
const location = ext.$typeArgs?.[$location] || ext[typeProp].location;
|
|
1121
|
-
message( 'ext-unexpected-type-property', [ location, ext ], {}, // error v7
|
|
1122
|
-
'Built-in types can\'t be extended with type properties' );
|
|
1123
|
-
// see also 'ext-invalid-type-property'
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
else {
|
|
1127
|
-
info( 'anno-builtin', [ ext.name.location, ext ], {} ); // TODO: better location?
|
|
1128
|
-
}
|
|
1129
|
-
// TODO: remove built-ins as CC candidates via accept property of ./shared.js
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
// Issue messages for annotations on namespaces and builtins
|
|
1134
|
-
// (TODO: really here?, probably split main artifacts vs returns)
|
|
1135
|
-
// see also createRemainingAnnotateStatements() where similar messages are reported
|
|
1136
|
-
function checkAnnotate( construct, art ) {
|
|
1137
|
-
// TODO: Handle extend statements properly: Different message for empty extend?
|
|
1105
|
+
// TODO: delete again - if not, what about extensions in contexts/services?
|
|
1106
|
+
// Check test.lsp-api.js! Links in extensions are needed.
|
|
1107
|
+
function setArtifactLinkForExtensions( source ) {
|
|
1108
|
+
if (!source.extensions)
|
|
1109
|
+
return;
|
|
1110
|
+
for (const ext of source.extensions) {
|
|
1111
|
+
if (!ext.name?.id)
|
|
1112
|
+
continue;
|
|
1138
1113
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
if (
|
|
1142
|
-
//
|
|
1114
|
+
const { name } = ext;
|
|
1115
|
+
const { path } = name;
|
|
1116
|
+
if (name._artifact === undefined) {
|
|
1117
|
+
resolvePath( name, ext.kind, ext ); // induce error & for LSP
|
|
1143
1118
|
}
|
|
1144
|
-
else if (
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
}, {
|
|
1149
|
-
std: 'Expected $(CODE)', // unused variant
|
|
1150
|
-
action: 'Expected $(KEYWORD) when annotating action return structure, i.e. $(CODE)',
|
|
1151
|
-
function: 'Expected $(KEYWORD) when annotating function return structure, i.e. $(CODE)',
|
|
1152
|
-
} );
|
|
1119
|
+
else if (model.options.lspMode && path?.[0]._artifact === undefined) {
|
|
1120
|
+
// we don't use resolvePath(…,'extend'), as that would add a dependency
|
|
1121
|
+
resolveDefinitionName( ext );
|
|
1122
|
+
setArtifactLink( path[path.length - 1], name._artifact );
|
|
1153
1123
|
}
|
|
1154
1124
|
}
|
|
1155
1125
|
}
|
|
1156
1126
|
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1127
|
+
function annotateFor( art, prop, name ) {
|
|
1128
|
+
const base = annotateBase( art );
|
|
1129
|
+
if (name === '' && prop === 'params')
|
|
1130
|
+
return base.returns || annotateCreate( base, name, base, 'returns' );
|
|
1131
|
+
const dict = base[prop] || (base[prop] = Object.create( null ));
|
|
1132
|
+
if (name == null)
|
|
1133
|
+
return dict;
|
|
1134
|
+
return dict[name] || annotateCreate( dict, name, base );
|
|
1162
1135
|
}
|
|
1163
1136
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
function extendArtifactAdd( art ) {
|
|
1170
|
-
const { includes } = art;
|
|
1171
|
-
if (includes) {
|
|
1172
|
-
if (includes.$original) // if extensions with includes:
|
|
1173
|
-
art.includes = includes.$original; // original includes have been stored
|
|
1174
|
-
if (art.includes?.length)
|
|
1175
|
-
applyIncludes( art, art ); // apply includes provided with definition
|
|
1176
|
-
else if (art.elements) // next include only after elements so far
|
|
1177
|
-
art.$postponeInclude += addedElements( art );
|
|
1178
|
-
|
|
1179
|
-
art.includes = includes;
|
|
1180
|
-
// early propagation of specific annotation assignments
|
|
1181
|
-
// TODO: propagate in effectiveType() ?
|
|
1182
|
-
propagateEarly( art, '@cds.autoexpose' );
|
|
1183
|
-
propagateEarly( art, '@fiori.draft.enabled' );
|
|
1184
|
-
}
|
|
1185
|
-
if (art._extensions?.$add)
|
|
1186
|
-
extendArtifact( art._extensions.$add, art ); // apply extensions
|
|
1187
|
-
checkRedefinitionThroughIncludes( art, 'elements' );
|
|
1188
|
-
checkRedefinitionThroughIncludes( art, 'actions' );
|
|
1189
|
-
}
|
|
1137
|
+
function annotateBase( art ) {
|
|
1138
|
+
while (art._outer) // TODO: think about anonymous target aspect
|
|
1139
|
+
art = art._outer;
|
|
1140
|
+
if (art.kind === 'annotate')
|
|
1141
|
+
return art;
|
|
1190
1142
|
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
* @param {XSN.Extension[]} extensions
|
|
1201
|
-
* @param {XSN.Definition} art
|
|
1202
|
-
* @param {String[]|false} [cyclicIncludeNames=false]
|
|
1203
|
-
*/
|
|
1204
|
-
function extendArtifact( extensions, art ) {
|
|
1205
|
-
if (!art.query && !art._main && !art._outer) { // TODO: remove _entities
|
|
1206
|
-
model._entities.push( art ); // add structure with includes in dep order
|
|
1207
|
-
}
|
|
1208
|
-
// TODO: complain if $inferred
|
|
1209
|
-
// checkExtensionsKind( extensions, art );
|
|
1210
|
-
extendMembers( extensions, art );
|
|
1211
|
-
reportIncludeCollisions( art );
|
|
1212
|
-
// TODO: complain about element extensions inside projection
|
|
1213
|
-
return true;
|
|
1143
|
+
// TODO: more to do if annotate can have `returns` property
|
|
1144
|
+
if (art.kind === 'select')
|
|
1145
|
+
art = art._parent;
|
|
1146
|
+
if (art._main)
|
|
1147
|
+
return annotateFor( art._parent, kindProperties[art.kind].dict, art.name.id );
|
|
1148
|
+
|
|
1149
|
+
const { id } = art.name;
|
|
1150
|
+
return model.$collectedExtensions[id] ||
|
|
1151
|
+
annotateCreate( model.$collectedExtensions, id );
|
|
1214
1152
|
}
|
|
1215
1153
|
|
|
1216
|
-
function
|
|
1217
|
-
const
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
const { prop, name, collisions } = grouped[key];
|
|
1228
|
-
const member = art[prop]?.[name];
|
|
1229
|
-
if (member?.$inferred === 'include') {
|
|
1230
|
-
const arts = [ ...collisions ].map( m => m._origin._main );
|
|
1231
|
-
message( 'ext-duplicate-include', [ art.name.location, member ],
|
|
1232
|
-
{ '#': prop, name, sorted_arts: arts } );
|
|
1233
|
-
}
|
|
1154
|
+
function annotateCreate( dict, id, parent, prop ) {
|
|
1155
|
+
const annotate = {
|
|
1156
|
+
__proto__: XsnArtifact.prototype,
|
|
1157
|
+
kind: 'annotate',
|
|
1158
|
+
name: { __proto__: XsnName.prototype, id, location: genLocation },
|
|
1159
|
+
$inferred: '',
|
|
1160
|
+
location: genLocation,
|
|
1161
|
+
};
|
|
1162
|
+
if (parent) {
|
|
1163
|
+
setLink( annotate, '_parent', parent );
|
|
1164
|
+
setLink( annotate, '_main', parent._main || parent );
|
|
1234
1165
|
}
|
|
1235
|
-
|
|
1166
|
+
dict[prop || id] = annotate;
|
|
1167
|
+
return annotate;
|
|
1236
1168
|
}
|
|
1237
1169
|
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
// TODO: do the whole extension stuff lazily if the elements are requested
|
|
1241
|
-
const elemExtensions = [];
|
|
1242
|
-
// if (art._main) // extensions already sorted for main artifacts
|
|
1243
|
-
// extensions.sort( layers.compareLayer );
|
|
1244
|
-
// TODO: use same sequence as in chooseAssignment() - better: use common code with that fn
|
|
1245
|
-
// console.log('EM:',art.name,extensions,art._extensions)
|
|
1246
|
-
for (const ext of extensions) { // those in extMap.includes
|
|
1247
|
-
if (art.$inferred === 'include') {
|
|
1248
|
-
error( 'ref-expected-direct-structure', [ ext.name.location, ext ],
|
|
1249
|
-
{ '#': 'elements', art } );
|
|
1250
|
-
}
|
|
1251
|
-
else if (art.$inferred) {
|
|
1252
|
-
error( 'extend-for-generated', [ ext.name.location, ext ], { art, keyword: 'extend' },
|
|
1253
|
-
'You can\'t use $(KEYWORD) on the generated $(ART)' ); // or with inferred elements
|
|
1254
|
-
}
|
|
1170
|
+
// Issue messages about dubious extensions ------------------------------------
|
|
1171
|
+
// checkXYZ() = return whether to extend, reportXYZ() = extend anyway
|
|
1255
1172
|
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1173
|
+
// called from extendArtifactAfter()
|
|
1174
|
+
function checkExtensionDictionary( ext, art, artProp, extProp ) {
|
|
1175
|
+
if (art.kind === 'annotate') // the super annotate
|
|
1176
|
+
return true;
|
|
1177
|
+
// assume dict not on art
|
|
1178
|
+
const dict = ext[extProp];
|
|
1179
|
+
const location = dict?.[$location] ||
|
|
1180
|
+
dictFirst( dict )?.name?.location || // for `annotate E:elem`
|
|
1181
|
+
ext.name.location;
|
|
1182
|
+
switch (artProp) {
|
|
1183
|
+
case 'params':
|
|
1184
|
+
// currently just via `annotate`, TODO: test w/ CSN input
|
|
1185
|
+
warning( 'anno-unexpected-params', [ location, ext ], {},
|
|
1186
|
+
'Parameters only exist for actions or functions' );
|
|
1187
|
+
// TODO text: or query entities
|
|
1188
|
+
break;
|
|
1189
|
+
case 'actions':
|
|
1190
|
+
// extendArtifactAdd() had created actions prop with correct actions extensions
|
|
1191
|
+
if (ext.kind === 'extend' && Object.keys( dict ).length) {
|
|
1192
|
+
error( 'def-unexpected-actions', [ location, ext ], {}, // TODO: ext-
|
|
1193
|
+
'Actions and functions only exist top-level and for entities' ); // or aspects
|
|
1194
|
+
}
|
|
1195
|
+
else { // annotate or empty dict
|
|
1196
|
+
warning( 'ext-ignoring-actions', [ location, ext ], {},
|
|
1197
|
+
'Actions and functions only exist top-level and for entities' );
|
|
1198
|
+
return true;
|
|
1199
|
+
}
|
|
1200
|
+
break;
|
|
1201
|
+
case 'elements':
|
|
1202
|
+
if (ext.kind === 'annotate') {
|
|
1203
|
+
warning( 'anno-unexpected-elements', [ location, ext ],
|
|
1204
|
+
{ '#': art.type?._artifact?.kind } );
|
|
1205
|
+
// extra msg variant for entity as parameter type
|
|
1206
|
+
}
|
|
1207
|
+
else if (ext.kind === 'extend' && Object.keys( dict ).length) {
|
|
1208
|
+
// TODO v8: also error with empty dict
|
|
1209
|
+
const msgid = [ 'type', 'aspect' ].includes( art.kind )
|
|
1210
|
+
? 'extend-type'
|
|
1211
|
+
: 'def-unexpected-elements';
|
|
1212
|
+
error( msgid, [ location, ext ], {} );
|
|
1213
|
+
}
|
|
1214
|
+
else { // annotate or empty dict
|
|
1215
|
+
warning( 'ext-ignoring-elements', [ location, ext ], {},
|
|
1216
|
+
'Only structures with directly specified elements can be extended by elements' );
|
|
1217
|
+
return true;
|
|
1218
|
+
}
|
|
1219
|
+
break;
|
|
1220
|
+
case 'enum':
|
|
1221
|
+
if (ext.kind === 'extend') {
|
|
1222
|
+
const msgid = art.kind === 'type' ? 'extend-type' : 'def-unexpected-enum';
|
|
1223
|
+
error( msgid, [ location, ext ], {} );
|
|
1276
1224
|
}
|
|
1225
|
+
break;
|
|
1226
|
+
case 'foreignKeys': {
|
|
1227
|
+
// currently just via `annotate`
|
|
1228
|
+
warning( 'ext-undefined-key', [ location, ext ], { '#': 'dict' } );
|
|
1229
|
+
break;
|
|
1277
1230
|
}
|
|
1231
|
+
default:
|
|
1232
|
+
if (model.options.testMode)
|
|
1233
|
+
throw new CompilerAssertion(`Missing case for prop: ${ artProp }`);
|
|
1278
1234
|
}
|
|
1279
|
-
|
|
1280
|
-
|
|
1235
|
+
return ext.kind === 'annotate';
|
|
1236
|
+
// Remark: to detect security-relevant annotation on (sub) members,
|
|
1237
|
+
// super-annotates must be created (→ return true) when no error is reported.
|
|
1238
|
+
}
|
|
1281
1239
|
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
for (const n in e.elements) {
|
|
1290
|
-
if (e.elements[n].kind === 'extend')
|
|
1291
|
-
pushToDict( dict, n, e.elements[n] );
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
for (const name in dict) {
|
|
1295
|
-
let obj = art;
|
|
1296
|
-
if (obj.targetAspect)
|
|
1297
|
-
obj = obj.targetAspect;
|
|
1298
|
-
while (obj.items)
|
|
1299
|
-
obj = obj.items;
|
|
1300
|
-
const validDict = obj.elements || obj.enum;
|
|
1301
|
-
const member = validDict && validDict[name];
|
|
1302
|
-
if (!member)
|
|
1303
|
-
extendNothing( dict[name], 'elements', name, art, validDict );
|
|
1304
|
-
}
|
|
1240
|
+
function reportDuplicate( name, location, art ) {
|
|
1241
|
+
if (art.$duplicates) // already reported in define.js
|
|
1242
|
+
return;
|
|
1243
|
+
error( 'duplicate-definition', [ art.name.location, art ], {
|
|
1244
|
+
name: art.name.id,
|
|
1245
|
+
'#': kindProperties[art.kind].normalized || art.kind,
|
|
1246
|
+
} );
|
|
1305
1247
|
}
|
|
1306
1248
|
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
//
|
|
1315
|
-
|
|
1316
|
-
if (extensions.every( ( ext, i ) => !i || file === layers.realname( ext ) ))
|
|
1249
|
+
function reportUnexpectedMemberExtensions( parent, ext, prop, name ) {
|
|
1250
|
+
const securityRelevant = hasSecurityAnno( ext ) ? '-sec' : '';
|
|
1251
|
+
const dict = (parent.kind === 'annotate') ? null : parent[prop];
|
|
1252
|
+
// real dictionary, not just one in the super-annotate
|
|
1253
|
+
|
|
1254
|
+
// checkExtensionDictionary() had complained about extension with unexpected
|
|
1255
|
+
// dict property → new message just for missing art member (or if security
|
|
1256
|
+
// relevant)
|
|
1257
|
+
if (dict ? dict[name] : !securityRelevant)
|
|
1317
1258
|
return;
|
|
1318
|
-
|
|
1319
|
-
//
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1259
|
+
|
|
1260
|
+
// Remark: there can currently be just an extend in elements/enum, not actions etc
|
|
1261
|
+
switch (prop) {
|
|
1262
|
+
case 'elements':
|
|
1263
|
+
case 'enum': {
|
|
1264
|
+
if (ext.kind === 'annotate' && parent.kind === 'entity' &&
|
|
1265
|
+
canBeDraftMember( name, parent, draftElements ))
|
|
1266
|
+
break;
|
|
1267
|
+
const msgId = (ext.kind === 'extend')
|
|
1268
|
+
? 'extend-undefined'
|
|
1269
|
+
: `ext-undefined-element${ securityRelevant }`;
|
|
1270
|
+
// eslint-disable-next-line no-nested-ternary
|
|
1271
|
+
const msgVn = (!parent._parent?.returns)
|
|
1272
|
+
? prop
|
|
1273
|
+
: (prop === 'enum' ? 'enum-returns' : 'returns');
|
|
1274
|
+
notFound( msgId, ext.name.location, ext,
|
|
1275
|
+
{ '#': msgVn, name, art: parent },
|
|
1276
|
+
dict );
|
|
1277
|
+
break;
|
|
1335
1278
|
}
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
'Unstable element order due to other extension in unrelated layer' );
|
|
1341
|
-
}
|
|
1342
|
-
lastExt = ext;
|
|
1343
|
-
open = open.filter( name => !extLayer._layerExtends[name] );
|
|
1344
|
-
open.push( extLayer.realname );
|
|
1279
|
+
case 'foreignKeys': {
|
|
1280
|
+
notFound( `ext-undefined-key${ securityRelevant }`, ext.name.location, ext,
|
|
1281
|
+
{ name }, parent.foreignKeys );
|
|
1282
|
+
break;
|
|
1345
1283
|
}
|
|
1284
|
+
case 'params':
|
|
1285
|
+
notFound( `ext-undefined-param${ securityRelevant }`, ext.name.location, ext,
|
|
1286
|
+
{ '#': 'param', name },
|
|
1287
|
+
dict );
|
|
1288
|
+
break;
|
|
1289
|
+
case 'actions':
|
|
1290
|
+
if (ext.kind === 'annotate' && parent.kind === 'entity' &&
|
|
1291
|
+
canBeDraftMember( name, parent, draftBoundActions ))
|
|
1292
|
+
break;
|
|
1293
|
+
notFound( `ext-undefined-action${ securityRelevant }`, ext.name.location, ext,
|
|
1294
|
+
{ '#': 'action', name },
|
|
1295
|
+
dict );
|
|
1296
|
+
break;
|
|
1297
|
+
default:
|
|
1298
|
+
if (model.options.testMode)
|
|
1299
|
+
throw new CompilerAssertion(`Missing case for prop: ${ prop }`);
|
|
1346
1300
|
}
|
|
1347
1301
|
}
|
|
1348
1302
|
|
|
1349
|
-
|
|
1350
1303
|
/**
|
|
1351
|
-
*
|
|
1352
|
-
*
|
|
1353
|
-
* @param {string} name
|
|
1354
|
-
* @param {XSN.Artifact} art
|
|
1355
|
-
* @param {object} validDict
|
|
1304
|
+
* Complain about invalid `extend service` and `extend context`.
|
|
1305
|
+
* Called in extendArtifactBefore().
|
|
1356
1306
|
*/
|
|
1357
|
-
function
|
|
1358
|
-
// TODO: probably too much magic in the creation of artName…
|
|
1359
|
-
const extMain = { ...(art._main || art) };
|
|
1360
|
-
const artName = searchName( art, name, dictKinds[prop] );
|
|
1361
|
-
setLink( artName, '_main', extMain );
|
|
1307
|
+
function reportInvalidExtensionKind( extensions, art ) {
|
|
1362
1308
|
for (const ext of extensions) {
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
*
|
|
1383
|
-
* (Only) if called recursively: `construct === parent`
|
|
1384
|
-
*
|
|
1385
|
-
* TODO: separate extension!
|
|
1386
|
-
*/
|
|
1387
|
-
function initMembers( construct, parent, block ) {
|
|
1388
|
-
// only called by extendMembers() and recursively
|
|
1389
|
-
// TODO: split extend from init
|
|
1390
|
-
const obj = initItemsLinks( construct, block );
|
|
1391
|
-
initExprAnnoBlock( construct, block, error );
|
|
1392
|
-
if (parent.targetAspect?.elements)
|
|
1393
|
-
parent = parent.targetAspect;
|
|
1394
|
-
const main = parent._main || parent;
|
|
1395
|
-
const isQueryExtension = construct.kind === 'extend' && main.query;
|
|
1396
|
-
|
|
1397
|
-
if (obj !== parent && obj.elements && parent.enum) { // applying the extension
|
|
1398
|
-
initElementsAsEnum();
|
|
1399
|
-
if (parent.enum[$inferred])
|
|
1400
|
-
setExpandStatus( parent, 'extend' );
|
|
1401
|
-
}
|
|
1402
|
-
else {
|
|
1403
|
-
if (checkDefinitions( construct, parent, 'elements', obj.elements || false ))
|
|
1404
|
-
forEachInOrder( obj, 'elements', init );
|
|
1405
|
-
if (checkDefinitions( construct, parent, 'enum', obj.enum || false ))
|
|
1406
|
-
forEachGeneric( obj, 'enum', init );
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
if (obj.foreignKeys)
|
|
1410
|
-
forEachInOrder( obj, 'foreignKeys', init );
|
|
1411
|
-
if (checkDefinitions( construct, parent, 'actions' ))
|
|
1412
|
-
forEachGeneric( construct, 'actions', init );
|
|
1413
|
-
if (checkDefinitions( construct, parent, 'params' ))
|
|
1414
|
-
forEachInOrder( construct, 'params', init );
|
|
1415
|
-
const { returns } = construct;
|
|
1416
|
-
if (returns) {
|
|
1417
|
-
const { kind } = construct;
|
|
1418
|
-
returns.kind = (kind === 'extend' || kind === 'annotate') ? kind : 'param';
|
|
1419
|
-
init( returns, '' ); // '' is special name for returns parameter
|
|
1420
|
-
}
|
|
1421
|
-
return;
|
|
1422
|
-
|
|
1423
|
-
// We allow `extend MyEnum with {…}` and not just `extend MyEnum with enum {…}`
|
|
1424
|
-
// for compatibility, with a warning.
|
|
1425
|
-
function initElementsAsEnum() {
|
|
1426
|
-
// in extensions, extended enums are represented as elements
|
|
1427
|
-
let hasElement = false;
|
|
1428
|
-
for (const n in obj.elements) {
|
|
1429
|
-
const e = obj.elements[n];
|
|
1430
|
-
if (e.kind === 'extend')
|
|
1431
|
-
continue;
|
|
1432
|
-
if (e.$syntax !== 'or-enum') { // parser might set $syntax: 'or-enum'
|
|
1433
|
-
// We do not want to complain separately about all element properties:
|
|
1434
|
-
error( 'ext-unexpected-element', [ e.location, construct ],
|
|
1435
|
-
{ name: e.name.id, code: 'extend … with enum' },
|
|
1436
|
-
// eslint-disable-next-line @stylistic/max-len
|
|
1437
|
-
'Unexpected elements like $(NAME) in an extension for an enum. Additionally, use $(CODE) when extending enums' );
|
|
1438
|
-
// Don't emit 'ext-expecting-enum' if this error is emitted.
|
|
1439
|
-
return;
|
|
1309
|
+
const kind = ext.expectedKind?.val;
|
|
1310
|
+
if (kind && kind !== art.kind) {
|
|
1311
|
+
const loc = ext.expectedKind.location;
|
|
1312
|
+
if (kind === 'context' || kind === 'service') {
|
|
1313
|
+
// We have no real artifact during the construction of a super-annotate statement:
|
|
1314
|
+
const msgArgs = {
|
|
1315
|
+
'#': (art.kind === 'service' || art.kind === 'annotate') ? art.kind : 'std',
|
|
1316
|
+
art,
|
|
1317
|
+
kind,
|
|
1318
|
+
code: 'extend … with definitions',
|
|
1319
|
+
keyword: 'extend service',
|
|
1320
|
+
};
|
|
1321
|
+
// TODO v7: Discuss: make this an error?
|
|
1322
|
+
warning( 'ext-invalid-kind', [ loc, ext ], msgArgs, {
|
|
1323
|
+
std: 'Artifact $(ART) is not of kind $(KIND), use $(CODE) instead',
|
|
1324
|
+
annotate: 'There is no artifact $(ART), use $(CODE) instead',
|
|
1325
|
+
// do not mention 'extend context', that is not in CAPire
|
|
1326
|
+
service: 'Artifact $(ART) is not of kind $(KIND), use $(CODE) or $(KEYWORD) instead',
|
|
1327
|
+
} );
|
|
1440
1328
|
}
|
|
1441
|
-
|
|
1442
|
-
hasElement = true; // warning with CDL input or `name: {}` in CSN input
|
|
1443
|
-
}
|
|
1444
|
-
if (!parent.type || parent.type.$inferred || (parent._main || parent).query) {
|
|
1445
|
-
error( 'extend-type', [ obj.elements[$location], construct ], {},
|
|
1446
|
-
'Only structures or enum types can be extended with elements/enums' );
|
|
1447
|
-
}
|
|
1448
|
-
else if (hasElement) {
|
|
1449
|
-
warning( 'ext-expecting-enum', [ obj.elements[$location], construct ],
|
|
1450
|
-
{ code: 'extend … with enum' }, 'Use $(CODE) when extending enums' );
|
|
1329
|
+
// TODO: Use similar checks for EXTEND ENTITY etc - 'ext-ignoring-kind'
|
|
1451
1330
|
}
|
|
1452
|
-
forEachGeneric( { enum: obj.elements }, 'enum', init );
|
|
1453
1331
|
}
|
|
1332
|
+
}
|
|
1454
1333
|
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
|
|
1334
|
+
// called in createSuperAnnotate()
|
|
1335
|
+
function reportExtensionOnBuiltin( art, ext ) {
|
|
1336
|
+
const refCtx = extensionRefContext( ext );
|
|
1337
|
+
if (resolvePath( ext.name, refCtx, ext ) && art?.builtin) {
|
|
1338
|
+
if (ext.kind === 'extend') {
|
|
1339
|
+
// extending built-ins with elements/enums already gives an error
|
|
1340
|
+
message( 'ext-unexpected-builtin', [ ext.name.location, ext ], {},
|
|
1341
|
+
'Built-in types should not be extended' ); // keep the text general
|
|
1342
|
+
// TODO v8: error - especially bad with includes extension
|
|
1343
|
+
const typeProp = typeParameters.list.find( p => ext[p] );
|
|
1344
|
+
if (typeProp) {
|
|
1345
|
+
const location = ext.$typeArgs?.[$location] || ext[typeProp].location;
|
|
1346
|
+
message( 'ext-unexpected-type-property', [ location, ext ], {}, // error v7
|
|
1347
|
+
'Built-in types can\'t be extended with type properties' );
|
|
1348
|
+
// see also 'ext-invalid-type-property'
|
|
1464
1349
|
}
|
|
1465
1350
|
}
|
|
1466
|
-
|
|
1467
|
-
if (!elem._block)
|
|
1468
|
-
setLink( elem, '_block', block );
|
|
1469
|
-
// if (!kindProperties[ elem.kind ]) console.log(elem.kind,elem.name)
|
|
1470
|
-
if ((elem.kind === 'extend' || elem.kind === 'annotate'))
|
|
1471
|
-
return;
|
|
1472
|
-
|
|
1473
|
-
if (isQueryExtension && elem.kind === 'element') {
|
|
1474
|
-
error( 'extend-query', [ elem.location, construct ], // TODO: searchName ?
|
|
1475
|
-
{ code: 'extend … with columns' },
|
|
1476
|
-
'Use $(CODE) to add select items to the query entity' );
|
|
1477
|
-
return;
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
|
-
const existing = parent[prop]?.[name];
|
|
1481
|
-
const shadowsIncludeMember = construct !== parent &&
|
|
1482
|
-
elem.$inferred !== 'include' &&
|
|
1483
|
-
existing?.$inferred === 'include';
|
|
1484
|
-
const add = construct !== parent && (!existing || elem.$inferred !== 'include');
|
|
1485
|
-
if (!add && existing?.$inferred === 'include' && elem.$inferred === 'include') {
|
|
1486
|
-
includeCollisions.push( {
|
|
1487
|
-
prop, name, existing, elem,
|
|
1488
|
-
} );
|
|
1489
|
-
}
|
|
1490
|
-
// don't dump with `entity T {}; extend T with { extend e {}; e {}; e {} };`:
|
|
1491
|
-
const { $duplicates } = elem;
|
|
1492
|
-
if ($duplicates === true && add)
|
|
1493
|
-
elem.$duplicates = null;
|
|
1494
|
-
if (add && elem.$inferred === 'include' && Array.isArray( $duplicates ))
|
|
1495
|
-
elem.$duplicates = null;
|
|
1496
|
-
if (shadowsIncludeMember) {
|
|
1497
|
-
parent[prop][name] = elem;
|
|
1498
|
-
setMemberParent( elem, name, parent );
|
|
1499
|
-
}
|
|
1500
1351
|
else {
|
|
1501
|
-
|
|
1502
|
-
if (!$duplicates) // not already reported
|
|
1503
|
-
checkRedefinition( elem );
|
|
1352
|
+
info( 'anno-builtin', [ ext.name.location, ext ], {} ); // TODO: better location?
|
|
1504
1353
|
}
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1354
|
+
// TODO: remove built-ins as CC candidates via accept property of ./shared.js
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1508
1357
|
|
|
1509
|
-
|
|
1358
|
+
// Called in extendArtifactAdd()
|
|
1359
|
+
function reportExtensionOnGenerated( ext, art, prop, extMembers ) {
|
|
1360
|
+
// Beware: if we allow element extensions later, we might still want to
|
|
1361
|
+
// disallow includes with elements, see reportInvalidIncludes(); additionally,
|
|
1362
|
+
// adding sub elements might still be wrong
|
|
1363
|
+
const location = ext[prop]?.[$location] || ext.name.location;
|
|
1364
|
+
if (ext.enum) { // enum extension on structure
|
|
1365
|
+
error( 'def-unexpected-enum', [ location, ext ], {} );
|
|
1366
|
+
}
|
|
1367
|
+
else if (art.$inferred === 'include') { // element of include
|
|
1368
|
+
error( 'ref-expected-direct-structure', [ location, ext ],
|
|
1369
|
+
{ '#': 'elements', art } );
|
|
1370
|
+
}
|
|
1371
|
+
else if (extMembers && Object.keys( extMembers ).length ||
|
|
1372
|
+
ext.includes?.some( ref => dictNonEmpty( ref._artifact.elements ))) {
|
|
1373
|
+
// TODO: we could allow extMembers containing `extend`s only, but then make
|
|
1374
|
+
// sure that we do not accidentially allow adding sub elements
|
|
1375
|
+
error( 'extend-for-generated', [ location, ext ],
|
|
1376
|
+
{ // eslint-disable-next-line no-nested-ternary
|
|
1377
|
+
'#': (art.query ? 'query' : ext.includes ? 'std' : prop),
|
|
1378
|
+
art,
|
|
1379
|
+
keyword: 'extend',
|
|
1380
|
+
}, {
|
|
1381
|
+
std: 'You can\'t use $(KEYWORD) on the generated $(ART)',
|
|
1382
|
+
query: 'You can\'t use $(KEYWORD) on the query to add elements',
|
|
1383
|
+
elements: 'You can\'t use $(KEYWORD) on the inferred elements of $(ART)',
|
|
1384
|
+
} );
|
|
1385
|
+
// TODO: for invalid includes, use specific ref-invalid-include messages
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1510
1388
|
|
|
1511
|
-
|
|
1512
|
-
|
|
1389
|
+
// Remark: the acceptFn for resolvePath() does a first check whether includes
|
|
1390
|
+
// are allowed
|
|
1391
|
+
function reportInvalidIncludes( art ) {
|
|
1392
|
+
const { elements } = art;
|
|
1393
|
+
for (const ref of art.includes) {
|
|
1394
|
+
const incl = ref._artifact;
|
|
1395
|
+
if (!incl)
|
|
1396
|
+
continue;
|
|
1397
|
+
if (!elements && (incl.elements || incl.kind !== 'aspect'))
|
|
1398
|
+
error( 'ref-invalid-include', [ ref.location, art ], { '#': 'bare' } );
|
|
1399
|
+
else if ((incl.elements ? incl.elements[$inferred] : incl.kind !== 'aspect') ||
|
|
1400
|
+
incl.query) // TODO: allow query entity and inferred elems soon
|
|
1401
|
+
error( 'ref-invalid-include', [ ref.location, art ] );
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1513
1404
|
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
if (
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
}
|
|
1522
|
-
elem.$syntax = 'calc';
|
|
1523
|
-
// TODO: it is not just "syntax" - maybe better test for `$calcDepElement`?
|
|
1524
|
-
createAndLinkCalcDepElement( elem );
|
|
1525
|
-
|
|
1526
|
-
// Special case (hack) for calculated elements that use composition+filter:
|
|
1527
|
-
// See "Notes on `$enclosed`" in `ExposingAssocWithFilter.md` for details.
|
|
1528
|
-
if (elem.target && elem.value.path?.[elem.value.path.length - 1]?.where) {
|
|
1529
|
-
delete elem.type;
|
|
1530
|
-
delete elem.on;
|
|
1531
|
-
delete elem.target;
|
|
1405
|
+
// Called in extendArtifactAdd()
|
|
1406
|
+
function reportTypeIncludesWithActions( art ) {
|
|
1407
|
+
for (const ref of art.includes || []) {
|
|
1408
|
+
const incl = ref._artifact;
|
|
1409
|
+
if (incl?.actions && Object.keys( incl.actions ).length) {
|
|
1410
|
+
warning( 'ref-ignoring-actions', [ ref.location, art ], { art: incl },
|
|
1411
|
+
'The actions of $(ART) are not added to the type' ); // TODO: info?
|
|
1532
1412
|
}
|
|
1533
1413
|
}
|
|
1534
1414
|
}
|
|
1535
1415
|
|
|
1536
|
-
//
|
|
1537
|
-
function
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
if (feature &&
|
|
1545
|
-
(feature === true || construct.kind !== 'extend' || feature( prop, parent )))
|
|
1546
|
-
return true;
|
|
1547
|
-
const location = dict[$location];
|
|
1416
|
+
// Called in extendArtifactBefore() and extendArtifactAfter()
|
|
1417
|
+
function reportUnexpectedReturns( ext, art ) {
|
|
1418
|
+
const msgId = hasSecurityAnno( ext.returns )
|
|
1419
|
+
? 'ext-unexpected-returns-sec'
|
|
1420
|
+
: 'ext-unexpected-returns';
|
|
1421
|
+
message( msgId, [ ext.returns.location, ext ],
|
|
1422
|
+
{ '#': art.kind, keyword: 'returns' } );
|
|
1423
|
+
}
|
|
1548
1424
|
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
'Actions and functions only exist top-level and for entities' ); // or aspects
|
|
1554
|
-
}
|
|
1555
|
-
else {
|
|
1556
|
-
warning( 'ext-ignoring-actions', [ location, construct ], {},
|
|
1557
|
-
'Actions and functions only exist top-level and for entities' );
|
|
1558
|
-
return false;
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
else if (parent.kind === 'action' || parent.kind === 'function') {
|
|
1562
|
-
error( 'ext-unexpected-action', [ construct.location, construct ], { '#': parent.kind }, {
|
|
1425
|
+
// Called in extendArtifactAfter()
|
|
1426
|
+
function reportMissingReturns( ext, art ) {
|
|
1427
|
+
if (ext.kind === 'extend') {
|
|
1428
|
+
error( 'ext-unexpected-action', [ ext.name.location, ext ], { '#': art.kind }, {
|
|
1563
1429
|
std: 'Actions and functions can\'t be extended, only annotated', // TODO: → ext-unsupported
|
|
1564
1430
|
action: 'Actions can\'t be extended, only annotated',
|
|
1565
1431
|
function: 'Functions can\'t be extended, only annotated',
|
|
1566
1432
|
} );
|
|
1567
1433
|
}
|
|
1568
|
-
else
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
'Extending artifacts with parameters is not supported' );
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
else if (feature) { // allowed in principle, but not with extend
|
|
1582
|
-
if (!Object.keys( dict ).length) {
|
|
1583
|
-
warning( 'ext-ignoring-elements', [ location, construct ], {},
|
|
1584
|
-
'Only structures with directly specified elements can be extended by elements' );
|
|
1585
|
-
return false;
|
|
1586
|
-
}
|
|
1587
|
-
else if (parent.$inferred === 'include') { // special case for better error message
|
|
1588
|
-
const variant = (construct.enum || construct.elements) ? 'elements' : 'std';
|
|
1589
|
-
error( 'ref-expected-direct-structure', [ location, construct ],
|
|
1590
|
-
{ '#': variant, art: parent } );
|
|
1591
|
-
}
|
|
1592
|
-
else if (prop !== 'enum' || !parent.enum ||
|
|
1593
|
-
!parent.type || parent.type.$inferred || (parent._main || parent).query) {
|
|
1594
|
-
error( 'extend-type', [ location, construct ], {},
|
|
1595
|
-
'Only structures or enum types can be extended with elements/enums' );
|
|
1596
|
-
}
|
|
1597
|
-
else {
|
|
1598
|
-
return true;
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
else if (prop === 'elements') {
|
|
1602
|
-
error( 'def-unexpected-elements', [ location, construct ], {},
|
|
1603
|
-
'Elements only exist in entities, types or typed constructs' );
|
|
1604
|
-
}
|
|
1605
|
-
else if (prop === 'columns') {
|
|
1606
|
-
error( 'extend-columns', [ location, construct ], { art: construct } );
|
|
1607
|
-
}
|
|
1608
|
-
else { // if (prop === 'enum') {
|
|
1609
|
-
error( 'def-unexpected-enum', [ location, construct ], {},
|
|
1610
|
-
'Enum symbols can only be defined for types or typed constructs' );
|
|
1434
|
+
else {
|
|
1435
|
+
warning( 'ext-expecting-returns', [ ext.name.location, ext ], {
|
|
1436
|
+
'#': art.kind, keyword: 'returns', code: 'annotate ‹name› with returns { … }',
|
|
1437
|
+
}, {
|
|
1438
|
+
std: 'Expected $(CODE)', // unused variant
|
|
1439
|
+
action: 'Expected $(KEYWORD) when annotating action return structure, i.e. $(CODE)',
|
|
1440
|
+
function: 'Expected $(KEYWORD) when annotating function return structure, i.e. $(CODE)',
|
|
1441
|
+
// eslint-disable-next-line @stylistic/max-len
|
|
1442
|
+
annotate: 'Expected $(KEYWORD) when annotating a return structure of an unknown action or function, i.e. $(CODE)',
|
|
1443
|
+
} );
|
|
1611
1444
|
}
|
|
1612
|
-
return construct === parent;
|
|
1613
1445
|
}
|
|
1614
1446
|
|
|
1615
|
-
|
|
1616
|
-
// includes ----------------------------------------------------------------
|
|
1617
|
-
|
|
1618
1447
|
/**
|
|
1619
|
-
*
|
|
1620
|
-
*
|
|
1621
|
-
*
|
|
1622
|
-
|
|
1623
|
-
* Sets `_ancestors` links on `art` if it is an entity, collecting the entity
|
|
1624
|
-
* includes with their ancestors.
|
|
1625
|
-
*
|
|
1626
|
-
* Examples:
|
|
1627
|
-
* ext === art: `entity E : F {}` => add elements of F to E
|
|
1628
|
-
* ext !== art: `extend E with F` => add elements of F to extension on E
|
|
1629
|
-
*
|
|
1630
|
-
* @param {XSN.Extension} ext
|
|
1631
|
-
* @param {XSN.Artifact} art
|
|
1448
|
+
* Report duplicates in parent[prop] that happen due to multiple includes having
|
|
1449
|
+
* the same member. Run after includes and extends in extendArtifactAdd() so
|
|
1450
|
+
* shadowing members have already replaced any include-derived proxy.
|
|
1632
1451
|
*/
|
|
1633
|
-
function
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1452
|
+
function reportRedefinitionThroughIncludes( parent, prop ) {
|
|
1453
|
+
if (!parent[prop])
|
|
1454
|
+
return;
|
|
1455
|
+
forEachInOrder( parent, prop, ( member, name ) => {
|
|
1456
|
+
if (member.$inferred === 'include' && Array.isArray( member.$duplicates )) {
|
|
1457
|
+
const includes = [ member, ...member.$duplicates ].map( dup => dup._origin._main );
|
|
1458
|
+
// TODO: 'ref-duplicate-include-member' with one message per affected include,
|
|
1459
|
+
// mentioning the problematic element/action names
|
|
1460
|
+
error( 'duplicate-definition', [ member.location, member ],
|
|
1461
|
+
{ '#': `include-${ prop }`, name, sorted_arts: includes } );
|
|
1462
|
+
}
|
|
1463
|
+
} );
|
|
1641
1464
|
}
|
|
1642
1465
|
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1466
|
+
// TODO: still a bit annotation assignment specific
|
|
1467
|
+
// Called in extendArtifactBefore().
|
|
1468
|
+
function reportDuplicateExtensions( extensions, prop, issue, index, art ) {
|
|
1469
|
+
// TODO: think about messages for these
|
|
1470
|
+
if (prop === 'elements' || prop === 'actions' || prop === 'columns' ||
|
|
1471
|
+
prop === 'params' || prop === '$add' ) {
|
|
1472
|
+
if (issue && (prop === '$add' || prop === 'columns'))
|
|
1473
|
+
reportUnstableExtensions( extensions, issue );
|
|
1474
|
+
return; // extensions currently handled extra
|
|
1648
1475
|
}
|
|
1649
|
-
// console.log( (ext===art?'D-INCL:':'E-INCL:'), art.kind, art.name.id,
|
|
1650
|
-
// ...ext.includes.map( r => r._artifact?.name.id ));
|
|
1651
|
-
if (!art.query && art.elements) // do not set art.elements and art.enums with query entity!
|
|
1652
|
-
includeMembers( ext, art, 'elements' );
|
|
1653
1476
|
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1477
|
+
const isTypeParam = typeParameters.list.includes( prop );
|
|
1478
|
+
const isAnnoOrDoc = prop.charAt(0) === '@' || prop === 'doc';
|
|
1479
|
+
if (!isAnnoOrDoc && !isTypeParam && prop !== 'orderBy')
|
|
1480
|
+
return;
|
|
1481
|
+
if (issue) {
|
|
1482
|
+
if (prop === 'orderBy' && issue === 'unrelated') {
|
|
1483
|
+
for (const ext of extensions) {
|
|
1484
|
+
const clause = ext[prop];
|
|
1485
|
+
if (clause) {
|
|
1486
|
+
message( 'ext-unstable-order', [ clause[0]?.location || ext.location, ext ],
|
|
1487
|
+
{ keyword: prop },
|
|
1488
|
+
// eslint-disable-next-line @stylistic/max-len
|
|
1489
|
+
'Unstable order of entries in the $(KEYWORD) clause due to another extension in unrelated layer' );
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
if (isAnnoOrDoc && prop !== 'doc' &&
|
|
1495
|
+
allAnnoValuesEqual( extensions, prop )) {
|
|
1496
|
+
if (issue === 'unrelated')
|
|
1497
|
+
return;
|
|
1498
|
+
for (const ext of extensions) {
|
|
1499
|
+
const anno = ext[prop];
|
|
1500
|
+
if (anno) {
|
|
1501
|
+
// annotations with equal value in the same layer -> warn
|
|
1502
|
+
warning( 'anno-duplicate-equal', [ anno.name?.location || anno.location, ext ],
|
|
1503
|
+
{ '#': 'std', anno: prop, type: art } );
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
// eslint-disable-next-line no-nested-ternary
|
|
1509
|
+
let msg = (index < 0)
|
|
1510
|
+
? 'anno-unstable-array'
|
|
1511
|
+
: (issue === true)
|
|
1512
|
+
? 'anno-duplicate'
|
|
1513
|
+
: 'anno-duplicate-unrelated-layer';
|
|
1514
|
+
if (prop === 'includes') {
|
|
1515
|
+
msg = (issue === true)
|
|
1516
|
+
? 'ext-duplicate-includes'
|
|
1517
|
+
: 'ext-unstable-includes';
|
|
1518
|
+
// TODO v7: location on include would be nicer
|
|
1519
|
+
}
|
|
1520
|
+
else if (!isAnnoOrDoc) {
|
|
1521
|
+
msg = (issue === true)
|
|
1522
|
+
? 'ext-duplicate-extend-type'
|
|
1523
|
+
: 'ext-duplicate-extend-type-unrelated-layer';
|
|
1524
|
+
// not sure whether to repeat the extended artifact in the message (we
|
|
1525
|
+
// have the semantic location, after all)
|
|
1526
|
+
// extend-repeated-intralayer / extend-unrelated-layer
|
|
1527
|
+
}
|
|
1528
|
+
const variant = prop === 'doc' ? 'doc' : 'std';
|
|
1529
|
+
for (const ext of extensions) {
|
|
1530
|
+
const anno = ext[prop];
|
|
1531
|
+
if (anno) {
|
|
1532
|
+
message( msg, [ anno.name?.location || anno.location, ext ],
|
|
1533
|
+
{ '#': variant, anno: prop, type: art } );
|
|
1663
1534
|
}
|
|
1664
1535
|
}
|
|
1665
1536
|
}
|
|
1537
|
+
else if (index > 0) { // more than one set (not just ...)
|
|
1538
|
+
const variant = prop === 'doc' ? 'doc' : 'std';
|
|
1539
|
+
const msgid = (isAnnoOrDoc)
|
|
1540
|
+
? 'anno-duplicate-same-file' // TODO: always ext-duplicate-…
|
|
1541
|
+
: 'ext-duplicate-same-file';
|
|
1542
|
+
while (index >= 0) { // do not report for trailing [...]
|
|
1543
|
+
const ext = extensions[index--];
|
|
1544
|
+
const anno = ext[prop];
|
|
1545
|
+
warning( msgid, [ anno.name?.location || anno.location, ext ],
|
|
1546
|
+
{ '#': variant, prop, anno: prop } );
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1666
1549
|
}
|
|
1667
1550
|
|
|
1668
1551
|
/**
|
|
1669
|
-
*
|
|
1670
|
-
*
|
|
1552
|
+
* Report 'Warning: Unstable element order due to repeated extensions'
|
|
1553
|
+
* except if all extensions are in the same file.
|
|
1671
1554
|
*
|
|
1672
|
-
*
|
|
1673
|
-
* @param {XSN.Artifact} art
|
|
1674
|
-
* @param {string} prop 'elements' or 'actions'
|
|
1555
|
+
* Called in extendArtifactBefore(), via reportDuplicateExtensions().
|
|
1675
1556
|
*/
|
|
1676
|
-
function
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
}
|
|
1688
|
-
let elementsAdded = 0;
|
|
1689
|
-
let hasNewElement = false;
|
|
1690
|
-
for (const ref of ext.includes) {
|
|
1691
|
-
// Elements of include are added after previously provided elements:
|
|
1692
|
-
if (prop === 'elements') {
|
|
1693
|
-
if (ref.$postponeInclude == null) {
|
|
1694
|
-
if (ref._artifact?.elements)
|
|
1695
|
-
ref.$postponeInclude = art.$postponeInclude || 0;
|
|
1696
|
-
}
|
|
1697
|
-
else if (ref.$postponeInclude > 0 && members) {
|
|
1698
|
-
let added = elementsAdded;
|
|
1699
|
-
let postpone = ref.$postponeInclude;
|
|
1700
|
-
elementsAdded += postpone;
|
|
1701
|
-
forEachInOrder( { [prop]: members }, prop, ( elem, name ) => {
|
|
1702
|
-
// The element could have been added in the previous loop (includes) to keep
|
|
1703
|
-
// the element order.
|
|
1704
|
-
if (--added < 0 && --postpone >= 0 && ext[prop][name] !== elem )
|
|
1705
|
-
dictAdd( ext[prop], name, elem );
|
|
1706
|
-
} );
|
|
1707
|
-
}
|
|
1708
|
-
if (ref.$postponeInclude != null) // not reset after bare aspect
|
|
1709
|
-
art.$postponeInclude = 0; // elements of next include directly after this one
|
|
1557
|
+
function reportUnstableExtensions( extensions, issue ) {
|
|
1558
|
+
for (const ext of extensions) {
|
|
1559
|
+
// TODO: location of complete includes / elements
|
|
1560
|
+
// (currently just for having lower diff in tests)
|
|
1561
|
+
const location = ext.includes?.[0]?.location ||
|
|
1562
|
+
ext.elements && Object.values( ext.elements )[0]?.location ||
|
|
1563
|
+
ext.columns?.[0]?.location ||
|
|
1564
|
+
ext.location;
|
|
1565
|
+
if (issue === 'unrelated') {
|
|
1566
|
+
message( 'extend-unrelated-layer', [ location, ext ], {},
|
|
1567
|
+
'Unstable element order due to other extension in unrelated layer' );
|
|
1710
1568
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
if (template[prop] && !ext[prop])
|
|
1714
|
-
ext[prop] = Object.create( null );
|
|
1715
|
-
const location = weakRefLocation( ref );
|
|
1716
|
-
|
|
1717
|
-
// prevent recompilation issue when localized entity is included in aspect or
|
|
1718
|
-
// entity without keys (via shadowing):
|
|
1719
|
-
const checkForLocalized = prop === 'elements' &&
|
|
1720
|
-
template.kind === 'entity' && !template.query &&
|
|
1721
|
-
withLocalizedData( template, ext );
|
|
1722
|
-
|
|
1723
|
-
// eslint-disable-next-line no-loop-func
|
|
1724
|
-
forEachInOrder( template, prop, ( origin, name ) => {
|
|
1725
|
-
if (checkForLocalized && (name === 'texts' || name === 'localized'))
|
|
1726
|
-
return;
|
|
1727
|
-
if (members && members[name]) {
|
|
1728
|
-
if (!ext[prop][name])
|
|
1729
|
-
dictAdd( ext[prop], name, members[name] ); // to keep order
|
|
1730
|
-
return;
|
|
1731
|
-
}
|
|
1732
|
-
hasNewElement = true;
|
|
1733
|
-
const elem = linkToOrigin( origin, name, parent, prop, location );
|
|
1734
|
-
setLink( elem, '_block', origin._block );
|
|
1735
|
-
if (!parent) // not yet set for EXTEND foo WITH bar => linkToOrigin() did not add it
|
|
1736
|
-
dictAdd( ext[prop], name, elem );
|
|
1737
|
-
elem.$inferred = 'include';
|
|
1738
|
-
if (origin.key && propagateKeys)
|
|
1739
|
-
elem.key = Object.assign( { $inferred: 'include' }, origin.key );
|
|
1740
|
-
if (origin.value && origin.$syntax === 'calc') {
|
|
1741
|
-
// TODO: If paths become invalid in the new artifact, should we mark
|
|
1742
|
-
// all usages in the expressions? Possibly just the first one?
|
|
1743
|
-
// TODO: Unify with other code in extend.js
|
|
1744
|
-
elem.value = Object.assign( { $inferred: 'include' },
|
|
1745
|
-
copyExpr( origin.value, location, true ) );
|
|
1746
|
-
elem.$syntax = 'calc';
|
|
1747
|
-
createAndLinkCalcDepElement( elem );
|
|
1748
|
-
setLink( elem, '_calcOrigin', origin._calcOrigin || origin );
|
|
1749
|
-
}
|
|
1750
|
-
// TODO: also complain if elem is just defined in art
|
|
1751
|
-
} );
|
|
1569
|
+
else {
|
|
1570
|
+
message( 'extend-repeated-intralayer', [ location, ext ] );
|
|
1752
1571
|
}
|
|
1753
1572
|
}
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
function allAnnoValuesEqual( extensions, prop ) {
|
|
1576
|
+
let first;
|
|
1577
|
+
let seen = false;
|
|
1578
|
+
for (const ext of extensions) {
|
|
1579
|
+
const anno = ext[prop];
|
|
1580
|
+
if (anno == null)
|
|
1581
|
+
continue;
|
|
1582
|
+
if (annotationHasEllipsis( anno ))
|
|
1583
|
+
return false;
|
|
1584
|
+
if (!seen) {
|
|
1585
|
+
first = anno;
|
|
1586
|
+
seen = true;
|
|
1587
|
+
}
|
|
1588
|
+
else if (!annoValueEqual( first, anno )) {
|
|
1589
|
+
return false;
|
|
1590
|
+
}
|
|
1771
1591
|
}
|
|
1592
|
+
return seen;
|
|
1772
1593
|
}
|
|
1773
1594
|
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
* (We could still use $inferred as speed-up if run without `testMode`.)
|
|
1780
|
-
*
|
|
1781
|
-
* It is as follows: the elements `texts` and `localized` in entity `‹E›` and
|
|
1782
|
-
* the entity `‹E›.texts` are considered compiler-generated for Localized Data if
|
|
1783
|
-
*
|
|
1784
|
-
* - `‹E›.texts` has a key element `locale`
|
|
1785
|
-
* (TODO: currently weakend to “entity exists”)
|
|
1786
|
-
* - `texts` of `‹E›` is an unmanaged composition to `‹E›.texts`
|
|
1787
|
-
* - `localized` of `‹E›` is an unmanaged association to `‹E›.texts`
|
|
1788
|
-
*/
|
|
1789
|
-
function withLocalizedData( { name, elements }, ext ) {
|
|
1790
|
-
const textsEntityName = `${ name.id }.texts`;
|
|
1791
|
-
// if we test (again) for element `locale` - it might come from an extend or
|
|
1792
|
-
// TextsAspect include, which might not have yet applied
|
|
1793
|
-
if (!model.definitions[textsEntityName])
|
|
1595
|
+
function annoValueEqual( a, b ) {
|
|
1596
|
+
if (a == null || b == null)
|
|
1597
|
+
return a == null && b == null;
|
|
1598
|
+
if (a.literal === 'array' || b.literal === 'array' ||
|
|
1599
|
+
a.path || b.path || a.struct || b.struct )
|
|
1794
1600
|
return false;
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1601
|
+
if (a.sym || b.sym) {
|
|
1602
|
+
return a.literal === 'enum' && b.literal === 'enum' &&
|
|
1603
|
+
a.sym.id === b.sym.id;
|
|
1604
|
+
}
|
|
1605
|
+
if (!!a.$tokenTexts !== !!b.$tokenTexts)
|
|
1606
|
+
return false;
|
|
1607
|
+
if (a.$tokenTexts && !('val' in a && 'val' in b))
|
|
1608
|
+
return false;
|
|
1609
|
+
// no val (undefined) as true for annotation values
|
|
1610
|
+
const aVal = ('val' in a) ? a.val : true;
|
|
1611
|
+
const bVal = ('val' in b) ? b.val : true;
|
|
1612
|
+
const aLit = ('val' in a) ? a.literal : 'boolean';
|
|
1613
|
+
const bLit = ('val' in b) ? b.literal : 'boolean';
|
|
1614
|
+
return aVal === bVal && aLit === bLit;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
// TODO: in shared?
|
|
1618
|
+
function notFound( msgId, location, address, args, validDict ) {
|
|
1619
|
+
const msg = message( msgId, [ location, address ], args );
|
|
1620
|
+
attachAndEmitValidNames( msg, validDict );
|
|
1801
1621
|
}
|
|
1802
1622
|
|
|
1623
|
+
// Foreign key extensions (currently postponed) -------------------------------
|
|
1624
|
+
|
|
1803
1625
|
/**
|
|
1804
|
-
*
|
|
1805
|
-
*
|
|
1806
|
-
*
|
|
1626
|
+
* Apply foreign key extensions. Because foreign keys are handled late in the compiler
|
|
1627
|
+
* (in tweak-assocs.js), we can't apply them in effectiveType(), yet.
|
|
1628
|
+
* Instead, we postpone applying them until all foreign keys were generated.
|
|
1629
|
+
*
|
|
1630
|
+
* @param art
|
|
1807
1631
|
*/
|
|
1808
|
-
function
|
|
1809
|
-
|
|
1632
|
+
function extendForeignKeys( art ) {
|
|
1633
|
+
// See extendArtifactAfter() for targetAspect/items handling.
|
|
1634
|
+
if (!art._extensions || art.items || art.targetAspect?.elements)
|
|
1810
1635
|
return;
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1636
|
+
|
|
1637
|
+
// push down foreign keys
|
|
1638
|
+
moveDictExtensions( art, art._extensions, 'foreignKeys', 'elements' );
|
|
1639
|
+
if (!art.foreignKeys)
|
|
1640
|
+
return;
|
|
1641
|
+
|
|
1642
|
+
forEachGeneric(art, 'foreignKeys', (key) => {
|
|
1643
|
+
if (!key._effectiveType)
|
|
1644
|
+
throw new CompilerAssertion( 'foreign key should have been processed' );
|
|
1645
|
+
extendArtifactBefore( key );
|
|
1646
|
+
// Adding foreign key not possible yet
|
|
1647
|
+
extendArtifactAfter( key );
|
|
1648
|
+
});
|
|
1818
1649
|
}
|
|
1819
1650
|
}
|
|
1820
1651
|
|
|
1652
|
+
// Utility functions ------------------------------------------------------------
|
|
1653
|
+
|
|
1654
|
+
function canBeDraftMember( name, parent, draftMembers ) {
|
|
1655
|
+
return parent?.kind === 'entity' && parent._service && draftMembers.includes( name );
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1821
1658
|
/**
|
|
1822
1659
|
* Group extensions by their layers. A definition (for specified elements)
|
|
1823
1660
|
* is considered to be provided in a layer named '', the lowest layer.
|
|
@@ -1915,6 +1752,7 @@ function compareExtensions( a, b ) {
|
|
|
1915
1752
|
/**
|
|
1916
1753
|
* Propagate the given `prop` (e.g. annotation) early, i.e. copy it from all `.includes`
|
|
1917
1754
|
* if they have the property.
|
|
1755
|
+
* TODO: move to ./utils.js,
|
|
1918
1756
|
*
|
|
1919
1757
|
* @param {XSN.Definition} art
|
|
1920
1758
|
* @param {string} prop
|