the declared target of the call site. This is needed to make sure
forName targets loaded with the Application loader get resolved to point
to the real metod reference for forName.
this issue actually manifested itself in the Kawa Chess program, and so
I have added an assertion to make sure this resolution is done properly.
Fixes#322
We add an option `createPhantomSuperclasses` to `ClassHierarchy`. When set, if a superclass is missing, we create a new `PhantomClass` in its place and allow the subclass to be added.
To use, you can create the `ClassHierarchy` with the new `ClassHierarchyFactory.makeWithPhantom` methods.
Boxing a primitive using the constructor ("new Integer(4)") always
creates a distinct new boxed instance. That's rarely what you need,
and in fact all of those constructors have been deprecated in Java 9.
Using the static "valueOf" method instead ("Integer.valueOf(4)") can
give better performance by reusing existing instances. You no longer
get a unique boxed object, but generally that's OK.
The existing code worked fine under Java 8, but Java 9 fails to
resolve type constraints unless it has more explicit information about
at least one of the arguments to anyOf. Weird.
If multiple tests both write to "/tmp/cg.txt" (for example), then
these tests cannot safely run concurrently. That never used to be a
problem with Maven, since our Maven tests were all strictly sequential
anyway. But parallelized testing using Gradle requires that we do
better. Fortunately, Java has perfectly reasonable APIs for
generating uniquely-named temporary files and directories.
If multiple tests both write to "/tmp/cg.txt" (for example), then
these tests cannot safely run concurrently. That never used to be a
problem with Maven, since our Maven tests were all strictly sequential
anyway. But parallelized testing using Gradle requires that we do
better. Fortunately, Java has perfectly reasonable APIs for
generating uniquely-named temporary files and directories.
Eclipse's automated code clean-up tool did most of the heavy lifting
here: it specifically has a clean-up option for converting functional
interfaces to lambdas. I merely had to revert the automated changes
for a single enumeration class for which it produced invalid results,
and for a few test inputs that apparently aren't set up to be compiled
with Java 8.
Casting to `Foo<Bar>` results in an unchecked-cast warning due to Java
generics type erasure. However, sometimes we don't really need a
`Foo<Bar>`, but could simply use any `Foo<?>`. Casting to the latter
creates no warning.
We already have plenty of examples of Serializable classes with this
field, and the vast majority of those fields have generated IDs rather
than "1L". From this I infer that using proper serialVersionUID
fields is considered appropriate WALA coding style.
One such annotation was unnecessary because the thing it was
suppressing no longer happens. Any future unnecessary warning
suppressions of this kind will now be treated as errors.
The other annotations were unnecessary because the corresponding
warnings have been disabled entirely in the Eclipse projects'
configurations. There seems to be no way to tell Eclipse to treat
these as anything other than "info" diagnostics in the future, so
that's how they will remain.
In general, my approach was to try to eliminate each unused parameter
using Eclipse's "Change Method Signature" refactoring. That did not
always succeed: a parameter may be unused in some base class method,
but then be used in subclass's override of that method. In cases
where refactoring to eliminate a parameter failed, I instead annotated
the parameter with '@SuppressWarnings("unused")' to silence the
warning.
Note: this group of changes creates a significant risk of
incompatibility for third-party WALA code. Some removed parameters
change externally-visible APIs. Furthermore, these changes do not
necessarily lead to Java compilation errors. For example, suppose
third-party code subclasses a WALA class or interface, overrides a
method, but does not annotate that method as @Override. Removing a
parameter means that the third-party method no longer overrides. This
can quietly change code behavior without compile-time errors or
warnings. This is exactly why one should use @Override wherever
possible, but we cannot guarantee that third-party WALA users have
done that.
Unnecessary "throws" declarations tend to cascade. If foo() calls
bar() and bar() falsely declares that it might throw IOException, that
often leads a programmer to declare that foo() might throw IOException
as well. Fixing the bar() throws declaration then reveals that we can
fix the foo() throws declaration too. By the time we reach a fixed
point with cleaning these up, we have removed roughly 320 unnecessary
throws declarations.
In a few cases, this cleanup even lets us remove entire "try
... catch" statements where the only thing being caught was an
exception that we now statically know cannot be thrown. Nice!
In Eclipse project configurations, upgrade any future such shenanigans
from warnings to errors. Now that we've fixed this, we don't want it
coming back again.
There is a potential drawback to this change. Conceivably some public
WALA API entry point might have declared that it could throw some
exception merely to reserve the *option* of throwing that exception in
third-party code that subclasses and overrides the API entry point in
question. I have no idea whether this is a significant concern in
practice, though.
The fix is to add "static" where appropriate, of course. I've also
simplified calls to such methods to reflect the fact that they no
longer need a specific object to call the method on.
In projects that contain test inputs, I've left the non-static
declarations unchanged, and instead downgraded the warning to be
ignored. In all other projects, this warning has been upgraded to an
error.
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.