\section{Type Inference for Java}
%The goal is to find a correct typing for a given Java program.
Type inference for Java has many use cases and could be used to help programmers by inserting correct types for them,
Finding better type solutions for already typed Java programs (for example more generical ones),
or allowing to write typeless Java code which is then type infered and thereby type checked by our algorithm.
The algorithm proposed in this paper can determine a correct typing for the untyped Java source code example shown in figure \ref{fig:intro-example-typeless}.
Our algorithm is also capable of finding solutions involving wildcards as shown in figure \ref{fig:intro-example-typed}.
This paper extends a type inference algorithm for Featherweight Java (\cite{TIforFGJ}) by adding wildcards.
The last step to create a type inference algorithm compatible to the Java type system.
The algorithm is a modified version of the \unify{} algorithm presented in \cite{plue09_1}.
The algorithm is a slightly improved version of the one in \cite{TIforFGJ} and added wildcard support.
Wildcards are existential types which have to be \textit{unpacked} before they can be used.
In Java this is done implicitly by a process called capture conversion \cite{JavaLanguageSpecification}.
The type system in \cite{WildcardsNeedWitnessProtection} makes this process explicit by using \texttt{let} statements.
Our type inference algorithm will accept an input program without let statements and add them where necessary.
The input to the type inference algorithm is a Featherweight Java program (example in figure \ref{fig:nested-list-example-typeless}) conforming to the syntax shown in figure \ref{fig:syntax}.
Type inference adds \texttt{let} statements in a fashion similar to the Java capture conversion \cite{WildFJ}.
We wrap every parameter of a method invocation in \texttt{let} statement unknowing if a capture conversion is necessary (see figure \ref{fig:nested-list-example-let}).
The \fjtype{} algorithm calculates constraints based on this intermediate representation,
which are then solved by the \unify{} algorithm
resulting in a correctly typed program (see figure \ref{fig:nested-list-example-typed}).
We figured the \texttt{let} statements to be obsolete for our use case.
Once the type inference algorithm found a correct type solution they can be inferred by the given type annotations.
% 1. Constraint generation
% 2. Insert typing
% # Showing soundness
% Every program in our calculus can be converted to a WildcardsNeedWitnessProtection program
\begin{figure}[tp]
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=fgj]
class List {
List add(A v) { ... }
}
class Example {
m(l, la, lb){
return l
.add(la.add(1))
.add(lb.add("str"));
}
}
\end{lstlisting}
\caption{Java method with missing return type}
\label{fig:nested-list-example-typeless}
\end{subfigure}
~
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=tfgj]
class List {
List add(A v) { ... }
}
class Example {
m(l, la, lb){
return let r2 : (*@$\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$@*) = {
let r1 : (*@$\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$@*) = l in {
let p1 : (*@$\exptype{List}{\type{Integer}}$@*) = {
let xa = la in xa.add(1)
} in x1.add(p1)
} in {
let p2 = {
let xb = lb in xb.add("str")
} in x2.add(p2)
};
}
}
\end{lstlisting}
\begin{lstlisting}[style=tfgj]
class List {
List add(A v) { ... }
}
class Example {
m((*@$\exptype{List}{\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}}$@*) l, List la, List lb){
return l
.add(la.add(1))
.add(lb.add("str"));
}
}
\end{lstlisting}
\caption{Featherweight Java Representation}
\label{fig:nested-list-example-let}
\end{subfigure}
~
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=tfgj]
class List {
List add(A v) { ... }
}
class Example {
m(List> l, List la, List lb){
return l
.add(la.add(1))
.add(lb.add("str"));
}
}
\end{lstlisting}
\caption{Java Representation}
\label{fig:nested-list-example-typed}
\end{subfigure}
%\caption{Example code}
%\label{fig:intro-example-code}
\end{figure}
%TODO
% The goal is to proof soundness in respect to the type rules introduced by \cite{aModelForJavaWithWildcards}
% and \cite{WildcardsNeedWitnessProtection}.
\begin{figure}[tp]
\begin{subfigure}[t]{0.49\linewidth}
\begin{lstlisting}[style=fgj]
genList() {
if( ... ) {
return new List();
} else {
return new List();
}
}
\end{lstlisting}
\caption{Java method with missing return type}
\label{fig:intro-example-typeless}
\end{subfigure}
~
\begin{subfigure}[t]{0.49\linewidth}
\begin{lstlisting}[style=tfgj]
List> genList() {
if( ... ) {
return new List();
} else {
return new List();
}
}
\end{lstlisting}
\caption{Correct type}
\label{fig:intro-example-typed}
\end{subfigure}
%\caption{Example code}
%\label{fig:intro-example-code}
\end{figure}
Existential types have to be \textit{unpacked} before they can be used \cite{WildcardsNeedWitnessProtection}.
In Java this is done implicitly.
%Our type inference algorithm has to add let statements surrounding method invocations.
\begin{figure}[tp]
\begin{constraintset}
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=fgj]
List super Integer> ls = ...;
ls.add(new Integer());
\end{lstlisting}
\caption{Method invocation}
\label{fig:intro-example-typeless}
\end{subfigure}
\end{constraintset}
\begin{constraintset}
\begin{subfigure}[t]{\linewidth}
\begin{lstlisting}[style=tfgj]
List super Integer> ls = ...;
let x : (*@ $\wctype{\wildcard{X}{\texttt{Object}}{\texttt{Integer}}}{List}{\rwildcard{X}}$ @*) = ls in x.add(new Integer());
\end{lstlisting}
\caption{Capture Conversion by \texttt{let}-statement}
\label{fig:intro-example-typed}
\end{subfigure}
\end{constraintset}
\end{figure}
% \subsection{Wildcards}
% Java subtyping involving generics is invariant.
% For example \texttt{List} is not a subtype of \texttt{List