private static Match GetMatchFromType(ITypeDetails t) { var assy = t.Assembly.Name; var className = t.FullName; return(new Match(assy, className)); }
private static string GetFriendlyTypeName(ITypeDetails t) { if (!t.IsGenericType) { return(t.FullName); } else { // Generics when asked for their full-name do crazy things like: // System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] // Which isn't much use to us as NewRelic uses a combination of backtick notation and angle brackets. // However, we can fiddle this... const string FORMAT = "{0}.{1}<{2}>"; string[] innerTypes = t.GenericArguments.Select(x => string.Format("{0}", GetFriendlyTypeName(x))).ToArray(); return(string.Format(FORMAT, t.Namespace, t.Name, string.Join(",", innerTypes))); } }
private static string GetGenericParameterTypeName(ITypeDetails parameterType, IEnumerable <ITypeDetails> orderedTypeContext) { if (parameterType.IsGenericType) { return(parameterType.FullName + "<" + string.Join(",", parameterType.GenericArguments.Select(x => GetGenericParameterTypeName(x, orderedTypeContext))) + ">"); } else { // Is this something that's in our context? int idx = 0; foreach (var genericArgument in orderedTypeContext) { if (genericArgument.Equals(parameterType)) { return(string.Format("MVAR {0}", idx)); } idx++; } } // Fall back to standard process return(GetFriendlyTypeName(parameterType)); }
protected virtual IEnumerable<InstrumentationTarget> GetInstrumentationSet(ITypeDetails t, InstrumentAttribute context) { var toReturn = new List<InstrumentationTarget>(); if (!t.IsGenericTypeDefinition) { // Does the type have an Instrument attribute? var typeLevelAttribute = t.InstrumentationContext; typeLevelAttribute = InstrumentAttribute.GetEffectiveInstrumentationContext(typeLevelAttribute, context); if (t.IsCompilerGenerated && (typeLevelAttribute == null || !typeLevelAttribute.IncludeCompilerGeneratedCode)) { // Bail out early - we've found a compiler-generated method and haven't been told to include 'em _logger.DebugFormat("Skipping type {0} - compiler-generated and configuration set to skip", t.FullName); return toReturn; } _logger.DebugFormat("Processing type {0}", t.FullName); var baseBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly; var propBindingFlags = baseBindingFlags; var methodBindingFlags = baseBindingFlags; var ctorBindingFlags = baseBindingFlags; if (typeLevelAttribute == null) { propBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public; methodBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public; ctorBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public; } else { if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicProperties) == InstrumentationScopes.PublicProperties) { propBindingFlags |= BindingFlags.Public; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicProperties) == InstrumentationScopes.NonPublicProperties) { propBindingFlags |= BindingFlags.NonPublic; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicMethods) == InstrumentationScopes.PublicMethods) { methodBindingFlags |= BindingFlags.Public; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicMethods) == InstrumentationScopes.NonPublicMethods) { methodBindingFlags |= BindingFlags.NonPublic; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicConstructors) == InstrumentationScopes.PublicConstructors) { ctorBindingFlags |= BindingFlags.Public; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicConstructors) == InstrumentationScopes.NonPublicConstructors) { ctorBindingFlags |= BindingFlags.NonPublic; } } _logger.DebugFormat("Prop flags {0}, Ctor flags {1}, Method flags {2}", propBindingFlags, ctorBindingFlags, methodBindingFlags); // Instrument everything in this type, irrespective of its member-level // details foreach (var methodDetails in t.GetMethods(methodBindingFlags)) { _logger.DebugFormat("Examining method {0}", methodDetails.ToString()); var attr = InstrumentAttribute.GetEffectiveInstrumentationContext(methodDetails.InstrumentationContext, typeLevelAttribute); if (attr != null && (!methodDetails.IsCompilerGenerated || attr.IncludeCompilerGeneratedCode)) { toReturn.Add(GetInstrumentationTarget(methodDetails, attr)); } } foreach (var propertyDetails in t.GetProperties(propBindingFlags)) { _logger.DebugFormat("Examining property {0}.{1}", t.FullName, propertyDetails.Name); var getMethod = propertyDetails.GetMethod; var setMethod = propertyDetails.SetMethod; if (getMethod != null && getMethod.ContainsGenericParameters) { getMethod = null; } if (setMethod != null && setMethod.ContainsGenericParameters) { setMethod = null; } if (getMethod != null) { var getMethodAttr = InstrumentAttribute.GetEffectiveInstrumentationContext(propertyDetails.InstrumentationContext, getMethod.InstrumentationContext, typeLevelAttribute); if (getMethodAttr != null) { toReturn.Add(GetInstrumentationTarget(getMethod, getMethodAttr)); } } if (setMethod != null) { var setMethodAttr = InstrumentAttribute.GetEffectiveInstrumentationContext(propertyDetails.InstrumentationContext, setMethod.InstrumentationContext, typeLevelAttribute); if (setMethodAttr != null) { toReturn.Add(GetInstrumentationTarget(setMethod, setMethodAttr)); } } } foreach (var constructorDetails in t.GetConstructors(ctorBindingFlags).Where(x => !x.ContainsGenericParameters)) { _logger.DebugFormat("Examining method {0}", constructorDetails.ToString()); var attr = InstrumentAttribute.GetEffectiveInstrumentationContext(constructorDetails.InstrumentationContext, typeLevelAttribute); if (attr != null) { toReturn.Add(GetInstrumentationTarget(constructorDetails, attr)); } } // Process nested types recursively, rather than enumerating them from the get-go so that we can apply // instrumentation scoping recursively too - the nested class will take on the instrumentation configuration // of the containing type, if any, or whatever's been passed down by initial settings foreach (var nested in t.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { toReturn.AddRange(GetInstrumentationSet(nested, typeLevelAttribute)); } } else { _logger.DebugFormat("Skipping type {0} - generic types not supported", t.FullName); } return toReturn; }
public DummyMethodDetails(ITypeDetails declaringType, string name) { this.DeclaringType = declaringType; this.Name = name; }
private static string GetGenericParameterTypeName(ITypeDetails parameterType, IEnumerable<ITypeDetails> orderedTypeContext) { if (parameterType.IsGenericType) { return parameterType.FullName + "<" + string.Join(",", parameterType.GenericArguments.Select(x => GetGenericParameterTypeName(x, orderedTypeContext))) + ">"; } else { // Is this something that's in our context? int idx = 0; foreach (var genericArgument in orderedTypeContext) { if (genericArgument.Equals(parameterType)) { return string.Format("MVAR {0}", idx); } idx++; } } // Fall back to standard process return GetFriendlyTypeName(parameterType); }
private static Match GetMatchFromType(ITypeDetails t) { var assy = t.Assembly.Name; var className = t.FullName; return new Match(assy, className); }
private static string GetFriendlyTypeName(ITypeDetails t) { if (!t.IsGenericType) { return t.FullName; } else { // Generics when asked for their full-name do crazy things like: // System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] // Which isn't much use to us as NewRelic uses a combination of backtick notation and angle brackets. // However, we can fiddle this... const string FORMAT = "{0}.{1}<{2}>"; string[] innerTypes = t.GenericArguments.Select(x => string.Format("{0}", GetFriendlyTypeName(x))).ToArray(); return string.Format(FORMAT, t.Namespace, t.Name, string.Join(",", innerTypes)); } }
protected override IEnumerable<InstrumentationTarget> GetInstrumentationSet(ITypeDetails t, InstrumentAttribute context) { if (this.FirstContext == null) { this.FirstContext = context; } this.ScannedTypes[t] = context; return base.GetInstrumentationSet(t, context); }
protected virtual IEnumerable <InstrumentationTarget> GetInstrumentationSet(ITypeDetails t, InstrumentAttribute context) { var toReturn = new List <InstrumentationTarget>(); if (!t.IsGenericTypeDefinition) { // Does the type have an Instrument attribute? var typeLevelAttribute = t.InstrumentationContext; typeLevelAttribute = InstrumentAttribute.GetEffectiveInstrumentationContext(typeLevelAttribute, context); if (t.IsCompilerGenerated && (typeLevelAttribute == null || !typeLevelAttribute.IncludeCompilerGeneratedCode)) { // Bail out early - we've found a compiler-generated method and haven't been told to include 'em _logger.DebugFormat("Skipping type {0} - compiler-generated and configuration set to skip", t.FullName); return(toReturn); } _logger.DebugFormat("Processing type {0}", t.FullName); var baseBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly; var propBindingFlags = baseBindingFlags; var methodBindingFlags = baseBindingFlags; var ctorBindingFlags = baseBindingFlags; if (typeLevelAttribute == null) { propBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public; methodBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public; ctorBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public; } else { if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicProperties) == InstrumentationScopes.PublicProperties) { propBindingFlags |= BindingFlags.Public; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicProperties) == InstrumentationScopes.NonPublicProperties) { propBindingFlags |= BindingFlags.NonPublic; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicMethods) == InstrumentationScopes.PublicMethods) { methodBindingFlags |= BindingFlags.Public; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicMethods) == InstrumentationScopes.NonPublicMethods) { methodBindingFlags |= BindingFlags.NonPublic; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicConstructors) == InstrumentationScopes.PublicConstructors) { ctorBindingFlags |= BindingFlags.Public; } if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicConstructors) == InstrumentationScopes.NonPublicConstructors) { ctorBindingFlags |= BindingFlags.NonPublic; } } _logger.DebugFormat("Prop flags {0}, Ctor flags {1}, Method flags {2}", propBindingFlags, ctorBindingFlags, methodBindingFlags); // Instrument everything in this type, irrespective of its member-level // details foreach (var methodDetails in t.GetMethods(methodBindingFlags)) { _logger.DebugFormat("Examining method {0}", methodDetails.ToString()); var attr = InstrumentAttribute.GetEffectiveInstrumentationContext(methodDetails.InstrumentationContext, typeLevelAttribute); if (attr != null && (!methodDetails.IsCompilerGenerated || attr.IncludeCompilerGeneratedCode)) { toReturn.Add(GetInstrumentationTarget(methodDetails, attr)); } } foreach (var propertyDetails in t.GetProperties(propBindingFlags)) { _logger.DebugFormat("Examining property {0}.{1}", t.FullName, propertyDetails.Name); var getMethod = propertyDetails.GetMethod; var setMethod = propertyDetails.SetMethod; if (getMethod != null && getMethod.ContainsGenericParameters) { getMethod = null; } if (setMethod != null && setMethod.ContainsGenericParameters) { setMethod = null; } if (getMethod != null) { var getMethodAttr = InstrumentAttribute.GetEffectiveInstrumentationContext(propertyDetails.InstrumentationContext, getMethod.InstrumentationContext, typeLevelAttribute); if (getMethodAttr != null) { toReturn.Add(GetInstrumentationTarget(getMethod, getMethodAttr)); } } if (setMethod != null) { var setMethodAttr = InstrumentAttribute.GetEffectiveInstrumentationContext(propertyDetails.InstrumentationContext, setMethod.InstrumentationContext, typeLevelAttribute); if (setMethodAttr != null) { toReturn.Add(GetInstrumentationTarget(setMethod, setMethodAttr)); } } } foreach (var constructorDetails in t.GetConstructors(ctorBindingFlags).Where(x => !x.ContainsGenericParameters)) { _logger.DebugFormat("Examining method {0}", constructorDetails.ToString()); var attr = InstrumentAttribute.GetEffectiveInstrumentationContext(constructorDetails.InstrumentationContext, typeLevelAttribute); if (attr != null) { toReturn.Add(GetInstrumentationTarget(constructorDetails, attr)); } } // Process nested types recursively, rather than enumerating them from the get-go so that we can apply // instrumentation scoping recursively too - the nested class will take on the instrumentation configuration // of the containing type, if any, or whatever's been passed down by initial settings foreach (var nested in t.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { toReturn.AddRange(GetInstrumentationSet(nested, typeLevelAttribute)); } } else { _logger.DebugFormat("Skipping type {0} - generic types not supported", t.FullName); } return(toReturn); }