/*******************************************************************************
* 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.compiler.core.IEGLConstants;
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.Annotation;
import org.eclipse.edt.mof.egl.ConstantField;
import org.eclipse.edt.mof.egl.Constructor;
import org.eclipse.edt.mof.egl.EGLClass;
import org.eclipse.edt.mof.egl.Field;
import org.eclipse.edt.mof.egl.Function;
import org.eclipse.edt.mof.egl.Library;
import org.eclipse.edt.mof.egl.ParameterizedType;
import org.eclipse.edt.mof.egl.Part;
import org.eclipse.edt.mof.egl.Type;
import org.eclipse.edt.mof.egl.utils.IRUtils;
public class EGLClassTemplate extends JavaTemplate {
public void preGenClassBody(EGLClass part, Context ctx) {
ctx.invoke(preGenUsedParts, part, ctx);
ctx.invoke(preGenFields, part, ctx);
ctx.invoke(preGenConstructors, part, ctx);
ctx.invoke(preGenFunctions, part, ctx);
}
public void preGenUsedParts(EGLClass part, Context ctx) {
for (Part item : IRUtils.getReferencedPartsFor(part)) {
ctx.invoke(preGenUsedPart, part, ctx, item);
}
}
public void preGenUsedPart(EGLClass part, Context ctx, Part arg) {
ctx.invoke(preGen, arg, ctx);
}
public void preGenFields(EGLClass part, Context ctx) {
for (Field field : part.getFields()) {
ctx.invoke(preGenField, part, ctx, field);
}
}
public void preGenField(EGLClass part, Context ctx, Field arg) {
ctx.invoke(preGen, arg, ctx);
}
public void preGenConstructors(EGLClass part, Context ctx) {
for (Constructor constructor : part.getConstructors()) {
ctx.invoke(preGenConstructor, part, ctx, constructor);
}
}
public void preGenConstructor(EGLClass part, Context ctx, Constructor arg) {
ctx.invoke(preGen, arg, ctx);
}
public void preGenFunctions(EGLClass part, Context ctx) {
for (Function function : part.getFunctions()) {
ctx.invoke(preGenFunction, part, ctx, function);
}
}
public void preGenFunction(EGLClass part, Context ctx, Function arg) {
ctx.invoke(preGen, arg, ctx);
}
public void genClassHeader(EGLClass part, Context ctx, TabbedWriter out) {
out.print("public ");
if (part.isAbstract()) {
out.print("abstract ");
}
out.print("class ");
ctx.invoke(genClassName, part, ctx, out);
out.print(" extends ");
ctx.invoke(genSuperClass, part, ctx, out);
ctx.invoke(genImplements, part, ctx, out);
out.println(" {");
ctx.invoke(genSerialVersionUID, part, ctx, out);
}
public void genImplements(EGLClass part, Context ctx, TabbedWriter out) {
}
public void genClassBody(EGLClass part, Context ctx, TabbedWriter out) {
// Add this part's file to the smap files list, so that this part is always the first file listed.
String file = IRUtils.getQualifiedFileName(part);
ctx.setCurrentFile(file);
if (ctx.getSmapFiles().indexOf(file) < 0) {
ctx.getSmapFiles().add(file);
}
ctx.invoke(genFields, part, ctx, out);
ctx.invoke(genLibraries, part, ctx, out);
ctx.invoke(genConstructors, part, ctx, out);
ctx.invoke(genInitializeMethods, part, ctx, out);
ctx.invoke(genGetterSetters, part, ctx, out);
ctx.invoke(genLibraryAccessMethods, part, ctx, out);
ctx.invoke(genFunctions, part, ctx, out);
}
public void genFields(EGLClass part, Context ctx, TabbedWriter out) {
for (Field field : part.getFields()) {
ctx.invoke(genField, part, ctx, out, field);
ctx.writeSmapLine();
}
// create the type constraint static hashmap, only if there are some parameterized types
boolean needConstraints = false;
for (Field field : part.getFields()) {
// we only want to add constraints for parameterized types
if (field.getType() instanceof ParameterizedType) {
needConstraints = true;
break;
}
}
if (needConstraints) {
out.println("private static java.util.HashMap<String, TypeConstraints> ezeTypeConstraints = new java.util.HashMap<String, TypeConstraints>();");
out.println("static {");
for (Field field : part.getFields()) {
// we only want to add constraints for parameterized types
if (field.getType() instanceof ParameterizedType) {
out.print("ezeTypeConstraints.put(\"");
ctx.invoke(genName, field, ctx, out);
out.print("\", new TypeConstraints(");
ctx.invoke(genRuntimeConstraint, field.getType(), ctx, out);
out.println("));");
}
}
out.println("}");
}
}
public void genField(EGLClass part, Context ctx, TabbedWriter out, Field arg) {
ctx.invoke(genDeclaration, arg, ctx, out);
}
@SuppressWarnings("unchecked")
public void genLibraries(EGLClass part, Context ctx, TabbedWriter out) {
List<Library> libraries = (List<Library>) ctx.getAttribute(ctx.getClass(), Constants.SubKey_partLibrariesUsed);
for (Library library : libraries) {
ctx.invoke(genLibrary, part, ctx, out, library);
ctx.writeSmapLine();
}
}
public void genLibrary(EGLClass part, Context ctx, TabbedWriter out, Library arg) {
out.print("public ");
ctx.invoke(genRuntimeTypeName, (Type) arg, ctx, out, TypeNameKind.EGLImplementation);
out.println(" " + Constants.LIBRARY_PREFIX + arg.getFullyQualifiedName().replace('.', '_') + ";");
}
public void genConstructors(EGLClass part, Context ctx, TabbedWriter out) {
ctx.invokeSuper(this, genConstructor, part, ctx, out);
for (Constructor constructor : part.getConstructors()) {
ctx.invoke(genConstructor, part, ctx, out, constructor);
ctx.writeSmapLine();
}
}
public void genConstructor(EGLClass part, Context ctx, TabbedWriter out, Constructor arg) {
ctx.invoke(genDeclaration, arg, ctx, out);
}
public void genInitializeMethods(EGLClass part, Context ctx, TabbedWriter out) {
out.println("public void ezeInitialize() {");
ctx.invoke(genInitializeMethodBody, part, ctx, out);
out.println("}");
}
public void genInitializeMethodBody(EGLClass part, Context ctx, TabbedWriter out) {
List<Field> fields = part.getFields();
if (fields.size() > 0) {
// Work around JDT issue - if there is at least 1 field without an initializer and at least 1 with, then add smap entry
// mapped to the part declaration line.
// Otherwise for some reason the stepIntos skip right over the rest of the function. Only do this if there is at
// least one initializer statement.
boolean hasInit = false;
boolean hasNoInit = false;
for (Field field : fields) {
if (!(field instanceof ConstantField)) {
if (field.getInitializerStatements() == null)
hasNoInit = true;
else
hasInit = true;
}
}
if (hasNoInit && hasInit) {
Annotation annotation = part.getAnnotation(IEGLConstants.EGL_LOCATION);
if (annotation != null && annotation.getValue(IEGLConstants.EGL_PARTLINE) != null) {
ctx.getSmapData().append("" + annotation.getValue(IEGLConstants.EGL_PARTLINE));
if (ctx.getCurrentFile() != null) {
if (ctx.getSmapFiles().indexOf(ctx.getCurrentFile()) < 0)
ctx.getSmapFiles().add(ctx.getCurrentFile());
ctx.getSmapData().append("#" + (ctx.getSmapFiles().indexOf(ctx.getCurrentFile()) + 1) + ":");
} else {
ctx.getSmapData().append("#1:");
}
ctx.getSmapData().append("" + out.getLineNumber() + "\n");
}
}
}
// now process the fields that don't have initializer statements
for (Field field : fields) {
if (!(field instanceof ConstantField) && field.getInitializerStatements() == null)
ctx.invoke(genInitializeMethod, part, ctx, out, field);
}
// now process the fields that do have initializer statements
for (Field field : fields) {
if (!(field instanceof ConstantField) && field.getInitializerStatements() != null) {
ctx.genSmapEnd(field, out);
ctx.invoke(genInitializeMethod, part, ctx, out, field);
ctx.writeSmapLine();
}
}
}
public void genInitializeMethod(EGLClass part, Context ctx, TabbedWriter out, Field arg) {
if (!(arg instanceof ConstantField))
ctx.invoke(genInitializeStatement, arg, ctx, out);
}
public void genInstanceInitializer(EGLClass part, Context ctx, TabbedWriter out) {
out.println();
out.println('{');
ctx.invoke(genInstanceInitializerBody, part, ctx, out);
out.println('}');
}
public void genInstanceInitializerBody(EGLClass part, Context ctx, TabbedWriter out) {
// Initialize consts, then invoke ezeInitialize()
for (Field field : part.getFields()) {
ctx.invoke(genInstanceInitializer, part, ctx, out, field);
}
out.println("ezeInitialize();");
}
public void genInstanceInitializer(EGLClass part, Context ctx, TabbedWriter out, Field arg) {
if (arg instanceof ConstantField) {
ctx.invoke(genInitializeStatement, arg, ctx, out);
}
}
public void genGetterSetters(EGLClass part, Context ctx, TabbedWriter out) {
for (Field field : part.getFields()) {
ctx.invoke(genGetterSetter, part, ctx, out, field);
ctx.writeSmapLine();
}
}
// we only generate getter and setters for fields within records or libraries, so do nothing if it gets back here
public void genGetterSetter(EGLClass part, Context ctx, TabbedWriter out, Field arg) {}
@SuppressWarnings("unchecked")
public void genLibraryAccessMethods(EGLClass part, Context ctx, TabbedWriter out) {
List<Library> libraries = (List<Library>) ctx.getAttribute(ctx.getClass(), Constants.SubKey_partLibrariesUsed);
for (Library library : libraries) {
ctx.invoke(genLibraryAccessMethod, part, ctx, out, library);
ctx.writeSmapLine();
}
}
public void genLibraryAccessMethod(EGLClass part, Context ctx, TabbedWriter out, Library arg) {
out.print("public ");
ctx.invoke(genRuntimeTypeName, (Type) arg, ctx, out, TypeNameKind.EGLImplementation);
out.println(" " + Constants.LIBRARY_PREFIX + arg.getFullyQualifiedName().replace('.', '_') + "() {");
out.println("if (" + Constants.LIBRARY_PREFIX + arg.getFullyQualifiedName().replace('.', '_') + " == null) {");
out.print(Constants.LIBRARY_PREFIX + arg.getFullyQualifiedName().replace('.', '_') + " = (");
ctx.invoke(genRuntimeTypeName, (Type) arg, ctx, out, TypeNameKind.EGLImplementation);
out.print(")org.eclipse.edt.javart.Runtime.getRunUnit().loadLibrary(\"");
if (ctx.mapsToNativeType(arg)) {
out.print(ctx.getNativeMapping(arg.getFullyQualifiedName()));
} else {
out.print(CommonUtilities.fullClassAlias(arg));
}
out.println("\");");
out.println("}");
out.println("return " + Constants.LIBRARY_PREFIX + arg.getFullyQualifiedName().replace('.', '_') + ";");
out.println("}");
}
public void genFunctions(EGLClass part, Context ctx, TabbedWriter out) {
for (Function function : part.getFunctions()) {
ctx.invoke(genFunction, part, ctx, out, function);
ctx.writeSmapLine();
}
}
public void genFunction(EGLClass part, Context ctx, TabbedWriter out, Function arg) {
ctx.invoke(genDeclaration, arg, ctx, out);
}
public void genAdditionalConstructorParams(EGLClass part, Context ctx, TabbedWriter out) {}
public void genAdditionalSuperConstructorArgs(EGLClass part, Context ctx, TabbedWriter out) {}
public void genDeclaration(EGLClass part, Context ctx, TabbedWriter out) {}
public void genSuperClass(EGLClass part, Context ctx, TabbedWriter out) {}
public Integer genFieldTypeClassName(EGLClass part, Context ctx, TabbedWriter out, Integer arrayDimensions) {
ctx.invoke(genRuntimeTypeName, part, ctx, out, TypeNameKind.EGLImplementation);
return arrayDimensions;
}
}