/* * 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("\"", "\\\""); } }