use of com.redhat.ceylon.compiler.java.codegen.recovery.Drop in project ceylon-compiler by ceylon.
the class ClassTransformer method addAtMembers.
private void addAtMembers(ClassDefinitionBuilder classBuilder, ClassOrInterface model, Tree.ClassOrInterface def) {
List<JCExpression> members = List.nil();
for (Declaration member : model.getMembers()) {
if (member instanceof ClassOrInterface == false && member instanceof TypeAlias == false) {
continue;
}
TypeDeclaration innerType = (TypeDeclaration) member;
Tree.Declaration innerTypeTree = findInnerType(def, innerType.getName());
if (innerTypeTree != null) {
TransformationPlan plan = errors().hasDeclarationAndMarkBrokenness(innerTypeTree);
if (plan instanceof Drop) {
continue;
}
}
if (innerType.isAlias() && innerTypeTree != null && Decl.isAncestorLocal(innerTypeTree))
// for the same reason we do not generate aliases in transform(ClassOrInterface def) let's not list them
continue;
JCAnnotation atMember;
// interfaces are moved to toplevel so they can lose visibility of member types if they are local
if (Decl.isLocal(model) && model instanceof Interface)
atMember = makeAtMember(innerType.getName());
else
atMember = makeAtMember(innerType.getType());
members = members.prepend(atMember);
}
classBuilder.annotations(makeAtMembers(members));
}
use of com.redhat.ceylon.compiler.java.codegen.recovery.Drop in project ceylon-compiler by ceylon.
the class CeylonVisitor method visit.
public void visit(Tree.ClassOrInterface decl) {
TransformationPlan plan = gen.errors().hasDeclarationAndMarkBrokenness(decl);
if (plan instanceof Drop) {
return;
}
if (skipHeaderMergeLater(decl)) {
return;
}
// To accept this class it is either not native or native for this backend
if (!acceptDeclaration(decl))
return;
int annots = gen.checkCompilerAnnotations(decl, defs);
if (Decl.withinClassOrInterface(decl)) {
if (Decl.withinInterface(decl)) {
classBuilder.getCompanionBuilder((Interface) decl.getDeclarationModel().getContainer()).defs(gen.classGen().transform(decl));
} else {
classBuilder.defs(gen.classGen().transform(decl));
}
} else {
appendList(gen.classGen().transform(decl));
}
gen.resetCompilerAnnotations(annots);
}
use of com.redhat.ceylon.compiler.java.codegen.recovery.Drop 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.java.codegen.recovery.Drop in project ceylon-compiler by ceylon.
the class CeylonVisitor method visit.
/*
* Compilation Unit
*/
public void visit(Tree.TypeAliasDeclaration decl) {
TransformationPlan plan = gen.errors().hasDeclarationAndMarkBrokenness(decl);
if (plan instanceof Drop) {
return;
}
int annots = gen.checkCompilerAnnotations(decl, defs);
if (Decl.withinClassOrInterface(decl)) {
if (Decl.withinInterface(decl)) {
classBuilder.getCompanionBuilder((Interface) decl.getDeclarationModel().getContainer()).defs(gen.classGen().transform(decl));
} else {
classBuilder.defs(gen.classGen().transform(decl));
}
} else {
appendList(gen.classGen().transform(decl));
}
gen.resetCompilerAnnotations(annots);
}
use of com.redhat.ceylon.compiler.java.codegen.recovery.Drop in project ceylon-compiler by ceylon.
the class CeylonVisitor method transformConstructor.
private void transformConstructor(Tree.Declaration ctor, Tree.ParameterList parameterList, Tree.DelegatedConstructor delegatedCtor, Tree.Block block, Constructor ctorModel, Map<Constructor, CtorDelegation> delegates) {
TransformationPlan plan = gen.errors().hasDeclarationAndMarkBrokenness(ctor);
if (plan instanceof Drop) {
return;
}
if (parameterList != null) {
for (Parameter param : parameterList.getModel().getParameters()) {
if (Naming.aliasConstructorParameterName(param.getModel())) {
gen.naming.addVariableSubst(param.getModel(), gen.naming.suffixName(Suffix.$param$, param.getName()));
}
}
}
final CtorDelegation delegation = delegates.get(ctorModel);
ListBuffer<JCStatement> stmts = ListBuffer.lb();
boolean delegatedTo = CtorDelegation.isDelegatedTo(delegates, ctorModel);
if (delegatedTo && !ctorModel.isAbstract()) {
Tree.InvocationExpression chainedCtorInvocation;
if (delegatedCtor != null) {
chainedCtorInvocation = delegatedCtor.getInvocationExpression();
} else {
chainedCtorInvocation = null;
}
// We need to generate $delegation$ delegation constructor
makeDelegationConstructor(ctor, parameterList, delegatedCtor, block, ctorModel, delegation, chainedCtorInvocation);
JCStatement delegateExpr;
if (chainedCtorInvocation != null) {
delegateExpr = gen.expressionGen().transformConstructorDelegation(chainedCtorInvocation, delegation.isSelfDelegation() ? delegation : new CtorDelegation(ctorModel, ctorModel), chainedCtorInvocation, classBuilder, !delegation.isSelfDelegation());
} else {
// In this case there is no extends clause in the source code
// so we have to construct the argument list "by hand".
ListBuffer<JCExpression> arguments = ListBuffer.<JCExpression>lb();
for (TypeParameter tp : ((Class) delegation.getConstructor().getContainer()).getTypeParameters()) {
arguments.add(gen.makeReifiedTypeArgument(tp.getType()));
}
arguments.add(gen.naming.makeNamedConstructorName(delegation.getConstructor(), true));
for (Parameter p : delegation.getConstructor().getFirstParameterList().getParameters()) {
arguments.add(gen.naming.makeName(p.getModel(), Naming.NA_IDENT));
}
delegateExpr = gen.make().Exec(gen.make().Apply(null, gen.naming.makeThis(), arguments.toList()));
}
stmts.add(delegateExpr);
} else if (delegatedCtor != null) {
stmts.add(gen.expressionGen().transformConstructorDelegation(delegatedCtor, delegation, delegatedCtor.getInvocationExpression(), classBuilder, false));
} else {
// no explicit extends clause
}
final boolean addBody;
if (delegatedTo && (delegation.isAbstractSelfOrSuperDelegation())) {
if (delegation.getConstructor().isAbstract()) {
stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(null, ctorModel));
addBody = true;
} else if (delegation.getExtendingConstructor() != null && delegation.getExtendingConstructor().isAbstract()) {
stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(delegation.getExtendingConstructor(), ctorModel));
addBody = true;
} else {
addBody = false;
}
} else if (delegation.isAbstractSelfDelegation()) {
// delegating to abstract
stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(delegation.getExtendingConstructor(), ctorModel));
addBody = true;
} else if (delegation.isConcreteSelfDelegation()) {
stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(delegation.getExtendingConstructor(), ctorModel));
addBody = true;
} else {
// super delegation
stmts.addAll(classBuilder.getInitBuilder().copyStatementsBetween(null, ctorModel));
addBody = true;
}
if (ctorModel.isAbstract() && !delegatedTo) {
stmts.add(gen.make().Throw(gen.make().NewClass(null, List.<JCExpression>nil(), gen.make().QualIdent(gen.syms().ceylonUninvokableErrorType.tsym), List.<JCExpression>nil(), null)));
}
List<JCStatement> following = ctorModel.isAbstract() ? List.<JCStatement>nil() : classBuilder.getInitBuilder().copyStatementsBetween(ctorModel, null);
if (addBody) {
if (following.isEmpty()) {
stmts.addAll(gen.statementGen().transformBlock(block));
} else {
Name label = gen.naming.aliasName(Naming.Unfix.$return$.toString());
Transformer<JCStatement, Return> prev = gen.statementGen().returnTransformer(gen.statementGen().new ConstructorReturnTransformer(label));
try {
stmts.add(gen.make().Labelled(label, gen.make().DoLoop(gen.make().Block(0, gen.statementGen().transformBlock(block, true)), gen.make().Literal(false))));
} finally {
gen.statementGen().returnTransformer(prev);
}
}
}
ThrowVisitor visitor = new ThrowVisitor();
block.visit(visitor);
if (!visitor.getDefinitelyReturnsViaThrow()) {
stmts.addAll(following);
}
String ctorName = !Decl.isDefaultConstructor(ctorModel) ? gen.naming.makeTypeDeclarationName(ctorModel) : null;
classBuilder.defs(gen.classGen().makeNamedConstructor(ctor, parameterList, ctorModel, classBuilder, Strategy.generateInstantiator(ctorModel), gen.classGen().transformConstructorDeclFlags(ctorModel), false, ctorName, stmts.toList(), DeclNameFlag.QUALIFIED));
}
Aggregations