@sap/cds-compiler 2.12.0 → 2.15.2
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 +221 -15
- package/bin/cdsc.js +125 -50
- package/bin/cdsse.js +2 -2
- package/doc/CHANGELOG_BETA.md +13 -6
- package/doc/CHANGELOG_DEPRECATED.md +22 -6
- package/doc/NameResolution.md +21 -16
- package/lib/api/main.js +47 -84
- package/lib/api/options.js +5 -6
- package/lib/api/validate.js +6 -11
- package/lib/backends.js +15 -23
- package/lib/base/dictionaries.js +0 -8
- package/lib/base/error.js +26 -0
- package/lib/base/keywords.js +7 -17
- package/lib/base/location.js +9 -4
- package/lib/base/message-registry.js +114 -18
- package/lib/base/messages.js +101 -90
- package/lib/base/model.js +2 -63
- package/lib/base/optionProcessorHelper.js +177 -123
- package/lib/checks/annotationsOData.js +12 -33
- package/lib/checks/arrayOfs.js +1 -34
- package/lib/checks/cdsPersistence.js +2 -1
- package/lib/checks/enricher.js +17 -1
- package/lib/checks/invalidTarget.js +3 -1
- package/lib/checks/managedWithoutKeys.js +3 -1
- package/lib/checks/selectItems.js +4 -4
- package/lib/checks/sql-snippets.js +27 -26
- package/lib/checks/types.js +1 -1
- package/lib/checks/validator.js +6 -11
- package/lib/compiler/assert-consistency.js +6 -3
- package/lib/compiler/base.js +1 -0
- package/lib/compiler/builtins.js +19 -6
- package/lib/compiler/checks.js +23 -60
- package/lib/compiler/cycle-detector.js +1 -1
- package/lib/compiler/define.js +1151 -0
- package/lib/compiler/extend.js +1000 -0
- package/lib/compiler/finalize-parse-cdl.js +237 -0
- package/lib/compiler/index.js +107 -39
- package/lib/compiler/kick-start.js +190 -0
- package/lib/compiler/moduleLayers.js +4 -4
- package/lib/compiler/populate.js +1227 -0
- package/lib/compiler/propagator.js +114 -46
- package/lib/compiler/resolve.js +1521 -0
- package/lib/compiler/shared.js +126 -65
- package/lib/compiler/tweak-assocs.js +535 -0
- package/lib/compiler/utils.js +197 -33
- package/lib/edm/.eslintrc.json +5 -0
- package/lib/edm/annotations/genericTranslation.js +38 -24
- package/lib/edm/annotations/preprocessAnnotations.js +2 -2
- package/lib/edm/csn2edm.js +219 -100
- package/lib/edm/edm.js +302 -230
- package/lib/edm/edmPreprocessor.js +554 -419
- package/lib/edm/edmUtils.js +138 -44
- package/lib/gen/Dictionary.json +100 -19
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +11 -1
- package/lib/gen/language.tokens +86 -83
- package/lib/gen/languageLexer.interp +10 -1
- package/lib/gen/languageLexer.js +860 -833
- package/lib/gen/languageLexer.tokens +78 -75
- package/lib/gen/languageParser.js +5765 -4480
- package/lib/json/csnVersion.js +10 -11
- package/lib/json/from-csn.js +15 -3
- package/lib/json/to-csn.js +126 -68
- package/lib/language/docCommentParser.js +4 -4
- package/lib/language/genericAntlrParser.js +123 -5
- package/lib/language/language.g4 +355 -156
- package/lib/language/multiLineStringParser.js +5 -5
- package/lib/main.d.ts +486 -59
- package/lib/main.js +41 -9
- package/lib/model/api.js +3 -1
- package/lib/model/csnRefs.js +252 -156
- package/lib/model/csnUtils.js +384 -297
- package/lib/model/enrichCsn.js +71 -29
- package/lib/model/revealInternalProperties.js +29 -8
- package/lib/model/sortViews.js +2 -1
- package/lib/modelCompare/compare.js +23 -18
- package/lib/optionProcessor.js +63 -26
- package/lib/render/manageConstraints.js +35 -32
- package/lib/render/toCdl.js +897 -947
- package/lib/render/toHdbcds.js +205 -257
- package/lib/render/toSql.js +264 -225
- package/lib/render/utils/common.js +136 -25
- package/lib/render/utils/sql.js +4 -3
- package/lib/render/utils/stringEscapes.js +111 -0
- package/lib/sql-identifier.js +1 -1
- package/lib/transform/.eslintrc.json +5 -0
- package/lib/transform/db/.eslintrc.json +3 -1
- package/lib/transform/db/applyTransformations.js +35 -12
- package/lib/transform/db/assertUnique.js +1 -1
- package/lib/transform/db/associations.js +104 -306
- package/lib/transform/db/cdsPersistence.js +2 -2
- package/lib/transform/db/constraints.js +58 -53
- package/lib/transform/db/expansion.js +60 -33
- package/lib/transform/db/flattening.js +582 -104
- package/lib/transform/db/groupByOrderBy.js +3 -1
- package/lib/transform/db/transformExists.js +66 -13
- package/lib/transform/db/views.js +11 -7
- package/lib/transform/draft/.eslintrc.json +38 -0
- package/lib/transform/{db/draft.js → draft/db.js} +6 -5
- package/lib/transform/draft/odata.js +227 -0
- package/lib/transform/forHanaNew.js +109 -208
- package/lib/transform/forOdataNew.js +59 -212
- package/lib/transform/localized.js +46 -26
- package/lib/transform/odata/toFinalBaseType.js +85 -11
- package/lib/transform/odata/typesExposure.js +147 -199
- package/lib/transform/odata/utils.js +2 -2
- package/lib/transform/transformUtilsNew.js +44 -33
- package/lib/transform/translateAssocsToJoins.js +3 -20
- package/lib/transform/universalCsn/.eslintrc.json +36 -0
- package/lib/transform/universalCsn/coreComputed.js +172 -0
- package/lib/transform/universalCsn/universalCsnEnricher.js +737 -0
- package/lib/transform/universalCsn/utils.js +63 -0
- package/lib/utils/moduleResolve.js +13 -6
- package/lib/utils/objectUtils.js +30 -0
- package/package.json +1 -1
- package/share/messages/README.md +26 -0
- package/share/messages/message-explanations.json +2 -1
- package/share/messages/syntax-expected-integer.md +37 -0
- package/lib/compiler/definer.js +0 -2361
- package/lib/compiler/resolver.js +0 -3079
- package/lib/transform/odata/attachPath.js +0 -96
- package/lib/transform/odata/expandStructKeysInAssociations.js +0 -59
- package/lib/transform/odata/generateForeignKeyElements.js +0 -261
- package/lib/transform/odata/referenceFlattener.js +0 -290
- package/lib/transform/odata/sortByAssociationDependency.js +0 -105
- package/lib/transform/odata/structuralPath.js +0 -72
- package/lib/transform/odata/structureFlattener.js +0 -171
- package/lib/transform/universalCsnEnricher.js +0 -237
package/lib/language/language.g4
CHANGED
|
@@ -393,7 +393,7 @@ artifactDef[ outer, defOnly = false ] locals[ annos = [] ] // cannot use `parent
|
|
|
393
393
|
| extendProjection[ $outer, this.startLocation(), $annos ]
|
|
394
394
|
| extendType[ $outer, this.startLocation(), $annos ]
|
|
395
395
|
| extendAspect[ $outer, this.startLocation(), $annos ]
|
|
396
|
-
|
|
396
|
+
// Streamlined Syntax
|
|
397
397
|
| extendArtifact[ $outer, this.startLocation(), $annos ]
|
|
398
398
|
)
|
|
399
399
|
|
|
|
@@ -418,7 +418,9 @@ contextDef[ outer, loc, annos, defOnly = false ] locals[ art, name = {} ]
|
|
|
418
418
|
this.docComment( $annos ); }
|
|
419
419
|
annotationAssignment_fix[ $annos ]*
|
|
420
420
|
(
|
|
421
|
-
'{'
|
|
421
|
+
'{' { $art.artifacts = this.createDict(); }
|
|
422
|
+
artifactDef[ $art, defOnly ]*
|
|
423
|
+
'}' { this.setDictEndLocation( $art.artifacts ); }
|
|
422
424
|
optionalSemi
|
|
423
425
|
|
|
|
424
426
|
requiredSemi
|
|
@@ -436,9 +438,9 @@ extendContext[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
436
438
|
{ this.docComment( $annos ); }
|
|
437
439
|
annotationAssignment_ll1[ $annos ]*
|
|
438
440
|
(
|
|
439
|
-
'{'
|
|
440
|
-
artifactDef[ $art, $service ? 'SERVICE' : 'CONTEXT'
|
|
441
|
-
'}'
|
|
441
|
+
'{' { $art.artifacts = this.createDict(); }
|
|
442
|
+
artifactDef[ $art, $service ? 'SERVICE' : 'CONTEXT' ]*
|
|
443
|
+
'}' { this.setDictEndLocation( $art.artifacts ); }
|
|
442
444
|
optionalSemi
|
|
443
445
|
|
|
|
444
446
|
requiredSemi
|
|
@@ -461,23 +463,35 @@ entityDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
461
463
|
)*
|
|
462
464
|
)?
|
|
463
465
|
'{'
|
|
464
|
-
{ $art.elements =
|
|
466
|
+
{ $art.elements = this.createDict(); } // better for include and annotate
|
|
465
467
|
elementDef[ $art ]*
|
|
466
|
-
'}'
|
|
468
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
467
469
|
// TODO: action definitions in a specific section?
|
|
468
|
-
(
|
|
470
|
+
(
|
|
471
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
472
|
+
actionFunctionDef[ $art ]*
|
|
473
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
474
|
+
)?
|
|
469
475
|
optionalSemi
|
|
470
476
|
|
|
|
471
477
|
AS
|
|
472
478
|
( qe=queryExpression
|
|
473
479
|
{ $art.query = $qe.query; $art['$'+'syntax'] = 'entity' }
|
|
474
|
-
(
|
|
480
|
+
(
|
|
481
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
482
|
+
actionFunctionDef[ $art ]*
|
|
483
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
484
|
+
optionalSemi
|
|
475
485
|
| requiredSemi
|
|
476
486
|
)
|
|
477
487
|
| qp=projectionSpec
|
|
478
488
|
{ $art.query = $qp.query; $art['$'+'syntax'] = 'projection'; }
|
|
479
489
|
projectionClauses[ $qp.query ]
|
|
480
|
-
(
|
|
490
|
+
(
|
|
491
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
492
|
+
actionFunctionDef[ $art ]*
|
|
493
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
494
|
+
)?
|
|
481
495
|
optionalSemi // TODO: not fully correct without columns or excluding
|
|
482
496
|
)
|
|
483
497
|
)
|
|
@@ -522,12 +536,12 @@ excludingClause[ query ]
|
|
|
522
536
|
:
|
|
523
537
|
// syntax is less than ideal - EXCLUDING is only useful for `*` - with
|
|
524
538
|
// this syntax, people wonder what happens with explicit select items
|
|
525
|
-
EXCLUDING '{'
|
|
539
|
+
EXCLUDING '{' { $query.excludingDict = this.createDict(); }
|
|
526
540
|
projectionExclusion[ $query ]
|
|
527
541
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
528
542
|
projectionExclusion[ $query ]
|
|
529
543
|
)*
|
|
530
|
-
'}'
|
|
544
|
+
'}' { this.setDictEndLocation( $query.excludingDict ); }
|
|
531
545
|
;
|
|
532
546
|
|
|
533
547
|
projectionExclusion[ outer ] locals[ art ]
|
|
@@ -562,13 +576,19 @@ extendEntity[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
562
576
|
|
|
563
577
|
extendForEntity[ art ]
|
|
564
578
|
:
|
|
565
|
-
'{'
|
|
579
|
+
'{' { $art.elements = this.createDict(); }
|
|
566
580
|
elementDefOrExtend[ $art ]*
|
|
567
|
-
'}'
|
|
568
|
-
(
|
|
581
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
582
|
+
(
|
|
583
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
584
|
+
actionFunctionDef[ $art ]*
|
|
585
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
586
|
+
)?
|
|
569
587
|
optionalSemi
|
|
570
588
|
|
|
|
571
|
-
ACTIONS '{'
|
|
589
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
590
|
+
actionFunctionDef[ $art ]*
|
|
591
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
572
592
|
optionalSemi
|
|
573
593
|
|
|
|
574
594
|
requiredSemi
|
|
@@ -594,10 +614,16 @@ extendProjection[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
594
614
|
)*
|
|
595
615
|
)?
|
|
596
616
|
'}'
|
|
597
|
-
(
|
|
617
|
+
(
|
|
618
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
619
|
+
actionFunctionDef[ $art ]*
|
|
620
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
621
|
+
)?
|
|
598
622
|
optionalSemi
|
|
599
623
|
|
|
|
600
|
-
ACTIONS '{'
|
|
624
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
625
|
+
actionFunctionDef[ $art ]*
|
|
626
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
601
627
|
optionalSemi
|
|
602
628
|
|
|
|
603
629
|
requiredSemi
|
|
@@ -702,12 +728,15 @@ aspectDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
702
728
|
)*
|
|
703
729
|
)?
|
|
704
730
|
)?
|
|
705
|
-
'{'
|
|
706
|
-
{ $art.elements = Object.create(null); } // better for include and annotate
|
|
731
|
+
'{' { $art.elements = this.createDict(); }
|
|
707
732
|
( elementDef[ $art ]* )
|
|
708
|
-
'}'
|
|
733
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
709
734
|
// TODO: action definitions in a specific section?
|
|
710
|
-
(
|
|
735
|
+
(
|
|
736
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
737
|
+
actionFunctionDef[ $art ]*
|
|
738
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
739
|
+
)?
|
|
711
740
|
optionalSemi
|
|
712
741
|
;
|
|
713
742
|
|
|
@@ -758,13 +787,82 @@ annotationDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
758
787
|
typeSpecSemi[ $art, $annos ] // also 'includes'...
|
|
759
788
|
;
|
|
760
789
|
|
|
761
|
-
extendArtifact[ outer, loc, annos ] locals[ art, name = {} ]
|
|
762
|
-
@after
|
|
790
|
+
extendArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
791
|
+
@after{ /* #ATN 1 */ this.attachLocation($art); }
|
|
763
792
|
:
|
|
764
793
|
simplePath[ $name, 'Extend' ]
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
794
|
+
(
|
|
795
|
+
{ $art = this.addItem( $outer, 'extensions', 'extend', $annos, { name: $name }, $loc ); }
|
|
796
|
+
|
|
|
797
|
+
':'
|
|
798
|
+
simplePath[ $elemName, 'ref']
|
|
799
|
+
{{
|
|
800
|
+
const def = this.addItem( $outer, 'extensions', 'extend', null, { name: $name }, $loc );
|
|
801
|
+
$art = this.artifactForElementAnnotateOrExtend( 'extend', def, $elemName.path, $annos, $loc );
|
|
802
|
+
}}
|
|
803
|
+
)
|
|
804
|
+
(
|
|
805
|
+
{ this.docComment( $annos ); }
|
|
806
|
+
annotationAssignment_ll1[ $annos ]*
|
|
807
|
+
(
|
|
808
|
+
'{' { $art.elements = this.createDict(); }
|
|
809
|
+
elementDefOrExtend[ $art ]*
|
|
810
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
811
|
+
optionalSemi
|
|
812
|
+
|
|
|
813
|
+
requiredSemi
|
|
814
|
+
)
|
|
815
|
+
|
|
|
816
|
+
WITH { this.noSemicolonHere(); this.docComment( $annos ); }
|
|
817
|
+
annotationAssignment_ll1[ $annos ]*
|
|
818
|
+
// #ATN: DEFINITIONS, COLUMNS, ACTIONS etc are not reserved and could be identifiers (ref).
|
|
819
|
+
(
|
|
820
|
+
includeRef[ $art ]
|
|
821
|
+
requiredSemi
|
|
822
|
+
|
|
|
823
|
+
'{' { $art.elements = this.createDict(); }
|
|
824
|
+
elementDefOrExtend[ $art ]*
|
|
825
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
826
|
+
optionalSemi
|
|
827
|
+
|
|
|
828
|
+
requiredSemi
|
|
829
|
+
|
|
|
830
|
+
{ this.disallowElementExtension( $elemName, $outer, 'definitions' ); }
|
|
831
|
+
DEFINITIONS
|
|
832
|
+
'{' { $art.artifacts = this.createDict(); }
|
|
833
|
+
artifactDef[ $art, true ]*
|
|
834
|
+
'}' { this.setDictEndLocation( $art.artifacts ); }
|
|
835
|
+
optionalSemi
|
|
836
|
+
|
|
|
837
|
+
{ this.disallowElementExtension( $elemName, $outer, 'columns' ); }
|
|
838
|
+
COLUMNS
|
|
839
|
+
'{' { $art.columns = []; }
|
|
840
|
+
(
|
|
841
|
+
selectItemDef[ $art.columns ]
|
|
842
|
+
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
843
|
+
selectItemDef[ $art.columns ]
|
|
844
|
+
)*
|
|
845
|
+
)?
|
|
846
|
+
'}'
|
|
847
|
+
optionalSemi
|
|
848
|
+
|
|
|
849
|
+
{ this.disallowElementExtension( $elemName, $outer, 'actions' ); }
|
|
850
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
851
|
+
actionFunctionDef[ $art ]*
|
|
852
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
853
|
+
optionalSemi
|
|
854
|
+
|
|
|
855
|
+
ELEMENTS '{' { $art.elements = this.createDict(); }
|
|
856
|
+
elementDefOrExtend[ $art ]*
|
|
857
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
858
|
+
optionalSemi
|
|
859
|
+
|
|
|
860
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
861
|
+
enumSymbolDef[ $art ]*
|
|
862
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
863
|
+
optionalSemi
|
|
864
|
+
)
|
|
865
|
+
)
|
|
768
866
|
;
|
|
769
867
|
|
|
770
868
|
extendWithOptElements[ art, annos ]
|
|
@@ -775,9 +873,9 @@ extendWithOptElements[ art, annos ]
|
|
|
775
873
|
includeRef[ $art ]
|
|
776
874
|
requiredSemi
|
|
777
875
|
|
|
|
778
|
-
'{'
|
|
876
|
+
'{' { $art.elements = this.createDict(); }
|
|
779
877
|
elementDefOrExtend[ $art ]*
|
|
780
|
-
'}'
|
|
878
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
781
879
|
optionalSemi
|
|
782
880
|
|
|
|
783
881
|
requiredSemi
|
|
@@ -786,59 +884,71 @@ extendWithOptElements[ art, annos ]
|
|
|
786
884
|
{ this.docComment( $annos ); }
|
|
787
885
|
annotationAssignment_ll1[ $annos ]*
|
|
788
886
|
(
|
|
789
|
-
'{'
|
|
887
|
+
'{' { $art.elements = this.createDict(); }
|
|
790
888
|
elementDefOrExtend[ $art ]*
|
|
791
|
-
'}'
|
|
889
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
792
890
|
optionalSemi
|
|
793
891
|
|
|
|
794
892
|
requiredSemi
|
|
795
893
|
)
|
|
796
894
|
;
|
|
797
895
|
|
|
798
|
-
annotateArtifact[ outer, loc, annos ] locals[ art, name = {} ]
|
|
896
|
+
annotateArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
799
897
|
@after { this.attachLocation($art); }
|
|
800
898
|
:
|
|
801
899
|
simplePath[ $name, 'Annotate' ]
|
|
802
|
-
|
|
900
|
+
(
|
|
901
|
+
{ $art = this.addItem( $outer, 'extensions', 'annotate', $annos, { name: $name }, $loc ); }
|
|
902
|
+
|
|
|
903
|
+
':'
|
|
904
|
+
simplePath[ $elemName, 'ref']
|
|
905
|
+
{{
|
|
906
|
+
const def = this.addItem( $outer, 'extensions', 'annotate', null, { name: $name }, $loc );
|
|
907
|
+
$art = this.artifactForElementAnnotateOrExtend( 'annotate', def, $elemName.path, $annos, $loc );
|
|
908
|
+
}}
|
|
909
|
+
)
|
|
910
|
+
|
|
803
911
|
( WITH { this.noSemicolonHere(); } )?
|
|
804
912
|
{ this.docComment( $annos ); }
|
|
805
913
|
annotationAssignment_ll1[ $annos ]*
|
|
806
914
|
(
|
|
807
|
-
'{'
|
|
915
|
+
'{' { $art.elements = this.createDict(); }
|
|
808
916
|
annotateElement[ $art ]*
|
|
809
|
-
'}'
|
|
917
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
810
918
|
(
|
|
811
919
|
ACTIONS
|
|
812
|
-
'{'
|
|
920
|
+
'{' { $art.actions = this.createDict(); }
|
|
813
921
|
annotateAction[ $art ]*
|
|
814
|
-
'}'
|
|
922
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
815
923
|
)?
|
|
816
924
|
optionalSemi
|
|
817
925
|
|
|
|
818
926
|
ACTIONS
|
|
819
|
-
'{'
|
|
927
|
+
'{' { $art.actions = this.createDict(); }
|
|
820
928
|
annotateAction[ $art ]*
|
|
821
|
-
'}'
|
|
929
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
822
930
|
optionalSemi
|
|
823
931
|
|
|
|
824
|
-
'('
|
|
932
|
+
'(' { $art.params = this.createDict(); }
|
|
825
933
|
annotateParam[ $art ]
|
|
826
934
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
827
935
|
annotateParam[ $art ]
|
|
828
936
|
)*
|
|
829
|
-
')'
|
|
937
|
+
')' { this.setDictEndLocation( $art.params ); }
|
|
830
938
|
(
|
|
831
|
-
RETURNS
|
|
939
|
+
RETURNS { $art['$'+'syntax'] = 'returns'; }
|
|
940
|
+
'{' { $art.elements = this.createDict(); }
|
|
832
941
|
annotateElement[ $art ]*
|
|
833
|
-
'}'
|
|
942
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
834
943
|
optionalSemi
|
|
835
944
|
|
|
|
836
945
|
requiredSemi
|
|
837
946
|
)
|
|
838
947
|
|
|
|
839
|
-
RETURNS
|
|
948
|
+
RETURNS { $art['$'+'syntax'] = 'returns'; }
|
|
949
|
+
'{' { $art.elements = this.createDict(); }
|
|
840
950
|
annotateElement[ $art ]*
|
|
841
|
-
'}'
|
|
951
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
842
952
|
optionalSemi
|
|
843
953
|
|
|
844
954
|
|
|
|
@@ -856,9 +966,9 @@ annotateElement[ outer ] locals[ art, annos = [] ]
|
|
|
856
966
|
this.docComment( $annos ); }
|
|
857
967
|
annotationAssignment_ll1[ $annos ]*
|
|
858
968
|
(
|
|
859
|
-
'{'
|
|
969
|
+
'{' { $art.elements = this.createDict(); }
|
|
860
970
|
annotateElement[ $art ]*
|
|
861
|
-
'}'
|
|
971
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
862
972
|
optionalSemi
|
|
863
973
|
|
|
|
864
974
|
requiredSemi
|
|
@@ -875,17 +985,17 @@ annotateAction [ outer ] locals [ art, annos = [] ]
|
|
|
875
985
|
this.docComment( $annos ); }
|
|
876
986
|
annotationAssignment_ll1[ $annos ]*
|
|
877
987
|
(
|
|
878
|
-
'('
|
|
988
|
+
'(' { $art.params = this.createDict(); }
|
|
879
989
|
annotateParam[ $art ]
|
|
880
990
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
881
991
|
annotateParam[ $art ]
|
|
882
992
|
)*
|
|
883
|
-
')'
|
|
993
|
+
')' { this.setDictEndLocation( $art.params ); }
|
|
884
994
|
)?
|
|
885
995
|
(
|
|
886
|
-
RETURNS '{'
|
|
996
|
+
RETURNS '{' { $art.elements = this.createDict(); }
|
|
887
997
|
annotateElement[ $art ]*
|
|
888
|
-
'}'
|
|
998
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
889
999
|
optionalSemi
|
|
890
1000
|
|
|
|
891
1001
|
requiredSemi
|
|
@@ -929,6 +1039,12 @@ enumSymbolDef[ outer ] locals[ art, annos = [] ]
|
|
|
929
1039
|
requiredSemi
|
|
930
1040
|
;
|
|
931
1041
|
|
|
1042
|
+
defaultValue[ art ] locals[ elem, elements = {} ]
|
|
1043
|
+
:
|
|
1044
|
+
// TODO: We may support structured default values here.
|
|
1045
|
+
DEFAULT expr=expression { $art.default = $expr.expr; }
|
|
1046
|
+
;
|
|
1047
|
+
|
|
932
1048
|
elementDefOrExtend[ outer ] locals[ annos = [] ]
|
|
933
1049
|
@after { /* #ATN 1 */ if ($ctx.art) this.attachLocation($art.art); }
|
|
934
1050
|
// tool complains if I test for ($art)
|
|
@@ -995,7 +1111,7 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
995
1111
|
:
|
|
996
1112
|
// TODO: it would be excellent to remove ELEMENT...
|
|
997
1113
|
// or have a special ident rule without the ELEMENT
|
|
998
|
-
// Reason: it would be good for error
|
|
1114
|
+
// Reason: it would be good for error recovery to start a major block without LL1 ambiguity
|
|
999
1115
|
// VIRTUAL is keyword, except if before the following tokens texts:
|
|
1000
1116
|
{ this.setLocalToken( 'VIRTUAL', 'VIRTUAL', /^[:{@=}]$/ ); }
|
|
1001
1117
|
virtual=VIRTUAL? key=KEY?
|
|
@@ -1047,7 +1163,7 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1047
1163
|
)
|
|
1048
1164
|
|
|
|
1049
1165
|
(
|
|
1050
|
-
array=ARRAY of=OF
|
|
1166
|
+
array=ARRAY of=OF
|
|
1051
1167
|
{ $art.items = { location: this.tokenLocation( $array, $of ) }; }
|
|
1052
1168
|
| many=MANY
|
|
1053
1169
|
{ $art.items = { location: this.tokenLocation( $many ) };}
|
|
@@ -1065,10 +1181,9 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1065
1181
|
{ this.docComment( $annos ); }
|
|
1066
1182
|
annotationAssignment_ll1[ $annos ]*
|
|
1067
1183
|
(
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
'}'
|
|
1184
|
+
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1185
|
+
enumSymbolDef[ $art.items ]*
|
|
1186
|
+
'}' { this.setDictEndLocation( $art.items.enum ); }
|
|
1072
1187
|
misplacedAnnotations[ $annos, 'syntax-anno-after-enum' ]?
|
|
1073
1188
|
)?
|
|
1074
1189
|
)
|
|
@@ -1092,13 +1207,14 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1092
1207
|
typeRefOptArgs[ $art ]
|
|
1093
1208
|
{ this.docComment( $annos ); }
|
|
1094
1209
|
annotationAssignment_ll1[ $annos ]*
|
|
1095
|
-
(
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
'}'
|
|
1210
|
+
(
|
|
1211
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1212
|
+
enumSymbolDef[ $art ]*
|
|
1213
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1099
1214
|
elementProperties[ $art ]?
|
|
1100
1215
|
misplacedAnnotations[ $annos, 'syntax-anno-after-enum' ]?
|
|
1101
|
-
|
|
|
1216
|
+
|
|
|
1217
|
+
elementProperties[ $art ]
|
|
1102
1218
|
{ this.docComment( $annos ); }
|
|
1103
1219
|
annotationAssignment_ll1[ $annos ]*
|
|
1104
1220
|
)?
|
|
@@ -1163,7 +1279,7 @@ selectItemDef[ outer ] locals[ annos = [] ]
|
|
|
1163
1279
|
;
|
|
1164
1280
|
|
|
1165
1281
|
selectItemDefBody[ outer, annos ] returns[ art = {} ]
|
|
1166
|
-
@after{ /* #ATN
|
|
1282
|
+
@after{ /* #ATN 2 */ this.attachLocation($art); }
|
|
1167
1283
|
:
|
|
1168
1284
|
(
|
|
1169
1285
|
e=expression
|
|
@@ -1219,6 +1335,12 @@ selectItemDefBody[ outer, annos ] returns[ art = {} ]
|
|
|
1219
1335
|
| typeRefOptArgs[ $art ] // TODO: annos here?
|
|
1220
1336
|
{ this.docComment( $annos ); }
|
|
1221
1337
|
annotationAssignment_ll1[ $annos ]*
|
|
1338
|
+
|
|
|
1339
|
+
typeAssociationBase[ $art, false ]
|
|
1340
|
+
// #ATN: path could start with MANY or ONE - make sure a token follows in same rule!
|
|
1341
|
+
( typeToMany[ $art ] | typeToOne[ $art ] | simplePath[ $art.target, 'artref' ] )
|
|
1342
|
+
typeAssociationCont[ $art ]?
|
|
1343
|
+
{ this.associationInSelectItem( $art ); }
|
|
1222
1344
|
)
|
|
1223
1345
|
)?
|
|
1224
1346
|
;
|
|
@@ -1249,7 +1371,7 @@ selectItemInlineDef[ outer ] locals[ annos = [] ]
|
|
|
1249
1371
|
|
|
1250
1372
|
parameterListDef[ art ]
|
|
1251
1373
|
:
|
|
1252
|
-
'('
|
|
1374
|
+
'(' { $art.params = this.createDict(); }
|
|
1253
1375
|
// also empty param list (we might do some hacking later to allow reserved words)
|
|
1254
1376
|
// see annotationAssignment_paren
|
|
1255
1377
|
(
|
|
@@ -1258,7 +1380,7 @@ parameterListDef[ art ]
|
|
|
1258
1380
|
parameterDef[ $art ]
|
|
1259
1381
|
)*
|
|
1260
1382
|
)?
|
|
1261
|
-
')'
|
|
1383
|
+
')' { this.setDictEndLocation( $art.params ); }
|
|
1262
1384
|
;
|
|
1263
1385
|
|
|
1264
1386
|
parameterDef[ outer ] locals[ art, annos = [] ]
|
|
@@ -1271,14 +1393,14 @@ parameterDef[ outer ] locals[ art, annos = [] ]
|
|
|
1271
1393
|
this.docComment( $annos ); }
|
|
1272
1394
|
annotationAssignment_fix[ $annos ]*
|
|
1273
1395
|
typeSpec[ $art ]
|
|
1274
|
-
|
|
1396
|
+
defaultValue[ $art ]?
|
|
1275
1397
|
{ this.docComment( $annos ); }
|
|
1276
1398
|
annotationAssignment_ll1[ $annos ]*
|
|
1277
1399
|
;
|
|
1278
1400
|
|
|
1279
1401
|
entityParameters[ art ]
|
|
1280
1402
|
:
|
|
1281
|
-
'('
|
|
1403
|
+
'(' { $art.params = this.createDict(); }
|
|
1282
1404
|
// also empty param list (we might do some hacking later to allow reserved words)
|
|
1283
1405
|
// see annotationAssignment_paren
|
|
1284
1406
|
(
|
|
@@ -1287,7 +1409,7 @@ entityParameters[ art ]
|
|
|
1287
1409
|
entityParameterDef[ $art ]
|
|
1288
1410
|
)*
|
|
1289
1411
|
)?
|
|
1290
|
-
')'
|
|
1412
|
+
')' { this.setDictEndLocation( $art.params ); }
|
|
1291
1413
|
;
|
|
1292
1414
|
|
|
1293
1415
|
entityParameterDef[ outer ] locals[ art, annos = [] ]
|
|
@@ -1300,7 +1422,7 @@ entityParameterDef[ outer ] locals[ art, annos = [] ]
|
|
|
1300
1422
|
this.docComment( $annos ); }
|
|
1301
1423
|
annotationAssignment_fix[ $annos ]*
|
|
1302
1424
|
typeSpec[ $art ]
|
|
1303
|
-
|
|
1425
|
+
defaultValue[ $art ]?
|
|
1304
1426
|
{ this.docComment( $annos ); }
|
|
1305
1427
|
annotationAssignment_ll1[ $annos ]*
|
|
1306
1428
|
;
|
|
@@ -1316,17 +1438,11 @@ nullability[ art ]
|
|
|
1316
1438
|
|
|
1317
1439
|
elementProperties[ elem ]
|
|
1318
1440
|
:
|
|
1319
|
-
nullability[$elem]
|
|
1320
|
-
|
|
1321
|
-
DEFAULT expr=expression
|
|
1322
|
-
{ $elem.default = $expr.expr; }
|
|
1323
|
-
)?
|
|
1441
|
+
nullability[ $elem ]
|
|
1442
|
+
defaultValue[ $elem ]?
|
|
1324
1443
|
|
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
{ $elem.default = $expr.expr; }
|
|
1328
|
-
)
|
|
1329
|
-
nullability[$elem]?
|
|
1444
|
+
defaultValue[ $elem ]
|
|
1445
|
+
nullability[ $elem ]?
|
|
1330
1446
|
|
|
|
1331
1447
|
eq='='
|
|
1332
1448
|
{ this.notSupportedYet( 'Calculated fields are not supported yet', $eq ); }
|
|
@@ -1377,10 +1493,10 @@ typeSpec[ art ] // for params
|
|
|
1377
1493
|
// TODO: no LOCALIZED ?
|
|
1378
1494
|
| typeRefOptArgs[ $art ]
|
|
1379
1495
|
nullability[ $art ]?
|
|
1380
|
-
(
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
'}'
|
|
1496
|
+
(
|
|
1497
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1498
|
+
enumSymbolDef[ $art ]*
|
|
1499
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1384
1500
|
)?
|
|
1385
1501
|
)
|
|
1386
1502
|
;
|
|
@@ -1390,7 +1506,7 @@ returnTypeSpec[ art, annos ]
|
|
|
1390
1506
|
:
|
|
1391
1507
|
ret=RETURNS { $art.returns = { location: this.tokenLocation( $ret ), kind: 'param' }; }
|
|
1392
1508
|
// #ATN: typeSimple can start with ARRAY or TYPE
|
|
1393
|
-
( typeStruct[ $art.returns ]
|
|
1509
|
+
( typeStruct[ $art.returns ]
|
|
1394
1510
|
nullability[ $art.returns ]?
|
|
1395
1511
|
| typeArray[ $art.returns ] // nullability is set in typeArray
|
|
1396
1512
|
| typeTypeOf[ $art.returns ]
|
|
@@ -1398,11 +1514,12 @@ returnTypeSpec[ art, annos ]
|
|
|
1398
1514
|
// TODO: no LOCALIZED ?
|
|
1399
1515
|
| typeRefOptArgs[ $art.returns ]
|
|
1400
1516
|
nullability[ $art.returns ]?
|
|
1401
|
-
(
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
'}'
|
|
1405
|
-
|
|
|
1517
|
+
(
|
|
1518
|
+
ENUM '{' { $art.returns.enum = this.createDict(); }
|
|
1519
|
+
enumSymbolDef[ $art.returns ]*
|
|
1520
|
+
'}' { this.setDictEndLocation( $art.returns.enum ); }
|
|
1521
|
+
|
|
|
1522
|
+
misplacedAnnotations[ $annos, 'syntax-anno-after-params' ]
|
|
1406
1523
|
)?
|
|
1407
1524
|
)
|
|
1408
1525
|
|
|
@@ -1443,7 +1560,7 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1443
1560
|
{ $art.items = { location: this.tokenLocation( $many ) };}
|
|
1444
1561
|
)
|
|
1445
1562
|
// #ATN: typeRefOptArgs can start with TYPE
|
|
1446
|
-
( typeStruct[ $art.items ]
|
|
1563
|
+
( typeStruct[ $art.items ]
|
|
1447
1564
|
nullability[ $art.items ]?
|
|
1448
1565
|
optionalSemi
|
|
1449
1566
|
| typeTypeOf[ $art.items ]
|
|
@@ -1455,21 +1572,24 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1455
1572
|
nullability[ $art.items ]?
|
|
1456
1573
|
{ this.docComment( $annos ); }
|
|
1457
1574
|
annotationAssignment_ll1[ $annos ]*
|
|
1458
|
-
(
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
'}'
|
|
1462
|
-
optionalSemi
|
|
1463
|
-
|
|
|
1575
|
+
(
|
|
1576
|
+
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1577
|
+
enumSymbolDef[ $art.items ]*
|
|
1578
|
+
'}' { this.setDictEndLocation( $art.items.enum ); }
|
|
1579
|
+
optionalSemi
|
|
1580
|
+
|
|
|
1581
|
+
requiredSemi
|
|
1464
1582
|
)
|
|
1465
1583
|
)
|
|
1466
1584
|
|
|
|
1467
1585
|
typeTypeOf[ $art ]
|
|
1586
|
+
defaultValue[ $art ]?
|
|
1468
1587
|
{ this.docComment( $annos ); }
|
|
1469
1588
|
annotationAssignment_ll1[ $annos ]* requiredSemi
|
|
1470
1589
|
|
|
|
1471
1590
|
l=LOCALIZED { $art.localized = this.valueWithTokenLocation( true, $l ); }
|
|
1472
1591
|
typeRefOptArgs[ $art ]
|
|
1592
|
+
defaultValue[ $art ]?
|
|
1473
1593
|
{ this.docComment( $annos ); }
|
|
1474
1594
|
annotationAssignment_ll1[ $annos ]*
|
|
1475
1595
|
requiredSemi
|
|
@@ -1478,34 +1598,22 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1478
1598
|
{ $art.type = {}; }
|
|
1479
1599
|
simplePath[ $art.type, 'artref' ]
|
|
1480
1600
|
(
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
(
|
|
1601
|
+
typeRefArgs[ $art ]
|
|
1602
|
+
{ this.docComment( $annos ); }
|
|
1603
|
+
annotationAssignment_ll1[ $annos ]*
|
|
1604
|
+
(
|
|
1605
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1606
|
+
enumSymbolDef[ $art ]*
|
|
1607
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1485
1608
|
(
|
|
1486
|
-
|
|
1487
|
-
{ $art['$'+'typeArgs'].push(
|
|
1488
|
-
{ literal: 'string', val: 'variable', location: this.tokenLocation($v) } );
|
|
1489
|
-
}
|
|
1490
|
-
|
|
|
1491
|
-
f=FLOATING
|
|
1492
|
-
{ $art['$'+'typeArgs'].push(
|
|
1493
|
-
{ literal: 'string', val: 'floating', location: this.tokenLocation($f) } );
|
|
1494
|
-
}
|
|
1609
|
+
optionalSemi
|
|
1495
1610
|
|
|
|
1496
|
-
|
|
1497
|
-
|
|
1611
|
+
defaultValue[ $art ]
|
|
1612
|
+
requiredSemi
|
|
1498
1613
|
)
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
annotationAssignment_ll1[ $annos ]*
|
|
1503
|
-
( ENUM '{'
|
|
1504
|
-
{ $art.enum = Object.create(null); }
|
|
1505
|
-
enumSymbolDef[ $art ]*
|
|
1506
|
-
'}'
|
|
1507
|
-
optionalSemi
|
|
1508
|
-
| requiredSemi
|
|
1614
|
+
|
|
|
1615
|
+
defaultValue[ $art ]?
|
|
1616
|
+
requiredSemi
|
|
1509
1617
|
)
|
|
1510
1618
|
|
|
|
1511
1619
|
':' // with element, e.g. `type T : E:elem enum { ... }`
|
|
@@ -1513,22 +1621,36 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1513
1621
|
simplePath[ $art.type, 'ref']
|
|
1514
1622
|
{ this.docComment( $annos ); }
|
|
1515
1623
|
annotationAssignment_ll1[ $annos ]*
|
|
1516
|
-
(
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
'}'
|
|
1520
|
-
|
|
1521
|
-
|
|
1624
|
+
(
|
|
1625
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1626
|
+
enumSymbolDef[ $art ]*
|
|
1627
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1628
|
+
(
|
|
1629
|
+
optionalSemi
|
|
1630
|
+
|
|
|
1631
|
+
defaultValue[ $art ]
|
|
1632
|
+
requiredSemi
|
|
1633
|
+
)
|
|
1634
|
+
|
|
|
1635
|
+
defaultValue[ $art ]?
|
|
1636
|
+
requiredSemi
|
|
1522
1637
|
)
|
|
1523
1638
|
|
|
|
1524
1639
|
{ this.docComment( $annos ); }
|
|
1525
1640
|
annotationAssignment_ll1[ $annos ]*
|
|
1526
|
-
(
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
'}'
|
|
1530
|
-
|
|
1531
|
-
|
|
1641
|
+
(
|
|
1642
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1643
|
+
enumSymbolDef[ $art ]*
|
|
1644
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1645
|
+
(
|
|
1646
|
+
optionalSemi
|
|
1647
|
+
|
|
|
1648
|
+
defaultValue[ $art ]
|
|
1649
|
+
requiredSemi
|
|
1650
|
+
)
|
|
1651
|
+
|
|
|
1652
|
+
defaultValue[ $art ]?
|
|
1653
|
+
requiredSemi
|
|
1532
1654
|
)
|
|
1533
1655
|
|
|
|
1534
1656
|
// TODO: complain if used in anno def?
|
|
@@ -1545,15 +1667,17 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1545
1667
|
typeStruct[ art, attachLoc = false ]
|
|
1546
1668
|
@after { if ($attachLoc) this.attachLocation($art); }
|
|
1547
1669
|
:
|
|
1548
|
-
{ $art.elements =
|
|
1549
|
-
|
|
1670
|
+
'{' { $art.elements = this.createDict(); }
|
|
1671
|
+
elementDef[ $art ]*
|
|
1672
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
1550
1673
|
;
|
|
1551
1674
|
|
|
1552
1675
|
typeCompoStruct[ art ]
|
|
1553
1676
|
@after { this.attachLocation($art); }
|
|
1554
1677
|
:
|
|
1555
|
-
{ $art.elements =
|
|
1556
|
-
|
|
1678
|
+
COMPOSITIONofBRACE { $art.elements = this.createDict(); }
|
|
1679
|
+
elementDef[ $art ]*
|
|
1680
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
1557
1681
|
;
|
|
1558
1682
|
|
|
1559
1683
|
typeArray[ art ]
|
|
@@ -1572,10 +1696,10 @@ typeArray[ art ]
|
|
|
1572
1696
|
nullability[ $art.items ]?
|
|
1573
1697
|
| typeRefOptArgs[ $art.items ]
|
|
1574
1698
|
nullability[ $art.items ]?
|
|
1575
|
-
(
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
'}'
|
|
1699
|
+
(
|
|
1700
|
+
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1701
|
+
enumSymbolDef[ $art.items ]*
|
|
1702
|
+
'}' { this.setDictEndLocation( $art.items.enum ); }
|
|
1579
1703
|
)?
|
|
1580
1704
|
)
|
|
1581
1705
|
;
|
|
@@ -1603,7 +1727,7 @@ typeAssociationBase[ art, handleTypeCompo ] // including Composition
|
|
|
1603
1727
|
typeAssociationCont[ art ]
|
|
1604
1728
|
:
|
|
1605
1729
|
(
|
|
1606
|
-
'{'
|
|
1730
|
+
'{' { $art.foreignKeys = this.createDict(); }
|
|
1607
1731
|
{ this.addDef( $art, 'foreignKeys' ); }
|
|
1608
1732
|
(
|
|
1609
1733
|
foreignKey[ $art ]
|
|
@@ -1611,7 +1735,7 @@ typeAssociationCont[ art ]
|
|
|
1611
1735
|
foreignKey[ $art ]
|
|
1612
1736
|
)*
|
|
1613
1737
|
)?
|
|
1614
|
-
'}'
|
|
1738
|
+
'}' { this.setDictEndLocation( $art.foreignKeys ); }
|
|
1615
1739
|
|
|
|
1616
1740
|
ON cond=condition
|
|
1617
1741
|
{ $art.on=$cond.cond; }
|
|
@@ -1622,7 +1746,7 @@ typeAssociationElementCont[ art, annos ] // including Composition
|
|
|
1622
1746
|
// optional NULL / NOT NULL for managed association only
|
|
1623
1747
|
:
|
|
1624
1748
|
(
|
|
1625
|
-
'{'
|
|
1749
|
+
'{' { $art.foreignKeys = this.createDict(); }
|
|
1626
1750
|
{ this.addDef( $art, 'foreignKeys' ); }
|
|
1627
1751
|
(
|
|
1628
1752
|
foreignKey[ $art ]
|
|
@@ -1630,7 +1754,7 @@ typeAssociationElementCont[ art, annos ] // including Composition
|
|
|
1630
1754
|
foreignKey[ $art ]
|
|
1631
1755
|
)*
|
|
1632
1756
|
)?
|
|
1633
|
-
'}'
|
|
1757
|
+
'}' { this.setDictEndLocation( $art.foreignKeys ); }
|
|
1634
1758
|
nullability[ $art ]?
|
|
1635
1759
|
|
|
|
1636
1760
|
ON cond=condition
|
|
@@ -1718,7 +1842,19 @@ typeRefOptArgs[ art ]
|
|
|
1718
1842
|
:
|
|
1719
1843
|
simplePath[ $art.type, 'artref' ]
|
|
1720
1844
|
(
|
|
1721
|
-
|
|
1845
|
+
typeRefArgs[ $art ]
|
|
1846
|
+
|
|
|
1847
|
+
':'
|
|
1848
|
+
{ $art.type.scope = $art.type.path.length; }
|
|
1849
|
+
simplePath[ $art.type, 'ref']
|
|
1850
|
+
)?
|
|
1851
|
+
;
|
|
1852
|
+
|
|
1853
|
+
typeRefArgs[ art ]
|
|
1854
|
+
:
|
|
1855
|
+
paren='('
|
|
1856
|
+
(
|
|
1857
|
+
// unnamed arguments
|
|
1722
1858
|
head=Number
|
|
1723
1859
|
{ $art['$'+'typeArgs'] = [ this.numberLiteral( $head ) ]; }
|
|
1724
1860
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
@@ -1737,14 +1873,45 @@ typeRefOptArgs[ art ]
|
|
|
1737
1873
|
{ $art['$'+'typeArgs'].push( this.numberLiteral( $tail ) ); }
|
|
1738
1874
|
)
|
|
1739
1875
|
)*
|
|
1740
|
-
')'
|
|
1741
1876
|
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1877
|
+
// named arguments
|
|
1878
|
+
typeNamedArg[ $art ]
|
|
1879
|
+
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
1880
|
+
typeNamedArg[ $art ]
|
|
1881
|
+
)*
|
|
1882
|
+
)
|
|
1883
|
+
')'
|
|
1746
1884
|
;
|
|
1747
1885
|
|
|
1886
|
+
typeNamedArg[ art ] locals[ arg = '' ]
|
|
1887
|
+
:
|
|
1888
|
+
name=ident['paramname']
|
|
1889
|
+
':'
|
|
1890
|
+
{ if (this.checkTypeFacet( $art, $name.id ))
|
|
1891
|
+
$arg = $name.id.id;
|
|
1892
|
+
}
|
|
1893
|
+
(
|
|
1894
|
+
val=Number
|
|
1895
|
+
{ if ($arg && $art && $name.id) {
|
|
1896
|
+
$art[$arg] = this.numberLiteral( $val );
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
|
|
|
1900
|
+
v=VARIABLE
|
|
1901
|
+
{ if ($arg && $art && $name.id) {
|
|
1902
|
+
$art[$arg] = { literal: 'string', val: 'variable', location: this.tokenLocation($v) };
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
|
|
|
1906
|
+
f=FLOATING
|
|
1907
|
+
{ if ($arg && $art && $name.id) {
|
|
1908
|
+
$art[$arg] = { literal: 'string', val: 'floating', location: this.tokenLocation($f) };
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
)
|
|
1912
|
+
;
|
|
1913
|
+
|
|
1914
|
+
|
|
1748
1915
|
// Queries -------------------------------------------------------------------
|
|
1749
1916
|
|
|
1750
1917
|
queryExpression returns[ query ] // QLSubqueryComplex, SubqueryComplex
|
|
@@ -1770,14 +1937,26 @@ orderByClause[ inQuery ] returns [ query ]
|
|
|
1770
1937
|
( ',' obn=orderBySpec { $query.orderBy.push( $obn.ob ); } )*
|
|
1771
1938
|
;
|
|
1772
1939
|
|
|
1940
|
+
// Generic function ORDER BY clause, e.g. `first_value(id order by name)`
|
|
1941
|
+
// lhsExpr is the left expression of the ORDER BY clause.
|
|
1942
|
+
functionOrderByClause[ lhsExpr ] returns [ expr ]
|
|
1943
|
+
@after { this.attachLocation( $expr ); }
|
|
1944
|
+
:
|
|
1945
|
+
o=ORDER b=BY { $expr = { op: this.valueWithTokenLocation( 'orderBy', $o, $b ) , args: [ $lhsExpr ] }}
|
|
1946
|
+
ob1=orderBySpec { $expr.args.push( $ob1.ob ); }
|
|
1947
|
+
( ',' obn=orderBySpec { $expr.args.push( $obn.ob ); } )*
|
|
1948
|
+
;
|
|
1949
|
+
|
|
1773
1950
|
overOrderByClause returns [ expr ]
|
|
1951
|
+
@after { this.attachLocation( $expr ); }
|
|
1774
1952
|
:
|
|
1775
|
-
o=ORDER b=BY { $expr = { op: this.valueWithTokenLocation( '
|
|
1953
|
+
o=ORDER b=BY { $expr = { op: this.valueWithTokenLocation( 'overOrderBy', $o, $b ) , args: [] }}
|
|
1776
1954
|
ob1=orderBySpec { $expr.args.push( $ob1.ob ); }
|
|
1777
1955
|
( ',' obn=orderBySpec { $expr.args.push( $obn.ob ); } )*
|
|
1778
1956
|
;
|
|
1779
1957
|
|
|
1780
1958
|
partitionByClause returns [ expr ]
|
|
1959
|
+
@after { this.attachLocation( $expr ); }
|
|
1781
1960
|
:
|
|
1782
1961
|
p=PARTITION b=BY { $expr = { op: this.valueWithTokenLocation( 'partitionBy', $p, $b ) , args: [] }}
|
|
1783
1962
|
e1=expression { $expr.args.push( $e1.expr ); }
|
|
@@ -1785,12 +1964,14 @@ partitionByClause returns [ expr ]
|
|
|
1785
1964
|
;
|
|
1786
1965
|
|
|
1787
1966
|
windowFrameClause returns [ wf ]
|
|
1967
|
+
@after { this.attachLocation( $wf ); }
|
|
1788
1968
|
:
|
|
1789
1969
|
r=ROWS { $wf = { op: this.valueWithTokenLocation( 'rows', $r ) , args: [] }}
|
|
1790
1970
|
wfe=windowFrameExtentSpec { $wf.args.push( $wfe.wfe ); }
|
|
1791
1971
|
;
|
|
1792
1972
|
|
|
1793
1973
|
windowFrameExtentSpec returns[ wfe ]
|
|
1974
|
+
@after { this.attachLocation( $wfe ); }
|
|
1794
1975
|
:
|
|
1795
1976
|
{ $wfe = {} }
|
|
1796
1977
|
windowFrameStartSpec [ $wfe ]
|
|
@@ -1820,6 +2001,7 @@ windowFrameBoundSpec returns [ wfb ]
|
|
|
1820
2001
|
;
|
|
1821
2002
|
|
|
1822
2003
|
windowFrameStartSpec [ wf ]
|
|
2004
|
+
@after { this.attachLocation( $wf ); }
|
|
1823
2005
|
:
|
|
1824
2006
|
u=UNBOUNDED p=PRECEDING
|
|
1825
2007
|
{
|
|
@@ -1832,7 +2014,7 @@ windowFrameStartSpec [ wf ]
|
|
|
1832
2014
|
$wf.op = this.valueWithTokenLocation( 'preceding', $p );
|
|
1833
2015
|
$wf.args = [ this.numberLiteral( $n ) ];
|
|
1834
2016
|
}
|
|
1835
|
-
|
|
|
2017
|
+
|
|
|
1836
2018
|
c=CURRENT r=ROW
|
|
1837
2019
|
{
|
|
1838
2020
|
$wf.op = this.valueWithTokenLocation( 'currentRow', $c, $r );
|
|
@@ -1841,7 +2023,7 @@ windowFrameStartSpec [ wf ]
|
|
|
1841
2023
|
;
|
|
1842
2024
|
|
|
1843
2025
|
overClause returns [ over ]
|
|
1844
|
-
@after { this.attachLocation($over); }
|
|
2026
|
+
@after { this.attachLocation( $over ); }
|
|
1845
2027
|
:
|
|
1846
2028
|
o=OVER { $over = { op: this.valueWithTokenLocation( 'over', $o ) , args: [] } }
|
|
1847
2029
|
'('
|
|
@@ -1895,9 +2077,10 @@ queryPrimary returns[ query = {} ]
|
|
|
1895
2077
|
(
|
|
1896
2078
|
FROM querySource[ $query ]
|
|
1897
2079
|
(
|
|
1898
|
-
mixin=MIXIN '{'
|
|
2080
|
+
mixin=MIXIN '{' { $query.mixin = this.createDict(); }
|
|
1899
2081
|
mixinElementDef[ $query ]*
|
|
1900
|
-
'}'
|
|
2082
|
+
'}' { this.setDictEndLocation( $query.mixin ); }
|
|
2083
|
+
INTO
|
|
1901
2084
|
)?
|
|
1902
2085
|
( ad=( ALL | DISTINCT ) // TODO: or directly after SELECT ?
|
|
1903
2086
|
{ $query.quantifier = this.valueWithTokenLocation( $ad.text.toLowerCase(), $ad ); }
|
|
@@ -2088,6 +2271,7 @@ conditionAnd returns [ cond ] locals [ args = [], andl = [] ]
|
|
|
2088
2271
|
( and=AND c2=conditionTerm { $args.push($c2.cond); $andl.push(this.valueWithTokenLocation( 'and', $and )) } )*
|
|
2089
2272
|
;
|
|
2090
2273
|
|
|
2274
|
+
// Note: New operators need to be added to functionExpressionOperatorsRequireParentheses[] in toCdl.js.
|
|
2091
2275
|
conditionTerm returns [ cond ]
|
|
2092
2276
|
@after{
|
|
2093
2277
|
if ($cond) { this.attachLocation($cond); } else { $cond = $expr.expr; }
|
|
@@ -2135,6 +2319,7 @@ conditionTerm returns [ cond ]
|
|
|
2135
2319
|
)? // optional: for conditions in parentheses
|
|
2136
2320
|
;
|
|
2137
2321
|
|
|
2322
|
+
// Note: New operators need to be added to functionExpressionOperatorsRequireParentheses[] in toCdl.js.
|
|
2138
2323
|
predicate[ cond, negated ]
|
|
2139
2324
|
// As an alternative, we could have a `negated` properties for the operations
|
|
2140
2325
|
// `isNull`(!), `in`, `between` and `like` (or produce the same AST as for
|
|
@@ -2351,6 +2536,7 @@ fromArguments[ pathStep ]
|
|
|
2351
2536
|
pathArguments[ pathStep, considerSpecial ]
|
|
2352
2537
|
@after{ /* #ATN 1 */ }
|
|
2353
2538
|
:
|
|
2539
|
+
{ this.excludeExpected([ 'ORDER' ]); }
|
|
2354
2540
|
paren='('
|
|
2355
2541
|
{ this.prepareGenericKeywords( $considerSpecial ); }
|
|
2356
2542
|
// ATN, LL2: Identifier can start both named arguments and the positional.
|
|
@@ -2372,6 +2558,13 @@ pathArguments[ pathStep, considerSpecial ]
|
|
|
2372
2558
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2373
2559
|
funcExpression[ $pathStep, $considerSpecial ]
|
|
2374
2560
|
)*
|
|
2561
|
+
// Note: We can't move this into funcExpression, or we would increase the ATN count because of `,` amiguity.
|
|
2562
|
+
( ob=functionOrderByClause[ $pathStep.args[$pathStep.args.length - 1] ]
|
|
2563
|
+
{
|
|
2564
|
+
// Remove the last entry which was copied to $ob.expr and push $ob.expr.
|
|
2565
|
+
$pathStep.args[$pathStep.args.length - 1] = $ob.expr;
|
|
2566
|
+
}
|
|
2567
|
+
)?
|
|
2375
2568
|
|
|
|
2376
2569
|
a=ALL { $pathStep.quantifier = this.valueWithTokenLocation( 'all', $a ); }
|
|
2377
2570
|
e1=expression { $pathStep.args = [ $e1.expr ]; }
|
|
@@ -2679,6 +2872,7 @@ ident[ category ] returns[ id ]
|
|
|
2679
2872
|
| ASSOCIATION
|
|
2680
2873
|
| BETWEEN
|
|
2681
2874
|
| BOTH
|
|
2875
|
+
| COLUMNS
|
|
2682
2876
|
| COMPOSITION
|
|
2683
2877
|
| CONTEXT
|
|
2684
2878
|
| CROSS
|
|
@@ -2686,8 +2880,10 @@ ident[ category ] returns[ id ]
|
|
|
2686
2880
|
| DAY
|
|
2687
2881
|
| DEFAULT
|
|
2688
2882
|
| DEFINE
|
|
2883
|
+
| DEFINITIONS
|
|
2689
2884
|
| DESC
|
|
2690
2885
|
| ELEMENT
|
|
2886
|
+
| ELEMENTS
|
|
2691
2887
|
| ELSE
|
|
2692
2888
|
| END
|
|
2693
2889
|
| ENTITY
|
|
@@ -2883,6 +3079,7 @@ ASPECT : [aA][sS][pP][eE][cC][tT] ;
|
|
|
2883
3079
|
ASSOCIATION : [aA][sS][sS][oO][cC][iI][aA][tT][iI][oO][nN] ;
|
|
2884
3080
|
BETWEEN : [bB][eE][tT][wW][eE][eE][nN] ;
|
|
2885
3081
|
BOTH : [bB][oO][tT][hH] ;
|
|
3082
|
+
COLUMNS : [cC][oO][lL][uU][mM][nN][sS];
|
|
2886
3083
|
COMPOSITION : [cC][oO][mM][pP][oO][sS][iI][tT][iI][oO][nN] ;
|
|
2887
3084
|
CONTEXT : [cC][oO][nN][tT][eE][xX][tT] ;
|
|
2888
3085
|
CROSS : [cC][rR][oO][sS][sS] ;
|
|
@@ -2890,8 +3087,10 @@ CURRENT : [cC][uU][rR][rR][eE][nN][tT] ;
|
|
|
2890
3087
|
DAY : [dD][aA][yY] ;
|
|
2891
3088
|
DEFAULT : [dD][eE][fF][aA][uU][lL][tT] ;
|
|
2892
3089
|
DEFINE : [dD][eE][fF][iI][nN][eE] ;
|
|
3090
|
+
DEFINITIONS : [dD][eE][fF][iI][nN][iI][tT][iI][oO][nN][sS] ;
|
|
2893
3091
|
DESC : [dD][eE][sS][cC] ;
|
|
2894
3092
|
ELEMENT : [eE][lL][eE][mM][eE][nN][tT] ;
|
|
3093
|
+
ELEMENTS : [eE][lL][eE][mM][eE][nN][tT][sS] ;
|
|
2895
3094
|
ELSE : [eE][lL][sS][eE] ;
|
|
2896
3095
|
END : [eE][nN][dD] ;
|
|
2897
3096
|
ENTITY : [eE][nN][tT][iI][tT][yY] ;
|