18fd8b75bd
Previously, a ShadowSyntheticExpression was its own kind of Expression unrelated to any of the Expression types defined in the kernel. It responded to visit requests by forwarding the visit request to the desugared expression. This had the advantage that for serialization purposes, ShadowSyntheticExpressions would automatically disappear. But it had the disadvantage that if a ShadowSyntheticExpression ever needed to be replaced with another node (e.g. because an implicit downcast was needed), the _ChildReplacer would get confused by the visitor forwarding and fail to replace the node properly. This CL fixes the problem by changing ShadowSyntheticExpression to a Let node of the form `let _ = null in desugaredExpression`. Since this is a genuine kernel expression, it no longer needs special visiting semantics, and node replacement works properly. In most circumstances, we replace the ShadowSyntheticExpression with its desugared equivalent during type inference, so the final serialized kernel representation is unchanged. However, in a few rare circumstances involving error recovery, a ShadowSyntheticExpression remains in the tree. Semantically this shouldn't be a problem, since the behavior of `let _ = null in x` is the same as the behavior of `x`. Nonetheless, I hope to get rid of these rare circumstances in follow up CLs. Change-Id: Iacf8c0028c424ac9ef98ef8302680e289bf7a017 Reviewed-on: https://dart-review.googlesource.com/21571 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Paul Berry <paulberry@google.com>