From 357c18903cf1f9c136f69cd60df8eb0637a91ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20G=C3=BCnter?= Date: Mon, 23 Feb 2026 17:09:23 +0100 Subject: [PATCH] Parse type arguments for more method invocations --- Language/Java/Parser.hs | 42 ++++++++++++++++++------------------ Language/Java/Pretty.hs | 3 ++- Language/Java/Syntax.hs | 10 ++++----- Language/Java/Transformer.hs | 4 ++-- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/Language/Java/Parser.hs b/Language/Java/Parser.hs index bbae530..24fd1e6 100644 --- a/Language/Java/Parser.hs +++ b/Language/Java/Parser.hs @@ -406,22 +406,22 @@ explConstrInv = noLoc . endSemi $ try ( do - tas <- neoptList refTypeArgs + rts <- neoptList refTypeArgs tok KW_This - ThisInvoke tas <$> noLoc args + ThisInvoke rts <$> noLoc args ) <|> try ( do - tas <- neoptList refTypeArgs + rts <- neoptList refTypeArgs tok KW_Super - SuperInvoke tas <$> noLoc args + SuperInvoke rts <$> noLoc args ) <|> ( do pri <- noLoc primary period - tas <- neoptList refTypeArgs + rts <- neoptList refTypeArgs tok KW_Super - PrimarySuperInvoke pri tas <$> noLoc args + PrimarySuperInvoke pri rts <$> noLoc args ) -- TODO: This should be parsed like class bodies, and post-checked. @@ -1367,9 +1367,9 @@ methodInvocationNPS = do return (SuperMethodCall (startLoc, loc) rts i as, loc) ) <|> ( do - (mn, i) <- qualifiedMethodName + (mn, rts, i) <- qualifiedMethodName (as, loc) <- args - return (MethodCall (startLoc, loc) mn i as, loc) + return (MethodCall (startLoc, loc) mn rts i as, loc) ) <|> ( do n <- noLoc name @@ -1382,34 +1382,34 @@ methodInvocationNPS = do return (constr (startLoc, loc) n rts i as, loc) ) -qualifiedMethodName :: P (Maybe Name, Ident) +qualifiedMethodName :: P (Maybe Name, [RefType], Ident) qualifiedMethodName = do startLoc <- getLocation - mapFst - ( \case + (mn, rts, i) <- go startLoc [] + let mn' = case mn of ([], _) -> Nothing (is, endLoc) -> Just (Name (startLoc, endLoc) (NonEmpty.fromList (reverse is))) - ) - <$> go startLoc [] + return (mn', rts, i) where - go :: Location -> [Ident] -> P (([Ident], Location), Ident) + go :: Location -> [Ident] -> P (([Ident], Location), [RefType], Ident) go endLoc nids = do (i, loc) <- ident - try - ( do - period - go loc (i : nids) + ( do + rts <- try (period >> refTypeArgs) + i' <- noLoc ident + return ((i : nids, loc), NonEmpty.toList rts, i') ) - <|> return ((nids, endLoc), i) + <|> try (period >> go loc (i : nids)) + <|> return ((nids, endLoc), [], i) methodInvocationSuffix :: P (Exp Parsed -> MethodInvocation Parsed, Location) methodInvocationSuffix = do startLoc <- getLocation period - _ <- neoptList refTypeArgs + rts <- neoptList refTypeArgs i <- noLoc ident (as, loc) <- args - return (\p -> PrimaryMethodCall (startLoc, loc) p [] i as, loc) + return (\p -> PrimaryMethodCall (startLoc, loc) p rts i as, loc) methodInvocationExp :: P (Exp Parsed) methodInvocationExp = diff --git a/Language/Java/Pretty.hs b/Language/Java/Pretty.hs index 95b7253..137d01b 100644 --- a/Language/Java/Pretty.hs +++ b/Language/Java/Pretty.hs @@ -511,13 +511,14 @@ instance (PrettyExtension p) => Pretty (FieldAccess p) where prettyPrec p name <> text "." <> prettyPrec p ident instance (PrettyExtension p) => Pretty (MethodInvocation p) where - prettyPrec p (MethodCall _ mName methodId args) = + prettyPrec p (MethodCall _ mName tArgs methodId args) = case mName of Nothing -> prettyPrec p methodId <> ppArgs p args Just name -> hcat [ prettyPrec p name, char '.', + ppTypeParams p tArgs, prettyPrec p methodId, ppArgs p args ] diff --git a/Language/Java/Syntax.hs b/Language/Java/Syntax.hs index 8adacc6..5dd3ba4 100644 --- a/Language/Java/Syntax.hs +++ b/Language/Java/Syntax.hs @@ -1276,8 +1276,8 @@ instance (EqualityExtension p) => Equality (LambdaExpression p) where -- | A method invocation expression is used to invoke a class or instance method. data MethodInvocation p - = -- | Invoking a specific named method. - MethodCall SourceSpan (Maybe (XNameClassification p)) Ident [Argument p] + = -- | Invoking a specific named method, giving arguments for any generic type parameters. + MethodCall SourceSpan (Maybe (XNameClassification p)) [RefType] Ident [Argument p] | -- | Invoking a method of a class computed from a primary expression, giving arguments for any generic type parameters. PrimaryMethodCall SourceSpan (Exp p) [RefType] Ident [Argument p] | -- | Invoking a method of the super class, giving arguments for any generic type parameters. @@ -1295,8 +1295,8 @@ deriving instance (ReadExtension p) => Read (MethodInvocation p) deriving instance (DataExtension p) => Data (MethodInvocation p) instance (EqualityExtension p) => Equality (MethodInvocation p) where - eq opt (MethodCall s1 mn1 i1 as1) (MethodCall s2 mn2 i2 as2) = - eq opt s1 s2 && eq opt mn1 mn2 && eq opt i1 i2 && eq opt as1 as2 + eq opt (MethodCall s1 mn1 rts1 i1 as1) (MethodCall s2 mn2 rts2 i2 as2) = + eq opt s1 s2 && eq opt mn1 mn2 && eq opt rts1 rts2 && eq opt i1 i2 && eq opt as1 as2 eq opt (PrimaryMethodCall s1 e1 rts1 i1 as1) (PrimaryMethodCall s2 e2 rts2 i2 as2) = eq opt s1 s2 && eq opt e1 e2 && eq opt rts1 rts2 && eq opt i1 i2 && eq opt as1 as2 eq opt (SuperMethodCall s1 rts1 i1 as1) (SuperMethodCall s2 rts2 i2 as2) = @@ -1308,7 +1308,7 @@ instance (EqualityExtension p) => Equality (MethodInvocation p) where eq _ _ _ = False instance Located (MethodInvocation p) where - sourceSpan (MethodCall s _ _ _) = s + sourceSpan (MethodCall s _ _ _ _) = s sourceSpan (PrimaryMethodCall s _ _ _ _) = s sourceSpan (SuperMethodCall s _ _ _) = s sourceSpan (ClassMethodCall s _ _ _ _) = s diff --git a/Language/Java/Transformer.hs b/Language/Java/Transformer.hs index eaba1d6..21e19c2 100644 --- a/Language/Java/Transformer.hs +++ b/Language/Java/Transformer.hs @@ -51,8 +51,8 @@ class AnalyzedTransformer a where transformToAnalyzed :: IdentCollection -> a Parsed -> a Analyzed instance AnalyzedTransformer MethodInvocation where - transformToAnalyzed scope (MethodCall srcspan Nothing idnt args) = MethodCall srcspan Nothing idnt (map (transformToAnalyzed scope) args) - transformToAnalyzed scope (MethodCall srcspan (Just name) idnt args) = MethodCall srcspan (Just (classifyName name scope)) idnt (map (transformToAnalyzed scope) args) + transformToAnalyzed scope (MethodCall srcspan Nothing refTypes idnt args) = MethodCall srcspan Nothing refTypes idnt (map (transformToAnalyzed scope) args) + transformToAnalyzed scope (MethodCall srcspan (Just name) refTypes idnt args) = MethodCall srcspan (Just (classifyName name scope)) refTypes idnt (map (transformToAnalyzed scope) args) transformToAnalyzed scope (PrimaryMethodCall srcspan expr refTypes idnt args) = PrimaryMethodCall srcspan (transformToAnalyzed scope expr) refTypes idnt (map (transformToAnalyzed scope) args) transformToAnalyzed scope (SuperMethodCall srcspan refTypes idnt args) = SuperMethodCall srcspan refTypes idnt (map (transformToAnalyzed scope) args) transformToAnalyzed scope (ClassMethodCall srcspan name refTypes idnt args) = ClassMethodCall srcspan name refTypes idnt (map (transformToAnalyzed scope) args)