use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon by eclipse.
the class CeylonVisitor method visit.
public void visit(Tree.ClassBody that) {
// Transform executable statements and declarations in the body
// except constructors. Record how constructors delegate.
HashMap<Constructor, CtorDelegation> delegates = new HashMap<Constructor, CtorDelegation>();
java.util.List<Statement> stmts = getBodyStatements(that);
HashMap<Constructor, CtorDelegation> broken = new HashMap<Constructor, CtorDelegation>();
for (Tree.Statement stmt : stmts) {
if (stmt instanceof Tree.Constructor) {
Tree.Constructor ctor = (Tree.Constructor) stmt;
Constructor ctorModel = ctor.getConstructor();
if (gen.errors().hasDeclarationAndMarkBrokenness(ctor) instanceof Drop) {
broken.put(ctorModel, CtorDelegation.brokenDelegation(ctorModel));
continue;
}
classBuilder.getInitBuilder().constructor(ctor);
if (ctor.getDelegatedConstructor() != null) {
// error recovery
if (ctor.getDelegatedConstructor().getInvocationExpression() != null) {
Tree.ExtendedTypeExpression p = (Tree.ExtendedTypeExpression) ctor.getDelegatedConstructor().getInvocationExpression().getPrimary();
Declaration delegatedDecl = p.getDeclaration();
delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
}
} else {
// implicitly delegating to superclass initializer
Type et = ModelUtil.getConstructedClass(ctorModel).getExtendedType();
if (et != null) {
Declaration delegatedDecl = et.getDeclaration();
delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
}
}
} else if (stmt instanceof Tree.Enumerated) {
Tree.Enumerated singleton = (Tree.Enumerated) stmt;
Constructor ctorModel = singleton.getEnumerated();
if (gen.errors().hasDeclarationAndMarkBrokenness(singleton) instanceof Drop) {
broken.put(ctorModel, CtorDelegation.brokenDelegation(ctorModel));
continue;
}
classBuilder.getInitBuilder().singleton(singleton);
if (singleton.getDelegatedConstructor() != null) {
Tree.ExtendedTypeExpression p = (Tree.ExtendedTypeExpression) singleton.getDelegatedConstructor().getInvocationExpression().getPrimary();
Declaration delegatedDecl = p.getDeclaration();
delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
} else {
// implicitly delegating to superclass initializer
Type et = ModelUtil.getConstructedClass(ctorModel).getExtendedType();
if (et != null) {
Declaration delegatedDecl = et.getDeclaration();
delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
}
}
} else if (stmt instanceof Tree.SpecifierStatement && ((Tree.SpecifierStatement) stmt).getRefinement()) {
HasErrorException error = gen.errors().getFirstErrorBlock(stmt);
if (error != null) {
classBuilder.broken();
}
stmt.visit(this);
} else {
HasErrorException error = gen.errors().getFirstErrorInitializer(stmt);
if (error != null) {
append(gen.makeThrowUnresolvedCompilationError(error));
} else {
stmt.visit(this);
}
}
}
// Now transform constructors
for (Tree.Statement stmt : stmts) {
if (stmt instanceof Tree.Constructor) {
Tree.Constructor ctor = (Tree.Constructor) stmt;
if (gen.errors().hasDeclarationError(ctor) instanceof Drop) {
continue;
}
transformConstructor(ctor, ctor.getParameterList(), ctor.getDelegatedConstructor(), ctor.getBlock(), ctor.getConstructor(), delegates);
} else if (stmt instanceof Tree.Enumerated) {
Tree.Enumerated ctor = (Tree.Enumerated) stmt;
if (gen.errors().hasDeclarationError(ctor) instanceof Drop) {
continue;
}
transformSingletonConstructor(delegates, ctor);
}
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon by eclipse.
the class GenerateJsVisitor method addToPrototype.
void addToPrototype(Node node, ClassOrInterface d, List<Tree.Statement> statements) {
final boolean isSerial = d instanceof Class && ((Class) d).isSerializable();
boolean enter = opts.isOptimize();
ArrayList<Parameter> plist = null;
final boolean isAbstractNative = TypeUtils.makeAbstractNative(d);
final String typename = names.name(d);
final boolean overrideToString = d.getDirectMember("toString", null, true) == null;
if (enter) {
enter = !statements.isEmpty() | overrideToString;
if (d instanceof Class) {
ParameterList cpl = ((Class) d).getParameterList();
if (cpl != null) {
plist = new ArrayList<>(cpl.getParameters().size());
plist.addAll(cpl.getParameters());
enter |= !plist.isEmpty();
}
}
}
if (enter || isSerial) {
final List<? extends Statement> prevStatements = currentStatements;
currentStatements = statements;
out("(function(", names.self(d), ")");
beginBlock();
if (enter) {
// First of all, add an object to store statics only if needed
for (Statement s : statements) {
}
// Generated attributes with corresponding parameters will remove them from the list
if (plist != null) {
for (Parameter p : plist) {
generateAttributeForParameter(node, (Class) d, p);
}
}
boolean statics = false;
InitDeferrer initDeferrer = new InitDeferrer();
for (Statement s : statements) {
if (!statics && s instanceof Tree.Declaration) {
Declaration sd = ((Tree.Declaration) s).getDeclarationModel();
if (sd.isStatic()) {
statics = true;
out(names.name(d), ".$st$={};");
}
}
if (!(s instanceof Tree.ClassOrInterface) && !(s instanceof Tree.AttributeDeclaration && ((Tree.AttributeDeclaration) s).getDeclarationModel().isParameter())) {
addToPrototype(d, s, plist, initDeferrer);
}
}
for (Statement s : statements) {
if (s instanceof Tree.ClassOrInterface) {
addToPrototype(d, s, plist, initDeferrer);
} else if (s instanceof Tree.Enumerated) {
// Add a simple attribute which really returns the singleton from the class
final Tree.Enumerated vc = (Tree.Enumerated) s;
Value vcd = vc.getDeclarationModel();
defineAttribute(names.self(d), names.name(vcd));
out("{return ", typename, names.constructorSeparator(vcd), names.name(vcd), "();},undefined,");
TypeUtils.encodeForRuntime(vc, vcd, vc.getAnnotationList(), this);
out(");");
}
}
for (String stmt : initDeferrer.deferred) {
out(stmt);
endLine();
}
if (d.isMember()) {
ClassOrInterface coi = ModelUtil.getContainingClassOrInterface(d.getContainer());
if (coi != null && d.inherits(coi)) {
out(names.self(d), ".", typename, "=", typename, ";");
}
}
}
if (isSerial && !isAbstractNative) {
SerializationHelper.addSerializer(node, (Class) d, this);
}
if (overrideToString) {
out(names.self(d), ".", "toString=function(){return this.string.valueOf();};");
}
endBlock();
out(")(", typename, ".$$.prototype)");
endLine(true);
currentStatements = prevStatements;
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon by eclipse.
the class GenerateJsVisitor method generateConstructorStatements.
/**
* Like visitStatements but for constructors, because we need to check if a statement is
* a specifier expression and generate it regardless of lexical/prototype mode.
*/
void generateConstructorStatements(final Tree.Declaration cnstr, List<? extends Tree.Statement> stmts) {
final List<String> oldRetainedVars = retainedVars.reset(null);
final List<? extends Statement> prevStatements = currentStatements;
currentStatements = stmts;
ReturnConstructorVisitor rcv = new ReturnConstructorVisitor(cnstr);
if (rcv.isReturns()) {
out("(function(){");
}
for (Tree.Statement s2 : stmts) {
if (s2 instanceof Tree.SpecifierStatement) {
Tree.SpecifierStatement ss = (Tree.SpecifierStatement) s2;
if (cnstr instanceof Tree.Constructor) {
specifierStatement(((Tree.Constructor) cnstr).getConstructor(), ss);
} else if (cnstr instanceof Tree.Enumerated) {
specifierStatement(((Tree.Enumerated) cnstr).getEnumerated(), ss);
}
} else {
s2.visit(this);
}
if (!opts.isMinify())
beginNewLine();
retainedVars.emitRetainedVars(this);
// every constructor adds metamodel to that attribute
if (!opts.isOptimize() && cnstr != null && s2 instanceof Tree.AttributeDeclaration) {
generatedAttributes.remove(((Tree.AttributeDeclaration) s2).getDeclarationModel());
}
}
if (rcv.isReturns()) {
out("}());");
}
retainedVars.reset(oldRetainedVars);
currentStatements = prevStatements;
}
Aggregations