@abaplint/core 2.101.15 → 2.101.17

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.
@@ -441,6 +441,7 @@ declare namespace BasicTypes {
441
441
  UnknownType,
442
442
  UTCLongType,
443
443
  VoidType,
444
+ XGenericType,
444
445
  XSequenceType,
445
446
  XStringType
446
447
  }
@@ -1310,7 +1311,7 @@ export declare class CurrentScope {
1310
1311
  addDeferred(token: Token | undefined): void;
1311
1312
  addListPrefix(identifiers: readonly TypedIdentifier[], prefix: string): void;
1312
1313
  addList(identifiers: readonly TypedIdentifier[]): void;
1313
- addReference(usage: Token | undefined, referencing: Identifier | undefined, type: ReferenceType | undefined, filename: string, extra?: IReferenceExtras): void;
1314
+ addReference(usage: Token | undefined, referencing: Identifier | undefined, type: ReferenceType | ReferenceType[] | undefined, filename: string, extra?: IReferenceExtras): void;
1314
1315
  addSQLConversion(fieldName: string, message: string, token: Token): void;
1315
1316
  findFunctionModule(name: string | undefined): FunctionModuleDefinition | undefined;
1316
1317
  findObjectDefinition(name: string | undefined): IClassDefinition | IInterfaceDefinition | undefined;
@@ -6793,6 +6794,14 @@ declare class WStaticArrowW extends Token {
6793
6794
  static railroad(): string;
6794
6795
  }
6795
6796
 
6797
+ declare class XGenericType extends AbstractType {
6798
+ toText(): string;
6799
+ isGeneric(): boolean;
6800
+ toABAP(): string;
6801
+ containsVoid(): boolean;
6802
+ toCDS(): string;
6803
+ }
6804
+
6796
6805
  declare class XSequenceType extends AbstractType {
6797
6806
  toText(): string;
6798
6807
  isGeneric(): boolean;
@@ -133,12 +133,19 @@ class CurrentScope {
133
133
  }
134
134
  }
135
135
  addReference(usage, referencing, type, filename, extra) {
136
- var _a;
136
+ var _a, _b;
137
137
  if (usage === undefined || type === undefined) {
138
138
  return;
139
139
  }
140
140
  const position = new _identifier_1.Identifier(usage, filename);
141
- (_a = this.current) === null || _a === void 0 ? void 0 : _a.getData().references.push({ position, resolved: referencing, referenceType: type, extra });
141
+ if (Array.isArray(type)) {
142
+ for (const t of type) {
143
+ (_a = this.current) === null || _a === void 0 ? void 0 : _a.getData().references.push({ position, resolved: referencing, referenceType: t, extra });
144
+ }
145
+ }
146
+ else {
147
+ (_b = this.current) === null || _b === void 0 ? void 0 : _b.getData().references.push({ position, resolved: referencing, referenceType: type, extra });
148
+ }
142
149
  }
143
150
  addSQLConversion(fieldName, message, token) {
144
151
  var _a;
@@ -92,6 +92,7 @@ class TypeUtils {
92
92
  else if (type instanceof basic_1.XStringType
93
93
  || type instanceof basic_1.HexType
94
94
  || type instanceof basic_1.VoidType
95
+ || type instanceof basic_1.XGenericType
95
96
  || type instanceof basic_1.XSequenceType
96
97
  || type instanceof basic_1.AnyType
97
98
  || type instanceof basic_1.UnknownType) {
@@ -208,12 +209,15 @@ class TypeUtils {
208
209
  }
209
210
  return false;
210
211
  }
211
- isAssignableStrict(source, target) {
212
+ isAssignableStrict(source, target, containsMethodCall = false) {
212
213
  var _a, _b, _c, _d, _e, _f;
213
214
  /*
214
215
  console.dir(source);
215
216
  console.dir(target);
216
217
  */
218
+ if (containsMethodCall) {
219
+ return this.isAssignable(source, target);
220
+ }
217
221
  if (source instanceof basic_1.CharacterType) {
218
222
  if (target instanceof basic_1.CharacterType) {
219
223
  if (((_a = source.getAbstractTypeData()) === null || _a === void 0 ? void 0 : _a.derivedFromConstant) === true) {
@@ -24,7 +24,7 @@ class BasicTypes {
24
24
  }
25
25
  lookupQualifiedName(name) {
26
26
  var _a;
27
- // argh, todo, rewrite this entire method, more argh
27
+ // argh, todo, rewrite this entire method, more argh, again argh
28
28
  if (name === undefined) {
29
29
  return undefined;
30
30
  }
@@ -45,7 +45,10 @@ class BasicTypes {
45
45
  const stru = oo.getTypeDefinitions().getByName(subTypeName);
46
46
  const struType = stru === null || stru === void 0 ? void 0 : stru.getType();
47
47
  if (stru && struType instanceof basic_1.StructureType) {
48
- const f = struType.getComponentByName(fieldName);
48
+ let f = struType.getComponentByName(fieldName);
49
+ if (split[2] && f instanceof basic_1.StructureType) {
50
+ f = f.getComponentByName(split[2]);
51
+ }
49
52
  if (f) {
50
53
  return new _typed_identifier_1.TypedIdentifier(stru.getToken(), stru.getFilename(), f);
51
54
  }
@@ -67,7 +70,10 @@ class BasicTypes {
67
70
  if (type) {
68
71
  const stru = type.getType();
69
72
  if (stru instanceof basic_1.StructureType) {
70
- const f = stru.getComponentByName(fieldName);
73
+ let f = stru.getComponentByName(fieldName);
74
+ if (split[2] && f instanceof basic_1.StructureType) {
75
+ f = f.getComponentByName(split[2]);
76
+ }
71
77
  if (f) {
72
78
  return new _typed_identifier_1.TypedIdentifier(type.getToken(), type.getFilename(), f);
73
79
  }
@@ -32,7 +32,9 @@ class AttributeChain {
32
32
  if (context === undefined) {
33
33
  throw new Error("Attribute or constant \"" + name + "\" not found in \"" + def.getName() + "\"");
34
34
  }
35
- scope.addReference(nameToken, context, type, filename);
35
+ for (const t of type) {
36
+ scope.addReference(nameToken, context, t, filename);
37
+ }
36
38
  // todo, loop, handle ArrowOrDash, ComponentName, TableExpression
37
39
  return context.getType();
38
40
  }
@@ -55,7 +55,7 @@ class MethodCallParam {
55
55
  if (sourceType === undefined) {
56
56
  throw new Error("No source type determined, method source");
57
57
  }
58
- else if (new _type_utils_1.TypeUtils(scope).isAssignableStrict(sourceType, targetType) === false) {
58
+ else if (new _type_utils_1.TypeUtils(scope).isAssignableStrict(sourceType, targetType, child.findFirstExpression(Expressions.MethodCallChain) !== undefined) === false) {
59
59
  throw new Error("Method parameter type not compatible");
60
60
  }
61
61
  }
@@ -30,6 +30,9 @@ class MethodParam {
30
30
  if (concat === "TYPE C" || concat.startsWith("TYPE C ")) {
31
31
  return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), filename, new cgeneric_type_1.CGenericType(), meta);
32
32
  }
33
+ else if (concat === "TYPE X" || concat.startsWith("TYPE X ")) {
34
+ return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), filename, new basic_1.XGenericType(), meta);
35
+ }
33
36
  const found = new basic_types_1.BasicTypes(filename, scope).parseType(type);
34
37
  if (found) {
35
38
  return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), filename, found, meta);
@@ -34,7 +34,7 @@ const _typed_identifier_1 = require("../../types/_typed_identifier");
34
34
  * DATA(bar) = VALUE #( ... ). give error, no type can be derived
35
35
  */
36
36
  class Source {
37
- runSyntax(node, scope, filename, targetType) {
37
+ runSyntax(node, scope, filename, targetType, writeReference = false) {
38
38
  if (node === undefined) {
39
39
  return undefined;
40
40
  }
@@ -161,12 +161,16 @@ class Source {
161
161
  return undefined;
162
162
  }
163
163
  let context = new unknown_type_1.UnknownType("todo, Source type");
164
+ const type = [_reference_1.ReferenceType.DataReadReference];
165
+ if (writeReference) {
166
+ type.push(_reference_1.ReferenceType.DataWriteReference);
167
+ }
164
168
  while (children.length >= 0) {
165
169
  if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.MethodCallChain) {
166
170
  context = new method_call_chain_1.MethodCallChain().runSyntax(first, scope, filename, targetType);
167
171
  }
168
172
  else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.FieldChain) {
169
- context = new field_chain_1.FieldChain().runSyntax(first, scope, filename, _reference_1.ReferenceType.DataReadReference);
173
+ context = new field_chain_1.FieldChain().runSyntax(first, scope, filename, type);
170
174
  }
171
175
  else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.StringTemplate) {
172
176
  context = new string_template_1.StringTemplate().runSyntax(first, scope, filename);
@@ -179,15 +183,14 @@ class Source {
179
183
  }
180
184
  else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.Dereference) {
181
185
  context = new dereference_1.Dereference().runSyntax(context);
182
- }
183
- else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.ArrowOrDash) {
186
+ // } else if (first instanceof ExpressionNode && first.get() instanceof Expressions.ArrowOrDash) {
184
187
  // console.dir("dash");
185
188
  }
186
189
  else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.ComponentChain) {
187
190
  context = new component_chain_1.ComponentChain().runSyntax(context, first, scope, filename);
188
191
  }
189
192
  else if (first instanceof nodes_1.ExpressionNode && first.get() instanceof Expressions.AttributeChain) {
190
- context = new attribute_chain_1.AttributeChain().runSyntax(context, first, scope, filename, _reference_1.ReferenceType.DataReadReference);
193
+ context = new attribute_chain_1.AttributeChain().runSyntax(context, first, scope, filename, type);
191
194
  }
192
195
  first = children.shift();
193
196
  if (first === undefined) {
@@ -20,12 +20,13 @@ class Loop {
20
20
  if (target === undefined) {
21
21
  target = node.findDirectExpression(Expressions.FSTarget);
22
22
  }
23
+ const write = (loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.findDirectTokenByText("ASSIGNING")) !== undefined;
23
24
  const sources = node.findDirectExpressions(Expressions.Source);
24
25
  let firstSource = node.findDirectExpression(Expressions.SimpleSource2);
25
26
  if (firstSource === undefined) {
26
27
  firstSource = sources[0];
27
28
  }
28
- let sourceType = firstSource ? new source_1.Source().runSyntax(firstSource, scope, filename, targetType) : undefined;
29
+ let sourceType = firstSource ? new source_1.Source().runSyntax(firstSource, scope, filename, targetType, write) : undefined;
29
30
  let rowType = undefined;
30
31
  const concat = node.concatTokens().toUpperCase();
31
32
  if (sourceType === undefined) {
@@ -6,7 +6,7 @@ class HexType extends _abstract_type_1.AbstractType {
6
6
  constructor(length, qualifiedName) {
7
7
  super({ qualifiedName: qualifiedName });
8
8
  if (length <= 0) {
9
- throw new Error("Bad LENGTHm, Hex");
9
+ throw new Error("Bad LENGTH, Hex");
10
10
  }
11
11
  this.length = length;
12
12
  }
@@ -42,6 +42,7 @@ __exportStar(require("./time_type"), exports);
42
42
  __exportStar(require("./unknown_type"), exports);
43
43
  __exportStar(require("./utc_long_type"), exports);
44
44
  __exportStar(require("./void_type"), exports);
45
+ __exportStar(require("./xgeneric_type"), exports);
45
46
  __exportStar(require("./xsequence_type"), exports);
46
47
  __exportStar(require("./xstring_type"), exports);
47
48
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XGenericType = void 0;
4
+ const _abstract_type_1 = require("./_abstract_type");
5
+ class XGenericType extends _abstract_type_1.AbstractType {
6
+ toText() {
7
+ return "```x```";
8
+ }
9
+ isGeneric() {
10
+ return true;
11
+ }
12
+ toABAP() {
13
+ throw new Error("x, generic");
14
+ }
15
+ containsVoid() {
16
+ return false;
17
+ }
18
+ toCDS() {
19
+ return "abap.TODO_CGENERIC";
20
+ }
21
+ }
22
+ exports.XGenericType = XGenericType;
23
+ //# sourceMappingURL=xgeneric_type.js.map
@@ -65,7 +65,7 @@ class Registry {
65
65
  }
66
66
  static abaplintVersion() {
67
67
  // magic, see build script "version.sh"
68
- return "2.101.15";
68
+ return "2.101.17";
69
69
  }
70
70
  getDDICReferences() {
71
71
  return this.ddicReferences;
@@ -6,7 +6,9 @@ const Expressions = require("../abap/2_statements/expressions");
6
6
  const _abap_rule_1 = require("./_abap_rule");
7
7
  const _basic_rule_config_1 = require("./_basic_rule_config");
8
8
  const _irule_1 = require("./_irule");
9
+ const position_1 = require("../position");
9
10
  const __1 = require("..");
11
+ const edit_helper_1 = require("../edit_helper");
10
12
  class AlignParametersConf extends _basic_rule_config_1.BasicRuleConfig {
11
13
  }
12
14
  exports.AlignParametersConf = AlignParametersConf;
@@ -33,8 +35,9 @@ https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#align-par
33
35
 
34
36
  Does not take effect on non functional method calls, use https://rules.abaplint.org/functional_writing/
35
37
 
36
- Also https://rules.abaplint.org/max_one_method_parameter_per_line/ can help aligning parameter syntax`,
37
- tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Styleguide],
38
+ If parameters are on the same row, no issues are reported, see
39
+ https://rules.abaplint.org/max_one_method_parameter_per_line/ for splitting parameters to lines`,
40
+ tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix],
38
41
  badExample: `CALL FUNCTION 'FOOBAR'
39
42
  EXPORTING
40
43
  foo = 2
@@ -96,16 +99,28 @@ DATA(sdf) = VALUE type(
96
99
  return undefined;
97
100
  }
98
101
  let expectedEqualsColumn = 0;
102
+ let row = 0;
99
103
  for (const p of candidate.parameters) {
100
104
  const currentCol = p.left.getLastToken().getCol() + p.left.getLastToken().getStr().length + 1;
105
+ if (p.eq.getRow() === row) {
106
+ return undefined;
107
+ }
108
+ row = p.eq.getRow();
101
109
  if (currentCol > expectedEqualsColumn) {
102
110
  expectedEqualsColumn = currentCol;
103
111
  }
104
112
  }
105
113
  for (const p of candidate.parameters) {
106
114
  if (p.eq.getCol() !== expectedEqualsColumn) {
115
+ let fix;
116
+ if (p.eq.getCol() < expectedEqualsColumn) {
117
+ fix = edit_helper_1.EditHelper.insertAt(file, p.eq, " ".repeat(expectedEqualsColumn - p.eq.getCol()));
118
+ }
119
+ else {
120
+ fix = edit_helper_1.EditHelper.deleteRange(file, new position_1.Position(p.eq.getRow(), expectedEqualsColumn), p.eq);
121
+ }
107
122
  const message = "Align parameters to column " + expectedEqualsColumn;
108
- return issue_1.Issue.atPosition(file, p.eq, message, this.getMetadata().key, this.getConfig().severity);
123
+ return issue_1.Issue.atPosition(file, p.eq, message, this.getMetadata().key, this.getConfig().severity, fix);
109
124
  }
110
125
  }
111
126
  return undefined;
@@ -45,11 +45,11 @@ DATA lt_bar TYPE STANDARD TABLE OF ty.`,
45
45
  const concat = tt.concatTokens().toUpperCase();
46
46
  if (concat.includes("TYPE TABLE OF")) {
47
47
  const message = "Specify table type";
48
- issues.push(issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
48
+ issues.push(issue_1.Issue.atPosition(file, tt.getFirstToken().getStart(), message, this.getMetadata().key, this.conf.severity));
49
49
  }
50
50
  else if (concat.includes(" WITH ") === false && concat.includes(" RANGE OF ") === false) {
51
51
  const message = "Specify table key";
52
- issues.push(issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
52
+ issues.push(issue_1.Issue.atPosition(file, tt.getFirstToken().getStart(), message, this.getMetadata().key, this.conf.severity));
53
53
  }
54
54
  }
55
55
  return issues;
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SelectSingleFullKey = exports.SelectSingleFullKeyConf = void 0;
4
4
  const issue_1 = require("../issue");
5
5
  const _basic_rule_config_1 = require("./_basic_rule_config");
6
- const _irule_1 = require("./_irule");
7
6
  const __1 = require("..");
8
7
  class SelectSingleFullKeyConf extends _basic_rule_config_1.BasicRuleConfig {
9
8
  constructor() {
@@ -23,7 +22,7 @@ class SelectSingleFullKey {
23
22
  shortDescription: `Detect SELECT SINGLE which are possibily not unique`,
24
23
  extendedInformation: `Table definitions must be known, ie. inside the errorNamespace`,
25
24
  pseudoComment: "EC CI_NOORDER",
26
- tags: [_irule_1.RuleTag.Experimental],
25
+ tags: [],
27
26
  };
28
27
  }
29
28
  initialize(reg) {
@@ -9,6 +9,12 @@ const _basic_rule_config_1 = require("./_basic_rule_config");
9
9
  const _statement_1 = require("../abap/2_statements/statements/_statement");
10
10
  const _irule_1 = require("./_irule");
11
11
  class UnnecessaryPragmaConf extends _basic_rule_config_1.BasicRuleConfig {
12
+ constructor() {
13
+ super(...arguments);
14
+ /** Allow NO_TEXT in global CLAS and INTF definitions,
15
+ its added automatically by SE24 in some cases where it should not */
16
+ this.allowNoTextGlobal = false;
17
+ }
12
18
  }
13
19
  exports.UnnecessaryPragmaConf = UnnecessaryPragmaConf;
14
20
  class UnnecessaryPragma extends _abap_rule_1.ABAPRule {
@@ -58,6 +64,7 @@ ENDIF.`,
58
64
  runParsed(file) {
59
65
  const issues = [];
60
66
  let noHandler = false;
67
+ let globalDefinition = false;
61
68
  const statements = file.getStatements();
62
69
  for (let i = 0; i < statements.length; i++) {
63
70
  const statement = statements[i];
@@ -65,6 +72,16 @@ ENDIF.`,
65
72
  if (statement.get() instanceof Statements.EndTry) {
66
73
  noHandler = false;
67
74
  }
75
+ else if (statement.get() instanceof Statements.ClassDefinition
76
+ || statement.get() instanceof Statements.Interface) {
77
+ if (statement.findDirectExpression(Expressions.ClassGlobal)) {
78
+ globalDefinition = true;
79
+ }
80
+ }
81
+ else if (statement.get() instanceof Statements.EndClass
82
+ || statement.get() instanceof Statements.EndInterface) {
83
+ globalDefinition = false;
84
+ }
68
85
  else if (statement.get() instanceof _statement_1.Comment) {
69
86
  continue;
70
87
  }
@@ -77,9 +94,16 @@ ENDIF.`,
77
94
  else {
78
95
  noHandler = this.containsNoHandler(statement, statements[i + 1]);
79
96
  }
80
- issues.push(...this.checkText(statement, file));
97
+ if (this.getConfig().allowNoTextGlobal === true && globalDefinition === true) {
98
+ // skip
99
+ }
100
+ else {
101
+ issues.push(...this.checkText(statement, file));
102
+ }
81
103
  issues.push(...this.checkNeeded(statement, file));
82
- issues.push(...this.checkSubrc(statement, nextStatement, file));
104
+ if (globalDefinition === false) {
105
+ issues.push(...this.checkSubrc(statement, nextStatement, file));
106
+ }
83
107
  }
84
108
  return issues;
85
109
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.101.15",
3
+ "version": "2.101.17",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -50,10 +50,10 @@
50
50
  },
51
51
  "homepage": "https://abaplint.org",
52
52
  "devDependencies": {
53
- "@microsoft/api-extractor": "^7.35.1",
53
+ "@microsoft/api-extractor": "^7.35.2",
54
54
  "@types/chai": "^4.3.5",
55
55
  "@types/mocha": "^10.0.1",
56
- "@types/node": "^20.2.5",
56
+ "@types/node": "^20.2.6",
57
57
  "chai": "^4.3.7",
58
58
  "eslint": "^8.42.0",
59
59
  "mocha": "^10.2.0",