use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class GenerateJsVisitor method qualifiedPath.
public String qualifiedPath(final Node that, final Declaration d, final boolean inProto) {
if (d instanceof Constructor) {
Class c = (Class) d.getContainer();
final String rval = qualifiedPath(that, c, inProto);
return rval.isEmpty() ? names.name(c) : rval + "." + names.name(c);
}
final boolean isMember = d.isClassOrInterfaceMember();
final boolean imported = isImported(that == null ? null : that.getUnit().getPackage(), d);
if (!isMember && imported) {
return names.moduleAlias(d.getUnit().getPackage().getModule());
} else if (opts.isOptimize() && !inProto) {
if (isMember && !(d.isParameter() && !d.isJsCaptured())) {
TypeDeclaration id = that.getScope().getInheritingDeclaration(d);
TypeDeclaration nd = null;
if (id == null) {
// a local declaration of some kind,
// perhaps in an outer scope
id = (TypeDeclaration) d.getContainer();
if (id.isNativeHeader()) {
nd = (TypeDeclaration) ModelUtil.getNativeDeclaration(id, Backend.JavaScript);
}
}
Scope scope = ModelUtil.getRealScope(that.getScope());
if (scope instanceof Value && !(ModelUtil.getRealScope(scope) instanceof ClassOrInterface)) {
scope = ModelUtil.getRealScope(scope.getContainer());
}
if ((scope != null) && (that instanceof Tree.ClassDeclaration || that instanceof Tree.InterfaceDeclaration || that instanceof Tree.Constructor)) {
// class/interface aliases have no own "this"
scope = scope.getContainer();
}
final StringBuilder path = new StringBuilder();
final Declaration innermostDeclaration = ModelUtil.getContainingDeclarationOfScope(scope);
while (scope != null) {
if (scope instanceof Constructor && scope == innermostDeclaration) {
TypeDeclaration consCont = (TypeDeclaration) scope.getContainer();
if (that instanceof Tree.BaseTypeExpression) {
path.append(names.name(consCont));
} else if (d.isStatic()) {
path.append(names.name(consCont)).append(".$st$");
} else {
path.append(names.self(consCont));
}
if (scope == id || (nd != null && scope == nd)) {
break;
}
scope = consCont;
} else if (scope instanceof TypeDeclaration) {
if (path.length() > 0) {
if (scope instanceof Constructor == false) {
Constructor constr = scope instanceof Class ? ((Class) scope).getDefaultConstructor() : null;
if ((constr == null || !ModelUtil.contains(constr, (Scope) innermostDeclaration)) && !d.isStatic()) {
path.append(".outer$");
}
}
} else if (d instanceof Constructor && ModelUtil.getContainingDeclaration(d) == scope) {
if (!d.getName().equals(((TypeDeclaration) scope).getName())) {
if (path.length() > 0) {
path.append('.');
}
path.append(names.name((TypeDeclaration) scope));
}
} else {
if (path.length() > 0) {
path.append('.');
}
if (d.isStatic()) {
if (d instanceof TypedDeclaration) {
TypedDeclaration orig = ((TypedDeclaration) d).getOriginalDeclaration();
path.append(names.name((ClassOrInterface) (orig == null ? d : orig).getContainer())).append(".$st$");
} else if (d instanceof TypeDeclaration) {
path.append(names.name((ClassOrInterface) d.getContainer())).append(".$st$");
}
} else {
path.append(names.self((TypeDeclaration) scope));
}
}
} else {
path.setLength(0);
}
if (scope == id || (nd != null && scope == nd)) {
break;
}
scope = scope.getContainer();
}
if (id != null && path.length() == 0 && !ModelUtil.contains(id, that.getScope())) {
// Import of toplevel object or constructor
if (imported) {
path.append(names.moduleAlias(id.getUnit().getPackage().getModule())).append('.');
}
if (id.isAnonymous()) {
path.append(names.objectName(id));
} else {
Import imp = findImport(that, d);
if (imp == null) {
path.append(names.name(id));
} else {
path.append(names.objectName(imp.getTypeDeclaration()));
}
}
}
return path.toString();
}
} else if (d != null) {
if (isMember && (d.isShared() || inProto || !d.isParameter() && AttributeGenerator.defineAsProperty(d))) {
TypeDeclaration id = d instanceof TypeAlias ? (TypeDeclaration) d : that.getScope().getInheritingDeclaration(d);
if (id == null) {
// a local declaration of some kind,
// perhaps in an outer scope
id = (TypeDeclaration) d.getContainer();
if (id.isToplevel() && !ModelUtil.contains(id, that.getScope())) {
// Import of toplevel object or constructor
final StringBuilder sb = new StringBuilder();
if (imported) {
sb.append(names.moduleAlias(id.getUnit().getPackage().getModule())).append('.');
}
sb.append(id.isAnonymous() ? names.objectName(id) : names.name(id));
return sb.toString();
} else if (d instanceof Constructor) {
return names.name(id);
} else {
// a shared local declaration
return names.self(id);
}
} else {
// inherited by an outer scope
return names.self(id);
}
}
}
return "";
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class Constructors method classStatementsBetweenConstructors.
/**
* Gather all class initializer statements that are between two constructors (or just before
* the second constructor, if the first one is null), including the statements from the
* second constructor
*/
static List<? extends Tree.Statement> classStatementsBetweenConstructors(final Tree.ClassDefinition cdef, final Tree.DelegatedConstructor dc, final Tree.Declaration c2, final GenerateJsVisitor gen) {
List<Tree.Statement> origs = cdef.getClassBody().getStatements();
if (NativeUtil.isForBackend(cdef.getDeclarationModel(), Backend.JavaScript)) {
Tree.Declaration nh = gen.getNativeHeader(cdef.getDeclarationModel());
if (nh == null && NativeUtil.hasNativeMembers(cdef.getDeclarationModel())) {
nh = cdef;
}
origs = NativeUtil.mergeStatements(cdef.getClassBody(), nh, Backend.JavaScript);
}
ArrayList<Tree.Statement> stmts = new ArrayList<>(origs.size());
// Find the constructor
Tree.Constructor c1 = null;
if (dc != null) {
TypeDeclaration xtd = (TypeDeclaration) ((Tree.ExtendedTypeExpression) dc.getInvocationExpression().getPrimary()).getDeclaration();
if (xtd instanceof Class && xtd == cdef.getDeclarationModel()) {
// It's the default constructor
for (Tree.Statement st : origs) {
if (st instanceof Tree.Constructor && ((Tree.Constructor) st).getDeclarationModel().getName() == null) {
c1 = (Tree.Constructor) st;
break;
}
}
} else {
for (Tree.Statement st : origs) {
if (st instanceof Tree.Constructor && TypeUtils.getConstructor(((Tree.Constructor) st).getDeclarationModel()) == xtd) {
c1 = (Tree.Constructor) st;
break;
}
}
}
}
boolean go = false;
for (Tree.Statement st : origs) {
if (st == c1 || c1 == null) {
go = true;
}
if (st == c2) {
if (c2 instanceof Tree.Constructor) {
stmts.addAll(((Tree.Constructor) c2).getBlock().getStatements());
} else if (c2 instanceof Tree.Enumerated) {
stmts.addAll(((Tree.Enumerated) c2).getBlock().getStatements());
}
return stmts;
}
if (go && st instanceof Tree.Constructor == false) {
stmts.add(st);
}
}
// Never happen!
return null;
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class Constructors method classConstructor.
static void classConstructor(final Tree.Constructor that, final Tree.ClassDefinition cdef, final List<Tree.Constructor> constructors, final GenerateJsVisitor gen) {
gen.comment(that);
final Constructor d = TypeUtils.getConstructor(that.getDeclarationModel());
final Class container = cdef.getDeclarationModel();
final String fullName = gen.getNames().name(container) + gen.getNames().constructorSeparator(d) + gen.getNames().name(d);
if (!TypeUtils.isNativeExternal(d) || !gen.stitchNative(d, that)) {
generateConstructor(that, cdef, constructors, fullName, gen);
}
// Add reference to metamodel
gen.out(fullName, ".$crtmm$=");
TypeUtils.encodeForRuntime(that, d, that.getAnnotationList(), gen);
gen.endLine(true);
gen.out(gen.getNames().name(container), ".", fullName, "=", fullName);
gen.endLine(true);
if (gen.outerSelf(container)) {
gen.out(".", fullName, "=", fullName);
gen.endLine(true);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class BmeGenerator method generateBme.
static void generateBme(final Tree.BaseMemberExpression bme, final GenerateJsVisitor gen, boolean nonNull) {
final boolean forInvoke = bme.getDirectlyInvoked();
Declaration decl = bme.getDeclaration();
if (decl != null) {
String name = decl.getName();
Package pkg = decl.getUnit().getPackage();
// map Ceylon true/false/null directly to JS true/false/null
if (pkg.isLanguagePackage()) {
if ("true".equals(name) || "false".equals(name) || "null".equals(name)) {
gen.out(name);
return;
}
}
if (ModelUtil.isConstructor(decl)) {
Constructor cd = TypeUtils.getConstructor(decl);
Declaration cdc = (Declaration) cd.getContainer();
if (!gen.qualify(bme, cd)) {
gen.out(gen.getNames().name(cdc), gen.getNames().constructorSeparator(decl));
}
if (decl instanceof Value) {
gen.out(gen.getNames().name(decl));
} else {
gen.out(gen.getNames().name(cd));
}
if (!forInvoke && decl instanceof Value) {
gen.out("()");
}
return;
}
}
String exp = gen.memberAccess(bme, null);
if (decl == null && gen.isInDynamicBlock()) {
if ("undefined".equals(exp)) {
gen.out(exp);
} else if (nonNull) {
gen.out("(typeof ", exp, "==='undefined'||", exp, "===null?");
gen.generateThrow(null, "Undefined or null reference: " + exp, bme);
gen.out(":", exp, ")");
} else {
gen.out(exp);
}
} else {
final boolean isCallable = !forInvoke && (decl instanceof Functional || bme.getUnit().getCallableDeclaration().equals(bme.getTypeModel().getDeclaration()));
final boolean hasTparms = hasTypeParameters(bme);
if (isCallable && (decl.isParameter() || (decl.isToplevel() && !hasTparms))) {
// Callables passed as arguments are already wrapped in JsCallable
gen.out(exp);
return;
}
String who = isCallable && decl.isMember() ? gen.getMember(bme, null) : null;
if (who == null || who.isEmpty()) {
// We may not need to wrap this in certain cases
ClassOrInterface cont = ModelUtil.getContainingClassOrInterface(bme.getScope());
who = cont == null ? "0" : gen.getNames().self(cont);
}
if (isCallable && (who != null || hasTparms)) {
if (hasTparms) {
// Function refs with type arguments must be passed as a special function
printGenericMethodReference(gen, bme, who, exp);
} else {
// Member methods must be passed as JsCallables
gen.out(gen.getClAlias(), "jsc$3(", who, ",", exp, ")");
}
} else {
gen.out(exp);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class BmeGenerator method generateBte.
static void generateBte(final Tree.BaseTypeExpression that, final GenerateJsVisitor gen, final boolean forceReference) {
Declaration d = that.getDeclaration();
if (d == null && gen.isInDynamicBlock()) {
// It's a native js type but will be wrapped in dyntype() call
String id = that.getIdentifier().getText();
gen.out("(typeof ", id, "==='undefined'?");
gen.generateThrow(null, "Undefined type " + id, that);
gen.out(":", id, ")");
} else {
boolean wrap = false;
String pname = null;
List<Parameter> params = null;
if ((forceReference || !that.getDirectlyInvoked()) && d instanceof TypeDeclaration) {
if (d.isParameterized()) {
wrap = true;
pname = gen.getNames().createTempVariable();
gen.out("function(");
if (d instanceof Class) {
params = ((Class) d).getParameterList().getParameters();
} else if (d instanceof Constructor) {
params = ((Constructor) d).getFirstParameterList().getParameters();
}
for (int i = 0; i < params.size(); i++) {
if (i > 0)
gen.out(",");
gen.out(pname, "$", Integer.toString(i));
}
gen.out("){return ");
}
}
if (d instanceof Constructor) {
// this happens with classes that have a default constructor with the same name as the type
if (gen.getNames().name(d).equals(gen.getNames().name((TypeDeclaration) d.getContainer()))) {
gen.qualify(that, (TypeDeclaration) d.getContainer());
} else {
gen.qualify(that, d);
}
} else {
if (d instanceof Class && d.isDynamic()) {
gen.out("new ");
}
gen.qualify(that, d);
}
gen.out(gen.getNames().name(d));
if (wrap) {
gen.out("(");
for (int i = 0; i < params.size(); i++) {
gen.out(pname, "$", Integer.toString(i), ",");
}
List<Type> targs = that.getTypeArguments() == null ? null : that.getTypeArguments().getTypeModels();
TypeUtils.printTypeArguments(that, TypeUtils.matchTypeParametersWithArguments(d.getTypeParameters(), targs), gen, false, null);
gen.out(");}");
}
}
}
Aggregations