public IType Resolve(ITypeResolveContext context) { if (ownerType == SymbolKind.Method) { IMethod method = context.CurrentMember as IMethod; if (method != null && index < method.TypeParameters.Count) { return(method.TypeParameters[index]); } return(DummyTypeParameter.GetMethodTypeParameter(index)); } else if (ownerType == SymbolKind.TypeDefinition) { ITypeDefinition typeDef = context.CurrentTypeDefinition; if (typeDef != null && index < typeDef.TypeParameters.Count) { return(typeDef.TypeParameters[index]); } return(DummyTypeParameter.GetClassTypeParameter(index)); } else { return(SpecialType.UnknownType); } }
static ITypeParameter GetTypeParameter(ref ITypeParameter[] typeParameters, SymbolKind symbolKind, int index) { ITypeParameter[] tps = typeParameters; while (index >= tps.Length) { // We don't have a normal type parameter for this index, so we need to extend our array. // Because the array can be used concurrently from multiple threads, we have to use // Interlocked.CompareExchange. ITypeParameter[] newTps = new ITypeParameter[index + 1]; tps.CopyTo(newTps, 0); for (int i = tps.Length; i < newTps.Length; i++) { newTps[i] = new DummyTypeParameter(symbolKind, i); } ITypeParameter[] oldTps = Interlocked.CompareExchange(ref typeParameters, newTps, tps); if (oldTps == tps) { // exchange successful tps = newTps; } else { // exchange not successful tps = oldTps; } } return(tps[index]); }