Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fixes #3099] Added ability to solve type with a list of expected type arguments #3213

Merged

Conversation

4everTheOne
Copy link
Contributor

Currently, when JP SS is trying to solve a type, it doesn't take into consideration the number of type arguments it expects to find. This have been an issue that was reported in #3099 where we can have two different classes/interfaces with the same name. In this scenario JP SS will return the first one it finds, and not the one that fits the expected type.

This PRs adds a new method in context to solve a type with the expected type arguments. If the type arguments is provided it will only find a type where the type arguments matchs the expected.

Examples

Lets imagine we have two declarations of Foo. We have com Alpha.Foo and Beta.Foo<T> where Foo is a inner class of Alpha and Foo<T> is a inner class of Beta. If we want to solve Alpha.Foo without arguments we can solve it like:

context.solveType("Foo", Collections.emptyList());

if we want to resolve it as Beta.Foo<T> we execute:

List<ResolvedType> expectedTypeArguments = ...;
context.solveType("Foo", expectedTypeArguments);

If we just want it to be resolved and don't care how many arguments it has we can use:

context.solveType("Foo"); // or context.solveType("Foo", null);

Implementation notes

  • The logic that was previously in ClassOrInterfaceDeclarationContext was moved to JavaParserTypeDeclarationAdapter, because AnnotationDeclarationContext should also follow the same rules;
  • JavaParserTypeDeclarationAdapter was reordered to match the expected behavior (the same order that was previously in ClassOrInterfaceDeclarationContext).

Related Issues

@4everTheOne 4everTheOne marked this pull request as draft March 30, 2021 11:23
@4everTheOne
Copy link
Contributor Author

This PR is not ready to be merged. This needs more tests to make sure the intended behavior is covered.

@codecov
Copy link

codecov bot commented May 21, 2021

Codecov Report

Merging #3213 (6da3f99) into master (3471517) will increase coverage by 0.012%.
The diff coverage is 90.909%.

Impacted file tree graph

@@               Coverage Diff               @@
##              master     #3213       +/-   ##
===============================================
+ Coverage     57.313%   57.326%   +0.012%     
- Complexity      2671      2680        +9     
===============================================
  Files            635       635               
  Lines          33566     33576       +10     
  Branches        5790      5791        +1     
===============================================
+ Hits           19238     19248       +10     
+ Misses         12275     12274        -1     
- Partials        2053      2054        +1     
Flag Coverage Δ
AlsoSlowTests 57.326% <90.909%> (+0.012%) ⬆️
javaparser-core 52.460% <ø> (ø)
javaparser-symbol-solver 36.749% <90.909%> (+0.018%) ⬆️
jdk-10 57.322% <90.909%> (+0.012%) ⬆️
jdk-11 57.322% <90.909%> (+0.012%) ⬆️
jdk-12 57.322% <90.909%> (+0.012%) ⬆️
jdk-13 57.319% <90.909%> (+0.009%) ⬆️
jdk-14 57.322% <90.909%> (+0.012%) ⬆️
jdk-15 57.322% <90.909%> (+0.015%) ⬆️
jdk-16 57.322% <90.909%> (+0.018%) ⬆️
jdk-8 57.324% <90.909%> (+0.012%) ⬆️
jdk-9 57.322% <90.909%> (+0.012%) ⬆️
macos-latest 57.314% <90.909%> (+0.012%) ⬆️
ubuntu-latest 57.311% <90.909%> (+0.012%) ⬆️
windows-latest 57.305% <90.909%> (+0.012%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...vaparsermodel/contexts/CompilationUnitContext.java 78.395% <ø> (ø)
...vaparser/symbolsolver/core/resolution/Context.java 86.170% <75.000%> (-0.787%) ⬇️
...del/contexts/JavaParserTypeDeclarationAdapter.java 90.654% <90.476%> (-1.265%) ⬇️
...contexts/AbstractMethodLikeDeclarationContext.java 75.675% <100.000%> (ø)
...ermodel/contexts/AnnotationDeclarationContext.java 63.636% <100.000%> (ø)
...del/contexts/AnonymousClassDeclarationContext.java 73.170% <100.000%> (ø)
...l/contexts/ClassOrInterfaceDeclarationContext.java 88.461% <100.000%> (ø)
...xts/ClassOrInterfaceDeclarationExtendsContext.java 100.000% <100.000%> (ø)
...vaparsermodel/contexts/EnumDeclarationContext.java 80.000% <100.000%> (ø)
...r/javaparsermodel/contexts/FieldAccessContext.java 65.853% <100.000%> (ø)
... and 3 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3471517...6da3f99. Read the comment docs.

@4everTheOne 4everTheOne marked this pull request as ready for review November 1, 2022 12:49
@4everTheOne
Copy link
Contributor Author

Ready to be reviewed! :)

