/// <summary> /// Returns the key/value pair for this key. /// </summary> /// <param name="key">The key to retrieve</param> /// <returns>The key/value pair for the key, or null if the key is not in the map.</returns> public override IMapEntry entryAt(object key) { IMapEntry me = _def.Keyslots.entryAt(key); return(me == null ? _ext.entryAt(key) : new MapEntry(me.key(), _vals[Util.ConvertToInt(me.val())])); }
public void EntryAtOnIndexInRangeReturnsEntry() { CPV v = new CPV(new object[] { 4, 5, 6 }); IMapEntry me = v.entryAt(1); Expect(me.key(), EqualTo(1)); Expect(me.val(), EqualTo(5)); }
private static CustomAttributeBuilder CreateCustomAttributeBuilder(IMapEntry me) { Type t = (Type)me.key(); IPersistentMap args = (IPersistentMap)me.val(); object[] ctorArgs = new object[0]; Type[] ctorTypes = Type.EmptyTypes; List <PropertyInfo> pInfos = new List <PropertyInfo>(); List <Object> pVals = new List <object>(); List <FieldInfo> fInfos = new List <FieldInfo>(); List <Object> fVals = new List <object>(); for (ISeq s = RT.seq(args); s != null; s = s.next()) { IMapEntry m2 = (IMapEntry)s.first(); Keyword k = (Keyword)m2.key(); object v = m2.val(); if (k == ARGS_KEY) { ctorArgs = GetCtorArgs((IPersistentVector)v); ctorTypes = GetCtorTypes(ctorArgs); } else { string name = k.Name; PropertyInfo pInfo = t.GetProperty(name); if (pInfo != null) { pInfos.Add(pInfo); pVals.Add(v); continue; } FieldInfo fInfo = t.GetField(name); if (fInfo != null) { fInfos.Add(fInfo); fVals.Add(v); continue; } throw new ArgumentException(String.Format("Unknown field/property: {0} for attribute: {1}", k.Name, t.FullName)); } } ConstructorInfo ctor = t.GetConstructor(ctorTypes); if (ctor == null) { throw new ArgumentException(String.Format("Unable to find constructor for attribute: {0}", t.FullName)); } CustomAttributeBuilder cb = new CustomAttributeBuilder(ctor, ctorArgs, pInfos.ToArray(), pVals.ToArray(), fInfos.ToArray(), fVals.ToArray()); return(cb); }
public void SeqOnNonEmptyIterates() { Dictionary <int, string> d = new Dictionary <int, string>(); d[1] = "a"; d[2] = "b"; IPersistentMap m = PersistentArrayMap.create(d); ISeq s = m.seq(); IMapEntry me1 = (IMapEntry)s.first(); IMapEntry me2 = (IMapEntry)s.next().first(); ISeq end = s.next().next(); Expect(s.count(), EqualTo(2)); Expect(me1.key(), EqualTo(1) | EqualTo(2)); Expect(me1.val(), EqualTo(((int)me1.key() == 1 ? "a" : "b"))); Expect(me2.key(), EqualTo(1) | EqualTo(2)); Expect(me2.val(), EqualTo(((int)me2.key() == 1 ? "a" : "b"))); Expect(end, Null); }
public void EntryAtOnExistingKeyWorks() { MapEntry me = new MapEntry(1, "abc"); IMapEntry me1 = me.entryAt(0); IMapEntry me2 = me.entryAt(1); Expect(me1.key()).To.Equal(0); Expect(me1.val()).To.Equal(1); Expect(me2.key()).To.Equal(1); Expect(me2.val()).To.Equal("abc"); }
private static IPersistentVector flattenMap(object form) { IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); keyvals = (IPersistentVector)keyvals.cons(e.key()); keyvals = (IPersistentVector)keyvals.cons(e.val()); } return(keyvals); }
public void EntryAtReturnsEntryforKey() { Dictionary <int, string> d = new Dictionary <int, string>(); d[1] = "a"; d[2] = "b"; IPersistentMap m = PersistentArrayMap.create(d); IMapEntry me = m.entryAt(1); Expect(me.key(), EqualTo(1)); Expect(me.val(), EqualTo("a")); }
public static Associative getThreadBindings() { Frame f = CurrentFrame; IPersistentMap ret = PersistentHashMap.EMPTY; for (ISeq bs = f.Bindings.seq(); bs != null; bs = bs.next()) { IMapEntry e = (IMapEntry)bs.first(); Var v = (Var)e.key(); TBox b = (TBox)e.val(); ret = ret.assoc(v, b.Val); } return(ret); }
public void IDictionary_GetEnumerator_returns_an_enumerator() { Dictionary <int, string> d = new Dictionary <int, string>(); d[1] = "a"; d[2] = "b"; IDictionary id = (IDictionary)PersistentArrayMap.create(d); IDictionaryEnumerator e = id.GetEnumerator(); Expect(e.MoveNext()); IMapEntry de1 = (IMapEntry)e.Current; Expect(e.MoveNext()); IMapEntry de2 = (IMapEntry)e.Current; Expect(e.MoveNext(), False); Expect(de1.key(), EqualTo(1) | EqualTo(2)); Expect(de2.key(), EqualTo(1) | EqualTo(2)); Expect(de1.val(), EqualTo(((int)de1.key()) == 1 ? "a" : "b")); Expect(de2.val(), EqualTo(((int)de2.key()) == 1 ? "a" : "b")); }
public static Expr Parse(IPersistentMap form) { IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); keyvals = (IPersistentVector)keyvals.cons(Compiler.GenerateAST(e.key())); keyvals = (IPersistentVector)keyvals.cons(Compiler.GenerateAST(e.val())); } Expr ret = new MapExpr(keyvals); return(Compiler.OptionallyGenerateMetaInit(form, ret)); }
/// <summary> /// Get the method for a dispatch value and cache it. /// </summary> /// <param name="dispatchVal">The disaptch value.</param> /// <returns>The mest method.</returns> private IFn FindAndCacheBestMethod(object dispatchVal) { IMapEntry bestEntry = null; foreach (IMapEntry me in MethodTable) { if (IsA(dispatchVal, me.key())) { if (bestEntry == null || Dominates(me.key(), bestEntry.key())) { bestEntry = me; } if (!Dominates(bestEntry.key(), me.key())) { throw new ArgumentException(String.Format("Multiple methods in multimethod {0} match dispatch value: {1} -> {2} and {3}, and neither is preferred", _name, dispatchVal, me.key(), bestEntry.key())); } } } if (bestEntry == null) { return(null); } // ensure basis has stayed stable throughout, else redo if (_cachedHierarchy == _hierarchy.deref()) { // place in cache _methodCache = _methodCache.assoc(dispatchVal, bestEntry.val()); return((IFn)bestEntry.val()); } else { ResetCache(); return(FindAndCacheBestMethod(dispatchVal)); } }
/// <summary> /// Push a new frame of bindings onto the binding stack. /// </summary> /// <param name="bindings">The new bindings.</param> /// <remarks>Lowercase name for core.clj compatability.</remarks> public static void pushThreadBindings(Associative bindings) { Frame f = CurrentFrame; Associative bmap = f.Bindings; for (ISeq bs = bindings.seq(); bs != null; bs = bs.next()) { IMapEntry e = (IMapEntry)bs.first(); Var v = (Var)e.key(); v.Validate(e.val()); v._count.incrementAndGet(); bmap = bmap.assoc(v, new Box(e.val())); } CurrentFrame = new Frame(bindings, bmap, f); }
private static List <CustomAttributeBuilder> CreateCustomAttributeBuilders(IMapEntry me) { Type t = (Type)me.key(); IPersistentSet inits = (IPersistentSet)me.val(); List <CustomAttributeBuilder> builders = new List <CustomAttributeBuilder>(inits.count()); for (ISeq s = RT.seq(inits); s != null; s = s.next()) { IPersistentMap init = (IPersistentMap)s.first(); builders.Add(CreateCustomAttributeBuilder(t, init)); } return(builders); }
public override object first() { object entry = _seq.first(); IMapEntry me = entry as IMapEntry; if (me != null) { return(me.key()); } else if (entry is DictionaryEntry) { return(((DictionaryEntry)entry).Key); } throw new InvalidCastException("Cannot convert hashtable entry to IMapEntry or DictionaryEntry"); }
public static Expr Parse(ParserContext pcon, IPersistentMap form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool keysConstant = true; bool valsConstant = true; bool allConstantKeysUnique = true; IPersistentSet constantKeys = PersistentHashSet.EMPTY; IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); Expr k = Compiler.Analyze(pconToUse, e.key()); Expr v = Compiler.Analyze(pconToUse, e.val()); keyvals = (IPersistentVector)keyvals.cons(k); keyvals = (IPersistentVector)keyvals.cons(v); if (k is LiteralExpr) { object kval = k.Eval(); if (constantKeys.contains(kval)) { allConstantKeysUnique = false; } else { constantKeys = (IPersistentSet)constantKeys.cons(kval); } } else { keysConstant = false; } if (!(v is LiteralExpr)) { valsConstant = false; } } Expr ret = new MapExpr(keyvals); if (form is IObj iobjForm && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); }
/// <summary> /// Notify all watchers. /// </summary> public void notifyWatches(object oldval, object newval) { IPersistentMap ws = _watches; if (ws.count() > 0) { for (ISeq s = ws.seq(); s != null; s = s.next()) { IMapEntry me = (IMapEntry)s.first(); IFn fn = (IFn)me.val(); if (fn != null) { fn.invoke(me.key(), this, oldval, newval); } } } }
public static void pushThreadBindings(Associative bindings) { Frame f = CurrentFrame; Associative bmap = f.Bindings; for (ISeq bs = bindings.seq(); bs != null; bs = bs.next()) { IMapEntry e = (IMapEntry)bs.first(); Var v = (Var)e.key(); if (!v._dynamic) { throw new InvalidOperationException(String.Format("Can't dynamically bind non-dynamic var: {0}/{1}", v.Namespace, v.Symbol)); } v.Validate(e.val()); v._threadBound.set(true); bmap = bmap.assoc(v, new TBox(Thread.CurrentThread, e.val())); } CurrentFrame = new Frame(bmap, f); }
public static Expr Parse(ParserContext pcon, IPersistentMap form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool constant = true; IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); Expr k = Compiler.Analyze(pconToUse, e.key()); Expr v = Compiler.Analyze(pconToUse, e.val()); keyvals = (IPersistentVector)keyvals.cons(k); keyvals = (IPersistentVector)keyvals.cons(v); if (!(k is LiteralExpr && v is LiteralExpr)) { constant = false; } } Expr ret = new MapExpr(keyvals); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); } else if (constant) { // This 'optimzation' works, mostly, unless you have nested map values. // The nested map values do not participate in the constants map, so you end up with the code to create the keys. // Result: huge duplication of keyword creation. 3X increase in init time to the REPL. //IPersistentMap m = PersistentHashMap.EMPTY; //for (int i = 0; i < keyvals.length(); i += 2) // m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val); //return new ConstantExpr(m); return(ret); } else { return(ret); } }
public ITransientMap conj(object val) { EnsureEditable(); { IMapEntry e = val as IMapEntry; if (e != null) { return(assoc(e.key(), e.val())); } } if (val is DictionaryEntry) { DictionaryEntry de = (DictionaryEntry)val; return(assoc(de.Key, de.Value)); } { IPersistentVector v = val as IPersistentVector; if (v != null) { if (v.count() != 2) { throw new ArgumentException("Vector arg to map conj must be a pair"); } return(assoc(v.nth(0), v.nth(1))); } } // TODO: also handle KeyValuePair? ITransientMap ret = this; for (ISeq es = RT.seq(val); es != null; es = es.next()) { IMapEntry e = (IMapEntry)es.first(); ret = ret.assoc(e.key(), e.val()); } return(ret); }
private static CustomAttributeBuilder CreateCustomAttributeBuilder(IMapEntry me) { Type t = (Type) me.key(); IPersistentMap args = (IPersistentMap)me.val(); object[] ctorArgs = new object[0]; Type[] ctorTypes = Type.EmptyTypes; List<PropertyInfo> pInfos = new List<PropertyInfo>(); List<Object> pVals = new List<object>(); List<FieldInfo> fInfos = new List<FieldInfo>(); List<Object> fVals = new List<object>(); for (ISeq s = RT.seq(args); s != null; s = s.next()) { IMapEntry m2 = (IMapEntry)s.first(); Keyword k = (Keyword) m2.key(); object v = m2.val(); if (k == ARGS_KEY) { ctorArgs = GetCtorArgs((IPersistentVector)v); ctorTypes = GetCtorTypes(ctorArgs); } else { string name = k.Name; PropertyInfo pInfo = t.GetProperty(name); if (pInfo != null) { pInfos.Add(pInfo); pVals.Add(v); continue; } FieldInfo fInfo = t.GetField(name); if (fInfo != null) { fInfos.Add(fInfo); fVals.Add(v); continue; } throw new ArgumentException(String.Format("Unknown field/property: {0} for attribute: {1}", k.Name, t.FullName)); } } ConstructorInfo ctor = t.GetConstructor(ctorTypes); if (ctor == null) throw new ArgumentException(String.Format("Unable to find constructor for attribute: {0}", t.FullName)); CustomAttributeBuilder cb = new CustomAttributeBuilder(ctor,ctorArgs,pInfos.ToArray(),pVals.ToArray(),fInfos.ToArray(),fVals.ToArray()); return cb; }
private static void EmitExposers(TypeBuilder proxyTB, Type superClass, IPersistentMap exposesFields) { for (ISeq s = RT.seq(exposesFields); s != null; s = s.next()) { IMapEntry me = (IMapEntry)s.first(); Symbol protectedFieldSym = (Symbol)me.key(); IPersistentMap accessMap = (IPersistentMap)me.val(); string fieldName = protectedFieldSym.Name; Symbol getterSym = (Symbol)accessMap.valAt(_getKw, null); Symbol setterSym = (Symbol)accessMap.valAt(_setKW, null); FieldInfo fld = null; if (getterSym != null || setterSym != null) { fld = superClass.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance); } if (getterSym != null) { MethodAttributes attribs = MethodAttributes.Public; if (fld.IsStatic) { attribs |= MethodAttributes.Static; } MethodBuilder mb = proxyTB.DefineMethod(getterSym.Name, attribs, fld.FieldType, Type.EmptyTypes); CljILGen gen = new CljILGen(mb.GetILGenerator()); //if (fld.IsStatic) // gen.Emit(OpCodes.Ldsfld, fld); //else //{ // gen.Emit(OpCodes.Ldarg_0); // gen.Emit(OpCodes.Ldfld, fld); //} if (!fld.IsStatic) { gen.EmitLoadArg(0); } gen.MaybeEmitVolatileOp(fld); gen.EmitFieldGet(fld); gen.Emit(OpCodes.Ret); } if (setterSym != null) { MethodAttributes attribs = MethodAttributes.Public; if (fld.IsStatic) { attribs |= MethodAttributes.Static; } MethodBuilder mb = proxyTB.DefineMethod(setterSym.Name, attribs, typeof(void), new Type[] { fld.FieldType }); CljILGen gen = new CljILGen(mb.GetILGenerator()); if (fld.IsStatic) { gen.Emit(OpCodes.Ldarg_0); //gen.Emit(OpCodes.Stsfld, fld); } else { gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); //gen.Emit(OpCodes.Stfld, fld); } gen.MaybeEmitVolatileOp(fld); gen.EmitFieldSet(fld); gen.Emit(OpCodes.Ret); } } }
static void DefineCtors(TypeBuilder proxyTB, Type superClass, string initName, string postInitName, ISeq ctors, ISeq ctorTypes, FieldBuilder initFB, FieldBuilder postInitFB, FieldBuilder stateFB, string factoryName) { ISeq s1 = ctors; for (ISeq s = ctorTypes; s != null; s = s.next()) { // TODO: Get rid of this mess by making sure the metadata on the keys of the constructors map gets copied to the constructor-types map. Sigh. IPersistentMap ctorAttributes = GenInterface.ExtractAttributes(RT.meta(((IMapEntry)s1.first()).key())); s1 = s1.next(); IMapEntry me = (IMapEntry)s.first(); ISeq thisParamTypesV = (ISeq)me.key(); ISeq baseParamTypesV = (ISeq)me.val(); Type[] thisParamTypes = CreateTypeArray(thisParamTypesV); Type[] baseParamTypes = CreateTypeArray(baseParamTypesV); BindingFlags flags = BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; ConstructorInfo superCtor = superClass.GetConstructor(flags, null, baseParamTypes, null); if (superCtor == null || superCtor.IsPrivate) { throw new InvalidOperationException("Base class constructor missing or private"); } ConstructorBuilder cb = proxyTB.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, thisParamTypes); GenInterface.SetCustomAttributes(cb, ctorAttributes); CljILGen gen = new CljILGen(cb.GetILGenerator()); Label noInitLabel = gen.DefineLabel(); Label noPostInitLabel = gen.DefineLabel(); Label endPostInitLabel = gen.DefineLabel(); Label endLabel = gen.DefineLabel(); LocalBuilder locSuperArgs = gen.DeclareLocal(typeof(object)); LocalBuilder locInitVal = gen.DeclareLocal(typeof(object)); if (initFB != null) { // init supplied EmitGetVar(gen, initFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, noInitLabel); gen.Emit(OpCodes.Castclass, typeof(IFn)); // box init args for (int i = 0; i < thisParamTypes.Length; i++) { gen.EmitLoadArg(i + 1); // gen.Emit(OpCodes.Ldarg, i + 1); if (thisParamTypes[i].IsValueType) { gen.Emit(OpCodes.Box, thisParamTypes[i]); } } gen.EmitCall(Compiler.Methods_IFn_invoke[thisParamTypes.Length]); // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[thisParamTypes.Length]); // Expecting: [[super-ctor-args...] state] // store the init return in a local gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Stloc, locInitVal); // store the first element in a local gen.EmitInt(0); // gen.Emit(OpCodes.Ldc_I4_0); gen.EmitCall(Method_RT_nth); // gen.Emit(OpCodes.Call, Method_RT_nth); gen.Emit(OpCodes.Stloc, locSuperArgs); // Stack this + super-ctor-args + call base-class ctor. gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); for (int i = 0; i < baseParamTypes.Length; i++) { gen.Emit(OpCodes.Ldloc, locSuperArgs); gen.EmitInt(i); // gen.Emit(OpCodes.Ldc_I4, i); gen.EmitCall(Method_RT_nth); // gen.Emit(OpCodes.Call, Method_RT_nth); if (baseParamTypes[i].IsValueType) { gen.Emit(OpCodes.Unbox_Any, baseParamTypes[i]); } else { gen.Emit(OpCodes.Castclass, baseParamTypes[i]); } } gen.Emit(OpCodes.Call, superCtor); if (stateFB != null) { gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldloc, locInitVal); gen.EmitInt(1); // gen.Emit(OpCodes.Ldc_I4_1); gen.EmitCall(Method_RT_nth); // gen.Emit(OpCodes.Call, Method_RT_nth); gen.Emit(OpCodes.Castclass, typeof(object)); gen.EmitFieldSet(stateFB); // gen.Emit(OpCodes.Stfld, stateFB); } gen.Emit(OpCodes.Br_S, endLabel); // No init found gen.MarkLabel(noInitLabel); gen.Emit(OpCodes.Pop); EmitUnsupported(gen, initName); gen.MarkLabel(endLabel); } else // no InitFB supplied. { bool ok = thisParamTypes.Length == baseParamTypes.Length; for (int i = 0; ok && i < thisParamTypes.Length; i++) { ok = baseParamTypes[i].IsAssignableFrom(thisParamTypes[i]); } if (!ok) { throw new InvalidOperationException(":init not specified, but ctor and super ctor args differ"); } gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); for (int i = 0; i < thisParamTypes.Length; i++) { gen.EmitLoadArg(i + 1); // gen.Emit(OpCodes.Ldarg, i + 1); if (baseParamTypes[i] != thisParamTypes[i]) { gen.Emit(OpCodes.Castclass, baseParamTypes[i]); } } gen.Emit(OpCodes.Call, superCtor); } if (postInitFB != null) { // post-init supplied EmitGetVar(gen, postInitFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, noPostInitLabel); gen.Emit(OpCodes.Castclass, typeof(IFn)); // box init args gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); for (int i = 0; i < thisParamTypes.Length; i++) { gen.EmitLoadArg(i + 1); // gen.Emit(OpCodes.Ldarg, i + 1); if (thisParamTypes[i].IsValueType) { gen.Emit(OpCodes.Box, thisParamTypes[i]); } gen.Emit(OpCodes.Castclass, thisParamTypes[i]); } gen.EmitCall(Compiler.Methods_IFn_invoke[thisParamTypes.Length + 1]); // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[thisParamTypes.Length + 1]); gen.Emit(OpCodes.Pop); gen.Emit(OpCodes.Br_S, endPostInitLabel); // no post-init found gen.MarkLabel(noPostInitLabel); gen.Emit(OpCodes.Pop); EmitUnsupported(gen, postInitName + " not defined"); gen.MarkLabel(endPostInitLabel); } gen.Emit(OpCodes.Ret); if (!String.IsNullOrEmpty(factoryName)) { MethodBuilder factoryMB = proxyTB.DefineMethod(factoryName, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, proxyTB, thisParamTypes); CljILGen genf = new CljILGen(factoryMB.GetILGenerator()); LocalBuilder[] locals = new LocalBuilder[thisParamTypes.Length]; for (int i = 0; i < thisParamTypes.Length; i++) { locals[i] = genf.DeclareLocal(thisParamTypes[i]); genf.EmitLoadArg(i); // genf.Emit(OpCodes.Ldarg, i); genf.Emit(OpCodes.Stloc, locals[i]); } for (int i = 0; i < thisParamTypes.Length; i++) { genf.EmitLoadArg(i); // genf.Emit(OpCodes.Ldarg, i); } genf.EmitNew(cb); // genf.Emit(OpCodes.Newobj, cb); genf.Emit(OpCodes.Ret); } } }
/// <summary> /// Get the method for a dispatch value and cache it. /// </summary> /// <param name="dispatchVal">The disaptch value.</param> /// <returns>The mest method.</returns> private IFn FindAndCacheBestMethod(object dispatchVal) { _rw.EnterWriteLock(); object bestValue; IPersistentMap mt = _methodTable; IPersistentMap pt = _preferTable; object ch = _cachedHierarchy; try { IMapEntry bestEntry = null; foreach (IMapEntry me in MethodTable) { if (IsA(dispatchVal, me.key())) { if (bestEntry == null || Dominates(me.key(), bestEntry.key())) { bestEntry = me; } if (!Dominates(bestEntry.key(), me.key())) { throw new ArgumentException(String.Format("Multiple methods in multimethod {0} match dispatch value: {1} -> {2} and {3}, and neither is preferred", _name, dispatchVal, me.key(), bestEntry.key())); } } } if (bestEntry == null) { bestValue = _methodTable.valAt(_defaultDispatchVal); if (bestValue == null) { return(null); } } else { bestValue = bestEntry.val(); } } finally { _rw.ExitWriteLock(); } // ensure basis has stayed stable throughout, else redo _rw.EnterWriteLock(); try { if (mt == _methodTable && pt == _preferTable && ch == _cachedHierarchy && _cachedHierarchy == _hierarchy.deref()) { // place in cache _methodCache = _methodCache.assoc(dispatchVal, bestValue); return((IFn)bestValue); } else { ResetCache(); return(FindAndCacheBestMethod(dispatchVal)); } } finally { _rw.ExitWriteLock(); } }
private static List<CustomAttributeBuilder> CreateCustomAttributeBuilders(IMapEntry me) { Type t = (Type)me.key(); IPersistentSet inits = (IPersistentSet)me.val(); List<CustomAttributeBuilder> builders = new List<CustomAttributeBuilder>(inits.count()); for (ISeq s = RT.seq(inits); s != null; s = s.next()) { IPersistentMap init = (IPersistentMap)s.first(); builders.Add(CreateCustomAttributeBuilder(t, init)); } return builders; }
public static Expr Parse(ParserContext pcon, IPersistentMap form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool keysConstant = true; bool valsConstant = true; bool allConstantKeysUnique = true; IPersistentSet constantKeys = PersistentHashSet.EMPTY; IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); Expr k = Compiler.Analyze(pconToUse, e.key()); Expr v = Compiler.Analyze(pconToUse, e.val()); keyvals = (IPersistentVector)keyvals.cons(k); keyvals = (IPersistentVector)keyvals.cons(v); if (k is LiteralExpr) { object kval = k.Eval(); if (constantKeys.contains(kval)) { allConstantKeysUnique = false; } else { constantKeys = (IPersistentSet)constantKeys.cons(kval); } } else { keysConstant = false; } if (!(v is LiteralExpr)) { valsConstant = false; } } Expr ret = new MapExpr(keyvals); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); } //else if (constant) //{ // This 'optimzation' works, mostly, unless you have nested map values. // The nested map values do not participate in the constants map, so you end up with the code to create the keys. // Result: huge duplication of keyword creation. 3X increase in init time to the REPL. // //IPersistentMap m = PersistentHashMap.EMPTY; // //for (int i = 0; i < keyvals.length(); i += 2) // // m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val); // //return new ConstantExpr(m); // return ret; //} else if (keysConstant) { // TBD: Add more detail to exception thrown below. if (!allConstantKeysUnique) { throw new ArgumentException("Duplicate constant keys in map"); } if (valsConstant) { // This 'optimzation' works, mostly, unless you have nested map values. // The nested map values do not participate in the constants map, so you end up with the code to create the keys. // Result: huge duplication of keyword creation. 3X increase in init time to the REPL. //IPersistentMap m = PersistentHashMap.EMPTY; //for (int i = 0; i < keyvals.length(); i += 2) // m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val); //return new ConstantExpr(m); return(ret); } else { return(ret); } } else { return(ret); } }
protected override object Read(PushbackTextReader r, char caret, object opts) { int startLine = -1; int startCol = -1; LineNumberingTextReader lntr = r as LineNumberingTextReader; if (lntr != null) { startLine = lntr.LineNumber; startCol = lntr.ColumnNumber; } IPersistentMap metaAsMap; { object meta = ReadAux(r, opts); if (meta is Symbol || meta is String) { metaAsMap = RT.map(RT.TagKey, meta); } else if (meta is Keyword) { metaAsMap = RT.map(meta, true); } else if ((metaAsMap = meta as IPersistentMap) == null) { throw new ArgumentException("Metadata must be Symbol,Keyword,String or Map"); } } object o = ReadAux(r, opts); if (o is IMeta) { if (startLine != -1 && o is ISeq) { metaAsMap = metaAsMap.assoc(RT.LineKey, startLine) .assoc(RT.ColumnKey, startCol) .assoc(RT.SourceSpanKey, RT.map( RT.StartLineKey, startLine, RT.StartColumnKey, startCol, RT.EndLineKey, lntr.LineNumber, RT.EndColumnKey, lntr.ColumnNumber)); } if (o is IReference iref) { iref.resetMeta(metaAsMap); return(o); } object ometa = RT.meta(o); for (ISeq s = RT.seq(metaAsMap); s != null; s = s.next()) { IMapEntry kv = (IMapEntry)s.first(); ometa = RT.assoc(ometa, kv.key(), kv.val()); } return(((IObj)o).withMeta((IPersistentMap)ometa)); } else { throw new ArgumentException("Metadata can only be applied to IMetas"); } }