Advertencias personalizadas del comstackdor

Cuando se usa ObsoleteAtribute en .Net, se obtienen advertencias del comstackdor que le dicen que el objeto / método / propiedad está obsoleto y se debe usar algo más. Actualmente estoy trabajando en un proyecto que requiere mucha refactorización de un código de ex empleados. Quiero escribir un atributo personalizado que pueda usar para marcar métodos o propiedades que generarán advertencias de comstackción que den los mensajes que escribo. Algo como esto

[MyAttribute("This code sux and should be looked at")] public void DoEverything() { } 
  Public Sub DoEverything() End Sub 

Quiero que esto genere una advertencia de comstackción que diga: “Este código sux y debería ser examinado”. Sé cómo crear un atributo personalizado, la pregunta es cómo hago que genere advertencias de comstackción en Visual Studio.

Actualizar

Esto ahora es posible con Roslyn (Visual Studio 2015). Puede construir un analizador de código para verificar un atributo personalizado


No creo que sea posible. ObsoleteAttribute es tratado especialmente por el comstackdor y se define en el estándar C #. ¿Por qué diablos es ObsoleteAttribute no aceptable? ¡Me parece que esta es precisamente la situación para la que fue diseñada, y logra precisamente lo que necesita!

También tenga en cuenta que Visual Studio también recoge las advertencias generadas por ObsoleteAttribute sobre la marcha, lo cual es muy útil.

No significa que no sea útil, solo se pregunta por qué no está interesado en usarlo …

Lamentablemente, ObsoleteAttribute está sellado (probablemente debido en parte al tratamiento especial), por lo que no puede subclasificar su propio atributo.

Del estándar C #: –

El atributo Obsoleto se usa para marcar tipos y miembros de tipos que ya no deberían usarse.

Si un progtwig usa un tipo o miembro que está decorado con el atributo Obsoleto, el comstackdor emite una advertencia o un error. Específicamente, el comstackdor emite una advertencia si no se proporciona ningún parámetro de error, o si se proporciona el parámetro de error y tiene el valor falso. El comstackdor emite un error si el parámetro de error está especificado y tiene el valor verdadero.

¿Eso no resume tus necesidades? … No vas a hacer nada mejor que eso, no creo.

No sé si esto funcionará, pero vale la pena intentarlo.

No puedes extender Obsoleto, porque es el final, pero tal vez puedas crear tu propio atributo y marcar esa clase como obsoleta como esta:

 [Obsolete("Should be refactored")] public class MustRefactor: System.Attribute{} 

Luego, cuando marque sus métodos con el atributo “MustRefactor”, se mostrarán las advertencias de comstackción.

Dije “tal vez” y “podría” porque no lo he intentado. Por favor, dime si no funciona, así que eliminaré la respuesta.

¡Saludos!

ACTUALIZACIÓN: Probado. Genera una advertencia de tiempo de comstackción, pero el mensaje de error parece divertido, debería verlo usted mismo y elegir. Esto está muy cerca de lo que quería lograr.

ACTUALIZACIÓN2: con este código genera estas advertencias (no muy agradable, pero no creo que haya algo mejor).

 public class User { private String userName; [TooManyArgs] // Will show warning: Try removing some arguments public User(String userName) { this.userName = userName; } public String UserName { get { return userName; } } [MustRefactor] // will show warning: Refactor is needed Here public override string ToString() { return "User: " + userName; } } [Obsolete("Refactor is needed Here")] public class MustRefactor : System.Attribute { } [Obsolete("Try removing some arguments")] public class TooManyArgs : System.Attribute { } 

En algunos comstackdores, puede usar #warning para emitir una advertencia:

 #warning "Do not use ABC, which is deprecated. Use XYZ instead." 

En los comstackdores de Microsoft, normalmente puede usar el mensaje pragma:

 #pragma message ( "text" ) 

Usted mencionó .Net, pero no especificó si estaba progtwigndo con C / C ++ o C #. Si está progtwigndo en C #, entonces debe saber que C # admite el formato #warning .

Actualmente estamos en medio de mucha refactorización en la que no pudimos arreglar todo de inmediato. Simplemente usamos el comando #warning preproc donde tenemos que volver atrás y mirar el código. Se muestra en la salida del comstackdor. No creo que puedas ponerlo en un método, pero podrías ponerlo solo dentro del método, y todavía es fácil de encontrar.

 public void DoEverything() { #warning "This code sucks" } 

En VS 2008 (+ sp1) # las advertencias no se muestran correctamente en la lista de errores después de Clean Soultion & Rebuild Solution, no todas. Algunas advertencias se muestran en la lista de errores solo después de abrir un archivo de clase particular. Entonces me vi obligado a usar un atributo personalizado:

 [Obsolete("Mapping ToDo")] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)] public class MappingToDo : System.Attribute { public string Comment = ""; public MappingToDo(string comment) { Comment = comment; } public MappingToDo() {} } 

