forked from typetools/checker-framework
-
Notifications
You must be signed in to change notification settings - Fork 29
Use adapted bounds for method type arguments #1850
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
Open
aosen-xiong
wants to merge
10
commits into
eisop:master
Choose a base branch
from
aosen-xiong:method-typevariables-from-use
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
1322f70
Use adapted bounds for method type arguments
aosen-xiong 8060201
Merge branch 'master' into method-typevariables-from-use
aosen-xiong f7cbccc
Reuse method receiver handling for type-variable bounds
aosen-xiong f49d910
Merge branch 'master' into method-typevariables-from-use
wmdietl df99a83
Fix doclint warnings
aosen-xiong b02a8e7
Install adapted executable type variables for viewpoint adaptation
aosen-xiong c3808e7
Merge branch 'master' into method-typevariables-from-use
aosen-xiong c23bd13
Leave AnnotatedTypeFactory unchanged
aosen-xiong 46e83c8
Leave BaseTypeVisitor unchanged
aosen-xiong ef1442d
Format ConstructorTypeVariableBounds with Spotless
aosen-xiong File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1265,7 +1265,7 @@ | |
| /** | ||
| * TypeVariableSubstitutor provides a method to replace type parameters with their arguments. | ||
| */ | ||
| protected TypeVariableSubstitutor createTypeVariableSubstitutor() { | ||
|
Check warning on line 1268 in framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java
|
||
| return new TypeVariableSubstitutor(); | ||
| } | ||
|
|
||
|
|
@@ -2398,6 +2398,52 @@ | |
| return res; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the method type-variable bounds adapted to the viewpoint of a method invocation. | ||
| * | ||
| * @param tree a method invocation | ||
| * @param invokedMethod the type of the invoked method | ||
| * @return the adapted method type parameter bounds | ||
| */ | ||
| public List<AnnotatedTypeParameterBounds> methodTypeVariableBoundsFromUse( | ||
| MethodInvocationTree tree, AnnotatedExecutableType invokedMethod) { | ||
| List<AnnotatedTypeParameterBounds> bounds = | ||
| CollectionsPlume.mapList( | ||
| AnnotatedTypeVariable::getBounds, invokedMethod.getTypeVariables()); | ||
|
|
||
| AnnotatedTypeMirror receiverType = getMethodReceiverType(tree); | ||
| if (viewpointAdapter != null && receiverType != null) { | ||
| viewpointAdapter.viewpointAdaptTypeParameterBounds(receiverType, bounds); | ||
| } | ||
| return bounds; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the receiver type used to viewpoint-adapt a method invocation. | ||
| * | ||
| * @param tree a method invocation tree | ||
| * @return the receiver type, or null if the invocation has no receiver | ||
| */ | ||
| private @Nullable AnnotatedTypeMirror getMethodReceiverType(MethodInvocationTree tree) { | ||
| ExecutableElement methodElt = TreeUtils.elementFromUse(tree); | ||
| if (ElementUtils.isStatic(methodElt)) { | ||
| return null; | ||
| } | ||
|
|
||
| AnnotatedTypeMirror receiverType = getReceiverType(tree); | ||
| if (receiverType == null | ||
| && (TreeUtils.isSuperConstructorCall(tree) | ||
| || TreeUtils.isThisConstructorCall(tree))) { | ||
| // super() and this() calls don't have a receiver, but they should be view-point adapted | ||
| // as if "this" is the receiver. | ||
| receiverType = getSelfType(tree); | ||
| } | ||
| if (receiverType != null && receiverType.getKind() == TypeKind.DECLARED) { | ||
| receiverType = applyCaptureConversion(receiverType); | ||
| } | ||
| return receiverType; | ||
| } | ||
|
|
||
| /** | ||
| * Creates and returns an AnnotatedNullType qualified with {@code annotations}. | ||
| * | ||
|
|
@@ -2733,17 +2779,7 @@ | |
| protected ParameterizedExecutableType methodFromUse( | ||
| MethodInvocationTree tree, boolean inferTypeArgs) { | ||
| ExecutableElement methodElt = TreeUtils.elementFromUse(tree); | ||
| AnnotatedTypeMirror receiverType = getReceiverType(tree); | ||
| if (receiverType == null | ||
| && (TreeUtils.isSuperConstructorCall(tree) | ||
| || TreeUtils.isThisConstructorCall(tree))) { | ||
| // super() and this() calls don't have a receiver, but they should be view-point adapted | ||
| // as if "this" is the receiver. | ||
| receiverType = getSelfType(tree); | ||
| } | ||
| if (receiverType != null && receiverType.getKind() == TypeKind.DECLARED) { | ||
| receiverType = applyCaptureConversion(receiverType); | ||
| } | ||
| AnnotatedTypeMirror receiverType = getMethodReceiverType(tree); | ||
|
|
||
| ParameterizedExecutableType result = | ||
| methodFromUse(tree, methodElt, receiverType, inferTypeArgs); | ||
|
|
||
72 changes: 72 additions & 0 deletions
72
framework/tests/viewpointtest/MethodTypeVariableBounds.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| import viewpointtest.quals.*; | ||
|
|
||
| public class MethodTypeVariableBounds { | ||
| static class Methods { | ||
| <T extends @ReceiverDependentQual Object> void noArg() {} | ||
|
|
||
| <T extends @ReceiverDependentQual Object> void withArg(T t) {} | ||
| } | ||
|
|
||
| void topReceiver( | ||
| @Top Methods methods, | ||
| @Top Object top, | ||
| @A Object a, | ||
| @B Object b, | ||
| @Bottom Object bottom) { | ||
| // @Top viewpoint-adapts @ReceiverDependentQual to @Lost, so only @Bottom is within the | ||
| // adapted method type parameter bound. | ||
| // :: error: (type.argument.type.incompatible) | ||
| methods.noArg(); | ||
|
|
||
| // :: error: (type.argument.type.incompatible) | ||
| methods.<@Top Object>withArg(top); | ||
|
|
||
| // :: error: (type.argument.type.incompatible) | ||
| methods.<@A Object>withArg(a); | ||
|
|
||
| // :: error: (type.argument.type.incompatible) | ||
| methods.<@B Object>withArg(b); | ||
|
|
||
| methods.<@Bottom Object>withArg(bottom); | ||
|
|
||
| // :: error: (type.arguments.not.inferred) | ||
| methods.withArg(top); | ||
|
|
||
| // :: error: (type.arguments.not.inferred) | ||
| methods.withArg(a); | ||
|
|
||
| // :: error: (type.arguments.not.inferred) | ||
| methods.withArg(b); | ||
|
|
||
| methods.withArg(bottom); | ||
| } | ||
|
|
||
| void aReceiver( | ||
| @A Methods methods, @Top Object top, @A Object a, @B Object b, @Bottom Object bottom) { | ||
| // @A viewpoint-adapts @ReceiverDependentQual to @A, so @A and @Bottom are within the | ||
| // adapted method type parameter bound. | ||
| // :: error: (type.argument.type.incompatible) | ||
| methods.noArg(); | ||
|
|
||
| // :: error: (type.argument.type.incompatible) | ||
| methods.<@Top Object>withArg(top); | ||
|
|
||
| methods.<@A Object>withArg(a); | ||
|
|
||
| // :: error: (type.argument.type.incompatible) | ||
| methods.<@B Object>withArg(b); | ||
|
|
||
| methods.<@Bottom Object>withArg(bottom); | ||
|
|
||
| // :: error: (type.arguments.not.inferred) | ||
| methods.withArg(top); | ||
|
|
||
| // :: error: (type.arguments.not.inferred) | ||
| methods.withArg(a); | ||
|
aosen-xiong marked this conversation as resolved.
|
||
|
|
||
| // :: error: (type.arguments.not.inferred) | ||
| methods.withArg(b); | ||
|
|
||
| methods.withArg(bottom); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cross-reference
getReceiverTypeand explain differences!