use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class GenerateJsVisitor method comment.
void comment(Tree.Declaration that) {
if (!opts.isComment() || opts.isMinify())
return;
endLine();
String dname = that.getNodeType();
if (dname.endsWith("Declaration") || dname.endsWith("Definition")) {
dname = dname.substring(0, dname.length() - 7);
}
if (that instanceof Tree.Constructor) {
Function dec = ((Tree.Constructor) that).getDeclarationModel();
String cname = ((Class) dec.getContainer()).getName();
out("//Constructor ", cname, ".", dec.getName() == null ? "<default>" : dec.getName());
} else {
out("//", dname, " ", that.getDeclarationModel().getName());
}
location(that);
endLine();
}
use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class InvocationGenerator method generateSpreadArgument.
private void generateSpreadArgument(final Tree.Primary primary, final Tree.SpreadArgument arg, Tree.Expression expr, final Parameter pd) {
TypedDeclaration td = pd == null ? null : pd.getModel();
int boxType = gen.boxUnboxStart(expr.getTerm(), td);
if (boxType == 4) {
arg.visit(gen);
gen.out(",");
describeMethodParameters(expr.getTerm());
gen.out(",");
TypeUtils.printTypeArguments(arg, arg.getTypeModel().getTypeArguments(), gen, false, arg.getTypeModel().getVarianceOverrides());
} else if (pd == null) {
final Declaration primDec = primary instanceof Tree.MemberOrTypeExpression ? ((Tree.MemberOrTypeExpression) primary).getDeclaration() : null;
if (gen.isInDynamicBlock() && primary instanceof Tree.MemberOrTypeExpression && (primDec == null || primDec.isDynamic() || (primDec instanceof TypedDeclaration && ((TypedDeclaration) primDec).isDynamicallyTyped())) && arg.getTypeModel() != null && arg.getTypeModel().getDeclaration().inherits((arg.getUnit().getTupleDeclaration()))) {
// Spread dynamic parameter
Type tupleType = arg.getTypeModel();
Type targ = tupleType.getTypeArgumentList().get(2);
arg.visit(gen);
gen.out(".$_get(0)");
int i = 1;
while (!targ.isSubtypeOf(arg.getUnit().getEmptyType())) {
gen.out(",");
arg.visit(gen);
gen.out(".$_get(" + (i++) + ")");
targ = targ.getTypeArgumentList().get(2);
}
} else {
arg.visit(gen);
}
} else if (pd.isSequenced()) {
arg.visit(gen);
if (!arg.getUnit().isSequentialType(arg.getTypeModel())) {
gen.out(".sequence()");
}
} else if (!arg.getTypeModel().isEmpty()) {
final String specialSpreadVar = gen.getNames().createTempVariable();
gen.out("(", specialSpreadVar, "=");
arg.visit(gen);
final boolean unknownSpread = arg.getTypeModel().isUnknown();
final String get0 = unknownSpread ? "[" : ".$_get(";
final String get1 = unknownSpread ? "]" : ")";
if (!unknownSpread && !arg.getUnit().isSequentialType(arg.getTypeModel())) {
gen.out(".sequence()");
}
gen.out(",");
if (pd.isDefaulted()) {
gen.out(gen.getClAlias(), "nn$(", specialSpreadVar, get0, "0", get1, ")?", specialSpreadVar, get0, "0", get1, ":undefined)");
} else {
gen.out(specialSpreadVar, get0, "0", get1, ")");
}
// Find out if there are more params
final List<Parameter> moreParams;
final Declaration pdd = pd.getDeclaration();
boolean found = false;
if (pdd instanceof Function) {
moreParams = ((Function) pdd).getFirstParameterList().getParameters();
} else if (pdd instanceof Class) {
moreParams = ((Class) pdd).getParameterList().getParameters();
} else {
// Check the parameters of the primary (obviously a callable, so this is a Tuple)
List<Parameter> cparms = TypeUtils.convertTupleToParameters(primary.getTypeModel().getTypeArgumentList().get(1));
cparms.remove(0);
moreParams = cparms;
found = true;
}
if (moreParams != null) {
int c = 1;
for (Parameter restp : moreParams) {
if (found) {
final String cs = Integer.toString(c++);
if (restp.isDefaulted()) {
gen.out(",", gen.getClAlias(), "nn$(", specialSpreadVar, get0, cs, get1, ")?", specialSpreadVar, get0, cs, get1, ":undefined");
} else if (restp.isSequenced()) {
if (c == 2) {
gen.out(",", specialSpreadVar, ".rest");
} else {
gen.out(",", specialSpreadVar, ".sublistFrom(", cs, ")");
}
} else {
gen.out(",", specialSpreadVar, get0, cs, get1);
}
} else {
found = restp.equals(pd);
}
}
}
}
gen.boxUnboxEnd(boxType);
}
use of org.eclipse.ceylon.model.typechecker.model.Class 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.Class 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);
}
use of org.eclipse.ceylon.model.typechecker.model.Class in project ceylon by eclipse.
the class TypeFactory method isTupleOfVariadicCallable.
/**
* Copy of Unit.isTupleLengthUnbounded which is more strict on what we consider variadic. For example
* we do not consider Args|[] as a variadic tuple in a Callable. See https://github.com/ceylon/ceylon-compiler/issues/1908
*/
public boolean isTupleOfVariadicCallable(Type args) {
if (args != null) {
/*Boolean simpleTupleLengthUnbounded =
isSimpleTupleLengthUnbounded(args);
if (simpleTupleLengthUnbounded != null) {
return simpleTupleLengthUnbounded.booleanValue();
}*/
if (isEmptyType(args)) {
return false;
} else if (isVariadicElement(args)) {
return true;
}
Class td = getTupleDeclaration();
Type tuple = nonemptyArgs(args).getSupertype(td);
if (tuple == null) {
return false;
} else {
while (true) {
java.util.List<Type> tal = tuple.getTypeArgumentList();
if (tal.size() >= 3) {
Type rest = tal.get(2);
if (rest == null) {
return false;
} else if (isEmptyType(rest)) {
return false;
} else if (isVariadicElement(rest)) {
return true;
} else {
tuple = nonemptyArgs(rest).getSupertype(td);
if (tuple == null) {
return false;
}
// else continue the loop!
}
} else {
return false;
}
}
}
}
return false;
}
Aggregations