blob: aade30f05feaf87503554f48f50e80212cf4a2ce [file] [log] [blame]
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.internal.jobjc.generator.classes;
import java.io.File;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
import com.apple.internal.jobjc.generator.FunctionGenerator;
import com.apple.internal.jobjc.generator.Utils;
import com.apple.internal.jobjc.generator.model.Category;
import com.apple.internal.jobjc.generator.model.Clazz;
import com.apple.internal.jobjc.generator.model.Constant;
import com.apple.internal.jobjc.generator.model.Framework;
import com.apple.internal.jobjc.generator.model.Function;
import com.apple.internal.jobjc.generator.model.NativeEnum;
import com.apple.internal.jobjc.generator.model.StringConstant;
import com.apple.internal.jobjc.generator.model.Struct;
import com.apple.internal.jobjc.generator.model.types.JType;
import com.apple.internal.jobjc.generator.model.types.JType.JStruct;
import com.apple.internal.jobjc.generator.utils.Fp;
import com.apple.internal.jobjc.generator.utils.JavaLang;
import com.apple.internal.jobjc.generator.utils.Fp.Map1;
import com.apple.internal.jobjc.generator.utils.JavaLang.JLCall;
import com.apple.internal.jobjc.generator.utils.JavaLang.JLField;
import com.apple.internal.jobjc.generator.utils.JavaLang.JLMethod;
import com.apple.internal.jobjc.generator.utils.JavaLang.JLReturn;
import com.apple.jobjc.JObjCRuntime;
import com.apple.jobjc.MacOSXFramework;
import com.apple.jobjc.Invoke.FunCall;
public class FrameworkClassFile extends GeneratedClassFile {
final Framework framework;
public FrameworkClassFile(final Framework framework) {
super(framework.pkg, framework.name + "Framework", MacOSXFramework.class.getName());
this.framework = framework;
}
@Override public void writeBeginning(final PrintStream out) {
List<String> binPaths = Fp.map(new Map1<File,String>(){
public String apply(File a) { return "\"" + a.getAbsolutePath() + "\""; }},
framework.binaries);
out.println(new Utils.Substituter(
"#public " + className + "(" + JObjCRuntime.class.getName() + " runtime) {~" +
"##super(runtime, new String[]{" + Fp.join(", ", binPaths) + "});~" +
"#}~"
));
}
@Override public void writeBody(final PrintStream out) {
for(final Struct struct : new ArrayList<Struct>(framework.structs)){
out.println("\tpublic " + struct.name + " make" + struct.name + "(){");
out.println("\t\treturn new " + struct.name + "(getRuntime());");
out.println("\t}");
out.println("\tpublic " + struct.name + " make" + struct.name + "(com.apple.jobjc.NativeBuffer base){");
out.println("\t\treturn new " + struct.name + "(getRuntime(), base);");
out.println("\t}");
}
for(final NativeEnum nenum : framework.enums){
if(nenum.ignore){
out.println("\t/**");
out.println("\t * @deprecated Suggestion: " + nenum.suggestion);
out.println("\t */");
out.println("\t@Deprecated");
}
out.println(String.format("\tpublic final %3$s %1$s(){ return %2$s; }",
nenum.name, nenum.valueToString(), nenum.type.getJType().getJavaReturnTypeName()));
}
for(final Constant konst : framework.constants){
String cacheName = "_" + konst.name;
final JType jtype = konst.type.getJType();
final String cast = jtype.getReturnTypeCast() == null ? "" : "(" + jtype.getReturnTypeCast() + ")";
out.println();
out.print(new JLField("private", jtype.getJavaTypeName(), cacheName, jtype.getDefaultReturnValue()));
JLMethod reader = new JLMethod("public final", jtype.getJavaReturnTypeName(), konst.name);
reader.body.add("if(" + cacheName + " != " + jtype.getDefaultReturnValue() + ") return " + cast + cacheName + ";");
String contextName = jtype instanceof JStruct ? "returnValue" : "nativeBuffer";
if(jtype instanceof JStruct)
reader.body.add(((JStruct)jtype).createReturnValue());
else
reader.body.add(jtype.createDeclareBuffer(contextName));
reader.body.add("getConstant(\"" + konst.name + "\", " + contextName + ", " + jtype.getCoderDescriptor().getCoderInstanceName() + ".sizeof());");
reader.body.add(jtype.createPop(contextName));
reader.body.add(cacheName + " = returnValue;");
reader.body.add(jtype.createReturn());
out.print(reader);
}
for(final StringConstant konst : framework.stringConstants){
if(Fp.any(new Map1<Constant,Boolean>(){ public Boolean apply(Constant a) {
return a.name.equals(konst.name);
}}, new ArrayList<Constant>(framework.constants))){
System.out.println("Warning: [" + framework.name + "] String constant " + konst.name + " is already defined in constants. Skipping.");
}
else{
out.println("\tpublic final String " + konst.name + "(){ return \"" + escapeQuotes(konst.value) + "\"; }");
}
}
/**
* Order classes to get stable output
*/
TreeSet<Clazz> sortedClasses = new TreeSet<Clazz>(framework.classes);
for (final Clazz clazz : sortedClasses) {
final String classClassName = clazz.name + "Class";
out.println(JavaLang.makeSingleton("_" + classClassName, clazz.name, classClassName, "getRuntime()"));
}
for (final Category cat : framework.categories) {
final String classClassName = cat.category.name + "Class";
out.println(JavaLang.makeSingleton("_" + classClassName, cat.category.name, classClassName, "getRuntime()"));
JLMethod jlm = new JLMethod("public", cat.category.name, cat.category.name, "final " + cat.category.superClass.getFullPath() + " obj");
jlm.body.add(new JLReturn(new JLCall("new " + cat.category.name, "obj", "getRuntime()")));
out.println(jlm);
}
for (final Function fxn : framework.functions){
FunctionGenerator.writeOutFunction(out, FunCall.class, fxn, null);
}
}
private String escapeQuotes(String s){
return s.replace("\"", "\\\"");
}
}