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

Added annotations to org.apache.dubbo.common.io #1

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

Maxi17
Copy link

@Maxi17 Maxi17 commented Jun 14, 2019

Apache Dubbo io case study

@kelloggm kelloggm self-requested a review June 20, 2019 15:49
@kelloggm kelloggm self-assigned this Jun 20, 2019
Copy link
Collaborator

@kelloggm kelloggm left a comment

Choose a reason for hiding this comment

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

Overall this is in good shape, but there are a few (mostly minor) changes and questions that I have before I'm ready to merge.

<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker</artifactId>
<version>2.8.1</version>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should be latest release when this is merged (so 2.8.2 right now)

@@ -434,7 +440,10 @@ public static String bytes2hex(byte[] bs, int off, int len) {
* @param len length.
* @return byte array.
*/
public static byte[] hex2bytes(final String str, final int off, int len) {
@SuppressWarnings({"argument.type.incompatible", "array.access.unsafe.high"}) /*
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here and elsewhere: can you preface these suppress warning annotations with index: (i.e. @SuppressWarnings({"index:argument.type.incompatible", "index:array.access.unsafe.high"})). That way if someone else typechecks this library with a different checker, their warnings won't be suppressed. It's also just good style.

}
DECODE_TABLE_MAP.put(hash, ret);
}
return ret;
}

@SuppressWarnings({"array.length.negative", "argument.type.incompatible"}) // Preconditions are enforced by the only caller of this private method.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why can't the preconditions be written as annotations?

@@ -873,6 +901,10 @@ private static int indexOf(char[] cs, char c) {
return -1;
}

@SuppressWarnings({"array.access.unsafe", "argument.type.incompatible"}) /*
#1. ret has length of 128, the loop stops at position 127
#2. It was verified that code has at least 64 characters. The ascii value of a chr is at most 127, which is a valid index for ret
Copy link
Collaborator

Choose a reason for hiding this comment

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

The checker ought to know that the maximum value of a char is 127. If that doesn't work, I would file a bug with a test case like:

void test(int @MinLen(128) [] array, @NonNegative char c) {
    array[c];
}

/**
* UnsafeByteArrayInputStream.
*/
public class UnsafeByteArrayInputStream extends InputStream {
protected byte[] mData;

protected int mPosition, mLimit, mMark = 0;
protected @IndexOrHigh("this.mData") int mPosition, mMark, mLimit = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not annotated mPosition as @LessThan("this.mLimit")? You use that fact to justify several warning suppressions later in the file.

/**
* Thread-unsafe StringReader.
*/
public class UnsafeStringReader extends Reader {
private String mString;

private int mPosition, mLimit, mMark;
private @IndexOrHigh("this.mString") int mPosition,mLimit, mMark;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Missing space in this line

@@ -34,7 +40,9 @@ public UnsafeStringReader(String str) {
}

@Override
public int read() throws IOException {
@SuppressWarnings({"return.type.incompatible", "argument.type.incompatible", "compound.assignment.type.incompatible"})
// A char is always greater than 0 and it has been previously verified that mPosition is less than the length of mString
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where/how was that verified? If it's a precondition of the method, you should express it as an annotation instead.

}

@Override
public long skip(long ns) throws IOException {
@SuppressWarnings("compound.assignment.type.incompatible") // n is valid because it was previously verified
public @NonNegative long skip(long ns) throws IOException {
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 convinced that this is the right specification for this method: I would expect that the argument ns should be @NonNegative. Why isn't that the case here?

@@ -80,7 +84,8 @@ public Writer append(CharSequence csq) {
}

@Override
public Writer append(CharSequence csq, int start, int end) {
@SuppressWarnings("argument.type.incompatible") // The documentation is inherited from the overridden method.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand what you mean by this? Are you saying that the spec on the inherited method is wrong?

Copy link
Author

Choose a reason for hiding this comment

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

I tried to say that the implementation of this method is similar to the overridden one, which is part of the JDK. That one has a documentation and specifies that the method can throw an IndexOutOfBoundsException

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you clarify in the comment exactly where the warning is being suppressed, and how the exception can be thrown? Alternatively, you could add a link to the JDK documentation on the web so that a reader can easily read it themselves. As it is now, it's very confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants