use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.
the class DeclarationVisitor method visit.
@Override
public void visit(Tree.Assertion that) {
Tree.ConditionList cl = that.getConditionList();
if (cl != null) {
for (Tree.Condition c : cl.getConditions()) {
c.setAssertion(true);
}
}
Declaration d = beginDeclaration(null);
super.visit(that);
endDeclaration(d);
}
use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.
the class DeclarationVisitor method visit.
@Override
public void visit(Tree.FunctionArgument that) {
Tree.Type type = that.getType();
final Function f = new Function();
f.setName("anonymous#" + fid++);
f.setAnonymous(true);
if (type.getToken() != null) {
f.setDeclaredVoid(type instanceof Tree.VoidModifier);
} else {
Tree.Block block = that.getBlock();
if (block != null) {
f.setDeclaredVoid(true);
new Visitor() {
@Override
public void visit(Tree.Declaration that) {
}
@Override
public void visit(Tree.TypedArgument that) {
}
@Override
public void visit(Tree.ObjectExpression that) {
}
@Override
public void visit(Tree.FunctionArgument that) {
}
@Override
public void visit(Tree.Return that) {
if (that.getExpression() != null) {
f.setDeclaredVoid(false);
}
super.visit(that);
}
}.visit(block);
}
}
that.setDeclarationModel(f);
visitArgument(that, f);
Scope o = enterScope(f);
Declaration d = beginDeclaration(f);
super.visit(that);
endDeclaration(d);
exitScope(o);
setParameterLists(f, that.getParameterLists(), that);
}
use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.
the class ClassTransformer method transformSpecifiedMethodBody.
List<JCStatement> transformSpecifiedMethodBody(Tree.MethodDeclaration def, SpecifierExpression specifierExpression) {
final Function model = def.getDeclarationModel();
Tree.MethodDeclaration methodDecl = def;
boolean isLazy = specifierExpression instanceof Tree.LazySpecifierExpression;
boolean returnNull = false;
JCExpression bodyExpr;
Tree.Term term = null;
if (specifierExpression != null && specifierExpression.getExpression() != null) {
term = Decl.unwrapExpressionsUntilTerm(specifierExpression.getExpression());
HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(term);
if (error != null) {
return List.<JCStatement>of(this.makeThrowUnresolvedCompilationError(error));
}
}
if (!isLazy && term instanceof Tree.FunctionArgument) {
// Function specified with lambda: Don't bother generating a
// Callable, just transform the expr to use as the method body.
Tree.FunctionArgument fa = (Tree.FunctionArgument) term;
Type resultType = model.getType();
returnNull = Decl.isUnboxedVoid(model);
final java.util.List<Tree.Parameter> lambdaParams = fa.getParameterLists().get(0).getParameters();
final java.util.List<Tree.Parameter> defParams = def.getParameterLists().get(0).getParameters();
List<Substitution> substitutions = List.nil();
for (int ii = 0; ii < lambdaParams.size(); ii++) {
substitutions = substitutions.append(naming.addVariableSubst((TypedDeclaration) lambdaParams.get(ii).getParameterModel().getModel(), defParams.get(ii).getParameterModel().getName()));
}
List<JCStatement> body = null;
if (fa.getExpression() != null)
bodyExpr = gen().expressionGen().transformExpression(fa.getExpression(), returnNull ? BoxingStrategy.INDIFFERENT : CodegenUtil.getBoxingStrategy(model), resultType);
else {
body = gen().statementGen().transformBlock(fa.getBlock());
// useless but satisfies branch checking
bodyExpr = null;
}
for (Substitution subs : substitutions) {
subs.close();
}
// if we have a whole body we're done
if (body != null)
return body;
} else if (!isLazy && typeFact().isCallableType(term.getTypeModel())) {
returnNull = isAnything(term.getTypeModel()) && term.getUnboxed();
Function method = methodDecl.getDeclarationModel();
boolean lazy = specifierExpression instanceof Tree.LazySpecifierExpression;
boolean inlined = CodegenUtil.canOptimiseMethodSpecifier(term, method);
Invocation invocation;
if ((lazy || inlined) && term instanceof Tree.MemberOrTypeExpression && ((Tree.MemberOrTypeExpression) term).getDeclaration() instanceof Functional) {
Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) term).getDeclaration();
Reference producedReference = ((Tree.MemberOrTypeExpression) term).getTarget();
invocation = new MethodReferenceSpecifierInvocation(this, (Tree.MemberOrTypeExpression) term, primaryDeclaration, producedReference, method, specifierExpression);
} else if (!lazy && !inlined) {
// must be a callable we stored
String name = naming.getMethodSpecifierAttributeName(method);
invocation = new CallableSpecifierInvocation(this, method, naming.makeUnquotedIdent(name), term, term);
} else if (isCeylonCallableSubtype(term.getTypeModel())) {
invocation = new CallableSpecifierInvocation(this, method, expressionGen().transformExpression(term), term, term);
} else {
throw new BugException(term, "unhandled primary: " + term == null ? "null" : term.getNodeType());
}
invocation.handleBoxing(true);
invocation.setErased(CodegenUtil.hasTypeErased(term) || getReturnTypeOfCallable(term.getTypeModel()).isNothing());
bodyExpr = expressionGen().transformInvocation(invocation);
} else {
Substitution substitution = null;
JCStatement varDef = null;
// Handle implementations of Java variadic methods
Parameter lastParameter = Decl.getLastParameterFromFirstParameterList(model);
if (lastParameter != null && Decl.isJavaVariadicIncludingInheritance(lastParameter)) {
SyntheticName alias = naming.alias(lastParameter.getName());
substitution = naming.addVariableSubst(lastParameter.getModel(), alias.getName());
varDef = substituteSequentialForJavaVariadic(alias, lastParameter);
}
bodyExpr = expressionGen().transformExpression(model, term);
if (varDef != null) {
// Turn into Let for java variadic methods
bodyExpr = make().LetExpr(List.of(varDef), bodyExpr);
substitution.close();
}
// The innermost of an MPL method declared void needs to return null
returnNull = Decl.isUnboxedVoid(model) && Decl.isMpl(model);
}
if (CodegenUtil.downcastForSmall(term, model)) {
bodyExpr = expressionGen().applyErasureAndBoxing(bodyExpr, term.getTypeModel(), false, !CodegenUtil.isUnBoxed(term), CodegenUtil.getBoxingStrategy(model), model.getType(), ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK);
}
List<JCStatement> body;
if (!Decl.isUnboxedVoid(model) || Decl.isMpl(model) || Strategy.useBoxedVoid(model)) {
if (returnNull) {
body = List.<JCStatement>of(make().Exec(bodyExpr), make().Return(makeNull()));
} else {
body = List.<JCStatement>of(make().Return(bodyExpr));
}
} else {
body = List.<JCStatement>of(make().Exec(bodyExpr));
}
return body;
}
use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.
the class ClassTransformer method addMissingUnrefinedMembers.
/**
* Recover from members not being refined in the class hierarchy
* by generating a stub method that throws.
*/
private void addMissingUnrefinedMembers(Node def, Class classModel, ClassDefinitionBuilder classBuilder) {
for (Reference unrefined : classModel.getUnimplementedFormals()) {
// classModel.getMember(memberName, null, false);
Declaration formalMember = unrefined.getDeclaration();
String errorMessage = "formal member '" + formalMember.getName() + "' of '" + ((TypeDeclaration) formalMember.getContainer()).getName() + "' not implemented in class hierarchy";
java.util.List<Type> params = new java.util.ArrayList<Type>();
for (TypeParameter tp : formalMember.getTypeParameters()) {
params.add(tp.getType());
}
if (formalMember instanceof Value) {
addRefinedThrowerAttribute(classBuilder, errorMessage, def, classModel, (Value) formalMember);
} else if (formalMember instanceof Function) {
addRefinedThrowerMethod(classBuilder, errorMessage, classModel, (Function) formalMember);
} else if (formalMember instanceof Class && formalMember.isClassMember()) {
addRefinedThrowerInstantiatorMethod(classBuilder, errorMessage, classModel, (Class) formalMember, unrefined);
}
// formal member class of interface handled in
// makeDelegateToCompanion()
}
}
use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.
the class ClassTransformer method serializationGet.
private void serializationGet(Class model, ClassDefinitionBuilder classBuilder) {
MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$get$.toString());
mdb.isOverride(true);
mdb.ignoreModelAnnotations();
mdb.modifiers(PUBLIC);
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(this, Unfix.reference.toString());
pdb.modifiers(FINAL);
pdb.type(new TransformedType(make().Type(syms().ceylonReachableReferenceType), null, makeAtNonNull()));
mdb.parameter(pdb);
mdb.resultType(new TransformedType(make().Type(syms().objectType), null, makeAtNonNull()));
/*
* public void $get$(Object reference, Object instance) {
* switch((String)reference) {
* case ("attr1")
* return ...;
* // ... other fields of this class
* case ("lateAttr1")
* if (!$init$lateAttr1) {
* return ceylon.language.serialization.uninitializedLateValue.get_();
* }
* return ...;
* case (null):
* return Outer.this;
* default:
* return super.get(reference);
*/
ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
boolean[] needsLookup = new boolean[] { false };
for (Declaration member : model.getMembers()) {
if (hasField(member)) {
if (member instanceof Function)
// TODO: This class is not serializable
continue;
ListBuffer<JCStatement> caseStmts = new ListBuffer<JCStatement>();
if (member instanceof Value && ((Value) member).isLate()) {
// TODO this should be encapsulated so the ADB and this
// code can just call something common
JCExpression test = AttributeDefinitionBuilder.field(this, null, member.getName(), (Value) member, false).buildUninitTest();
if (test != null) {
caseStmts.add(make().If(test, make().Return(makeLanguageSerializationValue("uninitializedLateValue")), null));
}
}
caseStmts.add(make().Return(makeSerializationGetter((Value) member)));
cases.add(make().Case(make().Literal(member.getQualifiedNameString()), caseStmts.toList()));
}
}
SyntheticName reference = naming.synthetic(Unfix.reference);
ListBuffer<JCStatement> defaultCase = new ListBuffer<JCStatement>();
if (extendsSerializable(model)) {
// super.get(reference);
defaultCase.add(make().Return(make().Apply(null, naming.makeQualIdent(naming.makeSuper(), Unfix.$get$.toString()), List.<JCExpression>of(reference.makeIdent()))));
} else {
// throw (or pass to something else to throw, based on policy)
defaultCase.add(make().Throw(make().NewClass(null, null, naming.makeQuotedFQIdent("java.lang.RuntimeException"), List.<JCExpression>of(make().Literal("unknown attribute")), null)));
}
cases.add(make().Case(null, defaultCase.toList()));
ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
if (needsLookup[0]) {
// if we needed to use a lookup object to reset final fields,
// prepend that variable
stmts.add(makeVar(FINAL, "lookup", naming.makeQualIdent(make().Type(syms().methodHandlesType), "Lookup"), make().Apply(null, naming.makeQuotedFQIdent("java.lang.invoke.MethodHandles.lookup"), List.<JCExpression>nil())));
}
JCSwitch swtch = make().Switch(make().Apply(null, naming.makeSelect(make().Apply(null, naming.makeSelect(make().TypeCast(make().Type(syms().ceylonMemberType), reference.makeIdent()), "getAttribute"), List.<JCExpression>nil()), "getQualifiedName"), List.<JCExpression>nil()), cases.toList());
if (model.isMember() && !model.getExtendedType().getDeclaration().isMember()) {
stmts.add(make().If(make().TypeTest(reference.makeIdent(), make().Type(syms().ceylonOuterType)), make().Return(expressionGen().makeOuterExpr(((TypeDeclaration) model.getContainer()).getType())), swtch));
} else {
stmts.add(swtch);
}
mdb.body(stmts.toList());
classBuilder.method(mdb);
}
Aggregations