@abaplint/cli 2.120.27 → 2.120.28

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.
Files changed (2) hide show
  1. package/build/cli.js +98 -20
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -9079,7 +9079,7 @@ const sql_field_1 = __webpack_require__(/*! ./sql_field */ "../core/build/src/ab
9079
9079
  const sql_grouping_sets_1 = __webpack_require__(/*! ./sql_grouping_sets */ "../core/build/src/abap/2_statements/expressions/sql_grouping_sets.js");
9080
9080
  class SQLGroupBy extends combi_1.Expression {
9081
9081
  getRunnable() {
9082
- const fieldName = (0, combi_1.alt)(sql_field_name_1.SQLFieldName, dynamic_1.Dynamic);
9082
+ const fieldName = (0, combi_1.seq)((0, combi_1.stopBefore)("ORDER", "BY"), (0, combi_1.alt)(sql_field_name_1.SQLFieldName, dynamic_1.Dynamic));
9083
9083
  const expr = (0, combi_1.ver)(version_1.Release.v740sp02, sql_field_1.SQLField, { also: combi_1.AlsoIn.OpenABAP });
9084
9084
  const newGroup = (0, combi_1.ver)(version_1.Release.v740sp02, (0, combi_1.seq)("GROUP BY", expr, (0, combi_1.altPrio)((0, combi_1.plus)((0, combi_1.seq)(",", expr)), (0, combi_1.optPrio)((0, combi_1.plus)(fieldName)))), { also: combi_1.AlsoIn.OpenABAP });
9085
9085
  const old = (0, combi_1.seq)((0, combi_1.plus)((0, combi_1.seq)(fieldName, ",")), fieldName);
@@ -29137,7 +29137,7 @@ function checkDatabaseFields(fields, dbSources, input, token) {
29137
29137
  if (field === "*") {
29138
29138
  continue;
29139
29139
  }
29140
- if (/^\w+$/.test(field) && type.getComponentByName(field) === undefined) {
29140
+ if (/^[A-Z_]\w*$/i.test(field) && type.getComponentByName(field) === undefined) {
29141
29141
  const message = `checkFields, field ${field} not found`;
29142
29142
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, token, message));
29143
29143
  return;
@@ -33823,7 +33823,7 @@ class Select {
33823
33823
  return;
33824
33824
  }
33825
33825
  (0, _check_database_fields_1.checkDatabaseFields)(fields.map(field => field.code), dbSources, input, node.getFirstToken());
33826
- const intoExpression = this.handleInto(node, input, fields, dbSources);
33826
+ const intoExpression = this.handleInto(node, input, fields, dbSources, from);
33827
33827
  const fae = node.findDirectExpression(Expressions.SQLForAllEntries);
33828
33828
  if (fae) {
33829
33829
  input.scope.push(_scope_type_1.ScopeType.OpenSQL, "SELECT", token.getStart(), input.filename);
@@ -33984,12 +33984,12 @@ class Select {
33984
33984
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
33985
33985
  }
33986
33986
  }
33987
- static handleInto(node, input, fields, dbSources) {
33987
+ static handleInto(node, input, fields, dbSources, from) {
33988
33988
  const intoTable = node.findDirectExpression(Expressions.SQLIntoTable);
33989
33989
  if (intoTable) {
33990
33990
  const inline = intoTable.findFirstExpression(Expressions.InlineData);
33991
33991
  if (inline) {
33992
- inline_data_1.InlineData.runSyntax(inline, input, this.buildTableType(fields, dbSources, input.scope));
33992
+ inline_data_1.InlineData.runSyntax(inline, input, this.buildTableType(fields, dbSources, input.scope, from));
33993
33993
  }
33994
33994
  return intoTable;
33995
33995
  }
@@ -34137,11 +34137,36 @@ class Select {
34137
34137
  return basic_1.VoidType.get("SELECT_todo13");
34138
34138
  }
34139
34139
  }
34140
- static buildTableType(fields, dbSources, scope) {
34141
- if (dbSources.length !== 1) {
34140
+ static buildTableType(fields, dbSources, scope, from) {
34141
+ var _a;
34142
+ const tableOptions = { withHeader: false, keyType: basic_1.TableKeyType.empty };
34143
+ if (dbSources.length > 1) {
34144
+ const sourceInfos = this.buildDatabaseSourceInfos(from, dbSources);
34145
+ if (fields.length === 1 && fields[0].code === "*") {
34146
+ const components = [];
34147
+ for (const info of sourceInfos) {
34148
+ const type = (_a = info.source) === null || _a === void 0 ? void 0 : _a.parseType(scope.getRegistry());
34149
+ if (!(type instanceof basic_1.StructureType)) {
34150
+ return basic_1.VoidType.get("SELECT_todo3");
34151
+ }
34152
+ components.push({ name: info.alias || info.name, type });
34153
+ }
34154
+ return new basic_1.TableType(new basic_1.StructureType(components), tableOptions, undefined);
34155
+ }
34156
+ const components = [];
34157
+ for (const field of fields) {
34158
+ const type = this.findFieldType(field.code, sourceInfos, scope);
34159
+ if (type === undefined) {
34160
+ return basic_1.VoidType.get("SELECT_todo3");
34161
+ }
34162
+ const name = field.as || field.code.split("~").pop();
34163
+ components.push({ name, type });
34164
+ }
34165
+ return new basic_1.TableType(new basic_1.StructureType(components), tableOptions, undefined);
34166
+ }
34167
+ else if (dbSources.length !== 1) {
34142
34168
  return basic_1.VoidType.get("SELECT_todo3");
34143
34169
  }
34144
- const tableOptions = { withHeader: false, keyType: basic_1.TableKeyType.empty };
34145
34170
  if (dbSources[0] === undefined) {
34146
34171
  // then its a voided table
34147
34172
  return new basic_1.TableType(basic_1.VoidType.get("SELECT_todo4"), tableOptions, undefined);
@@ -34167,6 +34192,39 @@ class Select {
34167
34192
  }
34168
34193
  return basic_1.VoidType.get("SELECT_todo7");
34169
34194
  }
34195
+ static buildDatabaseSourceInfos(from, dbSources) {
34196
+ const fromSources = from.findAllExpressions(Expressions.SQLFromSource);
34197
+ return dbSources.map((source, index) => {
34198
+ var _a, _b;
34199
+ const fromSource = fromSources[index];
34200
+ const name = ((_a = fromSource === null || fromSource === void 0 ? void 0 : fromSource.findFirstExpression(Expressions.DatabaseTable)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr().replace(/^\*/, "").toUpperCase()) || "";
34201
+ const alias = ((_b = fromSource === null || fromSource === void 0 ? void 0 : fromSource.findDirectExpression(Expressions.SQLAsName)) === null || _b === void 0 ? void 0 : _b.concatTokens().toUpperCase()) || "";
34202
+ return { source, name, alias };
34203
+ });
34204
+ }
34205
+ static findFieldType(code, sourceInfos, scope) {
34206
+ var _a;
34207
+ const separator = code.indexOf("~");
34208
+ const qualifier = separator >= 0 ? code.substring(0, separator) : undefined;
34209
+ const fieldName = separator >= 0 ? code.substring(separator + 1) : code;
34210
+ const candidates = qualifier === undefined
34211
+ ? sourceInfos
34212
+ : sourceInfos.filter(info => info.alias === qualifier || info.name === qualifier);
34213
+ for (const candidate of candidates) {
34214
+ let type = (_a = candidate.source) === null || _a === void 0 ? void 0 : _a.parseType(scope.getRegistry());
34215
+ for (const component of fieldName.split("-")) {
34216
+ if (!(type instanceof basic_1.StructureType)) {
34217
+ type = undefined;
34218
+ break;
34219
+ }
34220
+ type = type.getComponentByName(component);
34221
+ }
34222
+ if (type) {
34223
+ return type;
34224
+ }
34225
+ }
34226
+ return undefined;
34227
+ }
34170
34228
  static findFields(node, input) {
34171
34229
  var _a, _b;
34172
34230
  let expr = undefined;
@@ -34180,7 +34238,7 @@ class Select {
34180
34238
  let code = field.concatTokens().toUpperCase();
34181
34239
  const as = ((_b = field.findDirectExpression(Expressions.SQLAsName)) === null || _b === void 0 ? void 0 : _b.concatTokens()) || "";
34182
34240
  if (as !== "") {
34183
- code = code.replace(" AS " + as, "");
34241
+ code = code.replace(" AS " + as.toUpperCase(), "");
34184
34242
  }
34185
34243
  ret.push({ code, as, expression: field });
34186
34244
  }
@@ -35936,6 +35994,7 @@ var __importStar = (this && this.__importStar) || (function () {
35936
35994
  })();
35937
35995
  Object.defineProperty(exports, "__esModule", ({ value: true }));
35938
35996
  exports.ValueBody = void 0;
35997
+ const nodes_1 = __webpack_require__(/*! ../../nodes */ "../core/build/src/abap/nodes/index.js");
35939
35998
  const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "../core/build/src/abap/2_statements/expressions/index.js"));
35940
35999
  const for_1 = __webpack_require__(/*! ./for */ "../core/build/src/abap/5_syntax/expressions/for.js");
35941
36000
  const source_1 = __webpack_require__(/*! ./source */ "../core/build/src/abap/5_syntax/expressions/source.js");
@@ -35945,7 +36004,7 @@ const basic_1 = __webpack_require__(/*! ../../types/basic */ "../core/build/src/
35945
36004
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "../core/build/src/abap/5_syntax/_syntax_input.js");
35946
36005
  class ValueBody {
35947
36006
  static runSyntax(node, input, targetType) {
35948
- var _a, _b;
36007
+ var _a, _b, _c;
35949
36008
  if (node === undefined) {
35950
36009
  return targetType;
35951
36010
  }
@@ -35962,26 +36021,45 @@ class ValueBody {
35962
36021
  }
35963
36022
  }
35964
36023
  const fields = new Set();
35965
- for (const s of node.findDirectExpressions(Expressions.FieldAssignment)) {
35966
- field_assignment_1.FieldAssignment.runSyntax(s, input, targetType);
35967
- if (node.findDirectExpression(Expressions.ValueBodyLine) === undefined) {
35968
- // todo: refine, still needs to be checked when there are table lines
35969
- const fieldname = (_a = s.findDirectExpression(Expressions.FieldSub)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
36024
+ const hasTableLines = node.findDirectExpression(Expressions.ValueBodyLine) !== undefined;
36025
+ for (const child of node.getChildren()) {
36026
+ if (!(child instanceof nodes_1.ExpressionNode)) {
36027
+ continue;
36028
+ }
36029
+ else if (child.get() instanceof Expressions.FieldAssignment) {
36030
+ const fieldname = (_a = child.findDirectExpression(Expressions.FieldSub)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
36031
+ if (fieldname && hasTableLines === false && fields.has(fieldname)) {
36032
+ const message = "Duplicate field assignment";
36033
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, child.getFirstToken(), message));
36034
+ return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
36035
+ }
35970
36036
  if (fieldname) {
35971
- if (fields.has(fieldname)) {
36037
+ fields.add(fieldname);
36038
+ }
36039
+ }
36040
+ else if (child.get() instanceof Expressions.ValueBodyLine) {
36041
+ const rowFields = new Set(fields);
36042
+ for (const assignment of child.findDirectExpressions(Expressions.FieldAssignment)) {
36043
+ const fieldname = (_b = assignment.findDirectExpression(Expressions.FieldSub)) === null || _b === void 0 ? void 0 : _b.concatTokens().toUpperCase();
36044
+ if (fieldname && rowFields.has(fieldname)) {
35972
36045
  const message = "Duplicate field assignment";
35973
- input.issues.push((0, _syntax_input_1.syntaxIssue)(input, s.getFirstToken(), message));
36046
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, assignment.getFirstToken(), message));
35974
36047
  return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
35975
36048
  }
35976
- fields.add(fieldname);
36049
+ if (fieldname) {
36050
+ rowFields.add(fieldname);
36051
+ }
35977
36052
  }
35978
36053
  }
35979
36054
  }
36055
+ for (const s of node.findDirectExpressions(Expressions.FieldAssignment)) {
36056
+ field_assignment_1.FieldAssignment.runSyntax(s, input, targetType);
36057
+ }
35980
36058
  let type = undefined; // todo, this is only correct if there is a single source in the body
35981
36059
  for (const s of node.findDirectExpressions(Expressions.Source)) {
35982
36060
  type = source_1.Source.runSyntax(s, input, type);
35983
36061
  }
35984
- for (const s of ((_b = node.findDirectExpression(Expressions.ValueBase)) === null || _b === void 0 ? void 0 : _b.findDirectExpressions(Expressions.Source)) || []) {
36062
+ for (const s of ((_c = node.findDirectExpression(Expressions.ValueBase)) === null || _c === void 0 ? void 0 : _c.findDirectExpressions(Expressions.Source)) || []) {
35985
36063
  type = source_1.Source.runSyntax(s, input, type);
35986
36064
  }
35987
36065
  for (const foo of node.findDirectExpressions(Expressions.ValueBodyLine)) {
@@ -69773,7 +69851,7 @@ class Registry {
69773
69851
  }
69774
69852
  static abaplintVersion() {
69775
69853
  // magic, see build script "version.js"
69776
- return "2.120.27";
69854
+ return "2.120.28";
69777
69855
  }
69778
69856
  getDDICReferences() {
69779
69857
  return this.ddicReferences;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.120.27",
3
+ "version": "2.120.28",
4
4
  "description": "abaplint - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "homepage": "https://abaplint.org",
41
41
  "devDependencies": {
42
- "@abaplint/core": "^2.120.27",
42
+ "@abaplint/core": "^2.120.28",
43
43
  "@types/chai": "^4.3.20",
44
44
  "@types/minimist": "^1.2.5",
45
45
  "@types/mocha": "^10.0.10",