use of org.eclipse.ceylon.compiler.typechecker.tree.Tree in project ceylon by eclipse.
the class BoxingVisitor method visit.
@Override
public void visit(Tree.IfExpression that) {
super.visit(that);
if (that.getIfClause() == null || that.getElseClause() == null)
return;
Tree.Expression ifExpr = that.getIfClause().getExpression();
Tree.Expression elseExpr = that.getElseClause().getExpression();
if (ifExpr == null || elseExpr == null)
return;
if (CodegenUtil.isUnBoxed(ifExpr) && CodegenUtil.isUnBoxed(elseExpr) && !willEraseToObject(that.getUnit().denotableType(that.getTypeModel())))
CodegenUtil.markUnBoxed(that);
if (that.getTypeModel().isExactly(that.getUnit().getNullValueType())) {
CodegenUtil.markTypeErased(that);
}
// An If expression can never be raw, type erased or untrusted because
// it uses a Let with a new variable declaration, so the rawness,
// erasedness and untrustedness of its branches cannot propagate further
// up the tree.
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree in project ceylon by eclipse.
the class ExpressionVisitor method handleStaticReferenceImplicitTypeArguments.
/**
* Validate the type arguments to the qualifying type
* in a static reference when no type arguments are
* given explicitly.
*
* This is called later than usual because the type args
* might be inferrable from an invocation of the whole
* static reference.
*
* @param that the static reference
*/
private void handleStaticReferenceImplicitTypeArguments(Tree.QualifiedMemberOrTypeExpression that) {
Declaration member = that.getDeclaration();
Tree.TypeArguments tas = that.getTypeArguments();
// without type arguments to the qualifying type
if (isStaticReference(that)) {
if (member != null && !explicitTypeArguments(member, tas)) {
that.addError("type arguments could not be inferred: '" + member.getName(unit) + "' is generic");
}
// the reference to the qualifying type
Tree.StaticMemberOrTypeExpression smte = (Tree.StaticMemberOrTypeExpression) that.getPrimary();
// we have to get the type args from the tree
// here because the calling code doesn't know
// them (it is walking the qualifying reference)
Tree.TypeArguments typeArgs = smte.getTypeArguments();
TypeDeclaration type = (TypeDeclaration) smte.getDeclaration();
if (type != null && !explicitTypeArguments(type, typeArgs) && typeArgs.getTypeModels() == null) {
// nothing inferred
Declaration declaration = smte.getDeclaration();
smte.addError("missing type arguments to generic type qualifying static reference: '" + declaration.getName(unit) + "' declares type parameters " + typeParameterList(declaration));
}
}
Tree.Primary primary = that.getPrimary();
if (!that.getDirectlyInvoked() && (member.isStatic() || isConstructor(member)) && primary instanceof Tree.StaticMemberOrTypeExpression) {
Tree.StaticMemberOrTypeExpression smte = (Tree.StaticMemberOrTypeExpression) primary;
Declaration qualifyingType = smte.getDeclaration();
Tree.TypeArguments qtas = smte.getTypeArguments();
if (qualifyingType != null && qualifyingType.isParameterized() && !qualifyingType.isJava() && !explicitTypeArguments(qualifyingType, qtas)) {
if (explicitTypeArguments(member, tas)) {
Type functionType = genericFunctionType(qualifyingType, that.getScope(), member, that.getTarget(), unit);
that.setTypeModel(functionType);
checkNotJvm(that, "type functions are not supported on the JVM: '" + qualifyingType.getName(unit) + "' is generic (specify explicit type arguments)");
} else {
that.addError("missing explicit type arguments to generic qualifying type: '" + qualifyingType.getName(unit) + "' declares type parameters " + typeParameterList(qualifyingType));
}
}
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree in project ceylon by eclipse.
the class StatementTransformer method transform.
/**
* Transforms a Ceylon destructuring assignment to Java code.
* @param stmt The Ceylon destructure
* @return The Java tree
*/
List<JCStatement> transform(Tree.Destructure stmt) {
List<JCStatement> result = List.nil();
// Create temp var to hold result of expression
Tree.Pattern pat = stmt.getPattern();
Naming.SyntheticName tmpVarName = naming.synthetic(pat);
Expression destExpr = stmt.getSpecifierExpression().getExpression();
JCExpression typeExpr = makeJavaType(destExpr.getTypeModel());
JCExpression expr = expressionGen().transformExpression(destExpr);
at(stmt);
JCVariableDecl tmpVar = makeVar(Flags.FINAL, tmpVarName, typeExpr, expr);
result = result.append(tmpVar);
// Now add the destructured variables
List<VarDefBuilder> destructured = transformPattern(pat, tmpVarName.makeIdent());
for (VarDefBuilder vdb : destructured) {
Value v = vdb.var.getDeclarationModel();
at(vdb.var);
if (v.isClassMember() && v.isCaptured()) {
AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.getter(this, v.getName(), v);
adb.immutable();
classGen().current().attribute(adb);
classGen().current().defs(vdb.buildDefOnly());
result = result.append(make().Exec(make().Assign(vdb.name().makeIdentWithThis(), vdb.expr())));
} else {
result = result.append(vdb.build());
}
}
return result;
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree in project ceylon by eclipse.
the class ExpressionVisitor method visit.
/**
* Typecheck an invocation expression. Note that this
* is a tricky process involving type argument inference,
* anonymous function parameter type inference, function
* reference type argument inference, Java overload
* resolution, and argument type checking, and it all
* has to happen in exactly the right order, which is
* not at all the natural order for walking the tree.
*/
@Override
public void visit(Tree.InvocationExpression that) {
// assign some provisional argument types
// that will help with overload resolution
visitInvocationPositionalArgs(that);
// make a first attempt at resolving the
// invoked reference (but we don't have
// all the needed types yet)
Tree.Primary p = that.getPrimary();
p.visit(this);
// set up the parameter lists of all
// argument anonymous functions with
// inferred (missing) parameter lists
createAnonymousFunctionParameters(that);
// named argument lists are the easy
// case because they don't support
// anonymous functions with inferred
// parameter lists
Tree.NamedArgumentList nal = that.getNamedArgumentList();
if (nal != null) {
inferParameterTypes(p, nal);
nal.visit(this);
}
Tree.PositionalArgumentList pal = that.getPositionalArgumentList();
int argCount = 0;
boolean[] delayed = null;
if (pal != null) {
List<PositionalArgument> args = pal.getPositionalArguments();
argCount = args.size();
// infer parameter types as far as we
// can without having the inferred type
// parameters of the primary
delayed = inferParameterTypes(p, pal, false);
// which parameter type inference failed
for (int j = 0; j < argCount; j++) {
if (!delayed[j]) {
Tree.PositionalArgument pa = args.get(j);
if (pa != null) {
pa.visit(this);
}
}
}
}
// assign some additional types that
// we will use for overload resolution
visitInvocationPositionalArgs(that);
// now here's where overloading is
// finally resolved and then type
// argments are inferred
visitInvocationPrimary(that);
if (pal != null) {
List<PositionalArgument> args = pal.getPositionalArguments();
// now infer the remaining parameter
// types
inferParameterTypes(p, pal, true);
// missed the first time round
for (int j = 0; j < argCount; j++) {
if (delayed[j]) {
Tree.PositionalArgument pa = args.get(j);
if (pa != null) {
pa.visit(this);
}
}
}
}
// assignable to parameters)
if (isIndirectInvocation(that)) {
visitIndirectInvocation(that);
} else {
visitDirectInvocation(that);
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree in project ceylon by eclipse.
the class TypeUtils method encodeParameterListForRuntime.
public static void encodeParameterListForRuntime(final boolean resolveTargs, final Node n, final ParameterList plist, final GenerateJsVisitor gen) {
boolean first = true;
gen.out("[");
Map<String, Tree.Parameter> treeParams = new HashMap<>();
// Map of the parameters in the tree
if (n instanceof Tree.AnyMethod) {
for (Tree.ParameterList tplist : ((Tree.AnyMethod) n).getParameterLists()) {
for (Tree.Parameter tparm : tplist.getParameters()) {
if (tparm.getParameterModel() != null && tparm.getParameterModel().getName() != null) {
treeParams.put(tparm.getParameterModel().getName(), tparm);
}
}
}
}
for (Parameter p : plist.getParameters()) {
if (first)
first = false;
else
gen.out(",");
gen.out("{", MetamodelGenerator.KEY_NAME, ":'", p.getName(), "',");
gen.out(MetamodelGenerator.KEY_METATYPE, ":'", MetamodelGenerator.METATYPE_PARAMETER, "',");
Type ptype = p.getType();
if (p.getModel() instanceof Function) {
gen.out("$pt:'f',");
ptype = ((Function) p.getModel()).getTypedReference().getFullType();
}
if (p.isSequenced()) {
if (p.isAtLeastOne()) {
gen.out("seq:2,");
} else {
gen.out("seq:1,");
}
}
if (p.isDefaulted()) {
gen.out(MetamodelGenerator.KEY_DEFAULT, ":1,");
}
gen.out(MetamodelGenerator.KEY_TYPE, ":");
metamodelTypeNameOrList(resolveTargs, n, gen.getCurrentPackage(), ptype, null, gen);
if (p.getModel() instanceof Function) {
gen.out(",", MetamodelGenerator.KEY_RETURN_TYPE, ":");
metamodelTypeNameOrList(resolveTargs, n, gen.getCurrentPackage(), p.getType(), null, gen);
gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
encodeParameterListForRuntime(resolveTargs, n, ((Function) p.getModel()).getFirstParameterList(), gen);
}
Tree.Parameter tparm = p.getName() == null ? null : treeParams.get(p.getName());
if (tparm == null) {
if (p.getModel().getAnnotations() != null && !p.getModel().getAnnotations().isEmpty()) {
new ModelAnnotationGenerator(gen, p.getModel(), n).generateAnnotations();
}
} else if (tparm instanceof Tree.ParameterDeclaration) {
Tree.TypedDeclaration tdec = ((Tree.ParameterDeclaration) tparm).getTypedDeclaration();
if (tdec.getAnnotationList() != null && !tdec.getAnnotationList().getAnnotations().isEmpty()) {
outputAnnotationsFunction(tdec.getAnnotationList(), p.getDeclaration(), gen);
}
}
gen.out("}");
}
gen.out("]");
}
Aggregations