apex-mutation-testing 1.3.0-dev-83.21870988968-1 → 1.3.0-dev-83.22024108564-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.
Files changed (41) hide show
  1. package/README.md +1 -1
  2. package/lib/adapter/sObjectDescribeRepository.d.ts +10 -0
  3. package/lib/adapter/sObjectDescribeRepository.js +53 -0
  4. package/lib/adapter/sObjectDescribeRepository.js.map +1 -0
  5. package/lib/mutator/arithmeticOperatorMutator.d.ts +14 -2
  6. package/lib/mutator/arithmeticOperatorMutator.js +103 -2
  7. package/lib/mutator/arithmeticOperatorMutator.js.map +1 -1
  8. package/lib/mutator/baseListener.d.ts +3 -0
  9. package/lib/mutator/baseListener.js +4 -0
  10. package/lib/mutator/baseListener.js.map +1 -1
  11. package/lib/mutator/emptyReturnMutator.js +1 -2
  12. package/lib/mutator/emptyReturnMutator.js.map +1 -1
  13. package/lib/mutator/mutationListener.d.ts +3 -1
  14. package/lib/mutator/mutationListener.js +19 -2
  15. package/lib/mutator/mutationListener.js.map +1 -1
  16. package/lib/mutator/negationMutator.d.ts +6 -4
  17. package/lib/mutator/negationMutator.js +43 -23
  18. package/lib/mutator/negationMutator.js.map +1 -1
  19. package/lib/service/mutantGenerator.d.ts +3 -2
  20. package/lib/service/mutantGenerator.js +2 -3
  21. package/lib/service/mutantGenerator.js.map +1 -1
  22. package/lib/service/mutationTestingService.js +12 -3
  23. package/lib/service/mutationTestingService.js.map +1 -1
  24. package/lib/service/typeGatherer.d.ts +12 -0
  25. package/lib/service/typeGatherer.js +142 -0
  26. package/lib/service/typeGatherer.js.map +1 -0
  27. package/lib/service/typeMatcher.d.ts +13 -0
  28. package/lib/service/typeMatcher.js +19 -0
  29. package/lib/service/typeMatcher.js.map +1 -0
  30. package/lib/type/ApexMethod.d.ts +1 -2
  31. package/lib/type/ApexMethod.js +0 -2
  32. package/lib/type/ApexMethod.js.map +1 -1
  33. package/npm-shrinkwrap.json +242 -180
  34. package/oclif.manifest.json +1 -1
  35. package/package.json +7 -5
  36. package/lib/mutator/methodTypeListener.d.ts +0 -12
  37. package/lib/mutator/methodTypeListener.js +0 -114
  38. package/lib/mutator/methodTypeListener.js.map +0 -1
  39. package/lib/service/apexTypeResolver.d.ts +0 -9
  40. package/lib/service/apexTypeResolver.js +0 -18
  41. package/lib/service/apexTypeResolver.js.map +0 -1
package/README.md CHANGED
@@ -174,7 +174,7 @@ EXAMPLES
174
174
  $ sf apex mutation test run --apex-class MyClass --test-class MyClassTest
