@sap/cds-compiler 3.8.0 → 3.8.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.
@@ -1409,8 +1409,7 @@ function annotation( val, spec, xsn, csn, name ) {
1409
1409
  return undefined;
1410
1410
  n.absolute = absolute;
1411
1411
  if (variantIndex < absolute.length)
1412
- n.variant = { id: name.substring( variantIndex ), location: location() };
1413
-
1412
+ n.variant = refSplit( name.substring( variantIndex ), null );
1414
1413
  const r = annoValue( val, spec );
1415
1414
  r.name = n;
1416
1415
  return r;
@@ -974,7 +974,8 @@ function pushIdent( path, ident, prefix ) {
974
974
  }
975
975
 
976
976
  // For :param, #variant, #symbol, @(…) and @Begin and `@` inside annotation paths
977
- function reportUnexpectedSpace( prefix, location = this.tokenLocation( this._input.LT(1) ) ) {
977
+ function reportUnexpectedSpace( prefix = this._input.LT(-1),
978
+ location = this.tokenLocation( this._input.LT(1) ) ) {
978
979
  const prefixLoc = this.tokenLocation( prefix );
979
980
  if (prefixLoc.endLine !== location.line ||
980
981
  prefixLoc.endCol !== location.col) {
@@ -2583,7 +2583,7 @@ annotationAssignment_fix[ art ] locals[ assignment ]
2583
2583
  |
2584
2584
  { $assignment = { name: {} }; }
2585
2585
  annotationPath[ $assignment.name, 'anno' ]
2586
- annotationPathVariant[ $assignment.name ]?
2586
+ ( '#' annotationPathVariant[ $assignment.name ] )?
2587
2587
  { this.warnIfColonFollows( $assignment ); }
2588
2588
  )
2589
2589
  ;
@@ -2601,7 +2601,7 @@ annotationAssignment_ll1[ art ] locals[ assignment ]
2601
2601
  |
2602
2602
  { $assignment = { name: {} }; }
2603
2603
  annotationPath[ $assignment.name, 'anno' ]
2604
- annotationPathVariant[ $assignment.name ]?
2604
+ ( '#' annotationPathVariant[ $assignment.name ] )?
2605
2605
  (
2606
2606
  ':' { this.meltKeywordToIdentifier(true); } // allow path as anno value start with reserved
2607
2607
  val=annoValue[ $assignment ]
@@ -2627,11 +2627,7 @@ annotationAssignment_atn[ art ] locals[ assignment ]
2627
2627
  // before an "expression" which can start with a '#' for an enum value
2628
2628
  // -> used to introduce variant name if and only if in same line as previous token
2629
2629
  { this.setLocalToken( '#', 'HelperToken1', null, true ); }
2630
- (
2631
- hash=HelperToken1
2632
- { this.meltKeywordToIdentifier();; this.reportUnexpectedSpace( $hash ); }
2633
- variant=ident['variant'] { $assignment.name.variant = $variant.id; }
2634
- )?
2630
+ ( hash=HelperToken1 annotationPathVariant[ $assignment.name ] )?
2635
2631
  // ':' is in the follow set of this rule, as it is used in rule "selectItemDef"
2636
2632
  // before an "expression" which can start with a ':' for a parameter reference
2637
2633
  // -> used to introduce assignment value if and only if in same line as previous token
@@ -2643,11 +2639,7 @@ annotationAssignment_atn[ art ] locals[ assignment ]
2643
2639
  |
2644
2640
  atv='@'? annotationPath[ $assignment, 'ref', $atv ]
2645
2641
  { this.setLocalToken( '#', 'HelperToken1', null, true ); } // see above
2646
- (
2647
- hash=HelperToken1
2648
- { this.meltKeywordToIdentifier();; this.reportUnexpectedSpace( $hash ); }
2649
- variant=ident['variant'] { $assignment.variant = $variant.id; }
2650
- )?
2642
+ ( hash=HelperToken1 annotationPathVariant[ $assignment ] )?
2651
2643
  )
2652
2644
  )?
2653
2645
  )
@@ -2658,11 +2650,11 @@ annotationAssignment_paren[ art ]
2658
2650
  '('
2659
2651
  // allow completely useless `@()`; no warning anymore - who cares?
2660
2652
  {
2661
- this.meltKeywordToIdentifier();
2662
2653
  if (this.isStraightBefore(')')) {
2663
2654
  this.matchWildcard(); // we know it is the ')' - we do not reach the final match
2664
2655
  return $ctx;
2665
2656
  }
2657
+ this.meltKeywordToIdentifier();
2666
2658
  }
2667
2659
  annotationAssignment_1[ $art ]
2668
2660
  ( ','
@@ -2679,7 +2671,7 @@ annotationAssignment_1[ art ] locals[ assignment = { name: {} } ]
2679
2671
  @after { this.assignAnnotation( $art, $assignment ); }
2680
2672
  :
2681
2673
  annotationPath[ $assignment.name, 'anno' ]
2682
- annotationPathVariant[ $assignment.name ]?
2674
+ ( '#' annotationPathVariant[ $assignment.name ] )?
2683
2675
  (
2684
2676
  ':' { this.meltKeywordToIdentifier(true); } // allow path as anno value start with reserved
2685
2677
  val=annoValue[ $assignment ]
@@ -2704,11 +2696,11 @@ annotationPath[ art, category, headat = null ] locals[ _sync = 'nop' ]
2704
2696
  )*
2705
2697
  ;
2706
2698
 
2699
+ // Before calling this rule, match '#'
2707
2700
  annotationPathVariant[ art ] locals[ variant = {} ]
2708
2701
  @after { this.attachLocation($art); }
2709
2702
  :
2710
- // TODO: warning for space after '#'
2711
- hash='#' { this.meltKeywordToIdentifier();; this.reportUnexpectedSpace( $hash ); }
2703
+ { this.reportUnexpectedSpace();; this.meltKeywordToIdentifier(); }
2712
2704
  simplePath[ $variant, 'variant' ] { $art.variant = $variant; }
2713
2705
  ;
2714
2706
 
@@ -2719,7 +2711,7 @@ annoValue[ assignment ]
2719
2711
  // no docComment() here
2720
2712
  // this alternative is done with token rewrite in rule "annotationAssignment_atn"
2721
2713
  at='@'? annotationPath[ $assignment, 'ref', $at ]
2722
- annotationPathVariant[ $assignment ]?
2714
+ ( '#' annotationPathVariant[ $assignment ] )?
2723
2715
  ;
2724
2716
 
2725
2717
  annoValueBase[ assignment ] locals [ seenEllipsis = false ]
@@ -2739,6 +2731,7 @@ annoValueBase[ assignment ] locals [ seenEllipsis = false ]
2739
2731
  |
2740
2732
  '[' // no need for createArray() here, $assignment.location is set
2741
2733
  { $assignment.val = []; $assignment.literal = 'array'; }
2734
+ { this.meltKeywordToIdentifier(true); }
2742
2735
  (
2743
2736
  (
2744
2737
  head=annoSubValue { $assignment.val.push( $head.val ); }
@@ -2753,6 +2746,7 @@ annoValueBase[ assignment ] locals [ seenEllipsis = false ]
2753
2746
  )
2754
2747
  (
2755
2748
  ',' { if (this.isStraightBefore(']')) break; } // allow ',' before ']'
2749
+ { this.meltKeywordToIdentifier(true); }
2756
2750
  (
2757
2751
  tail=annoSubValue { $assignment.val.push( $tail.val ); }
2758
2752
  |
@@ -2794,7 +2788,7 @@ annoValueBase[ assignment ] locals [ seenEllipsis = false ]
2794
2788
  flattenedValue[ assignment ] locals[ val = { name: {} } ]
2795
2789
  :
2796
2790
  at='@'? annotationPath[ $val.name, 'name', $at ]
2797
- ( annotationPathVariant[ $val.name ] )?
2791
+ ( '#' annotationPathVariant[ $val.name ] )?
2798
2792
  (
2799
2793
  ':' { this.meltKeywordToIdentifier(true); } // allow path as anno value start with reserved
2800
2794
  annoValue[ $val ]
@@ -2805,7 +2799,8 @@ flattenedValue[ assignment ] locals[ val = { name: {} } ]
2805
2799
  namedValue[ struct ] locals[ val = { name: {} } ]
2806
2800
  :
2807
2801
  at='@'? annotationPath[ $val.name, 'name', $at ]
2808
- ( ':' sub=annoSubValue { Object.assign( $val, $sub.val ); } )?
2802
+ ( ':' { this.meltKeywordToIdentifier(true); }
2803
+ sub=annoSubValue { Object.assign( $val, $sub.val ); } )?
2809
2804
  {
2810
2805
  if (!$val.location) $val.location = $val.name.location;
2811
2806
  this.addDef( $val, $struct, 'struct', null, $val.name ); // TODO: re-check name
@@ -2830,8 +2825,10 @@ annoSubValue returns[ val = {} ]
2830
2825
  |
2831
2826
  '[' // no need for createArray() here, $val.location is set
2832
2827
  { $val.val = []; $val.literal = 'array'; }
2828
+ { this.meltKeywordToIdentifier(true); }
2833
2829
  ( head=annoSubValue { $val.val.push( $head.val ); }
2834
2830
  ( ',' { if (this.isStraightBefore(']')) break; } // allow ',' before ']'
2831
+ { this.meltKeywordToIdentifier(true); }
2835
2832
  tail=annoSubValue { $val.val.push( $tail.val ); }
2836
2833
  )*
2837
2834
  )?
@@ -2843,7 +2840,7 @@ annoSubValue returns[ val = {} ]
2843
2840
  { Object.assign( $val, this.numberLiteral( $num, $plus||$min ) ); }
2844
2841
  |
2845
2842
  at='@'? annotationPath[ $val, 'ref', $at ]
2846
- ( annotationPathVariant[ $val ] )?
2843
+ ( '#' annotationPathVariant[ $val ] )?
2847
2844
  |
2848
2845
  '('
2849
2846
  cond=condition
@@ -2857,7 +2854,7 @@ literalValue returns[ val ] locals[ tok ]
2857
2854
  @init{ $tok = this.getCurrentToken(); }
2858
2855
  @after { this.attachLocation($val); }
2859
2856
  :
2860
- hash='#' { this.meltKeywordToIdentifier();; this.reportUnexpectedSpace( $hash ); }
2857
+ hash='#' { this.reportUnexpectedSpace( $hash );; this.meltKeywordToIdentifier(); }
2861
2858
  name=ident['enumref'] // TODO v4: remove from this rule (not in enum!)
2862
2859
  { $val = { literal: 'enum', sym: $name.id } }
2863
2860
  |
@@ -620,6 +620,9 @@ function csnRefs( csn, universalReady ) {
620
620
  return resolvePath( path, art, parent, 'parent' );
621
621
  }
622
622
 
623
+ if (!qcache)
624
+ throw new CompilerAssertion( `Query not in cache at: ${ locationString(query.$location) }` );
625
+
623
626
  if (semantics.dynamic === 'query')
624
627
  // TODO: for ON condition in expand, would need to use cached _element
625
628
  return resolvePath( path, qcache.elements[head], null, 'query' );
@@ -882,8 +885,8 @@ function traverseFrom( from, fromSelect, parentQuery, callback ) {
882
885
  }
883
886
  else if (from.args) { // join
884
887
  from.args.forEach( arg => traverseFrom( arg, fromSelect, parentQuery, callback ) );
885
- if (from.on) // join-on, potentially having a sub query
886
- from.on.forEach( arg => traverseQuery( arg, null, fromSelect, callback ) );
888
+ if (from.on) // join-on, potentially having a sub query (in xpr)
889
+ from.on.forEach(arg => traverseExpr(arg, fromSelect, callback));
887
890
  }
888
891
  else { // sub query in FROM
889
892
  traverseQuery( from, fromSelect, parentQuery, callback );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-compiler",
3
- "version": "3.8.0",
3
+ "version": "3.8.2",
4
4
  "description": "CDS (Core Data Services) compiler and backends",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "author": "SAP SE (https://www.sap.com)",