use of org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName in project ceylon by eclipse.
the class AbstractTransformer method convertToIntForHashAttribute.
/**
* Turn this long value into an int value by applying (int)(e ^ (e >>> 32))
*/
public JCExpression convertToIntForHashAttribute(JCExpression value) {
SyntheticName tempName = naming.temp("hash");
JCExpression type = make().Type(syms().longType);
JCBinary combine = make().Binary(JCTree.Tag.BITXOR, makeUnquotedIdent(tempName.asName()), make().Binary(JCTree.Tag.USR, makeUnquotedIdent(tempName.asName()), makeInteger(32)));
return make().TypeCast(syms().intType, makeLetExpr(tempName, null, type, value, combine));
}
use of org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName in project ceylon by eclipse.
the class CallBuilder method build.
public JCExpression build() {
if (built) {
throw new BugException("already built");
}
built = true;
JCExpression result;
List<JCExpression> arguments;
final JCExpression newEncl;
if ((cbOpts & CB_ALIAS_ARGS) != 0) {
if (instantiateQualfier != null && instantiateQualfier.expression != null) {
if (instantiateQualfier.type == null) {
throw new BugException(MISSING_TYPE);
}
SyntheticName qualName = getQualifierName(basename);
appendStatement(gen.makeVar(Flags.FINAL, qualName, instantiateQualfier.type, instantiateQualfier.expression));
newEncl = qualName.makeIdent();
} else {
newEncl = null;
}
arguments = List.<JCExpression>nil();
int argumentNum = 0;
for (ExpressionAndType argumentAndType : argumentsAndTypes) {
SyntheticName name = getArgumentName(basename, argumentNum);
if (argumentAndType.type == null) {
throw new BugException(MISSING_TYPE);
}
if ((cbOpts & CB_ALIAS_ARGS) != 0) {
appendStatement(gen.makeVar(Flags.FINAL, name, argumentAndType.type, argumentAndType.expression));
}
arguments = arguments.append(name.makeIdent());
argumentNum++;
}
} else {
newEncl = this.instantiateQualfier != null ? this.instantiateQualfier.expression : null;
arguments = ExpressionAndType.toExpressionList(this.argumentsAndTypes);
}
if (haveLocation) {
gen.at(this.location);
}
switch(kind) {
case APPLY:
result = gen.make().Apply(this.typeargs.toList(), this.methodOrClass, arguments);
break;
case NEW:
result = gen.make().NewClass(newEncl, null, this.methodOrClass, arguments, classDefs);
break;
case ARRAY_READ:
result = gen.make().Indexed(this.methodOrClass, arguments.head);
break;
case ARRAY_WRITE:
{
JCExpression array;
if (arrayWriteNeedsCast)
array = gen.make().TypeCast(gen.make().TypeArray(gen.make().Type(gen.syms().objectType)), this.methodOrClass);
else
array = this.methodOrClass;
result = gen.make().Assign(gen.make().Indexed(array, arguments.head), arguments.tail.head);
}
break;
case NEW_ARRAY:
// methodOrClass must be a ArrayType, so we get the element type out
JCExpression elementTypeExpr = ((JCTree.JCArrayTypeTree) this.methodOrClass).elemtype;
if (arrayInstanceReifiedType == null) {
result = gen.make().NewArray(elementTypeExpr, List.of(arguments.head), null);
if (arrayInstanceCast != null) {
result = gen.make().TypeCast(arrayInstanceCast, result);
}
} else {
List<JCExpression> dimensions = List.nil();
if (arrayInstanceDimensions > 1) {
for (int i = 1; i < arrayInstanceDimensions; i++) {
dimensions = dimensions.prepend(gen.makeInteger(0));
}
}
dimensions = dimensions.prepend(arguments.head);
dimensions = dimensions.prepend(arrayInstanceReifiedType);
result = gen.utilInvocation().makeArray(dimensions);
}
if (arguments.tail.nonEmpty()) {
// must fill it
result = gen.utilInvocation().fillArray(List.of(result, arguments.tail.head));
}
break;
case NEW_ARRAY_WITH:
Declaration d = arrayType.getDeclaration();
if (d.equals(gen.typeFact().getJavaLongArrayDeclaration())) {
result = gen.utilInvocation().toLongArray(arguments.head, arguments.tail);
} else if (d.equals(gen.typeFact().getJavaIntArrayDeclaration())) {
result = gen.utilInvocation().toIntArray(arguments.head, arguments.tail);
} else if (d.equals(gen.typeFact().getJavaShortArrayDeclaration())) {
result = gen.utilInvocation().toShortArray(arguments.head, arguments.tail);
} else if (d.equals(gen.typeFact().getJavaCharArrayDeclaration())) {
result = gen.utilInvocation().toCharArray(arguments.head, arguments.tail);
} else if (d.equals(gen.typeFact().getJavaByteArrayDeclaration())) {
result = gen.utilInvocation().toByteArray(arguments.head, arguments.tail);
} else if (d.equals(gen.typeFact().getJavaBooleanArrayDeclaration())) {
result = gen.utilInvocation().toBooleanArray(arguments.head, arguments.tail);
} else if (d.equals(gen.typeFact().getJavaFloatArrayDeclaration())) {
result = gen.utilInvocation().toFloatArray(arguments.head, arguments.tail);
} else if (d.equals(gen.typeFact().getJavaDoubleArrayDeclaration())) {
result = gen.utilInvocation().toDoubleArray(arguments.head, arguments.tail);
} else {
// it must be an ObjectArray
result = gen.utilInvocation().toArray(arguments.tail.head, // don't use makeClassLiteral, because it doesn't c.l.Object -> j.l.Object
gen.makeSelect(gen.makeJavaType(arrayType.getTypeArgumentList().get(0), AbstractTransformer.JT_NO_PRIMITIVES), "class"), arguments.tail.tail);
}
break;
case FIELD_READ:
result = this.methodOrClass;
break;
default:
throw BugException.unhandledEnumCase(kind);
}
if ((cbOpts & CB_LET) != 0) {
if (voidMethod) {
result = gen.make().LetExpr(statements.toList().append(gen.make().Exec(result)), gen.makeNull());
} else if (!statements.isEmpty()) {
result = gen.make().LetExpr(statements.toList(), result);
}
}
return result;
}
use of org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName in project ceylon by eclipse.
the class CallableBuilder method buildTypeConstructor.
protected JCExpression buildTypeConstructor(Type callableType, JCNewClass callableInstance) {
JCExpression result;
// Wrap in an anonymous TypeConstructor subcla
MethodDefinitionBuilder rawApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.apply.toString());
rawApply.modifiers(Flags.PUBLIC);
rawApply.isOverride(true);
// for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
// apply.typeParameter(tp);
// }
rawApply.resultType(new TransformedType(gen.makeJavaType(callableType, AbstractTransformer.JT_RAW)));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
rawApply.parameter(pdb);
}
rawApply.body(List.<JCStatement>of(gen.make().Return(gen.make().Apply(null, gen.naming.makeUnquotedIdent(Naming.Unfix.$apply$.toString()), List.<JCExpression>of(gen.naming.makeUnquotedIdent("applied"))))));
MethodDefinitionBuilder typedApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.$apply$.toString());
typedApply.modifiers(Flags.PRIVATE);
// for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
// apply.typeParameter(tp);
// }
typedApply.resultType(new TransformedType(gen.makeJavaType(callableType)));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
typedApply.parameter(pdb);
}
ListBuffer<JCTypeParameter> typeParameters = new ListBuffer<JCTypeParameter>();
for (TypeParameter typeParameter : Strategy.getEffectiveTypeParameters(typeModel.getDeclaration())) {
Type typeArgument = typeModel.getTypeArguments().get(typeParameter);
typeParameters.add(gen.makeTypeParameter(typeParameter, null));
typedApply.body(gen.makeVar(Flags.FINAL, gen.naming.getTypeArgumentDescriptorName(typeParameter), gen.make().Type(gen.syms().ceylonTypeDescriptorType), gen.make().Indexed(gen.makeUnquotedIdent("applied"), gen.make().Literal(typeModel.getTypeArgumentList().indexOf(typeArgument)))));
}
typedApply.body(gen.make().Return(callableInstance));
// typedApply.body(body.toList());
MethodDefinitionBuilder ctor = MethodDefinitionBuilder.constructor(gen, false);
ctor.body(gen.make().Exec(gen.make().Apply(null, gen.naming.makeSuper(), List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))))));
SyntheticName n = gen.naming.synthetic(typeModel.getDeclaration().getName());
JCClassDecl classDef = gen.make().ClassDef(gen.make().Modifiers(0, List.<JCAnnotation>nil()), // name,
n.asName(), typeParameters.toList(), // extending
gen.make().QualIdent(gen.syms().ceylonAbstractTypeConstructorType.tsym), // implementing,
List.<JCExpression>nil(), List.<JCTree>of(ctor.build(), rawApply.build(), typedApply.build()));
result = gen.make().LetExpr(List.<JCStatement>of(classDef), gen.make().NewClass(null, null, n.makeIdent(), List.<JCExpression>nil(), // List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))),
null));
return result;
}
use of org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName 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.compiler.java.codegen.Naming.SyntheticName 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