11import {
22 ArgumentListCtx ,
3+ ArrayAccessSuffixCtx ,
34 BaseJavaCstVisitorWithDefaults ,
45 BinaryExpressionCtx ,
5- ClassOrInterfaceTypeToInstantiateCtx ,
66 BooleanLiteralCtx ,
7+ ClassOrInterfaceTypeToInstantiateCtx ,
78 ExpressionCstNode ,
89 ExpressionCtx ,
910 FloatingPointLiteralCtx ,
1011 FqnOrRefTypeCtx ,
1112 FqnOrRefTypePartCommonCtx ,
1213 FqnOrRefTypePartFirstCtx ,
1314 FqnOrRefTypePartRestCtx ,
14- IToken ,
1515 IntegerLiteralCtx ,
16+ IToken ,
1617 LiteralCtx ,
1718 MethodInvocationSuffixCtx ,
1819 NewExpressionCtx ,
1920 ParenthesisExpressionCtx ,
2021 PrimaryCtx ,
2122 PrimaryPrefixCtx ,
23+ PrimarySuffixCstNode ,
2224 PrimarySuffixCtx ,
2325 TernaryExpressionCtx ,
2426 UnaryExpressionCstNode ,
2527 UnaryExpressionCtx ,
26- UnqualifiedClassInstanceCreationExpressionCtx ,
27- ArrayAccessSuffixCtx
28+ UnqualifiedClassInstanceCreationExpressionCtx
2829} from 'java-parser'
29- import { Location } from '../types/ast'
3030import {
31+ ArgumentList ,
3132 ArrayAccess ,
3233 Assignment ,
3334 BinaryExpression ,
3435 ClassInstanceCreationExpression ,
3536 Expression ,
3637 ExpressionName ,
37- MethodInvocation ,
38+ FieldAccess ,
3839 Primary
3940} from '../types/blocks-and-statements'
41+ import { Location } from '../types/ast'
42+ import { getLocation } from './utils'
4043
4144export class ExpressionExtractor extends BaseJavaCstVisitorWithDefaults {
4245 private location : Location
@@ -194,72 +197,71 @@ export class ExpressionExtractor extends BaseJavaCstVisitorWithDefaults {
194197 }
195198
196199 primary ( ctx : PrimaryCtx ) : Primary {
197- let primary = this . visit ( ctx . primaryPrefix )
198200 if ( ctx . primarySuffix ) {
199201 const lastSuffix = ctx . primarySuffix [ ctx . primarySuffix . length - 1 ]
200- if ( lastSuffix . children . arrayAccessSuffix ) {
201- const newPrimaryCtx : PrimaryCtx = { primaryPrefix : ctx . primaryPrefix }
202- if ( ctx . primarySuffix . length - 1 > 0 ) {
203- const newSuffixArray = ctx . primarySuffix . filter (
204- ( _ , index ) => index !== ctx . primarySuffix ! . length - 1
205- )
206- newPrimaryCtx . primarySuffix = newSuffixArray
207- }
208- return {
209- ...this . visit ( lastSuffix . children . arrayAccessSuffix ) ,
210- primary : this . primary ( newPrimaryCtx )
211- }
212- }
213-
214- for ( const s of ctx . primarySuffix . filter ( s => ! s . children . methodInvocationSuffix ) ) {
215- primary += '.' + this . visit ( s )
216- }
217-
218- if ( ctx . primarySuffix [ ctx . primarySuffix . length - 1 ] . children . methodInvocationSuffix ) {
202+ const newPrimaryCtx : PrimaryCtx = { primaryPrefix : ctx . primaryPrefix }
203+ const primarySuffix : PrimarySuffixCstNode [ ] = [ ]
204+ for ( let i = 0 ; i < ctx . primarySuffix . length - 1 ; i ++ )
205+ primarySuffix . push ( ctx . primarySuffix [ i ] )
206+ if ( primarySuffix . length > 0 ) newPrimaryCtx . primarySuffix = primarySuffix
207+ const primary = this . primary ( newPrimaryCtx )
208+ const primaryRest = this . visit ( lastSuffix )
209+ if ( ! primaryRest ) return { } as Primary // Temporary
210+ if ( primary . kind === 'FieldAccess' && primaryRest . kind === 'MethodInvocation' ) {
211+ // example.test() -> primary: example.test, primaryRest: ()
219212 return {
220- kind : 'MethodInvocation' ,
221- identifier : primary ,
222- argumentList : this . visit ( ctx . primarySuffix [ ctx . primarySuffix . length - 1 ] ) ,
223- location : this . location
224- } as MethodInvocation
213+ ... primaryRest ,
214+ identifier : primary . identifier ,
215+ location : primary . location ,
216+ primary : primary . primary
217+ } as Primary
225218 }
219+ return { ...primaryRest , primary }
226220 }
227-
228- if ( ctx . primaryPrefix [ 0 ] . children . fqnOrRefType || ctx . primaryPrefix [ 0 ] . children . This ) {
229- return {
230- kind : 'ExpressionName' ,
231- name : primary ,
232- location : this . location
233- } as ExpressionName
234- }
235-
236- return primary
221+ return this . visit ( ctx . primaryPrefix ) as Primary
237222 }
238223
239224 primaryPrefix ( ctx : PrimaryPrefixCtx ) {
240- if ( ctx . literal ) {
241- return this . visit ( ctx . literal )
242- } else if ( ctx . parenthesisExpression ) {
243- return this . visit ( ctx . parenthesisExpression )
225+ if ( ctx . This ) {
226+ return { kind : 'This' }
227+ } else if ( ctx . Void ) {
228+ return { kind : 'Void' }
229+ } else if ( ctx . castExpression ) {
230+ throw new Error ( 'not implemented' )
244231 } else if ( ctx . fqnOrRefType ) {
245232 return this . visit ( ctx . fqnOrRefType )
233+ } else if ( ctx . literal ) {
234+ return this . visit ( ctx . literal )
246235 } else if ( ctx . newExpression ) {
247236 return this . visit ( ctx . newExpression )
248- } else if ( ctx . This ) {
249- return ctx . This [ 0 ] . image
237+ } else if ( ctx . parenthesisExpression ) {
238+ return this . visit ( ctx . parenthesisExpression )
239+ } else if ( ctx . switchStatement ) {
240+ throw new Error ( 'not implemented' )
241+ } else if ( ctx . unannPrimitiveTypeWithOptionalDimsSuffix ) {
242+ throw new Error ( 'not implemented' )
250243 }
251244 }
252245
253246 primarySuffix ( ctx : PrimarySuffixCtx ) {
254247 if ( ctx . methodInvocationSuffix ) {
255248 return this . visit ( ctx . methodInvocationSuffix )
256- } else if ( ctx . Identifier ) {
257- return ctx . Identifier [ 0 ] . image
249+ } else if ( ctx . Dot && ctx . Identifier ) {
250+ return {
251+ kind : 'FieldAccess' ,
252+ identifier : ctx . Identifier [ 0 ] . image ,
253+ location : getLocation ( ctx . Identifier [ 0 ] )
254+ }
255+ } else if ( ctx . arrayAccessSuffix ) {
256+ return this . visit ( ctx . arrayAccessSuffix )
258257 }
259258 }
260259
261260 methodInvocationSuffix ( ctx : MethodInvocationSuffixCtx ) {
262- return ctx . argumentList ? this . visit ( ctx . argumentList ) : [ ]
261+ return {
262+ kind : 'MethodInvocation' ,
263+ argumentList : ctx . argumentList ? this . visit ( ctx . argumentList ) : [ ]
264+ }
263265 }
264266
265267 newExpression ( ctx : NewExpressionCtx ) {
@@ -281,30 +283,52 @@ export class ExpressionExtractor extends BaseJavaCstVisitorWithDefaults {
281283 return ctx . Identifier [ 0 ] . image
282284 }
283285
284- argumentList ( ctx : ArgumentListCtx ) {
285- const expressionExtractor = new ExpressionExtractor ( )
286- return ctx . expression . map ( e => expressionExtractor . extract ( e ) )
286+ argumentList ( ctx : ArgumentListCtx ) : ArgumentList {
287+ const argumentList : Expression [ ] = [ ]
288+ ctx . expression . forEach ( expression => {
289+ const expressionExtractor = new ExpressionExtractor ( )
290+ const argumentExpression = expressionExtractor . extract ( expression )
291+ argumentList . push ( argumentExpression )
292+ } )
293+ return argumentList
287294 }
288295
289296 fqnOrRefType ( ctx : FqnOrRefTypeCtx ) {
290- let fqn = this . visit ( ctx . fqnOrRefTypePartFirst )
291- if ( ctx . fqnOrRefTypePartRest ) {
292- for ( const r of ctx . fqnOrRefTypePartRest ) {
293- fqn += '.' + this . visit ( r )
294- }
297+ const firstPart = this . visit ( ctx . fqnOrRefTypePartFirst )
298+ if ( ctx . Dot && ctx . fqnOrRefTypePartRest ) {
299+ const expressionName = this . visit ( ctx . fqnOrRefTypePartRest ) as ExpressionName
300+ return {
301+ kind : 'FieldAccess' ,
302+ identifier : expressionName . name ,
303+ primary : firstPart ,
304+ location : expressionName . location
305+ } as FieldAccess
295306 }
296- return fqn
307+ return firstPart
297308 }
298309
299310 fqnOrRefTypePartFirst ( ctx : FqnOrRefTypePartFirstCtx ) {
311+ if ( ctx . annotation ) throw new Error ( 'not implemented' )
300312 return this . visit ( ctx . fqnOrRefTypePartCommon )
301313 }
302314
303315 fqnOrRefTypePartCommon ( ctx : FqnOrRefTypePartCommonCtx ) {
304- return ctx . Identifier && ctx . Identifier [ 0 ] . image
316+ if ( ctx . Identifier ) {
317+ return {
318+ kind : 'ExpressionName' ,
319+ name : ctx . Identifier [ 0 ] . image ,
320+ location : getLocation ( ctx . Identifier [ 0 ] )
321+ } as Primary
322+ }
323+ throw new Error ( 'not implemented' )
305324 }
306325
307326 fqnOrRefTypePartRest ( ctx : FqnOrRefTypePartRestCtx ) {
327+ if ( ctx . annotation ) {
328+ throw new Error ( 'not implemented' )
329+ } else if ( ctx . typeArguments ) {
330+ throw new Error ( 'not implemented' )
331+ }
308332 return this . visit ( ctx . fqnOrRefTypePartCommon )
309333 }
310334
@@ -416,7 +440,8 @@ export class ExpressionExtractor extends BaseJavaCstVisitorWithDefaults {
416440 const expresionExtractor = new ExpressionExtractor ( )
417441 return {
418442 kind : 'ArrayAccess' ,
419- expression : expresionExtractor . extract ( ctx . expression [ 0 ] )
443+ expression : expresionExtractor . extract ( ctx . expression [ 0 ] ) ,
444+ location : getLocation ( ctx . LSquare [ 0 ] )
420445 }
421446 }
422447}
0 commit comments