-
Enhancement
-
Resolution: Fixed
-
P4
-
None
-
b46
-
Not verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8085309 | emb-9 | Maurizio Cimadamore | P4 | Resolved | Fixed | team |
Diagnostic objects are created from resource keys in a property file somewhere in langtools. This means that, when creatinga diagnostic (i.e. an error message), the programmer has to type in the resource key associated with the diagnostic to be generated - example:
log.error(pos, "abstract.cant.be.instantiated", t.tsym);
This approach is problematic for a number of reasons:
* a typo in the above string literal would lead to a problem during diagnostic localization (javac will display an error saying that no resource key with that name exists)
* argument arity mismatch; diagnostic resources have placeholder which can be used to add in extra information - example:
compiler.err.abstract.cant.be.instantiated=\
{0} is abstract; cannot be instantiated
If not enough arguments are supplied to the diagnostic factory method, javac will generate another error saying that it could not find a replacement for one of the placeholders in the diagnostic text. Conversely, if there are too many arguments (more than the number of the placeholders), no message will be displayed, but the raw diagnostic output (used during testing) will show all the additional arguments, making testing more brittle.
* argument kind mismatch; the most subtle error of all: if the compiler supplies a diagnostic argument that is fundamentally incompatible with what is expected by the diagnostic, the readability of the diagnostic might be seriously compromised - i.e. what if, in the above diagnostic, the compiler passed in the string "Hello!" as a placeholder? That would lead to the following error message being displayed:
Hello! is abstract; cannot be instantiated
No compiler error will occur here as the placeholder replacement is a purely string-based mechanism - as long as you have enough replacements, it will always succeed.
All this is very brittle and error-prone.
log.error(pos, "abstract.cant.be.instantiated", t.tsym);
This approach is problematic for a number of reasons:
* a typo in the above string literal would lead to a problem during diagnostic localization (javac will display an error saying that no resource key with that name exists)
* argument arity mismatch; diagnostic resources have placeholder which can be used to add in extra information - example:
compiler.err.abstract.cant.be.instantiated=\
{0} is abstract; cannot be instantiated
If not enough arguments are supplied to the diagnostic factory method, javac will generate another error saying that it could not find a replacement for one of the placeholders in the diagnostic text. Conversely, if there are too many arguments (more than the number of the placeholders), no message will be displayed, but the raw diagnostic output (used during testing) will show all the additional arguments, making testing more brittle.
* argument kind mismatch; the most subtle error of all: if the compiler supplies a diagnostic argument that is fundamentally incompatible with what is expected by the diagnostic, the readability of the diagnostic might be seriously compromised - i.e. what if, in the above diagnostic, the compiler passed in the string "Hello!" as a placeholder? That would lead to the following error message being displayed:
Hello! is abstract; cannot be instantiated
No compiler error will occur here as the placeholder replacement is a purely string-based mechanism - as long as you have enough replacements, it will always succeed.
All this is very brittle and error-prone.
- backported by
-
JDK-8085309 Devise scheme for better diagnostic creation
-
- Resolved
-
- relates to
-
JDK-8055388 Internationalization of sjavac output
-
- Open
-