Entonces, cuando marque un código con él

 [MappingToDo("Some comment")] public class MembershipHour : Entity { // ..... } 

Produce advertencias como esta:

Namespace.MappingToDo está obsoleto: ‘Mapping ToDo’.

No puedo cambiar el texto de la advertencia, ‘Algunos comentarios’ no se muestra Lista de errores. Pero saltará al lugar correcto en el archivo. Entonces, si necesita variar tales mensajes de advertencia, cree varios atributos.

Lo que estás tratando de hacer es un mal uso de los atributos. En su lugar, use la Lista de tareas de Visual Studio. Puede ingresar un comentario en su código de esta manera:

 //TODO: This code sux and should be looked at public class SuckyClass(){ //TODO: Do something really sucky here! } 

A continuación, abra Ver / Lista de tareas en el menú. La lista de tareas tiene dos categorías, tareas de usuario y Comentarios. Cambie a Comentarios y verá todos sus // Todo: allí. Hacer doble clic en un TODO saltará al comentario en su código.

Alabama

No creo que puedas. Hasta donde sé, el soporte para ObsoleteAttribute está esencialmente codificado en el comstackdor C #; no puedes hacer nada similar directamente.

Lo que podría hacer es usar una tarea MSBuild (o un evento posterior a la construcción) que ejecute una herramienta personalizada contra el ensamblado recién comstackdo. La herramienta personalizada se reflejaría sobre todos los tipos / métodos en el ensamblaje y consumiría su atributo personalizado, en cuyo punto podría imprimir a TextWriters por defecto o por error de System.Console.

Al observar la fuente de ObsoleteAttribute , no parece que se esté haciendo algo especial para generar una advertencia de comstackción, por lo que tendería a ir con @ technophile y decir que está codificado en el comstackdor. ¿Hay alguna razón por la que no desee simplemente usar ObsoleteAttribute para generar sus mensajes de advertencia?

Hay varios comentarios que sugieren insertar advertencias o pragma. ¡Obsoleto funciona de una manera muy diferente! Al marcar una función obsoleta de una biblioteca L, el mensaje obsoleto aumenta cuando un progtwig llama a la función incluso si el progtwig que llama no se encuentra en la biblioteca L. La advertencia plantea el mensaje ÚNICAMENTE cuando L está comstackdo.

Aquí está la Implementación de Roslyn, para que pueda crear sus propios atributos que den advertencias o errores sobre la marcha.

He creado un tipo de atributo llamado IdeMessage, que serás el atributo que genera advertencias:

 [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class IDEMessageAttribute : Attribute { public string Message; public IDEMessageAttribute(string message); } 

Para hacer esto, primero necesita instalar el SDK de Roslyn y comenzar un nuevo proyecto de VSIX con el analizador. He omitido algunas de las partes menos relevantes, como los mensajes, puede averiguar cómo hacerlo, en su analizador usted hace esto.

 public override void Initialize(AnalysisContext context) { context.RegisterSyntaxNodeAction(AnalyzerInvocation, SyntaxKind.InvocationExpression); } private static void AnalyzerInvocation(SyntaxNodeAnalysisContext context) { var invocation = (InvocationExpressionSyntax)context.Node; var methodDeclaration = (context.SemanticModel.GetSymbolInfo(invocation, context.CancellationToken).Symbol as IMethodSymbol); //There are several reason why this may be null eg invoking a delegate if (null == methodDeclaration) { return; } var methodAttributes = methodDeclaration.GetAttributes(); var attributeData = methodAttributes.FirstOrDefault(attr => IsIDEMessageAttribute(context.SemanticModel, attr, typeof(IDEMessageAttribute))); if(null == attributeData) { return; } var message = GetMessage(attributeData); var diagnostic = Diagnostic.Create(Rule, invocation.GetLocation(), methodDeclaration.Name, message); context.ReportDiagnostic(diagnostic); } static bool IsIDEMessageAttribute(SemanticModel semanticModel, AttributeData attribute, Type desiredAttributeType) { var desiredTypeNamedSymbol = semanticModel.Comstacktion.GetTypeByMetadataName(desiredAttributeType.FullName); var result = attribute.AttributeClass.Equals(desiredTypeNamedSymbol); return result; } static string GetMessage(AttributeData attribute) { if (attribute.ConstructorArguments.Length < 1) { return "This method is obsolete"; } return (attribute.ConstructorArguments[0].Value as string); } 

No hay CodeFixProvider para esto, puede eliminarlo de la solución.

Personalmente estoy más interesado en emitir un error si el atributo no es válido, como un parámetro no válido.