Thanks Alan! This sounds great.
On 4/5/2019 5:49 PM, Alan Malloy wrote:
Hello again, amber-spec-experts. I plan a follow-up of my recent
records report, this time looking at sealed types (from the same
proposal). This time, I am seeking suggestions before I get started.
In particular, for records, it was easy to find @AutoValue classes:
they have a well-defined annotation that I can search for.
Regrettably, we did not have the foresight to publish
a @TODOMigrateToSealedType annotation, and so I will have to use
heuristics to search for code that could have been written "better" if
sealed types were available.
So, I am looking for suggestions on two main axes (though feel free to
pipe in if there is a third axis you think I've missed):
1. Code patterns that you think people would write today, where
tomorrow they might instead use sealed types
2. What questions we can ask about occurrences of these code
patterns, having identified a list of them
We have brainstormed a few ideas for (1) already:
* if (x instanceof Foo) {} else if (x instanceof Bar) {} ...,
especially when the set of classes tested for covers every known
subclass of x's declared type
* Visitors. A visitor class is not itself sealed, but if a class or
interface C contains methods which accept a visitor as an
argument, we guess C probably wants to be sealed. Some heuristics
for identifying a visitor are obvious (it has Visitor in the name,
it has methods named visitXXX()...), but I am open to others
* A DIY "sealed" type might be an abstract class with only
package-private constructors, and a number of subclasses in the
same package each with public constructors
And some questions to ask in (2):
* How common are each of these things?
* Are implementations usually declared in the same package? Same
source file? Nested in the same class? Or scattered all over?
* Are sealed type hierarchies typically exactly 2 levels deep (one
interface, many direct subclasses), or is there an intricate tree?
In case it helps you refine your suggestions, here is a brief
description of my methodology and the tools available to me, stating
explicitly some stuff I glossed over in the records report earlier
this week.
We have a compiler plugin that accepts as input a visitor for javac
Tree objects. I declare what kinds of Trees I am interested in, and
the structure of data that I will produce as output (specified as a
protobuf file). Then, I write my visitor, and a batch job calls its
visit function for each Tree of interest in the whole of Google's
codebase. The output records it produces get stored in (an internal
version of) Google BigQuery. Finally, I learn about the results by
writing SQL-ish queries against the BigQuery database. The quickest
way to iterate is to just refine my queries, but the feedback loop on
improving my visitor is not too bad either - I think I went through 12
versions of my @AutoValue visitor before I had everything I wanted.
So, I hope that background helps, or that some of you just found it
interesting for its own sake. I am looking forward to any suggestions
you may have, and to finding out how badly (or not!) we have been
missing sealed types.