@jlerbsc
Copy link
Collaborator

jlerbsc commented Nov 1, 2022

Can you reorganize your commits?

@4everTheOne
Copy link
Contributor Author

Updated commit history to simplify reading

}
}
}

// Check if the node implements other types
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably "Check if the node extends other types"


assertTrue(alphaContext.solveType("Foo").isSolved());
assertTrue(alphaContext.solveType("Foo", Collections.emptyList()).isSolved());
assertFalse(alphaContext.solveType("Foo", Collections.singletonList(ResolvedPrimitiveType.INT)).isSolved());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the type "Foo" resolved in this context?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this assertions, there are three things being confirmed:

assertTrue(alphaContext.solveType("Foo").isSolved());
We are making sure, that we are retro-compatible, so if someones is using the API without type parameters, the type is solved using the previous rules.

assertTrue(alphaContext.solveType("Foo", Collections.emptyList()).isSolved());
Looking at the class definition, the class Foo does not have type parameters. In this test, we make surethat trying to resolve it with a empty list it's resolved. Note that a empty list in type arguments is the same as saying it does not have type parameter.

assertFalse(alphaContext.solveType("Foo", Collections.singletonList(ResolvedPrimitiveType.INT)).isSolved());
Test to make sure, if we try to resolve Foo with a type parameter, it's not resolved since the declaration says it does not have one.

ClassOrInterfaceDeclarationContext betaContext = new ClassOrInterfaceDeclarationContext(beta, typeSolver);

assertTrue(betaContext.solveType("Foo").isSolved());
assertFalse(betaContext.solveType("Foo", Collections.emptyList()).isSolved());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the expected result?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering now that Foo has a type argument (T), this test should Fail.
Since this assertion, is trying to solve a type "Foo" that does not have any type parameters.

This would be equivalent of doing this in IDE, which is not possible:

class Foo<T> {}

Foo<> fooObject;


assertTrue(betaContext.solveType("Foo").isSolved());
assertFalse(betaContext.solveType("Foo", Collections.emptyList()).isSolved());
assertTrue(betaContext.solveType("Foo", Collections.singletonList(ResolvedPrimitiveType.INT)).isSolved());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the expected result?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering now that Foo has a type argument (T), this test should be valid, since this assertion, is trying to solve a type "Foo" that does have a type parameters of integer type.

This would be equivalent of doing this in IDE, which is possible:

class Foo<T> {}

Foo<Integer> fooObject;

@jlerbsc jlerbsc merged commit f45b449 into javaparser:master Nov 2, 2022
@jlerbsc
Copy link
Collaborator

jlerbsc commented Nov 2, 2022

Thank you for this contribution.

@jlerbsc jlerbsc added this to the next release milestone Nov 2, 2022
@jlerbsc jlerbsc added PR: Added A PR that introduces new behaviour (e.g. functionality, tests) PR: Fixed A PR that offers a fix or correction labels Nov 2, 2022
@4everTheOne 4everTheOne deleted the fix/illegal-argument-exception branch November 2, 2022 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: Added A PR that introduces new behaviour (e.g. functionality, tests) PR: Fixed A PR that offers a fix or correction
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IllegalArgumentException when solving ClassOrInterfaceType
2 participants