Skip to content

Commit 2a9fb05

Browse files
committed
feat: simple declaration update for apex
1 parent c7d8a94 commit 2a9fb05

File tree

6 files changed

+1118
-21
lines changed

6 files changed

+1118
-21
lines changed

src/migration/related/ApexMigration.ts

Lines changed: 102 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,14 @@ export class ApexMigration extends BaseRelatedObjectMigration {
148148
parser.parse();
149149
const tokenUpdates: TokenUpdater[] = [];
150150
const tokenUpdatesForRemoteCalls = this.processApexFileForRemotecalls(file, parser);
151-
const tokeUpdatesForMethodCalls = this.processApexFileForMethodCalls(file, parser);
151+
const ipNameUpdateFailed = new Set<string>();
152+
const dmNameUpdateFailed = new Set<string>();
153+
const tokenUpdatesForMethodCalls = this.processApexFileForMethodCalls(file, parser, ipNameUpdateFailed);
154+
const tokenUpdatesForSimpleVarDeclarations = this.processApexFileForSimpleVarDeclarations(
155+
parser,
156+
ipNameUpdateFailed,
157+
dmNameUpdateFailed
158+
);
152159
const updateMessages: string[] = [];
153160

154161
if (tokenUpdatesForRemoteCalls && tokenUpdatesForRemoteCalls.length > 0) {
@@ -159,14 +166,37 @@ export class ApexMigration extends BaseRelatedObjectMigration {
159166
updateMessages.push(assessMessages.getMessage('fileUpdatedToAllowRemoteCalls'));
160167
}
161168
}
162-
if (tokeUpdatesForMethodCalls && tokeUpdatesForMethodCalls.length > 0) {
169+
if (tokenUpdatesForMethodCalls && tokenUpdatesForMethodCalls.length > 0) {
163170
if (type === 'migration') {
164171
updateMessages.push(migrateMessages.getMessage('fileUpdatedToAllowCalls'));
165172
} else {
166173
updateMessages.push(assessMessages.getMessage('fileUpdatedToAllowCalls'));
167174
}
168-
tokenUpdates.push(...tokeUpdatesForMethodCalls);
175+
tokenUpdates.push(...tokenUpdatesForMethodCalls);
176+
}
177+
178+
if (tokenUpdatesForSimpleVarDeclarations && tokenUpdatesForSimpleVarDeclarations.length > 0) {
179+
if (type === 'migration') {
180+
updateMessages.push(migrateMessages.getMessage('varDeclarationUpdated'));
181+
} else {
182+
updateMessages.push(assessMessages.getMessage('varDeclarationUpdated'));
183+
}
184+
tokenUpdates.push(...tokenUpdatesForSimpleVarDeclarations);
169185
}
186+
187+
const warnings: string[] = [];
188+
189+
if (ipNameUpdateFailed.size > 0) {
190+
ipNameUpdateFailed.forEach((name) => {
191+
warnings.push(assessMessages.getMessage('ipNameUpdateFailed', [name]));
192+
});
193+
}
194+
if (dmNameUpdateFailed.size > 0) {
195+
dmNameUpdateFailed.forEach((name) => {
196+
warnings.push(assessMessages.getMessage('dmNameUpdateFailed', [name]));
197+
});
198+
}
199+
170200
let difference = [];
171201
if (tokenUpdates && tokenUpdates.length > 0) {
172202
const updatedContent = parser.rewrite(tokenUpdates);
@@ -182,16 +212,60 @@ export class ApexMigration extends BaseRelatedObjectMigration {
182212
if (updateMessages.length === 0) {
183213
Logger.info(assessMessages.getMessage('fileNoOmnistudioCalls', [file.name]));
184214
}
185-
const warningMessage: string[] = this.processNonReplacableMethodCalls(file, parser);
215+
warnings.push(...this.processNonReplacableMethodCalls(file, parser));
186216
return {
187217
name: file.name,
188218
errors: [],
189-
warnings: warningMessage,
219+
warnings,
190220
infos: updateMessages,
191221
path: file.location,
192222
diff: JSON.stringify(difference),
193223
};
194224
}
225+
private processApexFileForSimpleVarDeclarations(
226+
parser: ApexASTParser,
227+
ipNameUpdateFailed: Set<string>,
228+
dmNameUpdateFailed: Set<string>
229+
): TokenUpdater[] {
230+
const simpleVarDeclarations = parser.simpleVarDeclarations;
231+
const tokenUpdates: TokenUpdater[] = [];
232+
// check and update for DM
233+
const dmVarInMethodCalls = parser.dmVarInMethodCalls;
234+
for (const varName of dmVarInMethodCalls) {
235+
const varToken = simpleVarDeclarations.get(varName);
236+
if (!varToken) {
237+
dmNameUpdateFailed.add(varName);
238+
continue;
239+
}
240+
const newName = `'${Stringutil.cleanName(varToken.text.substring(1, varToken.text.length - 1))}'`;
241+
if (newName === varToken.text) {
242+
continue;
243+
}
244+
tokenUpdates.push(new SingleTokenUpdate(newName, varToken));
245+
}
246+
// check and update for IP
247+
const ipVarInMethodCalls = parser.ipVarInMethodCalls;
248+
for (const varName of ipVarInMethodCalls) {
249+
const varToken = simpleVarDeclarations.get(varName);
250+
if (!varToken) {
251+
ipNameUpdateFailed.add(varName);
252+
continue;
253+
}
254+
const oldName = varToken.text.substring(1, varToken.text.length - 1);
255+
const parts = oldName.split('_');
256+
if (parts.length !== 2) {
257+
ipNameUpdateFailed.add(varName);
258+
continue;
259+
}
260+
const newName = `'${Stringutil.cleanName(parts[0])}_${Stringutil.cleanName(parts[1])}'`;
261+
if (newName === varToken.text) {
262+
continue;
263+
}
264+
tokenUpdates.push(new SingleTokenUpdate(newName, varToken));
265+
}
266+
267+
return tokenUpdates;
268+
}
195269

196270
private processApexFileForRemotecalls(file: File, parser: ApexASTParser): TokenUpdater[] {
197271
const implementsInterface = parser.implementsInterfaces;
@@ -281,7 +355,11 @@ export class ApexMigration extends BaseRelatedObjectMigration {
281355
return tokenUpdates;
282356
}
283357

284-
private processApexFileForMethodCalls(file: File, parser: ApexASTParser): TokenUpdater[] {
358+
private processApexFileForMethodCalls(
359+
file: File,
360+
parser: ApexASTParser,
361+
ipNameUpdateFailed: Set<string>
362+
): TokenUpdater[] {
285363
const namespaceChanges = parser.namespaceChanges;
286364
const tokenUpdates: TokenUpdater[] = [];
287365
if (namespaceChanges && namespaceChanges.has(this.namespace)) {
@@ -300,6 +378,24 @@ export class ApexMigration extends BaseRelatedObjectMigration {
300378
tokenUpdates.push(new SingleTokenUpdate(newName, token));
301379
}
302380
}
381+
382+
const ipParameters = methodParameters.get(ParameterType.IP_NAME);
383+
if (ipParameters) {
384+
for (const token of ipParameters) {
385+
const oldName = token.text;
386+
const parts = oldName.split('_');
387+
if (parts.length !== 2) {
388+
ipNameUpdateFailed.add(oldName);
389+
continue;
390+
}
391+
const newName = `'${Stringutil.cleanName(parts[0])}_${Stringutil.cleanName(parts[1])}'`;
392+
if (newName === oldName) {
393+
continue;
394+
}
395+
Logger.info(assessMessages.getMessage('inApexIpNameWillBeUpdated', [file.name, oldName, newName]));
396+
tokenUpdates.push(new SingleTokenUpdate(newName, token));
397+
}
398+
}
303399
return tokenUpdates;
304400
}
305401

src/utils/apex/parser/apexparser.ts

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ import {
1313
CompilationUnitContext,
1414
TypeRefContext,
1515
LiteralPrimaryContext,
16+
LocalVariableDeclarationContext,
17+
VariableDeclaratorContext,
18+
VariableDeclaratorsContext,
1619
} from '@apexdevtools/apex-parser';
17-
import { CharStreams, Token, TokenStreamRewriter } from 'antlr4ts';
20+
import { CharStreams, ParserRuleContext, Token, TokenStreamRewriter } from 'antlr4ts';
1821
import { ParseTreeWalker } from 'antlr4ts/tree/ParseTreeWalker';
22+
import { Logger } from '../../logger';
1923

2024
export class ApexASTParser {
2125
private apexFileContent: string;
@@ -30,6 +34,11 @@ export class ApexASTParser {
3034
private classDeclarationToken: Token;
3135
private hasCallMethod = false;
3236

37+
// token value will be enclosed in quotes
38+
private simpleVariableDeclarations: Map<string, Token> = new Map();
39+
private dmVariablesInMethodCalls: Set<string> = new Set();
40+
private ipVariablesInMethodCalls: Set<string> = new Set();
41+
3342
public get implementsInterfaces(): Map<InterfaceImplements, Token[]> {
3443
return this.implementsInterface;
3544
}
@@ -38,6 +47,16 @@ export class ApexASTParser {
3847
return this.classDeclarationToken;
3948
}
4049

50+
public get simpleVarDeclarations(): Map<string, Token> {
51+
return this.simpleVariableDeclarations;
52+
}
53+
public get dmVarInMethodCalls(): Set<string> {
54+
return this.dmVariablesInMethodCalls;
55+
}
56+
public get ipVarInMethodCalls(): Set<string> {
57+
return this.ipVariablesInMethodCalls;
58+
}
59+
4160
public get methodParameters(): Map<ParameterType, Token[]> {
4261
return this.methodParameter;
4362
}
@@ -116,16 +135,19 @@ export class ApexASTParser {
116135
const parameter = methodcall.parameter;
117136
if (!parameter) continue;
118137
const bundleName = dotMethodCall.expressionList().expression(parameter.position - 1);
119-
if (
120-
bundleName &&
121-
bundleName?.children &&
122-
bundleName.childCount > 0 &&
123-
bundleName.children[0] instanceof LiteralPrimaryContext
124-
) {
125-
const arg: LiteralPrimaryContext = bundleName.getChild(0) as LiteralPrimaryContext;
126-
const argValue = arg?.literal()?.StringLiteral();
127-
if (!argValue) continue;
128-
MapUtil.addToValueList(this.parser.methodParameter, parameter.type, argValue.symbol);
138+
if (bundleName && bundleName?.children && bundleName.childCount > 0) {
139+
if (bundleName.children[0] instanceof LiteralPrimaryContext) {
140+
const arg: LiteralPrimaryContext = bundleName.getChild(0) as LiteralPrimaryContext;
141+
const argValue = arg?.literal()?.StringLiteral();
142+
if (!argValue) continue;
143+
MapUtil.addToValueList(this.parser.methodParameter, parameter.type, argValue.symbol);
144+
} else {
145+
if (ParameterType.DR_NAME === parameter.type) {
146+
this.parser.dmVariablesInMethodCalls.add(bundleName.text);
147+
} else if (ParameterType.IP_NAME === parameter.type) {
148+
this.parser.ipVariablesInMethodCalls.add(bundleName.text);
149+
}
150+
}
129151
} else {
130152
this.parser.nonReplacableMethodParameter.push(methodcall);
131153
}
@@ -153,6 +175,22 @@ export class ApexASTParser {
153175
}
154176
}
155177
}
178+
public enterLocalVariableDeclaration(ctx: LocalVariableDeclarationContext): void {
179+
try {
180+
Logger.logVerbose(`Found variable declaration: ${ctx?.text}`);
181+
if (!checkIfValidSimpleDeclaration(ctx)) {
182+
return;
183+
}
184+
185+
const varName = ((ctx.children[1] as ParserRuleContext).children[0] as ParserRuleContext).children[0].text;
186+
const valueToken = (
187+
((ctx.children[1] as ParserRuleContext).children[0] as ParserRuleContext).children[2] as ParserRuleContext
188+
).start;
189+
this.parser.simpleVariableDeclarations.set(varName, valueToken);
190+
} catch (error) {
191+
Logger.logVerbose('Failed to check or parse variable declaration');
192+
}
193+
}
156194
}
157195
return new ApexMigrationListener(this);
158196
}
@@ -276,3 +314,26 @@ export class InsertAfterTokenUpdate implements TokenUpdater {
276314
rewriter.insertAfter(this.token, this.newText);
277315
}
278316
}
317+
318+
export function checkIfValidSimpleDeclaration(ctx: LocalVariableDeclarationContext): boolean {
319+
// check for String data type
320+
if (ctx.children?.length !== 2 || ctx.children[0].text !== 'String') {
321+
return false;
322+
}
323+
324+
// check number of tokens in the variable declaration
325+
if (
326+
!(ctx.children[1] instanceof VariableDeclaratorsContext) ||
327+
ctx.children[1].children?.length !== 1 ||
328+
!(ctx.children[1].children[0] instanceof VariableDeclaratorContext) ||
329+
ctx.children[1].children[0].children?.length !== 3
330+
) {
331+
return false;
332+
}
333+
334+
// check for string literal as initial value
335+
return (
336+
ctx.children[1].children[0].children[2].text.startsWith("'") &&
337+
ctx.children[1].children[0].children[2].text.endsWith("'")
338+
);
339+
}

src/utils/resultsbuilder/GlobalAutoNumberAssessmentReporter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class GlobalAutoNumberAssessmentReporter {
2323
Logger.captureVerboseData('GAN data', globalAutoNumberAssessmentInfos);
2424
return {
2525
title: 'Omni Global Auto Numbers Assessment Report',
26-
heading: 'Omni Global Auto Numbers Assessment Report',
26+
heading: 'Omni Global Auto Numbers Assessment Report',
2727
org: getOrgDetailsForReport(omnistudioOrgDetails),
2828
assessmentDate: new Date().toLocaleString(),
2929
total: globalAutoNumberAssessmentInfos?.length || 0,

test/migration/globalautonumber.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ describe('GlobalAutoNumberMigrationTool', () => {
7373
describe('getName', () => {
7474
it('should return correct name', () => {
7575
const result = globalAutoNumberMigrationTool.getName();
76-
expect(result).to.equal('GlobalAutoNumber');
76+
expect(result).to.equal('Omni Global Auto Number');
7777
});
7878
});
7979

@@ -255,7 +255,7 @@ describe('GlobalAutoNumberMigrationTool', () => {
255255

256256
// Assert
257257
expect(result).to.be.an('array').with.length(1);
258-
expect(result[0].name).to.equal('GlobalAutoNumber');
258+
expect(result[0].name).to.equal('Omni Global Auto Number');
259259
expect(result[0].results.size).to.equal(1);
260260
});
261261

@@ -346,7 +346,7 @@ describe('GlobalAutoNumberMigrationTool', () => {
346346

347347
// Assert
348348
expect(result).to.be.an('array').with.length(1);
349-
expect(result[0].name).to.equal('GlobalAutoNumber');
349+
expect(result[0].name).to.equal('Omni Global Auto Number');
350350
expect(result[0].results.size).to.equal(2);
351351
});
352352

0 commit comments

Comments
 (0)