private void MapMember(MemberReferenceExpression node, IMember member) { var baseType = member.DeclaringType; var mapped = member as IGenericMappedMember; if (mapped != null) { if (baseType == node.Target.ExpressionType) { return; } member = mapped.SourceMember; } var didMap = false; if (node.Target.ExpressionType != null) { var newType = node.Target.ExpressionType.ConstructedInfo; if (newType != null) { member = newType.Map(member); didMap = true; } else if (node.Target.ExpressionType.GenericInfo != null) { throw new System.InvalidOperationException("Bad target type"); } } if (!didMap && member.EntityType == EntityType.Method) { var gen = member as IGenericMethodInfo; if (gen != null) { foreach (var gp in gen.GenericParameters) { if (!_methodToStateMachineMapper.ContainsType(gp)) { var replacement = this._genericParams.FirstOrDefault(p => p.Name == gp.Name); if (replacement != null) { _methodToStateMachineMapper.Replace(gp, _methodToStateMachineMapper.MapType((IType)replacement.Entity)); } } } member = gen.ConstructMethod( gen.GenericParameters.Select(_methodToStateMachineMapper.MapType).ToArray()); } else { var con = member as IConstructedMethodInfo; if (con != null) { var gd = con.GenericDefinition.GenericInfo; member = gd.ConstructMethod(con.GenericArguments.Select(_methodToStateMachineMapper.MapType).ToArray()); } } } node.Entity = member; node.ExpressionType = member.Type; }
private static void CheckTypeForGenericParams( IType type, HashSet <string> genericsSet, BooClassBuilder builder, GeneratorTypeReplacer mapper) { if (type is IGenericParameter) { if (!genericsSet.Contains(type.Name)) { builder.AddGenericParameter(type.Name); genericsSet.Add(type.Name); } if (!mapper.ContainsType(type)) { mapper.Replace( type, (IType)builder.ClassDefinition.GenericParameters .First(gp => gp.Name.Equals(type.Name)).Entity); } } else { var genType = type as IConstructedTypeInfo; if (genType != null) { foreach (var arg in genType.GenericArguments) { CheckTypeForGenericParams(arg, genericsSet, builder, mapper); } } } }