001: /**************************************************************************/
002: /* N I C E */
003: /* A high-level object-oriented research language */
004: /* (c) Daniel Bonniot 2002 */
005: /* */
006: /* This program is free software; you can redistribute it and/or modify */
007: /* it under the terms of the GNU General Public License as published by */
008: /* the Free Software Foundation; either version 2 of the License, or */
009: /* (at your option) any later version. */
010: /* */
011: /**************************************************************************/package nice.tools.code;
012:
013: import mlsub.typing.*;
014: import gnu.bytecode.*;
015: import bossa.util.Internal;
016:
017: /**
018: Import native methods.
019:
020: @version $Date: 2004/11/22 14:40:58 $
021: @author Daniel Bonniot (bonniot@users.sourceforge.net)
022: */
023:
024: public class Import {
025: /**
026: Computes the Nice type of a native method.
027:
028: Uses its full signature (JDK 1.5) if available.
029: */
030: public static Polytype type(Method m) {
031: boolean constructor = m.isConstructor();
032:
033: ClassType declaringClass = m.getDeclaringClass();
034: Type[] paramTypes = m.getFullParameterTypes();
035: TypeVariable[] methodTypeParameters = m.getTypeParameters();
036:
037: TypeVariable[] typeParameters = null;
038: TypeSymbol[] niceTP = null;
039:
040: if (m.getStaticFlag()) {
041: if (methodTypeParameters != null) {
042: typeParameters = new TypeVariable[methodTypeParameters.length];
043:
044: for (int i = methodTypeParameters.length; --i >= 0;)
045: typeParameters[i] = methodTypeParameters[i];
046:
047: niceTP = makeTP(typeParameters);
048: }
049: } else {
050: TypeVariable[] classTypeParameters = declaringClass
051: .getParameters();
052: int nParams = classTypeParameters == null ? 0
053: : classTypeParameters.length;
054: nParams += methodTypeParameters == null ? 0
055: : methodTypeParameters.length;
056: if (nParams > 0) {
057: typeParameters = new TypeVariable[nParams];
058:
059: if (methodTypeParameters != null)
060: for (int i = methodTypeParameters.length; --i >= 0;)
061: typeParameters[--nParams] = methodTypeParameters[i];
062:
063: if (classTypeParameters != null)
064: for (int i = classTypeParameters.length; --i >= 0;)
065: typeParameters[--nParams] = classTypeParameters[i];
066:
067: niceTP = makeTP(typeParameters);
068: }
069: }
070:
071: mlsub.typing.Monotype[] params;
072: int n = 0; // index in params
073:
074: try {
075: if (m.getStaticFlag() || constructor)
076: params = new mlsub.typing.Monotype[paramTypes.length];
077: else {
078: params = new mlsub.typing.Monotype[paramTypes.length + 1];
079: params[n++] = Types.monotype(declaringClass.this Type(),
080: true, typeParameters, niceTP);
081: }
082:
083: boolean nonNullArgs = strictPackages.contains(m
084: .getDeclaringClass().getPackageName());
085:
086: for (int i = 0; i < paramTypes.length; i++)
087: params[n++] = Types.monotype(paramTypes[i], /*sure:*/
088: nonNullArgs, typeParameters, niceTP);
089:
090: gnu.bytecode.Type javaRetType = constructor ? declaringClass
091: .this Type()
092: : m.getFullReturnType();
093: mlsub.typing.Monotype retType = Types.monotype(javaRetType,
094: true, typeParameters, niceTP);
095:
096: Constraint cst = niceTP == null ? null : new Constraint(
097: niceTP, null);
098: return new Polytype(cst, new FunType(params, retType));
099: } catch (Types.ParametricClassException e) {
100: // The fetched method involves parametric java classes.
101: // Ignore.
102: Internal.warning("Java method " + m
103: + " was ignored.\nReason: " + e);
104: return null;
105: } catch (Types.NotIntroducedClassException e) {
106: // The fetched method involves invalid types.
107: // Ignore.
108: Internal.warning("Java method " + m
109: + " was ignored.\nReason: " + e);
110: return null;
111: }
112: }
113:
114: private static TypeSymbol[] makeTP(TypeVariable[] vars) {
115: TypeSymbol[] res = new TypeSymbol[vars.length];
116: for (int i = 0; i < vars.length; i++)
117: res[i] = new MonotypeVar(vars[i].getName());
118: return res;
119: }
120:
121: /****************************************************************
122: * Retyping policies
123: ****************************************************************/
124:
125: private static java.util.HashSet strictPackages = new java.util.HashSet();
126:
127: static void reset() {
128: strictPackages.clear();
129: }
130:
131: public static void addStrictPackage(String name) {
132: strictPackages.add(name);
133: }
134:
135: public static boolean isStrictPackage(String name) {
136: return strictPackages.contains(name);
137: }
138: }
|