use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon-compiler by ceylon.
the class MethodOrValueReferenceVisitor method usedIn.
/**
* Returns 1 if the declaration is captured in the given statements, 0 otherwise.
*/
private int usedIn(List<Statement> stmts) {
for (Tree.Statement stmt : stmts) {
// count declarations as usage
if (stmt instanceof Tree.TypedDeclaration && ((Tree.TypedDeclaration) stmt).getDeclarationModel() == declaration)
return 1;
stmt.visit(this);
if (declaration.isCaptured())
break;
}
boolean used = declaration.isCaptured();
FunctionOrValue fov = ((FunctionOrValue) declaration);
fov.setCaptured(false);
if (fov instanceof Value) {
Value val = (Value) fov;
if (val.getSetter() != null)
val.getSetter().setCaptured(false);
}
return used ? 1 : 0;
}
use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon-compiler by ceylon.
the class MethodOrValueReferenceVisitor method visit.
@Override
public void visit(Tree.ClassDefinition that) {
if (!that.getDeclarationModel().hasConstructors()) {
boolean cs = enterCapturingScope();
super.visit(that);
exitCapturingScope(cs);
} else {
// super special case for unshared members when we have constructors
if (!declaration.isCaptured() && declaration instanceof FunctionOrValue && declaration.isClassMember()) {
Map<Constructor, ConstructorPlan> constructorPlans = new HashMap<Constructor, ConstructorPlan>();
List<Tree.Statement> statements = new ArrayList<>(that.getClassBody().getStatements().size());
// find every constructor, and build a model of how they delegate
for (Tree.Statement stmt : that.getClassBody().getStatements()) {
if (stmt instanceof Tree.Constructor) {
Tree.Constructor ctor = (Tree.Constructor) stmt;
// build a new plan for it
ConstructorPlan plan = new ConstructorPlan();
plan.constructor = ctor;
constructorPlans.put(ctor.getConstructor(), plan);
// find every constructor which delegates to another constructor
if (ctor.getDelegatedConstructor() != null && ctor.getDelegatedConstructor().getInvocationExpression() != null) {
if (ctor.getDelegatedConstructor().getInvocationExpression().getPrimary() instanceof Tree.ExtendedTypeExpression) {
Tree.ExtendedTypeExpression ete = (Tree.ExtendedTypeExpression) ctor.getDelegatedConstructor().getInvocationExpression().getPrimary();
// are we delegating to a constructor (not a supertype) of the same class (this class)?
if (Decl.isConstructor(ete.getDeclaration()) && Decl.getConstructedClass(ete.getDeclaration()).equals(that.getDeclarationModel())) {
// remember the delegation
Constructor delegate = Decl.getConstructor(ete.getDeclaration());
ConstructorPlan delegatePlan = constructorPlans.get(delegate);
plan.delegate = delegatePlan;
// mark the delegate as delegated
delegatePlan.isDelegate = true;
// we have all the statements before us and after our delegate
plan.before.addAll(delegatePlan.after);
}
}
}
// if we have no delegate, we start with every common statement
if (plan.delegate == null)
plan.before.addAll(statements);
// also add all the constructor's statements
if (ctor.getBlock() != null) {
plan.before.addAll(ctor.getBlock().getStatements());
}
} else {
statements.add(stmt);
// make sure all existing constructors get this statement too
for (ConstructorPlan constructorPlan : constructorPlans.values()) constructorPlan.after.add(stmt);
}
}
// try every constructor plan and see if it's used in two methods
for (ConstructorPlan constructorPlan : constructorPlans.values()) {
visitConstructorPlan(constructorPlan);
// are we done?
if (declaration.isCaptured())
break;
}
}
// do regular capturing after that (for members), if required
if (!declaration.isCaptured())
super.visit(that);
}
}
use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon-compiler by ceylon.
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 = Decl.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 = Decl.getConstructedClass(ctorModel).getExtendedType();
if (et != null) {
Declaration delegatedDecl = et.getDeclaration();
delegates.put(ctorModel, ctorDelegation(ctorModel, delegatedDecl, broken));
}
}
} 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 com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement in project ceylon-compiler by ceylon.
the class StatementTransformer method transformBlock.
public List<JCStatement> transformBlock(Tree.Block block, boolean revertRet) {
if (block == null) {
return List.<JCStatement>nil();
}
at(block);
CeylonVisitor v = gen().visitor;
final ListBuffer<JCTree> prevDefs = v.defs;
final boolean prevInInitializer = v.inInitializer;
final ClassDefinitionBuilder prevClassBuilder = v.classBuilder;
List<JCStatement> result;
try {
v.defs = new ListBuffer<JCTree>();
v.inInitializer = false;
v.classBuilder = current();
java.util.Iterator<Statement> statements = block.getStatements().iterator();
while (statements.hasNext()) {
Tree.Statement stmt = statements.next();
Transformer<JCStatement, Return> returnTransformer;
if (revertRet && stmt instanceof Tree.Declaration) {
returnTransformer = returnTransformer(defaultReturnTransformer);
} else {
returnTransformer = this.returnTransformer;
}
try {
HasErrorException error = errors().getFirstErrorBlock(stmt);
if (error == null) {
stmt.visit(v);
} else {
v.append(this.makeThrowUnresolvedCompilationError(error));
break;
}
} finally {
returnTransformer(returnTransformer);
}
}
result = (List<JCStatement>) v.getResult().toList();
} finally {
v.classBuilder = prevClassBuilder;
v.inInitializer = prevInInitializer;
v.defs = prevDefs;
// Close Substitutions which were scoped to this block
Scope scope = block.getScope();
while (scope instanceof ConditionScope) {
scope = scope.getScope();
}
naming.closeScopedSubstitutions(scope);
}
return result;
}
Aggregations