ceylon / ceylon.ast

Apache License 2.0
18 stars 3 forks source link

provide a hook for preserving type checker information #87

Closed jvasileff closed 9 years ago

jvasileff commented 9 years ago

It would be nice to be able to preserve extra type checker information when converting RedHat nodes to Ceylon nodes. This could be supported with a user-defined hook, perhaps called advice, that allows callers to compilationUnitToCeylon to provide a function that will attach information to newly created nodes.

For example, the andOperationToCeylon function may look like:

"Converts a RedHat AST [[AndOp|JAndOp]] to a `ceylon.ast` [[AndOperation]]."
shared AndOperation andOperationToCeylon(
        JAndOp andOperation,
        Anything(JNode, Node) advice = noop) {
    "Check precedence"
    assert (is ConjoiningExpression left =
                expressionToCeylon(andOperation.leftTerm, advice),
            is NegatingExpression right =
                expressionToCeylon(andOperation.rightTerm, advice));
    value result = AndOperation(left, right);
    advice(andOperation, result);
    return result;
}

The advice function should be called after populating all children.

lucaswerkmeister commented 9 years ago

Should the compileX functions also have this? They won’t have much typechecker info anyways…

lucaswerkmeister commented 9 years ago

But OTOH they could have token information that would be impossible to attach later, since they create token stream + parser themselves. I think I’ll add it.

lucaswerkmeister commented 9 years ago

So there are a few nodes where the conversion isn’t quite straightforward, and the ceylon.ast node comes from several RedHat nodes:

I’ll call update for both RedHat nodes, I think.

jvasileff commented 9 years ago

I think that makes sense. update implementations can always use type tests to do whatever they need to do.

Can these non-one-to-one cases be documented?

lucaswerkmeister commented 9 years ago

Yeah, the package documentation might be a good place for that. (That is of course also the place where update itself is documented; I’m not going to add that for every parameter.)

lucaswerkmeister commented 9 years ago

Adding the hook is done. Still to do:

jvasileff commented 9 years ago

Thanks @lucaswerkmeister, this is working out very well!

I'd offer code for default implementations, but I think it will take some time for me to decide how exactly I'd like these to work. My current approach for model info is to use the most specific type possible. So, you only need to use exists (rather than narrowing with is) on get(key), but you need to be sure to use the right key.

Certainly there are pros/cons with either approach. But one nice thing about precisely typed keys is that you can avoid importing each redhat type for code that calls get, which can be a hassle due to name conflicts without https://github.com/ceylon/ceylon-spec/issues/1142.

lucaswerkmeister commented 9 years ago

Heads-up: Some of the missing node updates are because we fabricate a node out of thin air. I’m adding update calls for all of these, but not all of them make sense. (For instance, a JTuple’s sequencedArgument can be null, in which case I update the new ArgumentList() with the tuple itself.)

lucaswerkmeister commented 9 years ago

Oops, forgot to close this issue – last part should be done with d209e3d55a47d5d4116ce8bd0ddb4cc57faca6a4.