use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.
the class StatementTransformer method transform.
// FIXME There is a similar implementation in ClassGen!
public List<JCStatement> transform(Tree.AttributeDeclaration decl) {
ListBuffer<JCStatement> result = new ListBuffer<JCStatement>();
// If the attribute is really from a parameter then don't generate a local variable
Parameter parameter = CodegenUtil.findParamForDecl(decl);
if (parameter == null) {
final Name attrName = names().fromString(naming.substitute(decl.getDeclarationModel()));
Type t = decl.getDeclarationModel().getType();
JCExpression initialValue = null;
SpecifierOrInitializerExpression initOrSpec = decl.getSpecifierOrInitializerExpression();
if (initOrSpec != null) {
HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(initOrSpec.getExpression().getTerm());
if (error != null) {
return List.<JCStatement>of(this.makeThrowUnresolvedCompilationError(error));
}
int flags = CodegenUtil.downcastForSmall(initOrSpec.getExpression(), decl.getDeclarationModel()) ? ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK : 0;
flags |= decl.getDeclarationModel().hasUncheckedNullType() ? ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL : 0;
initialValue = expressionGen().transformExpression(initOrSpec.getExpression(), CodegenUtil.getBoxingStrategy(decl.getDeclarationModel()), decl.getDeclarationModel().getType(), flags);
} else if (decl.getDeclarationModel().isVariable()) {
// Java's definite initialization doesn't always work
// so give variable attribute declarations without
// initializers a default value. See #1153.
initialValue = makeDefaultExprForType(t);
if (CodegenUtil.getBoxingStrategy(decl.getDeclarationModel()) == BoxingStrategy.BOXED && canUnbox(t)) {
initialValue = boxType(initialValue, t);
}
}
List<JCAnnotation> annots = List.<JCAnnotation>nil();
int modifiers = transformLocalFieldDeclFlags(decl);
JCExpression typeExpr = makeJavaType(decl.getDeclarationModel(), t, modifiers);
result.append(at(decl.getIdentifier()).VarDef(at(decl.getIdentifier()).Modifiers(modifiers, annots), attrName, typeExpr, initialValue));
JCStatement outerSubs = openOuterSubstitutionIfNeeded(decl.getDeclarationModel(), t, modifiers);
if (outerSubs != null) {
result.append(outerSubs);
}
}
return result.toList();
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.
the class GenerateJsVisitor method initDefaultedParameters.
/**
* Create special functions with the expressions for defaulted parameters in a parameter list.
*/
void initDefaultedParameters(final Tree.ParameterList params, Tree.AnyMethod container) {
if (!(container instanceof Tree.MethodDeclaration || container.getDeclarationModel().isMember())) {
return;
}
final boolean isMember = container.getDeclarationModel().isMember();
for (final Tree.Parameter param : params.getParameters()) {
Parameter pd = param.getParameterModel();
if (pd.isDefaulted()) {
final SpecifierOrInitializerExpression expr = getDefaultExpression(param);
if (expr == null) {
continue;
}
if (isMember) {
qualify(params, container.getDeclarationModel());
out(names.name(container.getDeclarationModel()), "$defs$", pd.getName(), "=function");
} else {
out("function ", names.name(container.getDeclarationModel()), "$defs$", pd.getName());
}
params.visit(this);
out("{");
initSelf(expr);
out("return ");
if (param instanceof Tree.ParameterDeclaration) {
Tree.TypedDeclaration node = ((Tree.ParameterDeclaration) param).getTypedDeclaration();
if (node instanceof Tree.MethodDeclaration) {
// function parameter defaulted using "=>"
FunctionHelper.singleExprFunction(((Tree.MethodDeclaration) node).getParameterLists(), expr.getExpression(), null, true, true, this);
} else if (!isNaturalLiteral(expr.getExpression().getTerm())) {
expr.visit(this);
}
} else if (!isNaturalLiteral(expr.getExpression().getTerm())) {
expr.visit(this);
}
out(";}");
endLine(true);
}
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.
the class GenerateJsVisitor method getDefaultExpression.
/**
* Get the specifier expression for a Parameter, if one is available.
*/
SpecifierOrInitializerExpression getDefaultExpression(final Tree.Parameter param) {
final SpecifierOrInitializerExpression expr;
if (param instanceof Tree.ParameterDeclaration || param instanceof Tree.InitializerParameter) {
Tree.MethodDeclaration md = null;
if (param instanceof Tree.ParameterDeclaration) {
Tree.TypedDeclaration td = ((Tree.ParameterDeclaration) param).getTypedDeclaration();
if (td instanceof AttributeDeclaration) {
expr = ((Tree.AttributeDeclaration) td).getSpecifierOrInitializerExpression();
} else if (td instanceof Tree.MethodDeclaration) {
md = (Tree.MethodDeclaration) td;
expr = md.getSpecifierExpression();
} else {
param.addUnexpectedError("Don't know what to do with TypedDeclaration " + td.getClass().getName(), Backend.JavaScript);
expr = null;
}
} else {
expr = ((Tree.InitializerParameter) param).getSpecifierExpression();
}
} else {
param.addUnexpectedError("Don't know what to do with defaulted/sequenced param " + param, Backend.JavaScript);
expr = null;
}
return expr;
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.
the class MethodOrValueReferenceVisitor method visit.
@Override
public void visit(Tree.AttributeDeclaration that) {
final SpecifierOrInitializerExpression specifier = that.getSpecifierOrInitializerExpression();
Value model = that.getDeclarationModel();
boolean lse = inLazySpecifierExpression;
if (specifier != null && model.isLate() && model.isClassMember()) {
model.setCaptured(true);
inLazySpecifierExpression = true;
}
super.visit(that);
inLazySpecifierExpression = lse;
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.
the class GenerateJsVisitor method initParameters.
/**
* Initialize the sequenced, defaulted and captured parameters in a type declaration.
* @return The defaulted parameters that belong to a class, since their values have to be
* set later on.
*/
List<Tree.Parameter> initParameters(final Tree.ParameterList params, TypeDeclaration typeDecl, Functional m) {
List<Tree.Parameter> rparams = null;
for (final Tree.Parameter param : params.getParameters()) {
Parameter pd = param.getParameterModel();
String paramName = names.name(pd);
if (pd.isDefaulted() || pd.isSequenced()) {
out("if(", paramName, "===undefined){", paramName, "=");
if (pd.isDefaulted()) {
boolean done = false;
if (m instanceof Function) {
Function mf = (Function) m;
if (mf.getRefinedDeclaration() != mf) {
mf = (Function) mf.getRefinedDeclaration();
if (mf.isMember() || !mf.isImplemented()) {
qualify(params, mf);
out(names.name(mf), "$defs$", pd.getName(), "(");
boolean firstParam = true;
for (Parameter p : m.getFirstParameterList().getParameters()) {
if (firstParam) {
firstParam = false;
} else
out(",");
out(names.name(p));
}
out(")");
done = true;
}
}
} else if (pd.getDeclaration() instanceof Class) {
Class cdec = (Class) pd.getDeclaration().getRefinedDeclaration();
out(TypeGenerator.pathToType(params, cdec, this), ".$defs$", pd.getName(), "(", names.self(cdec));
for (Parameter p : ((Class) pd.getDeclaration()).getParameterList().getParameters()) {
if (!p.equals(pd)) {
out(",", names.name(p));
}
}
out(")");
if (rparams == null) {
rparams = new ArrayList<>(3);
}
rparams.add(param);
done = true;
}
if (!done) {
final SpecifierOrInitializerExpression expr = getDefaultExpression(param);
if (expr == null) {
param.addUnexpectedError("Default expression missing for " + pd.getName(), Backend.JavaScript);
out("undefined");
} else {
generateParameterExpression(param, expr, pd.getDeclaration() instanceof Scope ? (Scope) pd.getDeclaration() : null);
}
}
} else {
out(getClAlias(), "empty()");
}
out(";}");
endLine();
}
if (typeDecl != null && !(typeDecl instanceof ClassAlias) && (pd.getModel().isJsCaptured() || pd.getDeclaration() instanceof Class)) {
out(names.self(typeDecl), ".", names.valueName(pd.getModel()), "=", paramName);
if (!opts.isOptimize() && pd.isHidden()) {
// belt and suspenders...
out(";", names.self(typeDecl), ".", paramName, "=", paramName);
}
endLine(true);
}
}
return rparams;
}
Aggregations