175
175
  ```
176
176
 
177
- _See code: [src/commands/apex/mutation/test/run.ts](https://github.com/scolladon/apex-mutation-testing/blob/v1.3.0-dev-83.21870988968-1/src/commands/apex/mutation/test/run.ts)_
177
+ _See code: [src/commands/apex/mutation/test/run.ts](https://github.com/scolladon/apex-mutation-testing/blob/v1.3.0-dev-83.22024108564-1/src/commands/apex/mutation/test/run.ts)_
178
178
  <!-- commandsstop -->
179
179
 
180
180
  ## Backlog
@@ -0,0 +1,10 @@
1
+ import { Connection } from '@salesforce/core';
2
+ import { ApexType } from '../type/ApexMethod.js';
3
+ export declare class SObjectDescribeRepository {
4
+ private readonly connection;
5
+ private readonly fieldTypes;
6
+ constructor(connection: Connection);
7
+ describe(sObjectNames: string[]): Promise<void>;
8
+ isSObject(typeName: string): boolean;
9
+ resolveFieldType(sObjectTypeName: string, fieldPath: string): ApexType | undefined;
10
+ }
@@ -0,0 +1,53 @@
1
+ import { mapLimit } from 'async';
2
+ import { ApexType } from '../type/ApexMethod.js';
3
+ const DESCRIBE_FIELD_TYPE_MAP = {
4
+ int: ApexType.INTEGER,
5
+ double: ApexType.DOUBLE,
6
+ currency: ApexType.DECIMAL,
7
+ percent: ApexType.DOUBLE,
8
+ date: ApexType.DATE,
9
+ datetime: ApexType.DATETIME,
10
+ boolean: ApexType.BOOLEAN,
11
+ id: ApexType.ID,
12
+ reference: ApexType.ID,
13
+ string: ApexType.STRING,
14
+ textarea: ApexType.STRING,
15
+ email: ApexType.STRING,
16
+ phone: ApexType.STRING,
17
+ url: ApexType.STRING,
18
+ picklist: ApexType.STRING,
19
+ multipicklist: ApexType.STRING,
20
+ encryptedstring: ApexType.STRING,
21
+ };
22
+ const MAX_CONCURRENT_DESCRIBE_CALLS = 25;
23
+ export class SObjectDescribeRepository {
24
+ connection;
25
+ fieldTypes = new Map();
26
+ constructor(connection) {
27
+ this.connection = connection;
28
+ }
29
+ async describe(sObjectNames) {
30
+ await mapLimit(sObjectNames, MAX_CONCURRENT_DESCRIBE_CALLS, async (name) => {
31
+ try {
32
+ const describeResult = await this.connection.describe(name);
33
+ const fieldMap = new Map();
34
+ for (const field of describeResult.fields) {
35
+ fieldMap.set(field.name.toLowerCase(), DESCRIBE_FIELD_TYPE_MAP[field.type] ?? ApexType.OBJECT);
36
+ }
37
+ this.fieldTypes.set(name.toLowerCase(), fieldMap);
38
+ }
39
+ catch {
40
+ // Skip sObjects that fail to describe (graceful degradation)
41
+ }
42
+ });
43
+ }
44
+ isSObject(typeName) {
45
+ return this.fieldTypes.has(typeName.toLowerCase());
46
+ }
47
+ resolveFieldType(sObjectTypeName, fieldPath) {
48
+ return this.fieldTypes
49
+ .get(sObjectTypeName.toLowerCase())
50
+ ?.get(fieldPath.toLowerCase());
51
+ }
52
+ }
53
+ //# sourceMappingURL=sObjectDescribeRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sObjectDescribeRepository.js","sourceRoot":"","sources":["../../src/adapter/sObjectDescribeRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAqB,MAAM,uBAAuB,CAAA;AAEnE,MAAM,uBAAuB,GAA6B;IACxD,GAAG,EAAE,QAAQ,CAAC,OAAO;IACrB,MAAM,EAAE,QAAQ,CAAC,MAAM;IACvB,QAAQ,EAAE,QAAQ,CAAC,OAAO;IAC1B,OAAO,EAAE,QAAQ,CAAC,MAAM;IACxB,IAAI,EAAE,QAAQ,CAAC,IAAI;IACnB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;IAC3B,OAAO,EAAE,QAAQ,CAAC,OAAO;IACzB,EAAE,EAAE,QAAQ,CAAC,EAAE;IACf,SAAS,EAAE,QAAQ,CAAC,EAAE;IACtB,MAAM,EAAE,QAAQ,CAAC,MAAM;IACvB,QAAQ,EAAE,QAAQ,CAAC,MAAM;IACzB,KAAK,EAAE,QAAQ,CAAC,MAAM;IACtB,KAAK,EAAE,QAAQ,CAAC,MAAM;IACtB,GAAG,EAAE,QAAQ,CAAC,MAAM;IACpB,QAAQ,EAAE,QAAQ,CAAC,MAAM;IACzB,aAAa,EAAE,QAAQ,CAAC,MAAM;IAC9B,eAAe,EAAE,QAAQ,CAAC,MAAM;CACjC,CAAA;AAED,MAAM,6BAA6B,GAAG,EAAE,CAAA;AAExC,MAAM,OAAO,yBAAyB;IAGP;IAFZ,UAAU,GAAsB,IAAI,GAAG,EAAE,CAAA;IAE1D,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAEhD,KAAK,CAAC,QAAQ,CAAC,YAAsB;QAC1C,MAAM,QAAQ,CACZ,YAAY,EACZ,6BAA6B,EAC7B,KAAK,EAAE,IAAY,EAAE,EAAE;YACrB,IAAI,CAAC;gBACH,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;gBAC3D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAA;gBAC5C,KAAK,MAAM,KAAK,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;oBAC1C,QAAQ,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,EACxB,uBAAuB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,MAAM,CACvD,CAAA;gBACH,CAAC;gBACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAA;YACnD,CAAC;YAAC,MAAM,CAAC;gBACP,6DAA6D;YAC/D,CAAC;QACH,CAAC,CACF,CAAA;IACH,CAAC;IAEM,SAAS,CAAC,QAAgB;QAC/B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IACpD,CAAC;IAEM,gBAAgB,CACrB,eAAuB,EACvB,SAAiB;QAEjB,OAAO,IAAI,CAAC,UAAU;aACnB,GAAG,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC;YACnC,EAAE,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAA;IAClC,CAAC;CACF"}
@@ -1,9 +1,21 @@
1
1
  import { ParserRuleContext } from 'antlr4ts';
2
- import { BaseListener } from './baseListener.js';
3
- export declare class ArithmeticOperatorMutator extends BaseListener {
2
+ import { ReturnTypeAwareBaseListener } from './returnTypeAwareBaseListener.js';
3
+ export declare class ArithmeticOperatorMutator extends ReturnTypeAwareBaseListener {
4
4
  private readonly REPLACEMENT_MAP;
5
+ private static readonly NUMERIC_TYPES;
6
+ private methodScopeVariables;
7
+ private classFields;
8
+ enterMethodDeclaration(ctx: ParserRuleContext): void;
9
+ enterLocalVariableDeclaration(ctx: ParserRuleContext): void;
10
+ enterFormalParameter(ctx: ParserRuleContext): void;
11
+ enterFieldDeclaration(ctx: ParserRuleContext): void;
12
+ enterEnhancedForControl(ctx: ParserRuleContext): void;
5
13
  enterArth1Expression(ctx: ParserRuleContext): void;
6
14
  enterArth2Expression(ctx: ParserRuleContext): void;
7
15
  enterAssignExpression(_ctx: ParserRuleContext): void;
8
16
  private processArithmeticOperation;
17
+ private isNonNumericContext;
18
+ private isNonNumericOperand;
19
+ private resolveApexType;
20
+ private trackVariableDeclaration;
9
21
  }
@@ -1,12 +1,45 @@
1
1
  import { TerminalNode } from 'antlr4ts/tree/index.js';
2
- import { BaseListener } from './baseListener.js';
3
- export class ArithmeticOperatorMutator extends BaseListener {
2
+ import { ApexType } from '../type/ApexMethod.js';
3
+ import { ReturnTypeAwareBaseListener } from './returnTypeAwareBaseListener.js';
4
+ export class ArithmeticOperatorMutator extends ReturnTypeAwareBaseListener {
4
5
  REPLACEMENT_MAP = {
5
6
  '+': ['-', '*', '/'],
6
7
  '-': ['+', '*', '/'],
7
8
  '*': ['+', '-', '/'],
8
9
  '/': ['+', '-', '*'],
9
10
  };
11
+ static NUMERIC_TYPES = new Set([
12
+ ApexType.INTEGER,
13
+ ApexType.LONG,
14
+ ApexType.DOUBLE,
15
+ ApexType.DECIMAL,
16
+ ]);
17
+ methodScopeVariables = new Map();
18
+ classFields = new Map();
19
+ enterMethodDeclaration(ctx) {
20
+ super.enterMethodDeclaration(ctx);
21
+ this.methodScopeVariables = new Map();
22
+ }
23
+ enterLocalVariableDeclaration(ctx) {
24
+ this.trackVariableDeclaration(ctx, this.methodScopeVariables);
25
+ }
26
+ enterFormalParameter(ctx) {
27
+ if (ctx.children && ctx.children.length >= 2) {
28
+ const typeName = ctx.children[ctx.children.length - 2].text;
29
+ const paramName = ctx.children[ctx.children.length - 1].text;
30
+ this.methodScopeVariables.set(paramName, typeName.toLowerCase());
31
+ }
32
+ }
33
+ enterFieldDeclaration(ctx) {
34
+ this.trackVariableDeclaration(ctx, this.classFields);
35
+ }
36
+ enterEnhancedForControl(ctx) {
37
+ if (ctx.children && ctx.children.length >= 2) {
38
+ const typeName = ctx.children[0].text;
39
+ const varName = ctx.children[1].text;
40
+ this.methodScopeVariables.set(varName, typeName.toLowerCase());
41
+ }
42
+ }
10
43
  // Handle MUL, DIV, and MOD operations (*, /, %)
11
44
  enterArth1Expression(ctx) {
12
45
  this.processArithmeticOperation(ctx);
@@ -25,6 +58,9 @@ export class ArithmeticOperatorMutator extends BaseListener {
25
58
  const operatorText = operatorNode.text;
26
59
  const replacements = this.REPLACEMENT_MAP[operatorText];
27
60
  if (replacements) {
61
+ if (operatorText === '+' && this.isNonNumericContext(ctx)) {
62
+ return;
63
+ }
28
64
  for (const replacement of replacements) {
29
65
  this.createMutationFromTerminalNode(operatorNode, replacement);
30
66
  }
@@ -32,5 +68,70 @@ export class ArithmeticOperatorMutator extends BaseListener {
32
68
  }
33
69
  }
34
70
  }
71
+ isNonNumericContext(ctx) {
72
+ const leftText = ctx.getChild(0).text;
73
+ const rightText = ctx.getChild(2).text;
74
+ return (this.isNonNumericOperand(leftText) || this.isNonNumericOperand(rightText));
75
+ }
76
+ isNonNumericOperand(text) {
77
+ if (text.includes("'")) {
78
+ return true;
79
+ }
80
+ const variableType = this.methodScopeVariables.get(text) ?? this.classFields.get(text);
81
+ if (variableType !== undefined) {
82
+ return !ArithmeticOperatorMutator.NUMERIC_TYPES.has(this.resolveApexType(variableType));
83
+ }
84
+ if (text.includes('.')) {
85
+ const rootVar = text.split('.')[0];
86
+ const rootType = this.methodScopeVariables.get(rootVar) ?? this.classFields.get(rootVar);
87
+ if (rootType !== undefined) {
88
+ if (this._sObjectDescribeRepository?.isSObject(rootType)) {
89
+ const fieldName = text.split('.').slice(1).join('.');
90
+ const fieldType = this._sObjectDescribeRepository.resolveFieldType(rootType, fieldName);
91
+ if (fieldType !== undefined) {
92
+ return !ArithmeticOperatorMutator.NUMERIC_TYPES.has(fieldType);
93
+ }
94
+ return true;
95
+ }
96
+ return !ArithmeticOperatorMutator.NUMERIC_TYPES.has(this.resolveApexType(rootType));
97
+ }
98
+ }
99
+ const methodCallMatch = text.match(/^(\w+)\(/);
100
+ if (methodCallMatch) {
101
+ const methodName = methodCallMatch[1];
102
+ const methodInfo = this.typeTable.get(methodName);
103
+ if (methodInfo) {
104
+ return !ArithmeticOperatorMutator.NUMERIC_TYPES.has(methodInfo.type);
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ resolveApexType(typeName) {
110
+ const typeMap = {
111
+ integer: ApexType.INTEGER,
112
+ long: ApexType.LONG,
113
+ double: ApexType.DOUBLE,
114
+ decimal: ApexType.DECIMAL,
115
+ string: ApexType.STRING,
116
+ boolean: ApexType.BOOLEAN,
117
+ date: ApexType.DATE,
118
+ datetime: ApexType.DATETIME,
119
+ id: ApexType.ID,
120
+ };
121
+ return typeMap[typeName] ?? ApexType.OBJECT;
122
+ }
123
+ trackVariableDeclaration(ctx, target) {
124
+ if (ctx.children && ctx.children.length >= 2) {
125
+ const typeName = ctx.children[0].text;
126
+ for (let i = 1; i < ctx.children.length; i++) {
127
+ const child = ctx.children[i];
128
+ const childText = child.text;
129
+ if (childText !== ',' && childText !== '=') {
130
+ const varName = childText.split('=')[0];
131
+ target.set(varName, typeName.toLowerCase());
132
+ }
133
+ }
134
+ }
135
+ }
35
136
  }
36
137
  //# sourceMappingURL=arithmeticOperatorMutator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"arithmeticOperatorMutator.js","sourceRoot":"","sources":["../../src/mutator/arithmeticOperatorMutator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,MAAM,OAAO,yBAA0B,SAAQ,YAAY;IACxC,eAAe,GAA6B;QAC3D,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QACpB,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QACpB,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QACpB,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;KACrB,CAAA;IAED,gDAAgD;IAChD,oBAAoB,CAAC,GAAsB;QACzC,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAA;IACtC,CAAC;IAED,uCAAuC;IACvC,oBAAoB,CAAC,GAAsB;QACzC,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAA;IACtC,CAAC;IAED,qBAAqB,CAAC,IAAuB;QAC3C,oEAAoE;IACtE,CAAC;IAEO,0BAA0B,CAAC,GAAsB;QACvD,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;YAEpC,IAAI,YAAY,YAAY,YAAY,EAAE,CAAC;gBACzC,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAA;gBACtC,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAA;gBAEvD,IAAI,YAAY,EAAE,CAAC;oBACjB,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;wBACvC,IAAI,CAAC,8BAA8B,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;oBAChE,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"arithmeticOperatorMutator.js","sourceRoot":"","sources":["../../src/mutator/arithmeticOperatorMutator.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,12 @@
1
1
  import { ParserRuleContext, Token } from 'antlr4ts';
2
2
  import { TerminalNode } from 'antlr4ts/tree/index.js';
3
3
  import { ApexParserListener } from 'apex-parser';
4
+ import { SObjectDescribeRepository } from '../adapter/sObjectDescribeRepository.js';
4
5
  import { ApexMutation } from '../type/ApexMutation.js';
5
6
  export declare class BaseListener implements ApexParserListener {
6
7
  _mutations: ApexMutation[];
8
+ _sObjectDescribeRepository?: SObjectDescribeRepository;
9
+ setSObjectDescribeRepository(repository: SObjectDescribeRepository): void;
7
10
  protected createMutation(startToken: Token, endToken: Token, originalText: string, replacement: string): void;
8
11
  protected createMutationFromParserRuleContext(ctx: ParserRuleContext, replacement: string): void;
9
12
  protected createMutationFromTerminalNode(node: TerminalNode, replacement: string): void;
@@ -1,6 +1,10 @@
1
1
  // @ts-ignore: Base type with just a common _mutations property
2
2
  export class BaseListener {
3
3
  _mutations = [];
4
+ _sObjectDescribeRepository;
5
+ setSObjectDescribeRepository(repository) {
6
+ this._sObjectDescribeRepository = repository;
7
+ }
4
8
  createMutation(startToken, endToken, originalText, replacement) {
5
9
  this._mutations.push({
6
10
  mutationName: this.constructor.name,
@@ -1 +1 @@
1
- {"version":3,"file":"baseListener.js","sourceRoot":"","sources":["../../src/mutator/baseListener.ts"],"names":[],"mappings":"AAKA,+DAA+D;AAC/D,MAAM,OAAO,YAAY;IACvB,UAAU,GAAmB,EAAE,CAAA;IAErB,cAAc,CACtB,UAAiB,EACjB,QAAe,EACf,YAAoB,EACpB,WAAmB;QAEnB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACnB,YAAY,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YACnC,MAAM,EAAE;gBACN,UAAU;gBACV,QAAQ;gBACR,IAAI,EAAE,YAAY;aACnB;YACD,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;IAES,mCAAmC,CAC3C,GAAsB,EACtB,WAAmB;QAEnB,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QACjE,CAAC;IACH,CAAC;IAES,8BAA8B,CACtC,IAAkB,EAClB,WAAmB;QAEnB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QACvE,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"baseListener.js","sourceRoot":"","sources":["../../src/mutator/baseListener.ts"],"names":[],"mappings":"AAMA,+DAA+D;AAC/D,MAAM,OAAO,YAAY;IACvB,UAAU,GAAmB,EAAE,CAAA;IAC/B,0BAA0B,CAA4B;IAEtD,4BAA4B,CAAC,UAAqC;QAChE,IAAI,CAAC,0BAA0B,GAAG,UAAU,CAAA;IAC9C,CAAC;IAES,cAAc,CACtB,UAAiB,EACjB,QAAe,EACf,YAAoB,EACpB,WAAmB;QAEnB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACnB,YAAY,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YACnC,MAAM,EAAE;gBACN,UAAU;gBACV,QAAQ;gBACR,IAAI,EAAE,YAAY;aACnB;YACD,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;IAES,mCAAmC,CAC3C,GAAsB,EACtB,WAAmB;QAEnB,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QACjE,CAAC;IACH,CAAC;IAES,8BAA8B,CACtC,IAAkB,EAClB,WAAmB;QAEnB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QACvE,CAAC;IACH,CAAC;CACF"}
@@ -55,8 +55,7 @@ export class EmptyReturnMutator extends ReturnTypeAwareBaseListener {
55
55
  case ApexType.LIST:
56
56
  case ApexType.SET:
57
57
  case ApexType.MAP:
58
- case ApexType.CUSTOM_OBJECT:
59
- case ApexType.STANDARD_ENTITY:
58
+ case ApexType.SOBJECT:
60
59
  return `new ${typeInfo.returnType}()`;
61
60
  default:
62
61
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"emptyReturnMutator.js","sourceRoot":"","sources":["../../src/mutator/emptyReturnMutator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAc,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAA;AAE9E,MAAM,OAAO,kBAAmB,SAAQ,2BAA2B;IACjE,oBAAoB,CAAC,GAAsB;QACzC,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,CAAC;YACrC,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,8BAA8B,EAAE,CAAA;QACtD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAM;QACR,CAAC;QAED,oCAAoC;QACpC,IACE;YACE,QAAQ,CAAC,IAAI;YACb,QAAQ,CAAC,OAAO;YAChB,QAAQ,CAAC,OAAO;YAChB,QAAQ,CAAC,MAAM;YACf,QAAQ,CAAC,UAAU;YACnB,QAAQ,CAAC,IAAI;YACb,QAAQ,CAAC,QAAQ;YACjB,QAAQ,CAAC,IAAI;SACd,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EACzB,CAAC;YACD,OAAM;QACR,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,OAAM;QACR,CAAC;QAED,MAAM,cAAc,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QACtC,IAAI,CAAC,CAAC,cAAc,YAAY,iBAAiB,CAAC,EAAE,CAAC;YACnD,OAAM;QACR,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAChE,OAAM;QACR,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAA;QACpD,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,mCAAmC,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QACtE,CAAC;IACH,CAAC;IAEO,kBAAkB,CAAC,QAAoB;QAC7C,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;YACtB,KAAK,QAAQ,CAAC,MAAM,CAAC;YACrB,KAAK,QAAQ,CAAC,EAAE;gBACd,OAAO,IAAI,CAAA;YAEb,KAAK,QAAQ,CAAC,OAAO;gBACnB,OAAO,GAAG,CAAA;YAEZ,KAAK,QAAQ,CAAC,IAAI;gBAChB,OAAO,IAAI,CAAA;YAEb,KAAK,QAAQ,CAAC,MAAM,CAAC;YACrB,KAAK,QAAQ,CAAC,OAAO;gBACnB,OAAO,KAAK,CAAA;YAEd,KAAK,QAAQ,CAAC,IAAI;gBAChB,OAAO,kBAAkB,CAAA;YAE3B,KAAK,QAAQ,CAAC,IAAI,CAAC;YACnB,KAAK,QAAQ,CAAC,GAAG,CAAC;YAClB,KAAK,QAAQ,CAAC,GAAG,CAAC;YAClB,KAAK,QAAQ,CAAC,aAAa,CAAC;YAC5B,KAAK,QAAQ,CAAC,eAAe;gBAC3B,OAAO,OAAO,QAAQ,CAAC,UAAU,IAAI,CAAA;YAEvC;gBACE,OAAO,IAAI,CAAA;QACf,CAAC;IACH,CAAC;IAEM,YAAY,CAAC,IAAY,EAAE,cAAsB;QACtD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;QAEpC,MAAM,kBAAkB,GAA8C;YACpE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI;YAC7B,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,GAAG;YAC7B,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YACzE,OAAO,EAAE,IAAI,CAAC,EAAE,CACd,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YAC3D,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI;SAC5C,CAAA;QAED,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9D,OAAO,CACL,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,8BAA8B,CAAC;gBACtD,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,gCAAgC,CAAC,CACzD,CAAA;QACH,CAAC;QAED,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAC9D,CAAC;QAED,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAC9D,CAAC;QAED,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAA;QACb,CAAC;QAED,MAAM,YAAY,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAA;QAClD,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,YAAY,CAAC,cAAc,CAAC,CAAA;QACrC,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;CACF"}
1
+ {"version":3,"file":"emptyReturnMutator.js","sourceRoot":"","sources":["../../src/mutator/emptyReturnMutator.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { ApexParserListener } from 'apex-parser';
2
+ import { SObjectDescribeRepository } from '../adapter/sObjectDescribeRepository.js';
2
3
  import { ApexMethod } from '../type/ApexMethod.js';
3
4
  import { ApexMutation } from '../type/ApexMutation.js';
4
5
  import { BaseListener } from './baseListener.js';
@@ -7,6 +8,7 @@ export declare class MutationListener implements ApexParserListener {
7
8
  protected readonly typeTable?: Map<string, ApexMethod> | undefined;
8
9
  private listeners;
9
10
  _mutations: ApexMutation[];
11
+ private static readonly ALWAYS_FORWARD_METHODS;
10
12
  getMutations(): ApexMutation[];
11
- constructor(listeners: BaseListener[], coveredLines: Set<number>, typeTable?: Map<string, ApexMethod> | undefined);
13
+ constructor(listeners: BaseListener[], coveredLines: Set<number>, typeTable?: Map<string, ApexMethod> | undefined, sObjectDescribeRepository?: SObjectDescribeRepository);
12
14
  }
@@ -5,10 +5,20 @@ export class MutationListener {
5
5
  typeTable;
6
6
  listeners;
7
7
  _mutations = [];
8
+ // Methods that should always be called regardless of covered lines
9
+ // These are needed for tracking method context in type-aware mutators
10
+ static ALWAYS_FORWARD_METHODS = new Set([
11
+ 'enterMethodDeclaration',
12
+ 'exitMethodDeclaration',
13
+ 'enterLocalVariableDeclaration',
14
+ 'enterFormalParameter',
15
+ 'enterFieldDeclaration',
16
+ 'enterEnhancedForControl',
17
+ ]);
8
18
  getMutations() {
9
19
  return this._mutations;
10
20
  }
11
- constructor(listeners, coveredLines, typeTable) {
21
+ constructor(listeners, coveredLines, typeTable, sObjectDescribeRepository) {
12
22
  this.coveredLines = coveredLines;
13
23
  this.typeTable = typeTable;
14
24
  this.listeners = listeners;
@@ -19,6 +29,11 @@ export class MutationListener {
19
29
  }
20
30
  });
21
31
  }
32
+ if (sObjectDescribeRepository) {
33
+ this.listeners.forEach(listener => {
34
+ listener.setSObjectDescribeRepository(sObjectDescribeRepository);
35
+ });
36
+ }
22
37
  // Share mutations array across all listeners
23
38
  this.listeners
24
39
  .filter(listener => '_mutations' in listener)
@@ -36,7 +51,9 @@ export class MutationListener {
36
51
  return (...args) => {
37
52
  if (Array.isArray(args) && args.length > 0) {
38
53
  const ctx = args[0];
39
- if (this.coveredLines.has(ctx?.start?.line)) {
54
+ const shouldForward = MutationListener.ALWAYS_FORWARD_METHODS.has(prop) ||
55
+ this.coveredLines.has(ctx?.start?.line);
56
+ if (shouldForward) {
40
57
  this.listeners.forEach(listener => {
41
58
  if (prop in listener && typeof listener[prop] === 'function') {
42
59
  ;
@@ -1 +1 @@
1
- {"version":3,"file":"mutationListener.js","sourceRoot":"","sources":["../../src/mutator/mutationListener.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAA;AAE9E,2DAA2D;AAC3D,MAAM,OAAO,gBAAgB;IAUN;IACA;IAVb,SAAS,CAAgB;IACjC,UAAU,GAAmB,EAAE,CAAA;IAExB,YAAY;QACjB,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAED,YACE,SAAyB,EACN,YAAyB,EACzB,SAAmC;QADnC,iBAAY,GAAZ,YAAY,CAAa;QACzB,cAAS,GAAT,SAAS,CAA0B;QAEtD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAE1B,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAChC,IAAI,QAAQ,YAAY,2BAA2B,EAAE,CAAC;oBACpD,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;gBAClC,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,6CAA6C;QAC7C,IAAI,CAAC,SAAS;aACX,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,IAAI,QAAQ,CAAC;aAC5C,OAAO,CAAC,QAAQ,CAAC,EAAE;YAClB,CAAC;YAAC,QAAyB,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;QAC1D,CAAC,CAAC,CAAA;QAEJ,2EAA2E;QAC3E,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;YACrB,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;gBACpB,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;oBACnB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAA;gBACrB,CAAC;gBAED,wEAAwE;gBACxE,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;oBAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAsB,CAAA;wBACxC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;4BAC5C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;gCAChC,IAAI,IAAI,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;oCAC7D,CAAC;oCAAC,QAAQ,CAAC,IAAI,CAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;gCACrD,CAAC;4BACH,CAAC,CAAC,CAAA;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC,CAAA;YACH,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"mutationListener.js","sourceRoot":"","sources":["../../src/mutator/mutationListener.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAA;AAE9E,2DAA2D;AAC3D,MAAM,OAAO,gBAAgB;IAqBN;IACA;IArBb,SAAS,CAAgB;IACjC,UAAU,GAAmB,EAAE,CAAA;IAE/B,mEAAmE;IACnE,sEAAsE;IAC9D,MAAM,CAAU,sBAAsB,GAAG,IAAI,GAAG,CAAC;QACvD,wBAAwB;QACxB,uBAAuB;QACvB,+BAA+B;QAC/B,sBAAsB;QACtB,uBAAuB;QACvB,yBAAyB;KAC1B,CAAC,CAAA;IAEK,YAAY;QACjB,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAED,YACE,SAAyB,EACN,YAAyB,EACzB,SAAmC,EACtD,yBAAqD;QAFlC,iBAAY,GAAZ,YAAY,CAAa;QACzB,cAAS,GAAT,SAAS,CAA0B;QAGtD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAE1B,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAChC,IAAI,QAAQ,YAAY,2BAA2B,EAAE,CAAC;oBACpD,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;gBAClC,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,yBAAyB,EAAE,CAAC;YAC9B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAChC,QAAQ,CAAC,4BAA4B,CAAC,yBAAyB,CAAC,CAAA;YAClE,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,6CAA6C;QAC7C,IAAI,CAAC,SAAS;aACX,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,IAAI,QAAQ,CAAC;aAC5C,OAAO,CAAC,QAAQ,CAAC,EAAE;YAClB,CAAC;YAAC,QAAyB,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;QAC1D,CAAC,CAAC,CAAA;QAEJ,2EAA2E;QAC3E,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;YACrB,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;gBACpB,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;oBACnB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAA;gBACrB,CAAC;gBAED,wEAAwE;gBACxE,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;oBAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAsB,CAAA;wBACxC,MAAM,aAAa,GACjB,gBAAgB,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAc,CAAC;4BAC3D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;wBAEzC,IAAI,aAAa,EAAE,CAAC;4BAClB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;gCAChC,IAAI,IAAI,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;oCAC7D,CAAC;oCAAC,QAAQ,CAAC,IAAI,CAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;gCACrD,CAAC;4BACH,CAAC,CAAC,CAAA;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC,CAAA;YACH,CAAC;SACF,CAAC,CAAA;IACJ,CAAC"}
@@ -1,7 +1,9 @@
1
1
  import { ParserRuleContext } from 'antlr4ts';
2
- import { BaseListener } from './baseListener.js';
3
- export declare class NegationMutator extends BaseListener {
4
- private readonly EXCLUDED_VALUES;
2
+ import { ReturnTypeAwareBaseListener } from './returnTypeAwareBaseListener.js';
3
+ export declare class NegationMutator extends ReturnTypeAwareBaseListener {
4
+ private static readonly NUMERIC_TYPES;
5
+ private static readonly ZERO_LITERAL;
5
6
  enterReturnStatement(ctx: ParserRuleContext): void;
6
- private shouldSkipExpression;
7
+ private isNegatedExpression;
8
+ private formatNegation;
7
9
  }
@@ -1,36 +1,56 @@
1
- import { BaseListener } from './baseListener.js';
2
- export class NegationMutator extends BaseListener {
3
- // Values that should not be negated
4
- EXCLUDED_VALUES = new Set(['true', 'false', 'null']);
5
- // Handle return statements: return x; -> return -x;
1
+ import { ParserRuleContext } from 'antlr4ts';
2
+ import { TerminalNode } from 'antlr4ts/tree/index.js';
3
+ import { ApexType } from '../type/ApexMethod.js';
4
+ import { ReturnTypeAwareBaseListener } from './returnTypeAwareBaseListener.js';
5
+ export class NegationMutator extends ReturnTypeAwareBaseListener {
6
+ static NUMERIC_TYPES = new Set([
7
+ ApexType.INTEGER,
8
+ ApexType.LONG,
9
+ ApexType.DOUBLE,
10
+ ApexType.DECIMAL,
11
+ ]);
12
+ static ZERO_LITERAL = /^0+(\.0+)?[lLdD]?$/;
6
13
  enterReturnStatement(ctx) {
7
- // Get the expression from the return statement
8
- const expression = ctx.expression?.();
9
- if (!expression) {
14
+ if (!this.isCurrentMethodTypeKnown()) {
10
15
  return;
11
16
  }
12
- const expressionText = expression.text;
13
- // Skip if already negated
14
- if (expressionText.startsWith('-')) {
17
+ const typeInfo = this.getCurrentMethodReturnTypeInfo();
18
+ if (!typeInfo || !NegationMutator.NUMERIC_TYPES.has(typeInfo.type)) {
15
19
  return;
16
20
  }
17
- // Skip non-numeric values (strings, booleans, null)
18
- if (this.shouldSkipExpression(expressionText)) {
21
+ if (!ctx.children || ctx.children.length < 2) {
19
22
  return;
20
23
  }
21
- // Create mutation: x -> -x
22
- this.createMutationFromParserRuleContext(expression, `-${expressionText}`);
24
+ const expressionNode = ctx.children[1];
25
+ if (!(expressionNode instanceof ParserRuleContext)) {
26
+ return;
27
+ }
28
+ if (this.isNegatedExpression(expressionNode)) {
29
+ return;
30
+ }
31
+ const expressionText = expressionNode.text;
32
+ if (NegationMutator.ZERO_LITERAL.test(expressionText)) {
33
+ return;
34
+ }
35
+ const replacement = this.formatNegation(expressionText, expressionNode);
36
+ this.createMutationFromParserRuleContext(expressionNode, replacement);
23
37
  }
24
- shouldSkipExpression(text) {
25
- // Skip excluded values (true, false, null)
26
- if (this.EXCLUDED_VALUES.has(text.toLowerCase())) {
27
- return true;
38
+ isNegatedExpression(expr) {
39
+ if (expr.childCount !== 2) {
40
+ return false;
28
41
  }
29
- // Skip string literals
30
- if (text.startsWith("'") || text.startsWith('"')) {
31
- return true;
42
+ const firstChild = expr.getChild(0);
43
+ if (!(firstChild instanceof TerminalNode)) {
44
+ return false;
45
+ }
46
+ return firstChild.text === '-';
47
+ }
48
+ formatNegation(expressionText, expressionNode) {
49
+ const isComplexExpression = expressionNode.childCount > 1;
50
+ if (isComplexExpression) {
51
+ return `-(${expressionText})`;
32
52
  }
33
- return false;
53
+ return `-${expressionText}`;
34
54
  }
35
55
  }
36
56
  //# sourceMappingURL=negationMutator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"negationMutator.js","sourceRoot":"","sources":["../../src/mutator/negationMutator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAC/C,oCAAoC;IACnB,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAA;IAErE,oDAAoD;IACpD,oBAAoB,CAAC,GAAsB;QACzC,+CAA+C;QAC/C,MAAM,UAAU,GAAI,GAA8B,CAAC,UAAU,EAAE,EAAE,CAAA;QAEjE,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAM;QACR,CAAC;QAED,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,CAAA;QAEtC,0BAA0B;QAC1B,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,OAAM;QACR,CAAC;QAED,oDAAoD;QACpD,IAAI,IAAI,CAAC,oBAAoB,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9C,OAAM;QACR,CAAC;QAED,2BAA2B;QAC3B,IAAI,CAAC,mCAAmC,CAAC,UAAU,EAAE,IAAI,cAAc,EAAE,CAAC,CAAA;IAC5E,CAAC;IAEO,oBAAoB,CAAC,IAAY;QACvC,2CAA2C;QAC3C,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACjD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,uBAAuB;QACvB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACjD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;CACF"}
1
+ {"version":3,"file":"negationMutator.js","sourceRoot":"","sources":["../../src/mutator/negationMutator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAA;AAE9E,MAAM,OAAO,eAAgB,SAAQ,2BAA2B;IACtD,MAAM,CAAU,aAAa,GAAG,IAAI,GAAG,CAAC;QAC9C,QAAQ,CAAC,OAAO;QAChB,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,MAAM;QACf,QAAQ,CAAC,OAAO;KACjB,CAAC,CAAA;IAEM,MAAM,CAAU,YAAY,GAAG,oBAAoB,CAAA;IAE3D,oBAAoB,CAAC,GAAsB;QACzC,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,CAAC;YACrC,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,8BAA8B,EAAE,CAAA;QACtD,IAAI,CAAC,QAAQ,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnE,OAAM;QACR,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,OAAM;QACR,CAAC;QAED,MAAM,cAAc,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QACtC,IAAI,CAAC,CAAC,cAAc,YAAY,iBAAiB,CAAC,EAAE,CAAC;YACnD,OAAM;QACR,CAAC;QAED,IAAI,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7C,OAAM;QACR,CAAC;QAED,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,CAAA;QAC1C,IAAI,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YACtD,OAAM;QACR,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,cAAc,CAAC,CAAA;QAEvE,IAAI,CAAC,mCAAmC,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;IACvE,CAAC;IAEO,mBAAmB,CAAC,IAAuB;QACjD,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QACnC,IAAI,CAAC,CAAC,UAAU,YAAY,YAAY,CAAC,EAAE,CAAC;YAC1C,OAAO,KAAK,CAAA;QACd,CAAC;QAED,OAAO,UAAU,CAAC,IAAI,KAAK,GAAG,CAAA;IAChC,CAAC;IAEO,cAAc,CACpB,cAAsB,EACtB,cAAiC;QAEjC,MAAM,mBAAmB,GAAG,cAAc,CAAC,UAAU,GAAG,CAAC,CAAA;QAEzD,IAAI,mBAAmB,EAAE,CAAC;YACxB,OAAO,KAAK,cAAc,GAAG,CAAA;QAC/B,CAAC;QAED,OAAO,IAAI,cAAc,EAAE,CAAA;IAC7B,CAAC"}
@@ -1,9 +1,10 @@
1
1
  import { CommonTokenStream } from 'apex-parser';
2
+ import { SObjectDescribeRepository } from '../adapter/sObjectDescribeRepository.js';
3
+ import { ApexMethod } from '../type/ApexMethod.js';
2
4
  import { ApexMutation } from '../type/ApexMutation.js';
3
- import { ApexTypeResolver } from './apexTypeResolver.js';
4
5
  export declare class MutantGenerator {
5
6
  private tokenStream?;
6
7
  getTokenStream(): CommonTokenStream | undefined;
7
- compute(classContent: string, coveredLines: Set<number>, typeResolver?: ApexTypeResolver): ApexMutation[];
8
+ compute(classContent: string, coveredLines: Set<number>, methodTypeTable?: Map<string, ApexMethod>, sObjectDescribeRepository?: SObjectDescribeRepository): ApexMutation[];
8
9
  mutate(mutation: ApexMutation): string;
9
10
  }
@@ -23,12 +23,11 @@ export class MutantGenerator {
23
23
  getTokenStream() {
24
24
  return this.tokenStream;
25
25
  }
26
- compute(classContent, coveredLines, typeResolver) {
26
+ compute(classContent, coveredLines, methodTypeTable, sObjectDescribeRepository) {
27
27
  const lexer = new ApexLexer(new CaseInsensitiveInputStream('other', classContent));
28
28
  this.tokenStream = new CommonTokenStream(lexer);
29
29
  const parser = new ApexParser(this.tokenStream);
30
30
  const tree = parser.compilationUnit();
31
- const methodTypeTable = typeResolver?.analyzeMethodTypes(tree);
32
31
  const incrementListener = new IncrementMutator();
33
32
  const boundaryListener = new BoundaryConditionMutator();
34
33
  const emptyReturnListener = new EmptyReturnMutator();
@@ -64,7 +63,7 @@ export class MutantGenerator {
64
63
  removeConditionalsListener,
65
64
  switchListener,
66
65
  experimentalSwitchListener,
67
- ], coveredLines, methodTypeTable);
66
+ ], coveredLines, methodTypeTable, sObjectDescribeRepository);
68
67
  ParseTreeWalker.DEFAULT.walk(listener, tree);
69
68
  return listener.getMutations();
70
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mutantGenerator.js","sourceRoot":"","sources":["../../src/service/mutantGenerator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mutantGenerator.js","sourceRoot":"","sources":["../../src/service/mutantGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EACL,SAAS,EACT,UAAU,EAEV,0BAA0B,EAC1B,iBAAiB,EACjB,eAAe,GAChB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAA;AACnF,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAA;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAA;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAA;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAA;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAA;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAA;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAA;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAI3E,MAAM,OAAO,eAAe;IAClB,WAAW,CAAoB;IAEhC,cAAc;QACnB,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAEM,OAAO,CACZ,YAAoB,EACpB,YAAyB,EACzB,eAAyC,EACzC,yBAAqD;QAErD,MAAM,KAAK,GAAG,IAAI,SAAS,CACzB,IAAI,0BAA0B,CAAC,OAAO,EAAE,YAAY,CAAC,CACtD,CAAA;QACD,IAAI,CAAC,WAAW,GAAG,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAA;QAC/C,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,EAAE,CAAA;QAErC,MAAM,iBAAiB,GAAG,IAAI,gBAAgB,EAAE,CAAA;QAChD,MAAM,gBAAgB,GAAG,IAAI,wBAAwB,EAAE,CAAA;QACvD,MAAM,mBAAmB,GAAG,IAAI,kBAAkB,EAAE,CAAA;QACpD,MAAM,kBAAkB,GAAG,IAAI,iBAAiB,EAAE,CAAA;QAClD,MAAM,mBAAmB,GAAG,IAAI,kBAAkB,EAAE,CAAA;QACpD,MAAM,kBAAkB,GAAG,IAAI,iBAAiB,EAAE,CAAA;QAClD,MAAM,gBAAgB,GAAG,IAAI,wBAAwB,EAAE,CAAA;QACvD,MAAM,kBAAkB,GAAG,IAAI,yBAAyB,EAAE,CAAA;QAC1D,MAAM,uBAAuB,GAAG,IAAI,sBAAsB,EAAE,CAAA;QAC5D,MAAM,uBAAuB,GAAG,IAAI,sBAAsB,EAAE,CAAA;QAC5D,MAAM,gBAAgB,GAAG,IAAI,eAAe,EAAE,CAAA;QAC9C,MAAM,wBAAwB,GAAG,IAAI,uBAAuB,EAAE,CAAA;QAC9D,MAAM,sBAAsB,GAAG,IAAI,qBAAqB,EAAE,CAAA;QAC1D,MAAM,uBAAuB,GAAG,IAAI,sBAAsB,EAAE,CAAA;QAC5D,MAAM,0BAA0B,GAAG,IAAI,yBAAyB,EAAE,CAAA;QAClE,MAAM,cAAc,GAAG,IAAI,aAAa,EAAE,CAAA;QAC1C,MAAM,0BAA0B,GAAG,IAAI,yBAAyB,EAAE,CAAA;QAElE,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CACnC;YACE,gBAAgB;YAChB,iBAAiB;YACjB,gBAAgB;YAChB,mBAAmB;YACnB,kBAAkB;YAClB,mBAAmB;YACnB,kBAAkB;YAClB,kBAAkB;YAClB,uBAAuB;YACvB,uBAAuB;YACvB,gBAAgB;YAChB,wBAAwB;YACxB,sBAAsB;YACtB,uBAAuB;YACvB,0BAA0B;YAC1B,cAAc;YACd,0BAA0B;SAC3B,EACD,YAAY,EACZ,eAAe,EACf,yBAAyB,CAC1B,CAAA;QAED,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,QAA8B,EAAE,IAAI,CAAC,CAAA;QAElE,OAAO,QAAQ,CAAC,YAAY,EAAE,CAAA;IAChC,CAAC;IAEM,MAAM,CAAC,QAAsB;QAClC,qCAAqC;QACrC,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,WAAY,CAAC,CAAA;QAE3D,QAAQ,CAAC,OAAO,CACd,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,EACrC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EACnC,QAAQ,CAAC,WAAW,CACrB,CAAA;QAED,uBAAuB;QACvB,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAA;IAC3B,CAAC;CACF"}
@@ -1,7 +1,9 @@
1
1
  import { ApexClassRepository } from '../adapter/apexClassRepository.js';
2
2
  import { ApexTestRunner } from '../adapter/apexTestRunner.js';
3
- import { ApexTypeResolver } from './apexTypeResolver.js';
3
+ import { SObjectDescribeRepository } from '../adapter/sObjectDescribeRepository.js';
4
4
  import { MutantGenerator } from './mutantGenerator.js';
5
+ import { TypeGatherer } from './typeGatherer.js';
6
+ import { ApexClassTypeMatcher, SObjectTypeMatcher } from './typeMatcher.js';
5
7
  const errorStrategies = [
6
8
  {
7
9
  matches: msg => msg.startsWith('Deployment failed:'),
@@ -65,7 +67,14 @@ export class MutationTestingService {
65
67
  const customObjectTypes = dependencies
66
68
  .filter(dep => dep.RefMetadataComponentType === 'CustomObject')
67
69
  .map(dep => dep.RefMetadataComponentName);
68
- const typeResolver = new ApexTypeResolver(apexClassTypes, standardEntityTypes, customObjectTypes);
70
+ const apexClassMatcher = new ApexClassTypeMatcher(new Set(apexClassTypes));
71
+ const sObjectMatcher = new SObjectTypeMatcher(new Set([...standardEntityTypes, ...customObjectTypes]));
72
+ const typeGatherer = new TypeGatherer(apexClassMatcher, sObjectMatcher);
73
+ const { methodTypeTable, usedSObjectTypes } = typeGatherer.analyze(apexClass.Body);
74
+ this.spinner.stop('Done');
75
+ this.spinner.start(`Describing sObject field types for "${this.apexClassName}"`, undefined, { stdout: true });
76
+ const sObjectDescribeRepository = new SObjectDescribeRepository(this.connection);
77
+ await sObjectDescribeRepository.describe([...usedSObjectTypes]);
69
78
  this.spinner.stop('Done');
70
79
  this.spinner.start(`Testing original code"`, undefined, {
71
80
  stdout: true,
@@ -96,7 +105,7 @@ export class MutationTestingService {
96
105
  stdout: true,
97
106
  });
98
107
  const mutantGenerator = new MutantGenerator();
99
- const mutations = mutantGenerator.compute(apexClass.Body, coveredLines, typeResolver);
108
+ const mutations = mutantGenerator.compute(apexClass.Body, coveredLines, methodTypeTable, sObjectDescribeRepository);
100
109
  if (mutations.length === 0) {
101
110
  this.spinner.stop('0 mutations generated');
102
111
  throw new Error(this.messages.getMessage('error.noMutations', [