use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class GenerateJsVisitor method generateAttributeForParameter.
void generateAttributeForParameter(Node node, Class d, Parameter p) {
if (p.getDeclaration() instanceof Function && ModelUtil.isConstructor(p.getDeclaration())) {
return;
}
final FunctionOrValue pdec = p.getModel();
final String privname = names.valueName(pdec);
defineAttribute(names.self(d), names.name(pdec));
out("{");
if (pdec.isLate()) {
generateUnitializedAttributeReadCheck("this." + privname, names.name(p), null);
}
out("return this.", privname, ";}");
if (pdec.isVariable() || pdec.isLate()) {
final String param = names.createTempVariable();
out(",function(", param, "){");
// Because of this one case, we need to pass 3 args to this method
generateImmutableAttributeReassignmentCheck(pdec, "this." + privname, names.name(p));
out("return this.", privname, "=", param, ";}");
} else {
out(",undefined");
}
out(",");
TypeUtils.encodeForRuntime(node, pdec, this);
out(")");
endLine(true);
}
use of org.eclipse.ceylon.model.typechecker.model.Function 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.Function 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.Function in project ceylon by eclipse.
the class TypeGenerator method interfaceDefinition.
static void interfaceDefinition(final Tree.InterfaceDefinition that, final GenerateJsVisitor gen, InitDeferrer initDeferrer) {
// Don't even bother with nodes that have errors
if (errVisitor.hasErrors(that))
return;
final Interface d = that.getDeclarationModel();
// If it's inside a dynamic interface, don't generate anything
if (d.isClassOrInterfaceMember() && ((ClassOrInterface) d.getContainer()).isDynamic())
return;
final Interface natd = (Interface) ModelUtil.getNativeDeclaration(d, Backend.JavaScript);
final boolean headerWithoutBackend = NativeUtil.isHeaderWithoutBackend(that, Backend.JavaScript);
if (natd != null && (headerWithoutBackend || NativeUtil.isNativeHeader(that))) {
// It's a native header, remember it for later when we deal with its implementation
gen.saveNativeHeader(that);
return;
}
if (!(NativeUtil.isForBackend(that, Backend.JavaScript) || headerWithoutBackend)) {
return;
}
gen.comment(that);
gen.out(GenerateJsVisitor.function, gen.getNames().name(d));
final boolean withTargs = generateParameters(that.getTypeParameterList(), null, d, gen);
gen.beginBlock();
final List<Declaration> superDecs = new ArrayList<>(3);
if (!gen.opts.isOptimize()) {
new SuperVisitor(superDecs).visit(that.getInterfaceBody());
}
final Tree.SatisfiedTypes sats = that.getSatisfiedTypes();
if (withTargs) {
gen.out(gen.getClAlias(), "set_type_args(", gen.getNames().self(d), ",$$targs$$,", gen.getNames().name(d), ")");
gen.endLine(true);
}
callSupertypes(sats == null ? null : TypeUtils.getTypes(sats.getTypes()), null, d, that, superDecs, null, null, gen);
if (!d.isToplevel() && d.getContainer() instanceof Function && !((Function) d.getContainer()).getTypeParameters().isEmpty()) {
gen.out(gen.getClAlias(), "set_type_args(", gen.getNames().self(d), ",", gen.getNames().typeArgsParamName((Function) d.getContainer()), ",", gen.getNames().name(d), ")");
gen.endLine(true);
}
final List<Tree.Statement> stmts;
if (NativeUtil.isForBackend(d, Backend.JavaScript)) {
Tree.Declaration nh = gen.getNativeHeader(d);
if (nh == null && NativeUtil.hasNativeMembers(d)) {
nh = that;
}
stmts = NativeUtil.mergeStatements(that.getInterfaceBody(), nh, Backend.JavaScript);
} else {
stmts = that.getInterfaceBody().getStatements();
}
gen.visitStatements(stmts);
// returnSelf(d);
gen.endBlockNewLine();
if (d.isDynamic()) {
// Add the list of expected members here
final List<Declaration> members = d.getMembers();
gen.out(gen.getNames().name(d), ".dynmem$=[");
if (members.isEmpty()) {
gen.out("];");
} else {
gen.out("'");
boolean first = true;
for (Declaration m : members) {
if (first)
first = false;
else
gen.out("','");
gen.out(gen.getNames().name(m));
}
gen.out("'];");
}
}
// Add reference to metamodel
gen.out(gen.getNames().name(d), ".$crtmm$=");
TypeUtils.encodeForRuntime(that, d, that.getAnnotationList(), gen);
gen.endLine(true);
gen.share(d);
initializeType(that, gen, initDeferrer);
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class AbstractModelLoader method addConstructorMethorOrValue.
protected FunctionOrValue addConstructorMethorOrValue(Class klass, ClassMirror classMirror, MethodMirror ctor, Constructor constructor, boolean isNativeHeader) {
boolean isCeylon = classMirror.getAnnotation(CEYLON_CEYLON_ANNOTATION) != null;
if (ctor.getAnnotation(CEYLON_ENUMERATED_ANNOTATION) != null) {
klass.setEnumerated(true);
Value v = new Value();
v.setName(constructor.getName());
v.setType(constructor.getType());
v.setContainer(klass);
v.setScope(klass);
v.setUnit(klass.getUnit());
v.setVisibleScope(constructor.getVisibleScope());
// read annotations from the getter method
setNonLazyDeclarationProperties(v, ctor, ctor, classMirror, isCeylon);
setAnnotations(v, ctor, isNativeHeader);
klass.addMember(v);
return v;
} else {
setParameters(constructor, classMirror, ctor, true, klass, false);
klass.setConstructors(true);
Function f = new Function();
f.setName(constructor.getName());
f.setType(constructor.getType());
f.addParameterList(constructor.getParameterList());
f.setContainer(klass);
f.setScope(klass);
f.setUnit(klass.getUnit());
f.setVisibleScope(constructor.getVisibleScope());
// read annotations from the constructor
setNonLazyDeclarationProperties(f, ctor, ctor, classMirror, isCeylon);
setAnnotations(f, ctor, isNativeHeader);
klass.addMember(f);
return f;
}
}
Aggregations