@abaplint/core 2.100.6 → 2.101.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.
@@ -250,6 +250,33 @@ declare class At_3 extends Token {
250
250
  static railroad(): string;
251
251
  }
252
252
 
253
+ declare class ATCCheckCategory extends AbstractObject {
254
+ getType(): string;
255
+ getAllowedNaming(): {
256
+ maxLength: number;
257
+ allowNamespace: boolean;
258
+ };
259
+ getDescription(): string | undefined;
260
+ }
261
+
262
+ declare class ATCCheckObject extends AbstractObject {
263
+ getType(): string;
264
+ getAllowedNaming(): {
265
+ maxLength: number;
266
+ allowNamespace: boolean;
267
+ };
268
+ getDescription(): string | undefined;
269
+ }
270
+
271
+ declare class ATCCheckVariant extends AbstractObject {
272
+ getType(): string;
273
+ getAllowedNaming(): {
274
+ maxLength: number;
275
+ allowNamespace: boolean;
276
+ };
277
+ getDescription(): string | undefined;
278
+ }
279
+
253
280
  declare class AtFirst implements IStructure {
254
281
  getMatcher(): IStructureRunnable;
255
282
  }
@@ -1265,6 +1292,7 @@ export declare class CurrentScope {
1265
1292
  private static addBuiltIn;
1266
1293
  private constructor();
1267
1294
  getVersion(): Version;
1295
+ getRegistry(): IRegistry;
1268
1296
  addType(type: TypedIdentifier | undefined): void;
1269
1297
  addTypeNamed(name: string, type: TypedIdentifier | undefined): void;
1270
1298
  addExtraLikeType(type: TypedIdentifier | undefined): void;
@@ -1278,6 +1306,7 @@ export declare class CurrentScope {
1278
1306
  addListPrefix(identifiers: readonly TypedIdentifier[], prefix: string): void;
1279
1307
  addList(identifiers: readonly TypedIdentifier[]): void;
1280
1308
  addReference(usage: Token | undefined, referencing: Identifier | undefined, type: ReferenceType | undefined, filename: string, extra?: IReferenceExtras): void;
1309
+ addSQLConversion(fieldName: string, message: string, token: Token): void;
1281
1310
  findFunctionModule(name: string | undefined): FunctionModuleDefinition | undefined;
1282
1311
  findObjectDefinition(name: string | undefined): IClassDefinition | IInterfaceDefinition | undefined;
1283
1312
  isBadiDef(name: string): boolean;
@@ -3547,6 +3576,11 @@ declare interface IScopeData {
3547
3576
  idefs: IInterfaceDefinition[];
3548
3577
  forms: IFormDefinition[];
3549
3578
  references: IReference[];
3579
+ sqlConversion: {
3580
+ fieldName: string;
3581
+ message: string;
3582
+ token: Token;
3583
+ }[];
3550
3584
  }
3551
3585
 
3552
3586
  declare interface IScopeIdentifier {
@@ -4225,6 +4259,9 @@ declare namespace Objects {
4225
4259
  ActivationVariant,
4226
4260
  APIReleaseState,
4227
4261
  AssignmentServiceToAuthorizationGroup,
4262
+ ATCCheckCategory,
4263
+ ATCCheckObject,
4264
+ ATCCheckVariant,
4228
4265
  AuthorizationCheckField,
4229
4266
  AuthorizationGroup,
4230
4267
  AuthorizationObjectClass,
@@ -38,6 +38,9 @@ class CurrentScope {
38
38
  getVersion() {
39
39
  return this.reg.getConfig().getVersion();
40
40
  }
41
+ getRegistry() {
42
+ return this.reg;
43
+ }
41
44
  addType(type) {
42
45
  if (type === undefined) {
43
46
  return;
@@ -137,6 +140,10 @@ class CurrentScope {
137
140
  const position = new _identifier_1.Identifier(usage, filename);
138
141
  (_a = this.current) === null || _a === void 0 ? void 0 : _a.getData().references.push({ position, resolved: referencing, referenceType: type, extra });
139
142
  }
143
+ addSQLConversion(fieldName, message, token) {
144
+ var _a;
145
+ (_a = this.current) === null || _a === void 0 ? void 0 : _a.getData().sqlConversion.push({ fieldName, message, token });
146
+ }
140
147
  ///////////////////////////
141
148
  findFunctionModule(name) {
142
149
  if (name === undefined) {
@@ -8,7 +8,7 @@ class DatabaseTable {
8
8
  const name = token.getStr();
9
9
  if (name === "(") {
10
10
  // dynamic
11
- return;
11
+ return undefined;
12
12
  }
13
13
  const found = scope.getDDIC().lookupTableOrView2(name);
14
14
  if (found === undefined && scope.getDDIC().inErrorNamespace(name) === true) {
@@ -21,6 +21,7 @@ class DatabaseTable {
21
21
  scope.addReference(token, found.getIdentifier(), _reference_1.ReferenceType.TableReference, filename);
22
22
  scope.getDDICReferences().addUsing(scope.getParentObj(), { object: found, token: token, filename: filename });
23
23
  }
24
+ return found;
24
25
  }
25
26
  }
26
27
  exports.DatabaseTable = DatabaseTable;
@@ -6,17 +6,16 @@ const basic_1 = require("../../types/basic");
6
6
  const inline_data_1 = require("./inline_data");
7
7
  const target_1 = require("./target");
8
8
  const sql_from_1 = require("./sql_from");
9
- const source_1 = require("./source");
10
9
  const sql_for_all_entries_1 = require("./sql_for_all_entries");
11
10
  const _scope_type_1 = require("../_scope_type");
11
+ const sql_source_1 = require("./sql_source");
12
+ const sql_compare_1 = require("./sql_compare");
12
13
  class Select {
13
14
  runSyntax(node, scope, filename, skipImplicitInto = false) {
14
15
  var _a, _b;
15
16
  const token = node.getFirstToken();
16
17
  const from = node.findDirectExpression(Expressions.SQLFrom);
17
- if (from) {
18
- new sql_from_1.SQLFrom().runSyntax(from, scope, filename);
19
- }
18
+ const dbSources = from ? new sql_from_1.SQLFrom().runSyntax(from, scope, filename) : [];
20
19
  for (const inline of node.findAllExpressions(Expressions.InlineData)) {
21
20
  // todo, for now these are voided
22
21
  new inline_data_1.InlineData().runSyntax(inline, scope, filename, new basic_1.VoidType("SELECT_todo"));
@@ -42,11 +41,22 @@ class Select {
42
41
  }
43
42
  }
44
43
  }
45
- for (const s of node.findAllExpressions(Expressions.Source)) {
46
- new source_1.Source().runSyntax(s, scope, filename);
44
+ // OFFSET
45
+ for (const s of node.findDirectExpressions(Expressions.SQLSource)) {
46
+ new sql_source_1.SQLSource().runSyntax(s, scope, filename);
47
+ }
48
+ for (const up of node.findDirectExpressions(Expressions.SQLUpTo)) {
49
+ for (const s of up.findDirectExpressions(Expressions.SQLSource)) {
50
+ new sql_source_1.SQLSource().runSyntax(s, scope, filename);
51
+ }
52
+ }
53
+ for (const fae of node.findDirectExpressions(Expressions.SQLForAllEntries)) {
54
+ for (const s of fae.findDirectExpressions(Expressions.SQLSource)) {
55
+ new sql_source_1.SQLSource().runSyntax(s, scope, filename);
56
+ }
47
57
  }
48
- for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
49
- new source_1.Source().runSyntax(s, scope, filename);
58
+ for (const s of node.findAllExpressions(Expressions.SQLCompare)) {
59
+ new sql_compare_1.SQLCompare().runSyntax(s, scope, filename, dbSources);
50
60
  }
51
61
  if (scope.getType() === _scope_type_1.ScopeType.OpenSQL) {
52
62
  scope.pop(node.getLastToken().getEnd());
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SQLCompare = void 0;
4
+ const Expressions = require("../../2_statements/expressions");
5
+ const basic_1 = require("../../types/basic");
6
+ const sql_source_1 = require("./sql_source");
7
+ class SQLCompare {
8
+ runSyntax(node, scope, filename, tables) {
9
+ var _a;
10
+ let sourceType;
11
+ let token;
12
+ for (const s of node.findAllExpressions(Expressions.SQLSource)) {
13
+ token = s.getFirstToken();
14
+ sourceType = new sql_source_1.SQLSource().runSyntax(s, scope, filename);
15
+ }
16
+ const fieldName = (_a = node.findDirectExpression(Expressions.SQLFieldName)) === null || _a === void 0 ? void 0 : _a.concatTokens();
17
+ if (fieldName && sourceType && token) {
18
+ // check compatibility for rule sql_value_conversion
19
+ const targetType = this.findType(fieldName, tables, scope);
20
+ let message = "";
21
+ if (sourceType instanceof basic_1.IntegerType
22
+ && targetType instanceof basic_1.CharacterType) {
23
+ message = "Integer to CHAR conversion";
24
+ }
25
+ else if (sourceType instanceof basic_1.IntegerType
26
+ && targetType instanceof basic_1.NumericType) {
27
+ message = "Integer to NUMC conversion";
28
+ }
29
+ else if (sourceType instanceof basic_1.NumericType
30
+ && targetType instanceof basic_1.IntegerType) {
31
+ message = "NUMC to Integer conversion";
32
+ }
33
+ else if (sourceType instanceof basic_1.CharacterType
34
+ && targetType instanceof basic_1.IntegerType) {
35
+ message = "CHAR to Integer conversion";
36
+ }
37
+ else if (sourceType instanceof basic_1.CharacterType
38
+ && targetType instanceof basic_1.CharacterType
39
+ && sourceType.getLength() > targetType.getLength()) {
40
+ message = "Source field longer than database field, CHAR -> CHAR";
41
+ }
42
+ else if (sourceType instanceof basic_1.NumericType
43
+ && targetType instanceof basic_1.NumericType
44
+ && sourceType.getLength() > targetType.getLength()) {
45
+ message = "Source field longer than database field, NUMC -> NUMC";
46
+ }
47
+ if (message !== "") {
48
+ scope.addSQLConversion(fieldName, message, token);
49
+ }
50
+ }
51
+ }
52
+ findType(fieldName, tables, scope) {
53
+ for (const t of tables) {
54
+ const type = t === null || t === void 0 ? void 0 : t.parseType(scope.getRegistry());
55
+ if (type instanceof basic_1.StructureType) {
56
+ return type.getComponentByName(fieldName);
57
+ }
58
+ }
59
+ return undefined;
60
+ }
61
+ }
62
+ exports.SQLCompare = SQLCompare;
63
+ //# sourceMappingURL=sql_compare.js.map
@@ -6,6 +6,7 @@ const dynamic_1 = require("./dynamic");
6
6
  const database_table_1 = require("./database_table");
7
7
  class SQLFrom {
8
8
  runSyntax(node, scope, filename) {
9
+ const ret = [];
9
10
  const fromList = node.findAllExpressions(Expressions.SQLFromSource);
10
11
  for (const from of fromList) {
11
12
  for (const d of from.findAllExpressions(Expressions.Dynamic)) {
@@ -13,9 +14,10 @@ class SQLFrom {
13
14
  }
14
15
  const dbtab = from.findFirstExpression(Expressions.DatabaseTable);
15
16
  if (dbtab !== undefined) {
16
- new database_table_1.DatabaseTable().runSyntax(dbtab, scope, filename);
17
+ ret.push(new database_table_1.DatabaseTable().runSyntax(dbtab, scope, filename));
17
18
  }
18
19
  }
20
+ return ret;
19
21
  }
20
22
  }
21
23
  exports.SQLFrom = SQLFrom;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SQLSource = void 0;
4
+ const Expressions = require("../../2_statements/expressions");
5
+ const source_1 = require("./source");
6
+ class SQLSource {
7
+ runSyntax(node, scope, filename) {
8
+ for (const s of node.findAllExpressions(Expressions.Source)) {
9
+ return new source_1.Source().runSyntax(s, scope, filename);
10
+ }
11
+ for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
12
+ return new source_1.Source().runSyntax(s, scope, filename);
13
+ }
14
+ return undefined;
15
+ }
16
+ }
17
+ exports.SQLSource = SQLSource;
18
+ //# sourceMappingURL=sql_source.js.map
@@ -15,6 +15,7 @@ class ScopeData {
15
15
  extraLikeTypes: {},
16
16
  deferred: [],
17
17
  references: [],
18
+ sqlConversion: [],
18
19
  };
19
20
  }
20
21
  getData() {
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ATCCheckCategory = void 0;
4
+ const _abstract_object_1 = require("./_abstract_object");
5
+ class ATCCheckCategory extends _abstract_object_1.AbstractObject {
6
+ getType() {
7
+ return "CHKC";
8
+ }
9
+ getAllowedNaming() {
10
+ return {
11
+ maxLength: 30,
12
+ allowNamespace: true,
13
+ };
14
+ }
15
+ getDescription() {
16
+ // todo
17
+ return undefined;
18
+ }
19
+ }
20
+ exports.ATCCheckCategory = ATCCheckCategory;
21
+ //# sourceMappingURL=atc_check_category.js.map
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ATCCheckObject = void 0;
4
+ const _abstract_object_1 = require("./_abstract_object");
5
+ class ATCCheckObject extends _abstract_object_1.AbstractObject {
6
+ getType() {
7
+ return "CHKO";
8
+ }
9
+ getAllowedNaming() {
10
+ return {
11
+ maxLength: 30,
12
+ allowNamespace: true,
13
+ };
14
+ }
15
+ getDescription() {
16
+ // todo
17
+ return undefined;
18
+ }
19
+ }
20
+ exports.ATCCheckObject = ATCCheckObject;
21
+ //# sourceMappingURL=atc_check_object.js.map
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ATCCheckVariant = void 0;
4
+ const _abstract_object_1 = require("./_abstract_object");
5
+ class ATCCheckVariant extends _abstract_object_1.AbstractObject {
6
+ getType() {
7
+ return "CHKV";
8
+ }
9
+ getAllowedNaming() {
10
+ return {
11
+ maxLength: 30,
12
+ allowNamespace: true,
13
+ };
14
+ }
15
+ getDescription() {
16
+ // todo
17
+ return undefined;
18
+ }
19
+ }
20
+ exports.ATCCheckVariant = ATCCheckVariant;
21
+ //# sourceMappingURL=atc_check_variant.js.map
@@ -17,6 +17,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./activation_variant"), exports);
18
18
  __exportStar(require("./api_release_state"), exports);
19
19
  __exportStar(require("./assignment_service_to_authorization_group"), exports);
20
+ __exportStar(require("./atc_check_category"), exports);
21
+ __exportStar(require("./atc_check_object"), exports);
22
+ __exportStar(require("./atc_check_variant"), exports);
20
23
  __exportStar(require("./authorization_check_field"), exports);
21
24
  __exportStar(require("./authorization_group"), exports);
22
25
  __exportStar(require("./authorization_object_class"), exports);
@@ -65,7 +65,7 @@ class Registry {
65
65
  }
66
66
  static abaplintVersion() {
67
67
  // magic, see build script "version.sh"
68
- return "2.100.6";
68
+ return "2.101.1";
69
69
  }
70
70
  getDDICReferences() {
71
71
  return this.ddicReferences;
@@ -58,6 +58,9 @@ class CloudTypes {
58
58
  || obj instanceof Objects.InboundService
59
59
  || obj instanceof Objects.Interface
60
60
  || obj instanceof Objects.LockObject
61
+ || obj instanceof Objects.ATCCheckCategory
62
+ || obj instanceof Objects.ATCCheckObject
63
+ || obj instanceof Objects.ATCCheckVariant
61
64
  || obj instanceof Objects.MessageClass
62
65
  || obj instanceof Objects.Package
63
66
  || obj instanceof Objects.RestrictionType
@@ -143,6 +143,7 @@ __exportStar(require("./smim_consistency"), exports);
143
143
  __exportStar(require("./space_before_colon"), exports);
144
144
  __exportStar(require("./space_before_dot"), exports);
145
145
  __exportStar(require("./sql_escape_host_variables"), exports);
146
+ __exportStar(require("./sql_value_conversion"), exports);
146
147
  __exportStar(require("./start_at_tab"), exports);
147
148
  __exportStar(require("./static_call_via_instance"), exports);
148
149
  __exportStar(require("./strict_sql"), exports);
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SQLValueConversion = exports.SQLValueConversionConf = void 0;
4
+ const issue_1 = require("../issue");
5
+ const _basic_rule_config_1 = require("./_basic_rule_config");
6
+ const objects_1 = require("../objects");
7
+ const syntax_1 = require("../abap/5_syntax/syntax");
8
+ const _abap_object_1 = require("../objects/_abap_object");
9
+ class SQLValueConversionConf extends _basic_rule_config_1.BasicRuleConfig {
10
+ }
11
+ exports.SQLValueConversionConf = SQLValueConversionConf;
12
+ class SQLValueConversion {
13
+ constructor() {
14
+ this.conf = new SQLValueConversionConf();
15
+ }
16
+ getMetadata() {
17
+ return {
18
+ key: "sql_value_conversion",
19
+ title: "Implicit SQL Value Conversion",
20
+ shortDescription: `Ensure types match when selecting from database`,
21
+ extendedInformation: `
22
+ * Integer to CHAR conversion
23
+ * Integer to NUMC conversion
24
+ * NUMC to Integer conversion
25
+ * CHAR to Integer conversion
26
+ * Source field longer than database field, CHAR -> CHAR
27
+ * Source field longer than database field, NUMC -> NUMC`,
28
+ tags: [],
29
+ };
30
+ }
31
+ getConfig() {
32
+ return this.conf;
33
+ }
34
+ setConfig(conf) {
35
+ this.conf = conf;
36
+ }
37
+ initialize(reg) {
38
+ this.reg = reg;
39
+ return this;
40
+ }
41
+ run(obj) {
42
+ if (!(obj instanceof _abap_object_1.ABAPObject) || obj instanceof objects_1.Interface) {
43
+ return [];
44
+ }
45
+ // messages defined in sql_compare.ts
46
+ const issues = this.traverse(new syntax_1.SyntaxLogic(this.reg, obj).run().spaghetti.getTop());
47
+ return issues;
48
+ }
49
+ traverse(node) {
50
+ const ret = [];
51
+ for (const r of node.getData().sqlConversion) {
52
+ const file = this.reg.getFileByName(node.getIdentifier().filename);
53
+ if (file === undefined) {
54
+ continue;
55
+ }
56
+ ret.push(issue_1.Issue.atToken(file, r.token, r.message, this.getMetadata().key, this.getConfig().severity));
57
+ }
58
+ for (const c of node.getChildren()) {
59
+ ret.push(...this.traverse(c));
60
+ }
61
+ return ret;
62
+ }
63
+ }
64
+ exports.SQLValueConversion = SQLValueConversion;
65
+ //# sourceMappingURL=sql_value_conversion.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.100.6",
3
+ "version": "2.101.1",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -48,12 +48,12 @@
48
48
  },
49
49
  "homepage": "https://abaplint.org",
50
50
  "devDependencies": {
51
- "@microsoft/api-extractor": "^7.34.9",
51
+ "@microsoft/api-extractor": "^7.35.0",
52
52
  "@types/chai": "^4.3.5",
53
53
  "@types/mocha": "^10.0.1",
54
- "@types/node": "^20.2.1",
54
+ "@types/node": "^20.2.3",
55
55
  "chai": "^4.3.7",
56
- "eslint": "^8.40.0",
56
+ "eslint": "^8.41.0",
57
57
  "mocha": "^10.2.0",
58
58
  "c8": "^7.13.0",
59
59
  "source-map-support": "^0.5.21",