CaseTypes.ceylon
import ceylon.ast.core {
CaseTypes,
MemberName,
Node,
PrimaryType
}
import com.redhat.ceylon.compiler.typechecker.tree {
JNode=Node,
Tree {
JBaseMemberExpression=BaseMemberExpression,
JCaseTypes=CaseTypes,
JInferredTypeArguments=InferredTypeArguments,
JStaticType=StaticType
}
}
import org.antlr.runtime {
Token
}
import ceylon.interop.java {
CeylonIterable
}
"Converts RedHat AST [[CaseTypes|JCaseTypes]] to `ceylon.ast` [[CaseTypes]]."
shared CaseTypes caseTypesToCeylon(JCaseTypes caseTypes, Anything(JNode,Node) update = noop) {
/*
Note: currently, the compiler doesn’t explicitly track the order of case types
( https://github.com/ceylon/ceylon-spec/issues/947 ).
We work around this by using the tokens’ indexes to get the original order.
(This trick originally comes from ceylon.formatter.)
*/
assert (nonempty cases
= concatenate(CeylonIterable(caseTypes.types), CeylonIterable(caseTypes.baseMemberExpressions))
.sort(byIncreasing(compose(Token.tokenIndex, JNode.token))));
PrimaryType|MemberName primaryTypeOrMemberNameToCeylon(JStaticType|JBaseMemberExpression that, Anything(JNode,Node) update = noop) {
switch (that)
case (is JStaticType) {
assert (is PrimaryType type = typeToCeylon(that, update));
return type;
}
case (is JBaseMemberExpression) {
"Must not have type arguments"
assert (that.typeArguments is JInferredTypeArguments);
return lIdentifierToCeylon(that.identifier, update);
}
}
value result = CaseTypes(cases.collect(propagateUpdate(primaryTypeOrMemberNameToCeylon, update)));
update(caseTypes, result);
return result;
}
"Compiles the given [[code]] for Case Types
into [[CaseTypes]] using the Ceylon compiler
(more specifically, the rule for `caseTypes`)."
shared CaseTypes? compileCaseTypes(String code, Anything(JNode,Node) update = noop) {
if (exists jCaseTypes = createParser(code).caseTypes()) {
return caseTypesToCeylon(jCaseTypes, update);
} else {
return null;
}
}