/* * synchronized Class emit() * { * if (cls == null) * cls = FPodEmit.emitAndLoad(fpod); * return cls; * } * * synchronized void precompiled(Class cls) * throws Exception * { * this.cls = cls; * FPodEmit.initFields(fpod, cls); * } */ internal Type findType(int qname) { if (qname == 0xFFFF || qname == -1) { return(null); } // lookup type with typeRef index FTypeRef reference = fpod.typeRef(qname); // if generic instance, then this type must be used in a method // signature, not type meta-data (b/c I can't subclass generic types), // so it's safe that my pod has been loaded and is now registered (in // case the generic type is parameterized via types in my pod) if (reference.isGenericInstance()) { return(TypeParser.load(reference.signature, true, this)); } // otherwise I need to handle if I am loading my own pod, because // I might not yet be added to the system namespace if I'm just // loading my own hollow types string podName = reference.podName; string typeName = reference.typeName; Pod pod = podName == m_name ? this : doFind(podName, true, null); Type type = pod.type(typeName, false); if (type != null) { if (reference.isNullable()) { type = type.toNullable(); } return(type); } // handle generic parameter types (for sys pod only) if (m_name == "sys") { type = Sys.genericParamType(typeName); if (type != null) { if (reference.isNullable()) { type = type.toNullable(); } return(type); } } // lost cause throw UnknownTypeErr.make(podName + "::" + typeName).val; }
/// <summary> /// Parameterize t, where t is a generic parameter type such as V. /// </summary> internal Type parameterize(Type t) { bool nullable = t.isNullable(); Type nn = t.toNonNullable(); if (nn is ListType) { t = parameterizeListType((ListType)nn); } else if (nn is FuncType) { t = parameterizeFuncType((FuncType)nn); } else { t = doParameterize(nn); } return(nullable ? t.toNullable() : t); }
/// <summary> /// Given a list of objects, compute the most specific type which they all /// share,or at worst return sys::Obj. This method does not take into /// account interfaces, only extends class inheritance. /// </summary> public static Type common(object[] objs, int n) { if (objs.Length == 0) { return(Sys.ObjType.toNullable()); } bool nullable = false; Type best = null; for (int i = 0; i < n; ++i) { object obj = objs[i]; if (obj == null) { nullable = true; continue; } Type t = @typeof(obj); if (best == null) { best = t; continue; } while (!t.@is(best)) { best = best.@base(); if (best == null) { return(nullable ? Sys.ObjType.toNullable() : Sys.ObjType); } } } if (best == null) { best = Sys.ObjType; } return(nullable ? best.toNullable() : best); }
/// <summary> /// Parameterize t, where t is a generic parameter type such as V. /// </summary> internal Type parameterize(Type t) { bool nullable = t.isNullable(); Type nn = t.toNonNullable(); if (nn is ListType) t = parameterizeListType((ListType)nn); else if (nn is FuncType) t = parameterizeFuncType((FuncType)nn); else t = doParameterize(nn); return nullable ? t.toNullable() : t; }
////////////////////////////////////////////////////////////////////////// // Collection ////////////////////////////////////////////////////////////////////////// /// <summary> /// collection := list | map /// </summary> private object readCollection(Field curField, Type t) { // opening [ consume(Token.LBRACKET, "Expecting '['"); // if this could be a map type signature: // [qname:qname] // [qname:qname][] // [qname:qname][][] ... // or it could just be the type signature of // of a embedded simple, complex, or list Type peekType = null; if (curt == Token.ID && t == null) { // peek at the type peekType = readType(); // if we have [mapType] then this is non-inferred type signature if (curt == Token.RBRACKET && peekType is MapType) { t = peekType; peekType = null; consume(); while (curt == Token.LRBRACKET) { consume(); t = t.toListOf(); } if (curt == Token.QUESTION) { consume(); t = t.toNullable(); } if (curt == Token.POUND) { consume(); return t; } consume(Token.LBRACKET, "Expecting '['"); } } // handle special case of [,] if (curt == Token.COMMA && peekType == null) { consume(); consume(Token.RBRACKET, "Expecting ']'"); return new List(toListOfType(t, curField, false)); } // handle special case of [:] if (curt == Token.COLON && peekType == null) { consume(); consume(Token.RBRACKET, "Expecting ']'"); return new Map(toMapType(t, curField, false)); } // read first list item or first map key object first = readObj(null, peekType, false); // now we can distinguish b/w list and map if (curt == Token.COLON) return readMap(toMapType(t, curField, true), first); else return readList(toListOfType(t, curField, true), first); }