@@ -14,22 +14,22 @@ import {
1414 CompilationUnitContext ,
1515 TypeRefContext ,
1616} from '@apexdevtools/apex-parser' ;
17- import { CharStreams , Token } from 'antlr4ts' ;
17+ import { CharStreams , Token , TokenStreamRewriter } from 'antlr4ts' ;
1818import { ParseTreeWalker } from 'antlr4ts/tree/ParseTreeWalker' ;
1919
2020export class ApexASTParser {
2121 private apexFileContent : string ;
22- private implementsInterface : Map < string , Token > = new Map ( ) ;
22+ private implementsInterface : Map < InterfaceImplements , Token [ ] > = new Map ( ) ;
2323 private methodParameter : Map < string , Token > = new Map ( ) ;
2424 private namespaceChange : Map < string , Token [ ] > = new Map ( ) ;
2525 private namespace : string ;
2626 // private callsMethods: Map<string, Token[]>;
27- private interfaceNames : Set < string > ;
27+ private interfaceNames : InterfaceImplements [ ] ;
2828 // private className: string;
2929 private astListener : ApexParserListener ;
3030 private methodCalls : Set < MethodCall > ;
3131
32- public get implementsInterfaces ( ) : Map < string , Token > {
32+ public get implementsInterfaces ( ) : Map < InterfaceImplements , Token [ ] > {
3333 return this . implementsInterface ;
3434 }
3535
@@ -42,7 +42,7 @@ export class ApexASTParser {
4242
4343 public constructor (
4444 apexFileContent : string ,
45- interfaceNames : Set < string > ,
45+ interfaceNames : InterfaceImplements [ ] ,
4646 methodCalls : Set < MethodCall > ,
4747 namespace : string
4848 ) {
@@ -63,6 +63,15 @@ export class ApexASTParser {
6363 return context ;
6464 }
6565
66+ public rewrite ( ) : string {
67+ const lexer = new ApexLexer ( new CaseInsensitiveInputStream ( CharStreams . fromString ( this . apexFileContent ) ) ) ;
68+ const tokens = new CommonTokenStream ( lexer ) ;
69+ const rewriter = new TokenStreamRewriter ( tokens ) ;
70+ const parser = new ApexParser ( tokens ) ;
71+ parser . compilationUnit ( ) ;
72+ return rewriter . getText ( ) ;
73+ }
74+
6675 private createASTListener ( ) : ApexParserListener {
6776 class ApexMigrationListener implements ApexParserListener {
6877 public constructor ( private parser : ApexASTParser ) {
@@ -73,15 +82,23 @@ export class ApexASTParser {
7382 if ( ! interfaceToBeSearched ) return ;
7483 if ( ! ctx . typeList ( ) || ! ctx . typeList ( ) . typeRef ( ) ) return ;
7584 for ( const typeRefContext of ctx . typeList ( ) . typeRef ( ) )
76- for ( const typeNameContext of typeRefContext . typeName ( ) ) {
77- if ( ! typeNameContext . id ( ) || ! typeNameContext . id ( ) . Identifier ( ) ) continue ;
78- if ( interfaceToBeSearched . has ( typeNameContext . id ( ) . Identifier ( ) . symbol . text ) ) {
79- this . parser . implementsInterface . set (
80- typeNameContext . id ( ) . Identifier ( ) . symbol . text ,
81- typeNameContext . id ( ) . Identifier ( ) . symbol
82- ) ;
83- }
85+ for ( const toSearch of this . parser . interfaceNames ) {
86+ const matchingTokens = InterfaceMatcher . getMatchingTokens ( toSearch , typeRefContext ) ;
87+ if ( matchingTokens . length === 0 ) continue ;
88+ this . parser . implementsInterface . set ( toSearch , matchingTokens ) ;
89+ // Logger.logger.info('For interface ${toSearch.name} found tokens ${matchingTokens}');
8490 }
91+ /*
92+ for (const typeNameContext of typeRefContext.typeName()) {
93+ if (!typeNameContext.id() || !typeNameContext.id().Identifier()) continue;
94+ if (interfaceToBeSearched.has(typeNameContext.id().Identifier().symbol.text)) {
95+ this.parser.implementsInterface.set(
96+ typeNameContext.id().Identifier().symbol.text,
97+ typeNameContext.id().Identifier().symbol
98+ );
99+ }
100+ }
101+ */
85102 }
86103 public enterDotExpression ( ctx : DotExpressionContext ) : void {
87104 // console.log('*********');
@@ -150,3 +167,36 @@ export class MethodCall {
150167 else return `${ this . className } .${ this . methodName } ()` ;
151168 }
152169}
170+
171+ export class InterfaceImplements {
172+ public name : string ;
173+ public namespace : string ;
174+
175+ public constructor ( name : string , namespace ?: string ) {
176+ this . name = name ;
177+ if ( namespace ) this . namespace = namespace ;
178+ }
179+ }
180+ export class InterfaceMatcher {
181+ public static getMatchingTokens ( checkFor : InterfaceImplements , ctx : TypeRefContext ) : Token [ ] {
182+ const tokens : Token [ ] = [ ] ;
183+ const typeNameContexts = ctx . typeName ( ) ;
184+ if ( ! typeNameContexts ) return tokens ;
185+ if (
186+ ! checkFor . namespace &&
187+ typeNameContexts . length === 1 &&
188+ checkFor . name === typeNameContexts [ 0 ] ?. id ( ) ?. Identifier ( ) ?. symbol ?. text
189+ ) {
190+ tokens . push ( typeNameContexts [ 0 ] . id ( ) . Identifier ( ) . symbol ) ;
191+ } else if (
192+ checkFor . namespace &&
193+ typeNameContexts . length === 2 &&
194+ checkFor . namespace === typeNameContexts [ 0 ] ?. id ( ) ?. Identifier ( ) ?. symbol ?. text &&
195+ checkFor . name === typeNameContexts [ 1 ] ?. id ( ) ?. Identifier ( ) ?. symbol ?. text
196+ ) {
197+ tokens . push ( typeNameContexts [ 0 ] . id ( ) . Identifier ( ) . symbol ) ;
198+ tokens . push ( typeNameContexts [ 1 ] . id ( ) . Identifier ( ) . symbol ) ;
199+ }
200+ return tokens ;
201+ }
202+ }
0 commit comments