1919import liquidjava .rj_language .ast .UnaryExpression ;
2020import liquidjava .rj_language .ast .Var ;
2121import liquidjava .utils .Utils ;
22+ import liquidjava .utils .constants .Keys ;
2223
2324import org .antlr .v4 .runtime .tree .ParseTree ;
2425import org .apache .commons .lang3 .NotImplementedException ;
2526import rj .grammar .RJParser .AliasCallContext ;
2627import rj .grammar .RJParser .ArgsContext ;
28+ import rj .grammar .RJParser .DotCallContext ;
2729import rj .grammar .RJParser .ExpBoolContext ;
2830import rj .grammar .RJParser .ExpContext ;
2931import rj .grammar .RJParser .ExpGroupContext ;
5153import rj .grammar .RJParser .ProgContext ;
5254import rj .grammar .RJParser .StartContext ;
5355import rj .grammar .RJParser .StartPredContext ;
54- import rj .grammar .RJParser .TargetInvocationContext ;
5556import rj .grammar .RJParser .VarContext ;
56- import spoon .reflect .cu .SourcePosition ;
5757import liquidjava .diagnostics .errors .ArgumentMismatchError ;
5858
5959/**
@@ -82,6 +82,8 @@ else if (rc instanceof OperandContext)
8282 return operandCreate (rc );
8383 else if (rc instanceof LiteralExpressionContext )
8484 return literalExpressionCreate (rc );
85+ else if (rc instanceof DotCallContext )
86+ return dotCallCreate ((DotCallContext ) rc );
8587 else if (rc instanceof FunctionCallContext )
8688 return functionCallCreate ((FunctionCallContext ) rc );
8789 else if (rc instanceof LiteralContext )
@@ -156,9 +158,7 @@ else if (rc instanceof LitContext)
156158 return create (((LitContext ) rc ).literal ());
157159 else if (rc instanceof VarContext ) {
158160 return new Var (((VarContext ) rc ).ID ().getText ());
159- } else if (rc instanceof TargetInvocationContext ) {
160- // TODO Finish Invocation with Target (a.len())
161- return null ;
161+
162162 } else {
163163 return create (((InvocationContext ) rc ).functionCall ());
164164 }
@@ -171,15 +171,57 @@ private Expression functionCallCreate(FunctionCallContext rc) throws LJError {
171171 String name = Utils .qualifyName (prefix , ref );
172172 List <Expression > args = getArgs (gc .args ());
173173 if (args .isEmpty ())
174- throw new ArgumentMismatchError ("Ghost call cannot have empty arguments" );
174+ args .add (new Var (Keys .THIS )); // implicit this: size() => this.size()
175+
175176 return new FunctionInvocation (name , args );
176- } else {
177+ } else if ( rc . aliasCall () != null ) {
177178 AliasCallContext gc = rc .aliasCall ();
178179 String ref = gc .ID_UPPER ().getText ();
179180 List <Expression > args = getArgs (gc .args ());
180181 if (args .isEmpty ())
181182 throw new ArgumentMismatchError ("Alias call cannot have empty arguments" );
183+
182184 return new AliasInvocation (ref , args );
185+ } else {
186+ return dotCallCreate (rc .dotCall ());
187+ }
188+ }
189+
190+ /**
191+ * Handles both cases of dot calls: this.func(args) and targetFunc(this).func(args) Converts them to func(this,
192+ * args) and func(targetFunc(this), args) respectively
193+ */
194+ private Expression dotCallCreate (DotCallContext rc ) throws LJError {
195+ if (rc .OBJECT_TYPE () != null ) {
196+ String text = rc .OBJECT_TYPE ().getText ();
197+
198+ // check if there are multiple fields (e.g. this.a.b)
199+ if (text .chars ().filter (ch -> ch == '.' ).count () > 1 )
200+ throw new SyntaxError ("Multiple dot notation is not allowed" , text );
201+
202+ // this.func(args) => func(this, args)
203+ int dot = text .indexOf ('.' );
204+ String target = text .substring (0 , dot );
205+ String simpleName = text .substring (dot + 1 );
206+ String name = Utils .qualifyName (prefix , simpleName );
207+ List <Expression > args = getArgs (rc .args (0 ));
208+ if (!args .isEmpty () && args .get (0 )instanceof Var v && v .getName ().equals (Keys .THIS )
209+ && target .equals (Keys .THIS ))
210+ throw new SyntaxError ("Cannot use both dot notation and explicit 'this' argument. Use either 'this."
211+ + simpleName + "()' or '" + simpleName + "(this)'" , text );
212+
213+ args .add (0 , new Var (target ));
214+ return new FunctionInvocation (name , args );
215+
216+ } else {
217+ // targetFunc(this).func(args) => func(targetFunc(this), args)
218+ String targetFunc = rc .ID (0 ).getText ();
219+ String func = rc .ID (1 ).getText ();
220+ String name = Utils .qualifyName (prefix , func );
221+ List <Expression > targetArgs = getArgs (rc .args (0 ));
222+ List <Expression > funcArgs = getArgs (rc .args (1 ));
223+ funcArgs .add (0 , new FunctionInvocation (targetFunc , targetArgs ));
224+ return new FunctionInvocation (name , funcArgs );
183225 }
184226 }
185227
0 commit comments