/*******************************************************************************
* Copyright © 2011, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.edt.gen.java.templates;
import java.util.List;
import org.eclipse.edt.gen.java.CommonUtilities;
import org.eclipse.edt.gen.java.Constants;
import org.eclipse.edt.gen.java.Context;
import org.eclipse.edt.mof.codegen.api.TabbedWriter;
import org.eclipse.edt.mof.egl.Expression;
import org.eclipse.edt.mof.egl.Field;
import org.eclipse.edt.mof.egl.FunctionMember;
import org.eclipse.edt.mof.egl.NullLiteral;
import org.eclipse.edt.mof.egl.Part;
import org.eclipse.edt.mof.egl.Record;
import org.eclipse.edt.mof.egl.ReturnStatement;
import org.eclipse.edt.mof.egl.utils.IRUtils;
import org.eclipse.edt.mof.egl.utils.TypeUtils;
public class RecordTemplate extends JavaTemplate {
@SuppressWarnings("unchecked")
public void preGen(Record part, Context ctx) {
// process anything else the superclass needs to do
ctx.invokeSuper(this, preGen, part, ctx);
// Add SMAP file
ctx.setCurrentFile(IRUtils.getQualifiedFileName(part));
// ignore adding this entry to the list, if it is the part we are currently generating
if (((Part) ctx.getAttribute(ctx.getClass(), Constants.SubKey_partBeingGenerated)).getFullyQualifiedName().equalsIgnoreCase(
part.getFullyQualifiedName()))
return;
// when we get here, it is because a part is being referenced by the original part being generated. Add it to the
// parts used table if it doesn't already exist
boolean found = false;
List<Record> records = (List<Record>) ctx.getAttribute(ctx.getClass(), Constants.SubKey_partRecordsUsed);
for (Record record : records) {
if (part.getTypeSignature().equalsIgnoreCase(record.getTypeSignature())) {
found = true;
break;
}
}
if (!found)
records.add(part);
}
public void genConstructor(Record part, Context ctx, TabbedWriter out) {
out.print("public ");
ctx.invoke(genClassName, part, ctx, out);
out.print("(");
ctx.invoke(genAdditionalConstructorParams, part, ctx, out);
out.println(") {");
out.print("super(");
ctx.invoke(genAdditionalSuperConstructorArgs, part, ctx, out);
out.println(");");
out.println("}");
out.println("{");
out.println("ezeInitialize();");
out.println("}");
// generate inherited methods
genConstructorEzeCopy(part, ctx, out);
genConstructorEzeNewValue(part, ctx, out);
genConstructorEzeSetEmpty(part, ctx, out);
genConstructorIsVariableDataLength(part, ctx, out);
genConstructorLoadFromBuffer(part, ctx, out);
genConstructorSizeInBytes(part, ctx, out);
genConstructorStoreInBuffer(part, ctx, out);
}
protected void genConstructorEzeCopy(Record part, Context ctx, TabbedWriter out) {
out.println("public void ezeCopy(Object source) {");
out.print("ezeCopy(");
out.print("(");
ctx.invoke(genClassName, part, ctx, out);
out.println(") source);");
out.println("}");
out.println("public void ezeCopy(eglx.lang.AnyValue source) {");
List<Field> fields = part.getFields();
if (fields != null && fields.size() != 0) {
for (Field field : fields) {
if (TypeUtils.isReferenceType(field.getType()) || ctx.mapsToPrimitiveType(field.getType())) {
out.print("this.");
ctx.invoke(genName, field, ctx, out);
out.print(" = ((");
ctx.invoke(genClassName, part, ctx, out);
out.print(") source).");
ctx.invoke(genName, field, ctx, out);
out.println(";");
} else if (field.isNullable()) {
out.print("this.");
ctx.invoke(genName, field, ctx, out);
out.print(" = ");
out.print("org.eclipse.edt.runtime.java.eglx.lang.AnyValue.ezeCopyTo(");
out.print("((");
ctx.invoke(genClassName, part, ctx, out);
out.print(") source).");
ctx.invoke(genName, field, ctx, out);
out.print(", ");
out.print("this.");
ctx.invoke(genName, field, ctx, out);
out.print(")");
out.println(";");
} else {
out.print("this.");
ctx.invoke(genName, field, ctx, out);
out.print(".ezeCopy(");
out.print("((");
ctx.invoke(genClassName, part, ctx, out);
out.print(") source).");
ctx.invoke(genName, field, ctx, out);
out.println(");");
}
}
}
out.println("}");
}
protected void genConstructorEzeNewValue(Record part, Context ctx, TabbedWriter out) {
out.print("public ");
ctx.invoke(genClassName, part, ctx, out);
out.println(" ezeNewValue(Object... args) {");
out.print("return new ");
ctx.invoke(genClassName, part, ctx, out);
out.println("();");
out.println("}");
}
protected void genConstructorEzeSetEmpty(Record part, Context ctx, TabbedWriter out) {
out.println("public void ezeSetEmpty() {");
List<Field> fields = part.getFields();
if (fields != null && fields.size() != 0) {
for (Field field : fields) {
if (TypeUtils.isReferenceType(field.getType()) || ctx.mapsToPrimitiveType(field.getType())) {
ctx.invoke(genName, field, ctx, out);
out.print(" = ");
ctx.invoke(genInitialization, field, ctx, out);
out.println(";");
} else if (field.isNullable()) {
out.print("if (");
ctx.invoke(genName, field, ctx, out);
out.println(" != null)");
out.print("this.");
ctx.invoke(genName, field, ctx, out);
out.print(".ezeSetEmpty(");
out.println(");");
} else {
out.print("this.");
ctx.invoke(genName, field, ctx, out);
out.print(".ezeSetEmpty(");
out.println(");");
}
}
}
out.println("}");
}
protected void genConstructorIsVariableDataLength(Record part, Context ctx, TabbedWriter out) {
out.println("public boolean isVariableDataLength() {");
out.println("return false;");
out.println("}");
}
protected void genConstructorLoadFromBuffer(Record part, Context ctx, TabbedWriter out) {
out.println("public void loadFromBuffer(ByteStorage buffer, Program program) {");
out.println("}");
}
protected void genConstructorSizeInBytes(Record part, Context ctx, TabbedWriter out) {
out.println("public int sizeInBytes() {");
out.println("return 0;");
out.println("}");
}
protected void genConstructorStoreInBuffer(Record part, Context ctx, TabbedWriter out) {
out.println("public void storeInBuffer(ByteStorage buffer) {");
out.println("}");
}
public void genConstructorOptions(Record part, Context ctx, TabbedWriter out) {}
public void genAccessor(Record part, Context ctx, TabbedWriter out) {
ctx.invoke(genName, part, ctx, out);
}
public void genRuntimeTypeName(Record part, Context ctx, TabbedWriter out, TypeNameKind arg) {
ctx.invoke(genPartName, part, ctx, out);
}
public void genSuperClass(Record part, Context ctx, TabbedWriter out) {
out.print("org.eclipse.edt.runtime.java.eglx.lang.AnyValue");
}
public void genAssignment(Record type, Context ctx, TabbedWriter out, Expression arg1, Expression arg2, String arg3) {
if (TypeUtils.isValueType(type)) {
// because of initialization logic for field declarations, we must always assign as well as ezecopyto
// otherwise, if a null is passed in as the to arg (2nd) and it doesn't get updated on return
ctx.invoke(genExpression, arg1, ctx, out);
out.print(arg3);
out.print("org.eclipse.edt.runtime.java.eglx.lang.AnyValue.ezeCopyTo(");
// if the parameter is non-nullable but the argument is nullable, we have a special case
if (!arg1.isNullable() && arg2.isNullable() && !CommonUtilities.isBoxedOutputTemp(arg2, ctx)) {
out.print("org.eclipse.edt.javart.util.JavartUtil.checkNullable(");
// if this is the null literal, we need to cast this to prevent the javagen ambiguous errors
if (arg2 instanceof NullLiteral)
out.print("(eglx.lang.AnyValue) ");
ctx.invoke(genExpression, arg2, ctx, out);
out.print(")");
} else {
// if this is the null literal, we need to cast this to prevent the javagen ambiguous errors
if (arg2 instanceof NullLiteral)
out.print("(eglx.lang.AnyValue) ");
ctx.invoke(genExpression, arg2, ctx, out);
}
out.print(", ");
ctx.invoke(genExpression, arg1, ctx, out);
out.print(")");
} else {
ctx.invoke(genExpression, arg1, ctx, out);
out.print(arg3);
ctx.invoke(genExpression, arg2, ctx, out);
}
}
public void genReturnStatement(Record type, Context ctx, TabbedWriter out, ReturnStatement arg) {
if (TypeUtils.isValueType(type) && arg.getExpression() != null) {
String temporary = ctx.nextTempName();
ctx.invoke(genRuntimeTypeName, type, ctx, out, TypeNameKind.JavaPrimitive);
out.println(" " + temporary + " = null;");
out.print("return (");
out.print("org.eclipse.edt.runtime.java.eglx.lang.AnyValue.ezeCopyTo(");
Expression returnExpr = IRUtils.makeExprCompatibleToType(arg.getExpression(), ((FunctionMember) arg.getContainer()).getType());
// if the parameter is non-nullable but the argument is nullable, we have a special case
if (!((FunctionMember) arg.getContainer()).isNullable() && arg.getExpression().isNullable() && !CommonUtilities.isBoxedOutputTemp(arg.getExpression(), ctx)) {
out.print("org.eclipse.edt.javart.util.JavartUtil.checkNullable(");
// if this is the null literal, we need to cast this to prevent the javagen ambiguous errors
if (returnExpr instanceof NullLiteral)
out.print("(eglx.lang.AnyValue) ");
ctx.invoke(genExpression, returnExpr, ctx, out);
out.print(")");
} else {
// if this is the null literal, we need to cast this to prevent the javagen ambiguous errors
if (returnExpr instanceof NullLiteral)
out.print("(eglx.lang.AnyValue) ");
ctx.invoke(genExpression, returnExpr, ctx, out);
}
out.print(", ");
out.print(temporary);
out.print(")");
out.print(")");
} else
ctx.invoke(genReturnStatement, arg, ctx, out);
}
public void genGetterSetter(Record part, Context ctx, TabbedWriter out, Field arg) {
ctx.invoke(genGetter, arg, ctx, out);
ctx.invoke(genSetter, arg, ctx, out);
}
}