To set the scene, it might be useful to provide a couple of examples of converted code, illustrating the challenges.
Here's a rather simple method in Java:
@Override
public AtomicSequence atomize() throws XPathException {
return tree.getTypedValueOfElement(this);
}
And here is the C# code that we generate:
public override net.sf.saxon.om.AtomicSequence atomize() { return tree.getTypedValueOfElement(this); }
Nothing very remarkable there, but it actually requires a fair bit of analysis of the Java code to establish that the conversion in this case is fairly trivial. For example:
The class name AtomicSequence
has been expanded; this requires analysis
of the import
declarations in the module, and it can't be done without knowing the full
set of packages and classes available.
The @Override
declaration is optional in Java, but optional
is mandatory in C#; moreover they don't mean quite the same thing, for example when overriding
methods defined in an interface or abstract class.
The conversion of Java this
to C# this
works here,
but there are other contexts where it doesn't work.
Now let's take a more complex example. Consider the following Java code:
public Map<String, Sequence> getDefaultOptions() { Map<String, Sequence> result = new HashMap<>(); for (Map.Entry<String, Sequence> entry : defaultValues.entrySet()) { result.put(entry.getKey(), entry.getValue()); } return result; }
In C# this becomes (with abbreviated namespace qualifiers, for readability):
public S.C.G.IDictionary<string, n.s.s.o.Sequence> getDefaultOptions() {
S.C.G.IDictionary<string, n.s.s.o.Sequence> result =
new S.C.G.Dictionary<string, n.s.s.o.Sequence>();
foreach (S.C.G.KeyValuePair<string, n.s.s.o.Sequence> entry in defaultValues) {
result[entry.Key] = entry.Value;
}
return result;
}
There's a lot going on here:
We've replaced the Java Map
with a C# Dictionary
, and its put()
method has been replaced with an indexed assignment;
The Java iterable defaultValues.entrySet()
has been replaced with the C# enumerable
defaultValues
;
The references to entry.getKey()
and entry.getValue()
have been replaced with property accessors entry.Key
and entry.Value
.
The replacement of result.put(key, value)
by result[key] = value
is fine in this context, but it needs care, because if the return value of the expression is used,
the Java code returns the previous value associated with the key, while the C# code returns the new
value. The rewrite works here only because the expression appears in a context where its result
is discarded.