forked from typetools/checker-framework
-
Notifications
You must be signed in to change notification settings - Fork 11
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
Implement @ThrowsException annotation #135
Open
d367wang
wants to merge
14
commits into
opprop:master
Choose a base branch
from
d367wang:throw-exception-annotation
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 all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
b0f69e7
initial implementation of ThrowsException annotation
d367wang cd3eeb5
add test cases
d367wang ae80a09
remove redundant <p> in ThrowsException Javadoc
d367wang f256c1d
modify issue 2076 test case
d367wang 4865454
Merge branch 'master' of https://github.com/opprop/checker-framework …
d367wang 6a8bde0
add edges for @ThrowsException and @TerminatesExecution method
d367wang 41ae712
link node with @TerminatesExecution to exceptional-exit block
d367wang f306464
resolve conficts and merge with opprop/master
d367wang 86bca15
Merge branch 'master' of https://github.com/opprop/checker-framework …
d367wang 11721c1
remove flag exitImmediately and recover the handling of @TerminatesEx…
d367wang 3aff59a
restrict value of @ThrowsException to be subtype of RuntimeException
d367wang 750c50d
Merge branch 'master' of https://github.com/opprop/checker-framework …
d367wang be5df7e
redefine @ThrowsException semantic
d367wang dba393f
update test case Issue2076
d367wang 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 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,28 @@ | ||
// Test case for issue #2076: | ||
// https://github.com/typetools/checker-framework/issues/2076 | ||
|
||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
import org.checkerframework.checker.nullness.qual.Nullable; | ||
import org.checkerframework.dataflow.qual.ThrowsException; | ||
|
||
public class Issue2076 { | ||
private @Nullable Object mObj = null; | ||
|
||
@ThrowsException(NullPointerException.class) | ||
public void buildAndThrowNPE() {} | ||
|
||
public @NonNull Object m1() { | ||
if (mObj == null) { | ||
buildAndThrowNPE(); | ||
} | ||
return mObj; | ||
} | ||
|
||
public void m2(@Nullable Object obj) { | ||
int n; | ||
if (obj == null) { | ||
buildAndThrowNPE(); | ||
} | ||
n = obj.hashCode(); | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
checker/tests/nullness/flow/ThrowExceptionAnnotationTest.java
This file contains 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,68 @@ | ||
import java.io.IOException; | ||
import org.checkerframework.checker.nullness.qual.Nullable; | ||
import org.checkerframework.dataflow.qual.ThrowsException; | ||
|
||
public class ThrowExceptionAnnotationTest { | ||
private @Nullable Object mObj = null; | ||
|
||
@ThrowsException(IOException.class) | ||
public void foo() throws IOException {} | ||
|
||
@ThrowsException(NullPointerException.class) | ||
public void bar() {} | ||
|
||
public void m1(@Nullable Object obj) { | ||
int n; | ||
try { | ||
foo(); | ||
|
||
// :: error: (dereference.of.nullable) | ||
int x = obj.hashCode(); | ||
|
||
} catch (IOException e) { | ||
// :: error: (dereference.of.nullable) | ||
int x = obj.hashCode(); | ||
} finally { | ||
} | ||
} | ||
|
||
public void m2(@Nullable Object obj) { | ||
int n; | ||
try { | ||
foo(); | ||
|
||
} catch (IOException e) { | ||
} finally { | ||
// :: error: (dereference.of.nullable) | ||
int x = obj.hashCode(); | ||
} | ||
} | ||
|
||
public void m3(@Nullable Object obj) { | ||
int n; | ||
try { | ||
foo(); | ||
|
||
} catch (IOException e) { | ||
} finally { | ||
} | ||
|
||
// :: error: (dereference.of.nullable) | ||
int x = obj.hashCode(); | ||
} | ||
|
||
public void m4(@Nullable Object obj) throws IOException { | ||
int n; | ||
if (obj == null) { | ||
foo(); | ||
} | ||
n = obj.hashCode(); | ||
} | ||
|
||
public void m5() { | ||
if (mObj == null) { | ||
bar(); | ||
} | ||
int x = mObj.hashCode(); | ||
} | ||
} |
This file contains 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
56 changes: 56 additions & 0 deletions
56
dataflow/src/main/java/org/checkerframework/dataflow/qual/ThrowsException.java
This file contains 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,56 @@ | ||
package org.checkerframework.dataflow.qual; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* {@code ThrowsException} is a method declaration annotation indicating that a method always throws | ||
* an exception. | ||
* | ||
* <p>The annotation enables flow-sensitive type refinement to be more precise. | ||
* | ||
* <p>For example, given a method {@code throwsNullPointerException()} defined as | ||
* | ||
* <pre> | ||
* public throwsNullPointerException() { | ||
* throw new NullPointerException(); | ||
* } | ||
* </pre> | ||
* | ||
* then after the following code | ||
* | ||
* <pre> | ||
* if (x == null) { | ||
* throwsNullPointerException(); | ||
* } | ||
* </pre> | ||
* | ||
* the Nullness Checker can determine that {@code x} is non-null. | ||
* | ||
* <p>The annotation's value represents the type of exception that the method <b>unconditionally</b> | ||
* throws. The type of the exception can be checked exception, unchecked exception and error. | ||
* Whichever the case is, Checker Framework always assumes the type specified in {@code | ||
* ThrowsException} annotation overrides the one specified in the method signature. | ||
* | ||
* <p>Note that when the method itself already declares to throw a checked exception, then the type | ||
* of exception specified in {@code ThrowsException} annotation is required to be | ||
* <em>compatible</em>, means the type specified in {@code ThrowsException} annotation is a subtype | ||
* of the one specified in the method declaration. Otherwise Checker Framework issues an error. | ||
* | ||
* <p>The annotation is a <em>trusted</em> annotation, meaning that it is not checked whether the | ||
* annotated method really unconditionally throws an exception. | ||
* | ||
* <p>This annotation is inherited by subtypes, just as if it were meta-annotated with | ||
* {@code @InheritedAnnotation}. | ||
*/ | ||
// @InheritedAnnotation cannot be written here, because "dataflow" project cannot depend on | ||
// "framework" project. | ||
@Documented | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) | ||
public @interface ThrowsException { | ||
Class<? extends Throwable> value(); | ||
} |
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.
If
value
is changing to array, maybe this part needs to be updated