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

Enable Error Prone check: AnnotateFormatMethod #14933

Conversation

ksobolew
Copy link
Contributor

@ksobolew ksobolew commented Nov 7, 2022

Description

The idea of it is simple: when it sees a pair of a format string and format arguments passes to a format method, and these two are parameters of a method, it asks the method to be annotated as a format methods as well. This works in tandem with FormatStringAnnotation (see also: #9512) as it allows it to detect more cases of malformed format strings and misused format methods (of which it found plenty in trino-main and trino-spi; most of them are missed opportunities to use the format method, but there are a couple of actual bad format strings).

Requires: #15051, #15052

Non-technical explanation

Better compile-time checks and better code quality.

Release notes

(x) This is not user-visible or docs only and no release notes are required.
( ) Release notes are required, please propose a release note for me.
( ) Release notes are required, with the following suggested text:

# Section
* Fix some things. ({issue}`issuenumber`)

@ksobolew
Copy link
Contributor Author

ksobolew commented Nov 7, 2022

(I suppose I could split it into several smaller commits)

@kokosing
Copy link
Member

kokosing commented Nov 7, 2022

I suppose I could split it into several smaller commits

👍

@ksobolew ksobolew force-pushed the kudi/error-prone-annotate-format-method branch from 2005910 to a954267 Compare November 8, 2022 12:55
@ksobolew
Copy link
Contributor Author

ksobolew commented Nov 8, 2022

There you go: 14 commits :)

@ksobolew ksobolew force-pushed the kudi/error-prone-annotate-format-method branch 2 times, most recently from e66e37e to a2b64a1 Compare November 10, 2022 09:17
core/trino-spi/pom.xml Outdated Show resolved Hide resolved
Copy link
Member

@kokosing kokosing left a comment

Choose a reason for hiding this comment

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

LGTM for the below commits and the first commit. If you could extract them as separate PR I can merge it.

I left two comments that are required to move forward. I haven't reviewed entire PR.

image

@ksobolew
Copy link
Contributor Author

LGTM for the below commits and the first commit. If you could extract them as separate PR I can merge it.

Extracted as #15051

@ksobolew ksobolew force-pushed the kudi/error-prone-annotate-format-method branch from a2b64a1 to b57878d Compare November 16, 2022 14:46
@ksobolew
Copy link
Contributor Author

Flaky hit: #14487

@kokosing
Copy link
Member

Please rebase

@ksobolew ksobolew force-pushed the kudi/error-prone-annotate-format-method branch from b57878d to 6d0e340 Compare November 17, 2022 10:24
ksobolew added a commit to ksobolew/trino that referenced this pull request Feb 2, 2023
The `in` parameter recently changed type from `SliceInput` to
`DataSeekableInputStream`, the latter of which does not implement
`toString`. Error Prone complains with `ObjectToString` because of that.

Note that this only happens with trinodb#14933 merged, because otherwise the
`verify` method is not a `@FormatMethod` and Error Prone can't verify
correctness of its invocations.

Passing `location` instead of `in` as the format string arguments is
correct, because the stream is derived from a file at the location named
by `location`.
@ksobolew ksobolew force-pushed the kudi/error-prone-annotate-format-method branch from 6d0e340 to d28de07 Compare February 2, 2023 09:10
@@ -3163,7 +3166,9 @@ private Type coerceToSingleType(StackableAstVisitorContext<Context> context, Nod
return superType;
}

throw semanticException(TYPE_MISMATCH, node, message, firstType, secondType);
@SuppressWarnings("FormatStringAnnotation") // Error Prone wants the types of format arguments to be the same as where @FormatString is declared, but we need them to be different
TrinoException exception = semanticException(TYPE_MISMATCH, node, message, firstType, secondType);
Copy link
Member

Choose a reason for hiding this comment

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

new TrinoException?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know, I think it's valid, just hits some limitations of Java type system (or Error Prone's interpretation of it)

findepi pushed a commit that referenced this pull request Feb 2, 2023
The `in` parameter recently changed type from `SliceInput` to
`DataSeekableInputStream`, the latter of which does not implement
`toString`. Error Prone complains with `ObjectToString` because of that.

Note that this only happens with #14933 merged, because otherwise the
`verify` method is not a `@FormatMethod` and Error Prone can't verify
correctness of its invocations.

Passing `location` instead of `in` as the format string arguments is
correct, because the stream is derived from a file at the location named
by `location`.
See also: 2ec0529

