boxUnboxEnd(box);
out(";");
return;
}
if (bme != null) {
Declaration bmeDecl = bme.getDeclaration();
if (specStmt.getSpecifierExpression() instanceof LazySpecifierExpression) {
// attr => expr;
final boolean property = defineAsProperty(bmeDecl);
if (property) {
defineAttribute(qualifiedPath(specStmt, bmeDecl), names.name(bmeDecl));
} else {
if (bmeDecl.isMember()) {
qualify(specStmt, bmeDecl);
} else {
out ("var ");
}
out(names.getter(bmeDecl), "=function()");
}
beginBlock();
if (outer != null) { initSelf(specStmt); }
out ("return ");
if (!isNaturalLiteral(specStmt.getSpecifierExpression().getExpression().getTerm())) {
specStmt.getSpecifierExpression().visit(this);
}
out(";");
endBlock();
if (property) {
out(",undefined,");
TypeUtils.encodeForRuntime(specStmt, bmeDecl, this);
out(")");
}
endLine(true);
directAccess.remove(bmeDecl);
}
else if (outer != null) {
// "attr = expr;" in a prototype definition
if (bmeDecl.isMember() && (bmeDecl instanceof Value) && bmeDecl.isActual()) {
out("delete ", names.self(outer), ".", names.name(bmeDecl));
endLine(true);
}
}
else if (bmeDecl instanceof MethodOrValue) {
// "attr = expr;" in an initializer or method
final MethodOrValue moval = (MethodOrValue)bmeDecl;
if (moval.isVariable()) {
// simple assignment to a variable attribute
BmeGenerator.generateMemberAccess(bme, new GenerateCallback() {
@Override public void generateValue() {
int boxType = boxUnboxStart(expr.getTerm(), moval);
if (dynblock > 0 && !Util.isTypeUnknown(moval.getType())
&& Util.isTypeUnknown(expr.getTypeModel())) {
TypeUtils.generateDynamicCheck(expr, moval.getType(), GenerateJsVisitor.this, false,
expr.getTypeModel().getTypeArguments());
} else {
expr.visit(GenerateJsVisitor.this);
}
if (boxType == 4) {
out(",");
if (moval instanceof Method) {
//Add parameters
TypeUtils.encodeParameterListForRuntime(specStmt,
((Method)moval).getParameterLists().get(0), GenerateJsVisitor.this);
out(",");
} else {
//TODO extract parameters from Value
out("[/*VALUE Callable params", moval.getClass().getName(), "*/],");
}
TypeUtils.printTypeArguments(expr, expr.getTypeModel().getTypeArguments(),
GenerateJsVisitor.this, false, expr.getTypeModel().getVarianceOverrides());
}
boxUnboxEnd(boxType);
}
}, null, this);
out(";");
} else if (moval.isMember()) {
if (moval instanceof Method) {
//same as fat arrow
qualify(specStmt, bmeDecl);
out(names.name(moval), "=function ", names.name(moval), "(");
//Build the parameter list, we'll use it several times
final StringBuilder paramNames = new StringBuilder();
final List<com.redhat.ceylon.compiler.typechecker.model.Parameter> params =
((Method) moval).getParameterLists().get(0).getParameters();
for (com.redhat.ceylon.compiler.typechecker.model.Parameter p : params) {
if (paramNames.length() > 0) paramNames.append(",");
paramNames.append(names.name(p));
}
out(paramNames.toString());
out("){");
for (com.redhat.ceylon.compiler.typechecker.model.Parameter p : params) {
if (p.isDefaulted()) {
out("if(", names.name(p), "===undefined)", names.name(p),"=");
qualify(specStmt, moval);
out(names.name(moval), "$defs$", p.getName(), "(", paramNames.toString(), ")");
endLine(true);
}
}
out("return ");
if (!isNaturalLiteral(specStmt.getSpecifierExpression().getExpression().getTerm())) {
specStmt.getSpecifierExpression().visit(this);
}
out("(", paramNames.toString(), ");}");
endLine(true);
} else {
// Specifier for a member attribute. This actually defines the
// member (e.g. in shortcut refinement syntax the attribute
// declaration itself can be omitted), so generate the attribute.
AttributeGenerator.generateAttributeGetter(null, moval,
specStmt.getSpecifierExpression(), null, this, directAccess);
}
} else {
// Specifier for some other attribute, or for a method.
if (opts.isOptimize()
|| (bmeDecl.isMember() && (bmeDecl instanceof Method))) {
qualify(specStmt, bmeDecl);
}
out(names.name(bmeDecl), "=");
if (dynblock > 0 && Util.isTypeUnknown(expr.getTypeModel())
&& !Util.isTypeUnknown(((MethodOrValue) bmeDecl).getType())) {
TypeUtils.generateDynamicCheck(expr, ((MethodOrValue) bmeDecl).getType(), this, false,
expr.getTypeModel().getTypeArguments());
} else {
specStmt.getSpecifierExpression().visit(this);
}
out(";");
}
}
}
else if ((term instanceof ParameterizedExpression)
&& (specStmt.getSpecifierExpression() != null)) {
final ParameterizedExpression paramExpr = (ParameterizedExpression)term;
if (paramExpr.getPrimary() instanceof BaseMemberExpression) {
// func(params) => expr;
final BaseMemberExpression bme2 = (BaseMemberExpression) paramExpr.getPrimary();
final Declaration bmeDecl = bme2.getDeclaration();
if (bmeDecl.isMember()) {
qualify(specStmt, bmeDecl);
} else {
out("var ");
}
out(names.name(bmeDecl), "=");