use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class GenerateJsVisitor method specifierStatement.
private void specifierStatement(final TypeDeclaration outer, final Tree.SpecifierStatement specStmt) {
final Tree.Expression expr = specStmt.getSpecifierExpression().getExpression();
final Tree.Term term = specStmt.getBaseMemberExpression();
final Tree.StaticMemberOrTypeExpression smte = term instanceof Tree.StaticMemberOrTypeExpression ? (Tree.StaticMemberOrTypeExpression) term : null;
if (isInDynamicBlock() && ModelUtil.isTypeUnknown(term.getTypeModel())) {
if (smte != null && smte.getDeclaration() == null) {
out(smte.getIdentifier().getText());
} else {
term.visit(this);
if (term instanceof BaseMemberExpression) {
Declaration dec = ((BaseMemberExpression) term).getDeclaration();
if (dec instanceof Value) {
Value v = (Value) dec;
if (v.isMember()) {
// Assignment to dynamic member
out("_");
}
}
}
}
out("=");
int box = boxUnboxStart(expr, term);
expr.visit(this);
if (box == 4)
out("/*TODO: callable targs 6.1*/");
boxUnboxEnd(box);
out(";");
return;
}
if (smte != null) {
final Declaration bmeDecl = smte.getDeclaration();
if (specStmt.getSpecifierExpression() instanceof LazySpecifierExpression) {
// attr => expr;
final boolean property = AttributeGenerator.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, false), "=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) {
// since #451 we now generate an attribute here
if (outer instanceof Constructor || bmeDecl.isMember() && bmeDecl instanceof Value && bmeDecl.isActual()) {
assignment(outer, bmeDecl, expr);
}
} else if (bmeDecl instanceof FunctionOrValue) {
// "attr = expr;" in an initializer or method
final FunctionOrValue moval = (FunctionOrValue) bmeDecl;
if (moval.isVariable() || moval.isLate()) {
// simple assignment to a variable attribute
BmeGenerator.generateMemberAccess(smte, new GenerateCallback() {
@Override
public void generateValue() {
int boxType = boxUnboxStart(expr.getTerm(), moval);
if (isInDynamicBlock() && !ModelUtil.isTypeUnknown(moval.getType()) && ModelUtil.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 Function) {
// Add parameters
TypeUtils.encodeParameterListForRuntime(true, specStmt, ((Function) moval).getFirstParameterList(), GenerateJsVisitor.this);
out(",");
} else {
// TODO extract parameters from Value
final Type ps = moval.getUnit().getCallableTuple(moval.getType());
if (ps == null || ps.isSubtypeOf(moval.getUnit().getEmptyType())) {
out("[],");
} else {
out("[/*VALUE Callable params ", ps.asString() + "*/],");
}
}
TypeUtils.printTypeArguments(expr, expr.getTypeModel().getTypeArguments(), GenerateJsVisitor.this, false, expr.getTypeModel().getVarianceOverrides());
}
boxUnboxEnd(boxType);
}
}, qualifiedPath(smte, moval), this);
out(";");
} else if (moval.isMember()) {
if (moval instanceof Function) {
// same as fat arrow
qualify(specStmt, bmeDecl);
if (expr.getTerm() instanceof Tree.FunctionArgument) {
((Tree.FunctionArgument) expr.getTerm()).getDeclarationModel().setRefinedDeclaration(moval);
out(names.name(moval), "=");
specStmt.getSpecifierExpression().visit(this);
out(";");
} else {
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<Parameter> params = ((Function) moval).getFirstParameterList().getParameters();
for (Parameter p : params) {
if (paramNames.length() > 0)
paramNames.append(",");
paramNames.append(names.name(p));
}
out(paramNames.toString());
out("){");
for (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 {
// declaration itself can be omitted), so generate the attribute.
if (opts.isOptimize()) {
// #451
out(names.self(ModelUtil.getContainingClassOrInterface(moval.getScope())), ".", names.valueName(moval), "=");
specStmt.getSpecifierExpression().visit(this);
endLine(true);
} else {
AttributeGenerator.generateAttributeGetter(null, moval, specStmt.getSpecifierExpression(), null, this, directAccess, verboseStitcher);
}
}
} else {
// Specifier for some other attribute, or for a method.
if (opts.isOptimize() || bmeDecl.isMember() && bmeDecl instanceof Function) {
qualify(specStmt, bmeDecl);
}
out(names.name(bmeDecl), "=");
if (isInDynamicBlock() && ModelUtil.isTypeUnknown(expr.getTypeModel()) && !ModelUtil.isTypeUnknown(((FunctionOrValue) bmeDecl).getType())) {
TypeUtils.generateDynamicCheck(expr, ((FunctionOrValue) bmeDecl).getType(), this, false, expr.getTypeModel().getTypeArguments());
} else {
if (expr.getTerm() instanceof Tree.FunctionArgument) {
Function fun = ((Tree.FunctionArgument) expr.getTerm()).getDeclarationModel();
if (fun.isAnonymous()) {
fun.setRefinedDeclaration(moval);
}
}
specStmt.getSpecifierExpression().visit(this);
}
out(";");
}
}
} else if ((term instanceof Tree.ParameterizedExpression) && (specStmt.getSpecifierExpression() != null)) {
final Tree.ParameterizedExpression paramExpr = (Tree.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), "=");
FunctionHelper.singleExprFunction(paramExpr.getParameterLists(), expr, bmeDecl instanceof Scope ? (Scope) bmeDecl : null, true, true, this);
out(";");
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class MetamodelHelper method generateOpenType.
static void generateOpenType(final Tree.MetaLiteral that, final Declaration d, final GenerateJsVisitor gen, boolean compilingLanguageModule) {
final Module m = d.getUnit().getPackage().getModule();
final boolean isConstructor = ModelUtil.isConstructor(d) || that instanceof Tree.NewLiteral;
if (d instanceof TypeParameter == false) {
if (compilingLanguageModule) {
gen.out("$init$");
} else {
gen.out(gen.getClAlias());
}
}
if (d instanceof org.eclipse.ceylon.model.typechecker.model.Interface) {
gen.out("OpenInterface$jsint");
} else if (isConstructor) {
if (TypeUtils.getConstructor(d).isValueConstructor()) {
gen.out("OpenValueConstructor$jsint");
} else {
gen.out("OpenCallableConstructor$jsint");
}
} else if (d instanceof Class) {
gen.out("openClass$jsint");
} else if (d instanceof Function) {
gen.out("OpenFunction$jsint");
} else if (d instanceof Value) {
gen.out("OpenValue$jsint");
} else if (d instanceof org.eclipse.ceylon.model.typechecker.model.IntersectionType) {
gen.out("OpenIntersection");
} else if (d instanceof org.eclipse.ceylon.model.typechecker.model.UnionType) {
gen.out("OpenUnion");
} else if (d instanceof TypeParameter) {
generateOpenType(that, ((TypeParameter) d).getDeclaration(), gen, compilingLanguageModule);
gen.out(".getTypeParameterDeclaration('", d.getName(), "')");
return;
} else if (d instanceof org.eclipse.ceylon.model.typechecker.model.NothingType) {
gen.out("NothingType");
} else if (d instanceof TypeAlias) {
gen.out("OpenAlias$jsint(");
if (compilingLanguageModule) {
gen.out(")(");
}
if (d.isMember()) {
// Make the chain to the top-level container
ArrayList<Declaration> parents = new ArrayList<>(2);
Declaration pd = (Declaration) d.getContainer();
while (pd != null) {
parents.add(0, pd);
pd = pd.isMember() ? (Declaration) pd.getContainer() : null;
}
for (Declaration _d : parents) {
gen.out(gen.getNames().name(_d), ".$$.prototype.");
}
}
gen.out(gen.getNames().name(d), ")");
return;
}
// TODO optimize for local declarations
if (compilingLanguageModule) {
gen.out("()");
}
gen.out("(", gen.getClAlias());
final String pkgname = d.getUnit().getPackage().getNameAsString();
if (Objects.equals(that.getUnit().getPackage().getModule(), d.getUnit().getPackage().getModule())) {
gen.out("lmp$(ex$,'");
} else {
// TODO use $ for language module as well
gen.out("fmp$('", m.getNameAsString(), "','", m.getVersion(), "','");
}
gen.out("ceylon.language".equals(pkgname) ? "$" : pkgname, "'),");
if (d.isMember() || isConstructor) {
if (isConstructor) {
final Class actualClass;
final String constrName;
if (d instanceof Class) {
actualClass = (Class) d;
constrName = "$c$";
} else {
actualClass = (Class) d.getContainer();
if (d instanceof Constructor && ((Constructor) d).isValueConstructor()) {
constrName = gen.getNames().name(actualClass.getDirectMember(d.getName(), null, false));
} else {
constrName = gen.getNames().name(d);
}
}
if (gen.isImported(that.getUnit().getPackage(), actualClass)) {
gen.out(gen.getNames().moduleAlias(actualClass.getUnit().getPackage().getModule()), ".");
}
if (actualClass.isMember()) {
outputPathToDeclaration(that, actualClass, gen);
}
gen.out(gen.getNames().name(actualClass), gen.getNames().constructorSeparator(d), constrName, ")");
return;
} else {
outputPathToDeclaration(that, d, gen);
}
}
if (d instanceof Value || d.isParameter()) {
if (!d.isMember())
gen.qualify(that, d);
if (d.isStatic() && d instanceof Value && ((Value) d).getType().getDeclaration().isAnonymous()) {
gen.out(gen.getNames().name(d), ")");
} else {
gen.out(gen.getNames().getter(d, true), ")");
}
} else {
if (d.isAnonymous()) {
final String oname = gen.getNames().objectName(d);
if (d.isToplevel()) {
gen.qualify(that, d);
}
gen.out("$init$", oname);
if (!d.isToplevel()) {
gen.out("()");
}
} else {
if (!d.isMember())
gen.qualify(that, d);
gen.out(gen.getNames().name(d));
}
gen.out(")");
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class Singletons method valueConstructor.
static void valueConstructor(final Tree.ClassDefinition cdef, final Tree.Enumerated that, final GenerateJsVisitor gen) {
final Value d = that.getDeclarationModel();
final Constructor c = that.getEnumerated();
final Tree.DelegatedConstructor dc = that.getDelegatedConstructor();
final TypeDeclaration td = (TypeDeclaration) c.getContainer();
final String objvar = gen.getNames().createTempVariable();
final String selfvar = gen.getNames().self(td);
final String typevar = gen.getNames().name(td);
final String singvar = gen.getNames().name(d);
final boolean nested = cdef.getDeclarationModel().isClassOrInterfaceMember();
final String constructorName = typevar + gen.getNames().constructorSeparator(c) + singvar;
gen.out(nested ? "this." : "var ", objvar, "=undefined;function ", constructorName, "(){if(", nested ? "this." : "", objvar, "===undefined){");
if (dc == null) {
gen.out("$init$", typevar, "();");
}
if (nested) {
gen.out("var ", selfvar, "=");
} else {
gen.out(objvar, "=");
}
gen.out("new ", typevar, ".$$;");
if (td.isClassOrInterfaceMember()) {
gen.out(nested ? selfvar : objvar, ".outer$=this;");
}
if (dc != null) {
Tree.InvocationExpression invoke = dc.getInvocationExpression();
invoke.getPrimary().visit(gen);
gen.out("(");
// For now, only positional invocations are allowed here
gen.getInvoker().generatePositionalArguments(invoke.getPrimary(), invoke.getPositionalArgumentList(), invoke.getPositionalArgumentList().getPositionalArguments(), false, false);
if (!invoke.getPositionalArgumentList().getPositionalArguments().isEmpty()) {
gen.out(",");
}
if (!dc.getType().getTypeModel().getTypeArguments().isEmpty()) {
TypeUtils.printTypeArguments(dc, dc.getType().getTypeModel().getTypeArguments(), gen, false, dc.getType().getTypeModel().getVarianceOverrides());
gen.out(",");
}
gen.out(nested ? selfvar : objvar, ")");
gen.endLine(true);
}
if (!nested) {
gen.out("var ", selfvar, "=", objvar, ";");
}
ClassGenerator.addFunctionTypeArguments(cdef.getDeclarationModel(), objvar, gen);
ClassGenerator.callSupertypes(cdef, cdef.getDeclarationModel(), typevar, gen);
List<? extends Tree.Statement> stmts = Constructors.classStatementsBetweenConstructors(cdef, null, that, gen);
if (!stmts.isEmpty()) {
gen.generateConstructorStatements(that, stmts);
}
stmts = Constructors.classStatementsAfterConstructor(cdef, that);
if (!stmts.isEmpty()) {
gen.visitStatements(stmts);
}
if (nested) {
gen.out("this.", objvar, "=", selfvar, ";");
}
gen.out("}return ", nested ? "this." : "", objvar, ";};", constructorName, ".$crtmm$=");
TypeUtils.encodeForRuntime(that, that.getDeclarationModel(), that.getAnnotationList(), gen);
gen.out(";");
if (td.isClassOrInterfaceMember()) {
gen.outerSelf(td);
gen.out(".", constructorName, "=", constructorName, ";");
} else if (td.isShared()) {
gen.out("ex$.", constructorName, "=", constructorName, ";");
}
gen.out(gen.getNames().name(td), ".", constructorName, "=", constructorName);
gen.endLine(true);
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class TypeGenerator method callSuperclass.
static void callSuperclass(final Tree.SimpleType extendedType, final Tree.InvocationExpression invocation, final Class d, final ParameterList plist, final Node that, final boolean pseudoAbstractConstructor, final List<Declaration> superDecs, final GenerateJsVisitor gen) {
TypeDeclaration typeDecl = extendedType.getDeclarationModel();
if (invocation != null) {
Tree.PositionalArgumentList argList = invocation.getPositionalArgumentList();
final String qpath;
if (typeDecl instanceof Constructor) {
final String path = gen.qualifiedPath(that, (TypeDeclaration) typeDecl.getContainer(), false);
if (path.isEmpty()) {
qpath = gen.getNames().name((TypeDeclaration) typeDecl.getContainer());
} else {
qpath = path + "." + gen.getNames().name((TypeDeclaration) typeDecl.getContainer());
}
} else {
if (typeDecl.isStatic()) {
Declaration _cont = ModelUtil.getContainingDeclaration(typeDecl);
String qp = gen.qualifiedPath(that, _cont, false);
qpath = qp + (qp.isEmpty() ? "" : ".") + gen.getNames().name(_cont);
} else {
qpath = gen.qualifiedPath(that, typeDecl, false);
}
}
if (pseudoAbstractConstructor) {
if (typeDecl instanceof Constructor) {
gen.out(gen.memberAccessBase(extendedType, typeDecl, false, qpath), "$$a(");
} else {
gen.out(gen.memberAccessBase(extendedType, typeDecl, false, qpath), gen.getNames().constructorSeparator(typeDecl), "$c$$$a(");
}
} else {
gen.out(gen.memberAccessBase(extendedType, typeDecl, false, qpath), (gen.opts.isOptimize() && (gen.getSuperMemberScope(extendedType) != null)) ? ".call(this," : "(");
}
gen.getInvoker().generatePositionalArguments(invocation.getPrimary(), argList, argList.getPositionalArguments(), false, false);
if (argList.getPositionalArguments().size() > 0) {
gen.out(",");
}
// There may be defaulted args we must pass as undefined
if (plist != null && plist.getParameters().size() > argList.getPositionalArguments().size()) {
for (int i = argList.getPositionalArguments().size(); i < plist.getParameters().size(); i++) {
org.eclipse.ceylon.model.typechecker.model.Parameter p = plist.getParameters().get(i);
if (p.isSequenced()) {
gen.out(gen.getClAlias(), "empty(),");
} else {
gen.out("undefined,");
}
}
}
// If the supertype has type arguments, add them to the call
List<TypeParameter> typeParams;
if (typeDecl instanceof Constructor) {
// Output the type arguments to the constructor,
// UNLESS you're in the same class, then just pass the type arguments object
typeParams = ((Class) typeDecl.getContainer()).getTypeParameters();
if (typeParams != null && !typeParams.isEmpty()) {
typeParams = null;
if (ModelUtil.contains(d, typeDecl)) {
gen.out("$$targs$$,");
} else {
TypeUtils.printTypeArguments(that, extendedType.getTypeModel().getQualifyingType().getTypeArguments(), gen, false, null);
gen.out(",");
}
}
} else {
typeParams = typeDecl.getTypeParameters();
}
if (typeParams != null && !typeParams.isEmpty()) {
List<Type> typeArgs = null;
if (extendedType.getTypeArgumentList() != null) {
typeArgs = extendedType.getTypeArgumentList().getTypeModels();
}
TypeUtils.printTypeArguments(that, TypeUtils.matchTypeParametersWithArguments(typeParams, typeArgs), gen, false, null);
gen.out(",");
}
gen.out(gen.getNames().self(d), ")");
gen.endLine(true);
}
copySuperMembers(typeDecl, superDecs, d, gen);
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class Constructors method generateConstructor.
private static void generateConstructor(final Tree.Constructor that, final Tree.ClassDefinition cdef, final List<Tree.Constructor> constructors, final String fullName, final GenerateJsVisitor gen) {
final Constructor d = TypeUtils.getConstructor(that.getDeclarationModel());
final Class container = cdef.getDeclarationModel();
final Tree.DelegatedConstructor delcons = that.getDelegatedConstructor();
final TypeDeclaration superdec;
final ParameterList superplist;
final boolean callAbstract;
if (delcons == null) {
superdec = null;
superplist = null;
callAbstract = false;
} else {
superdec = delcons.getType().getDeclarationModel();
/**
* Is the delegated constructor is within the same class we call its abstract version
*/
callAbstract = superdec instanceof Class ? superdec == container : ((Constructor) superdec).getContainer() == container;
superplist = superdec instanceof Class ? ((Class) superdec).getParameterList() : ((Constructor) superdec).getFirstParameterList();
}
gen.out("function ", fullName, "$$a");
final boolean withTargs = TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
final String me = gen.getNames().self(container);
gen.beginBlock();
gen.initParameters(that.getParameterList(), container, null);
if (delcons != null) {
TypeGenerator.callSuperclass(delcons.getType(), delcons.getInvocationExpression(), container, superplist, that, callAbstract, null, gen);
}
// If there's a delegated constructor, run the statements after that one and before this one
gen.generateConstructorStatements(that, classStatementsBetweenConstructors(cdef, delcons, that, gen));
gen.out("return ", me, ";");
gen.endBlockNewLine(true);
gen.out("function ", fullName);
TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
gen.beginBlock();
if (!d.isAbstract()) {
gen.out("$init$", gen.getNames().name(container), "();");
gen.endLine();
gen.declareSelf(container);
gen.referenceOuter(container);
}
gen.initParameters(that.getParameterList(), container, null);
if (!d.isAbstract()) {
// Call common initializer
gen.out(gen.getNames().name(container), "$$c(");
if (withTargs) {
gen.out("$$targs$$,");
}
gen.out(me, ");");
gen.endLine();
}
gen.out(fullName, "$$a");
TypeGenerator.generateParameters(cdef.getTypeParameterList(), that.getParameterList(), container, gen);
gen.endLine(true);
if (d.isNative()) {
gen.stitchConstructorHelper(cdef, "_cons_before");
}
gen.visitStatements(classStatementsAfterConstructor(cdef, that));
if (d.isNative()) {
gen.stitchConstructorHelper(cdef, "_cons_after");
}
gen.out("return ", me, ";");
gen.endBlockNewLine(true);
}
Aggregations