This is currently not enforced in Error Prone because it requires
annotating more methods in `airlift:log` with `@FormatMethod`, but
that's hard to do, because it will change their semantics.
This annotation allows more cases to be checked by the
`FormatStringAnnotation` checker. Fixes up all the trivial cases where
they can be used as a format methods but weren't; there's also a less
trivial case of a method in `ExpressionAnalyzer` which also needs to be
annotated, but with a quirk. And also one helper method which now is
also a format method, even though it's not currently used this way
This is not entirely a "fix" because passing extra format arguments does
not cause failure at runtime, but it's still sloppy and error-prone
(and, fittingly, Error Prone will complain about it loudly).
Fixes up all the remaining trivial cases where is could be used as a
format method but wasn't.

Note that `PlanPrinter#formatFrame` cannot be (trivially) refactored to
call `appendDetails` directly, because it's used in two different
contexts.
The biggest one is the constructors of `ParquetCorruptionException`,
actually.
...and fix remaining trivial uses of them.
The idea of it is simple: when it sees a pair of a format string and
format arguments passes to a format method, and these two are parameters
of a method, it asks the method to be annotated as a format method as
well. This works in tandem with `FormatStringAnnotation` as it allows it
to detect more cases of malformed format strings and misused format
methods.
@ksobolew ksobolew force-pushed the kudi/error-prone-annotate-format-method branch from d28de07 to 5b04fba Compare February 3, 2023 10:12
@ksobolew
Copy link
Contributor Author

ksobolew commented Feb 3, 2023

I also added (at the beginning) a small-ish commit which changes some logger calls to use formatted messages. I though it was relevant (it also makes it easier for me to work on the main branch, because in my setup Error Prone complains about these).

Copy link
Member

@findepi findepi left a comment

Choose a reason for hiding this comment

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

I stopped reviewing before "Make some conditional uses of NodeRepresentation#appendDetails explicit"

I know i will have to re-review everything. Please split the PR into smaller, so that we don;t have to re-review same code multiple times.

@@ -571,7 +571,7 @@ private <T> T executeWithSession(SessionCallable<T> sessionCallable)
throw e;
}
long delay = Math.min(schedule.nextDelay().toMillis(), timeLeft);
log.warn(e.getMessage());
Copy link
Member

Choose a reason for hiding this comment

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

does log.warn(String) do any interpolation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

does log.warn(String) do any interpolation?

Not at this moment. I made a change upstream to make it easier to detect places like this, but it's a semantics change.

Copy link
Member

Choose a reason for hiding this comment

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

we should not do a semantics change.
what's the problem with log.warn(String) not doing any interpolation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what's the problem with log.warn(String) not doing any interpolation?

It's arguably inconsistent with the overload which does take parameters. If this overload didn't exist, or if it would be marked as a format method, it would behave the same way the String.format("abcde") behaves, which does do interpolation (the only interpolation it can do is "%%", though). But this is very arguable and people's expectations differ. I would expect this to be consistent across all invocations, but other people don't like it.

But the primary reason I would like log.warn(String) to be a format method is to allow Error Prone detect cases where the log message is constructed using concatenation. log.warn(e.getMessage()); is a casualty of this, unfortunately :)

@@ -110,7 +110,7 @@ public ListenableFuture<Void> execute(
propertyMetadata.decode(objectValue);
}
catch (RuntimeException e) {
throw semanticException(INVALID_SESSION_PROPERTY, statement, e.getMessage());
throw semanticException(INVALID_SESSION_PROPERTY, statement, "Invalid session property value '%s': %s", propertyName.toString(), e.getMessage());
Copy link
Member

Choose a reason for hiding this comment

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

SET SESSION is invoked for a particular session property.
we don't need to provide the property name in the exception message, do we?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The other places that throw in this method do provide the property name, so I wanted to be consistent.

Copy link
Member

Choose a reason for hiding this comment

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

awesome. can this be a separate change, or even separate PR?
this change is orthognal to error-prone

@ksobolew
Copy link
Contributor Author

ksobolew commented Feb 3, 2023

I know i will have to re-review everything. Please split the PR into smaller, so that we don;t have to re-review same code multiple times.

Sure. First two: #15962 and #15963

@ksobolew
Copy link
Contributor Author

ksobolew commented Feb 3, 2023

Next one: #15964

@ksobolew ksobolew closed this Feb 3, 2023
@ksobolew ksobolew deleted the kudi/error-prone-annotate-format-method branch February 3, 2023 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

3 participants