blob: 82ee3f7aaef7f0c86a400335157a477293200b91 [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.model.types;
import com.apple.internal.jobjc.generator.model.CFType;
import com.apple.internal.jobjc.generator.model.Clazz;
import com.apple.internal.jobjc.generator.model.Opaque;
import com.apple.internal.jobjc.generator.model.Struct;
import com.apple.internal.jobjc.generator.model.coders.ComplexCoderDescriptor;
import com.apple.internal.jobjc.generator.model.types.JType.JCFType;
import com.apple.internal.jobjc.generator.model.types.JType.JClass;
import com.apple.internal.jobjc.generator.model.types.JType.JObject;
import com.apple.internal.jobjc.generator.model.types.JType.JOpaque;
import com.apple.internal.jobjc.generator.model.types.JType.JPointer;
import com.apple.internal.jobjc.generator.model.types.JType.JPrimitive;
import com.apple.internal.jobjc.generator.model.types.JType.JSelector;
import com.apple.internal.jobjc.generator.model.types.JType.JStruct;
import com.apple.internal.jobjc.generator.model.types.JType.JUnknown;
import com.apple.internal.jobjc.generator.model.types.JType.JVoid;
import com.apple.internal.jobjc.generator.model.types.NType.NClass;
import com.apple.internal.jobjc.generator.model.types.NType.NObject;
import com.apple.internal.jobjc.generator.model.types.NType.NPointer;
import com.apple.internal.jobjc.generator.model.types.NType.NPrimitive;
import com.apple.internal.jobjc.generator.model.types.NType.NSelector;
import com.apple.internal.jobjc.generator.model.types.NType.NStruct;
import com.apple.internal.jobjc.generator.model.types.NType.NVoid;
import com.apple.internal.jobjc.generator.utils.Fp.CacheMap;
import com.apple.internal.jobjc.generator.utils.Fp.Dispatcher;
import com.apple.internal.jobjc.generator.utils.Fp.Map0;
public class TypeToJType {
private static TypeToJType INST = new TypeToJType();
public static TypeToJType inst(){ return INST; }
private CacheMap<Type,JType> cache = new CacheMap<Type,JType>();
public JType getJTypeFor(final Type type){
return cache.get(type, new Map0<JType>(){
public JType apply() {
try {
return Dispatcher.dispatch(TypeToJType.this.getClass(), TypeToJType.this, "accept", type, type.type32, type.type64);
} catch (NoSuchMethodException e) {
return new JUnknown(type);
}
}});
}
protected JType accept(Type type, NObject nt32, NObject nt64){
if ("id".equals(type.name)) return JObject.ID_TYPE;
final String className = type.name.replaceAll("\\*$", "");
assert !className.endsWith("*");
final Clazz clazz = TypeCache.inst().getClassForName(className);
if (clazz == null) return new JUnknown(type);
// TODO Instead of JUnknown, ID_TYPE might be more appropriate. Investigate.
return new JObject(type, clazz);
}
protected JType accept(Type type, NPointer nt32, NPointer nt64){
final CFType cfType = TypeCache.inst().getCFTypeForName(type.name);
if(cfType != null) return new JCFType(cfType);
final Opaque opaque = TypeCache.inst().getOpaqueForName(type.name);
if(opaque != null) return new JOpaque(opaque);
if("void*".equals(type.name)) return JPointer.VOID_PTR;
if(type.name != null && type.name.endsWith("*")){
final String subDeclaredType = type.name.substring(0, type.name.length() - 1);
final Type subType = TypeCache.inst().getTypeByName(subDeclaredType);
if (subType == null) return new JUnknown(type);
// TODO Instead of JUnknown, VOID_PTR might be a good fallback. Investigate.
final JType javaType = TypeToJType.inst().getJTypeFor(subType).getParameterizableType();
final JPointer pointer = new JPointer(javaType);
return pointer;
}
return new JUnknown(type);
}
protected JType accept(Type type, NPrimitive nt32, NPrimitive nt64){
final ComplexCoderDescriptor coderDesc = ComplexCoderDescriptor.getCoderDescriptorFor(type.type32, type.type64);
if (coderDesc == null) return null;
return new JPrimitive(type, coderDesc);
}
protected JType accept(Type type, NVoid nt32, NVoid nt64){
return JVoid.INST;
}
protected JType accept(Type type, NSelector nt32, NSelector nt64){
return JSelector.INST;
}
protected JType accept(Type type, NClass nt32, NClass nt64){
return JClass.INST;
}
protected JType accept(Type type, NStruct nt32, NStruct nt64){
Struct st = TypeCache.inst().getStructForName(type.name);
return st != null ? new JStruct(st) : new JUnknown(type);
// TODO We could probably generate a struct here based on the type. But we need access to its parent framework.
// Maybe we could use a fallback anonymous struct, but we need the SIZEOF.
}
}