tipo texto tecnicas setfont refactorizacion letra instalar fuentes fuente font example cursiva codigo cambiar java ide automated-refactoring

texto - setfont java



Refactorización de fuente Java de 7000 referencias. (12)

Necesito cambiar la firma de un método usado en todo el código base.

Específicamente, el método void log(String) tomará dos argumentos adicionales ( Class c, String methodName ), que deben ser proporcionados por el llamante, dependiendo del método donde se llame. No puedo simplemente pasar null o similar.

Para dar una idea del alcance, Eclipse encontró 7000 referencias a ese método, por lo que si lo cambio, todo el proyecto caerá. Me llevará semanas arreglarlo manualmente.

Hasta donde puedo decir, el plugin de refactorización de Eclipse de Eclipse no está a la altura de la tarea, pero realmente quiero automatizarlo.
Entonces, ¿cómo puedo hacer el trabajo?


¿Realmente necesitas cambiar el código de llamada y la firma del método? A lo que me refiero es que parece que los parámetros agregados están destinados a darle la clase y el método de llamada para agregar a sus datos de registro. Si el único requisito es simplemente agregar la clase / método de llamada a los datos de registro, entonces Thread.currentThread (). GetStackTrace () debería funcionar. Una vez que tenga el StackTraceElement [] puede obtener el nombre de la clase y el nombre del método para la persona que llama.


Creo que hay varios pasos para lidiar con esto, ya que no es solo un problema técnico sino una ''situación'':

  1. Rechazar hacerlo en poco tiempo debido al riesgo.
  2. Señale los problemas causados ​​por no usar marcos estándar, sino reinventar la rueda (como dice Paul).
  3. Insista en usar Log4j o equivalente si hace el cambio.
  4. Use la refactorización de Eclipse en partes sensibles para realizar los cambios y lidiar con los distintos valores predeterminados.

He utilizado la refactorización de Eclipse en cambios bastante grandes para corregir el código maloliente, hoy en día es bastante robusto.


Eclipse puede hacer eso utilizando Refactor -> Cambiar la firma del método y proporcionar valores predeterminados para los nuevos parámetros .

Para el parámetro de clase, el valor predeterminado debe ser this.getClass (), pero tiene razón en su comentario. No sé cómo hacerlo para el parámetro de nombre de método.


El hecho es que su problema no consiste en utilizar un motor de clic y reproducción que le permita reemplazar todas las apariciones de

log("some weird message");

por

log(this.getClass(), new Exception().getStackTrace()[1].getMethodName());

Como tiene pocas posibilidades de trabajar en varios casos (como los métodos estáticos, como ejemplo).

Tendría a sugerirte que eche un vistazo a la spoon . Esta herramienta permite el análisis y la transformación del código fuente, lo que le permite lograr su operación en una operación lenta pero basada en código, pero controlada.

Sin embargo, también podría considerar la posibilidad de transformar su método real con un rastreo de pila de exploración para obtener información o, mejor aún, usar log4j internamente y un formateador de registro que muestra la información correcta.


Estoy de acuerdo con la respuesta de Seanizer de que desea una herramienta que pueda analizar Java. Eso es necesario pero no suficiente; Lo que realmente desea es una herramienta que pueda realizar un cambio de masa confiable.

Para hacer esto, desea una herramienta que pueda analizar Java, que pueda hacer coincidir los patrones con el código analizado, instalar la llamada de reemplazo y escupir la respuesta sin destruir el resto del código fuente.

Nuestro kit de herramientas de reingeniería de software de DMS puede hacer todo esto para una variedad de idiomas, incluido Java. Analiza los sistemas java completos de origen, construye árboles de sintaxis abstracta (para todo el conjunto de código).

DMS puede aplicar transformaciones de fuente a fuente dirigidas por patrones para lograr el cambio deseado.

Para lograr el efecto de OP, aplicaría la siguiente transformación de programa :

rule replace_legacy_log(s:STRING): expression -> expression " log(/s) " -> " log( /s, /class/(/), /method/(/) ) "

Lo que dice esta regla es, busque una llamada a registro que tenga un solo argumento de cadena y reemplácelo con una llamada a registro con dos argumentos más determinados por la clase de funciones auxiliares y el método .

Estas funciones determinan el nombre del método que contiene y el nombre de la clase que contiene para la raíz del nodo AST donde la regla encuentra una coincidencia.

La regla está escrita en "formulario fuente", pero en realidad coincide con el AST y reemplaza los AST encontrados con el AST modificado.

Para recuperar la fuente modificada, le pide a DMS que simplemente imprima (para hacer un buen diseño) o que imprima con fidelidad (si desea que se conserve el diseño del código anterior). DMS conserva comentarios, números radixes, etc.

Si la aplicación existente tiene más de una definición de la función de "registro", deberá agregar un calificador:

... if IsDesiredLog().

donde IsDesiredLog utiliza la tabla de símbolos de DMS y la información de herencia para determinar si el registro específico se refiere a la definición de interés.


Genial, puedo copiar una de mis respuestas anteriores y solo necesito editar un poquito:

Creo que lo que necesitas hacer es usar un analizador de código fuente como javaparser para hacer esto.

Para cada archivo fuente java, analícelo en una CompilationUnit, cree un visitante , probablemente utilizando ModifierVisitorAdapter como clase base, y anule (al menos) la visit(MethodCallExpr, arg) . Luego escriba la CompilationUnit modificada en un archivo nuevo y haga una diferencia después.

No recomendaría cambiar el archivo fuente original, pero crear un árbol de archivos sombra puede ser una buena idea (por ejemplo, archivo antiguo: src/main/java/com/mycompany/MyClass.java , nuevo archivo src/main/refactored/com/mycompany/MyClass.java , de esa manera puede diferenciar todos los directorios).


Pruebe refactor usando intellij. Tiene una característica llamada SSR (búsqueda y reemplazo estructural). Puede referirse a clases, nombres de métodos, etc. para un contexto. (La respuesta de Seanizer es más prometedora, la he votado)


Si la clase y el nombre del método se requieren para "¿de dónde vino este registro?" escriba datos, luego otra opción es imprimir un seguimiento de pila en su método de registro. P.ej

public void log(String text) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw, true); new Throwable.printStackTrace(pw); pw.flush(); sw.flush(); String stackTraceAsLog = sw.toString(); //do something with text and stackTraceAsLog }


Si las líneas que necesita reemplazar se dividen en una pequeña cantidad de categorías, entonces lo que necesita es Perl:

find -name ''*.java'' | xargs perl -pi -e ''s/log/(([^,)]*?)/)/log(/1, "foo", "bar")/g''

Supongo que no sería demasiado difícil hackear un script que pondría el nombre de clase (derivado del nombre de archivo) como segundo argumento. Obtener el nombre del método como tercer argumento se deja como un ejercicio para el lector.


Tal vez estoy siendo ingenuo, pero ¿por qué no puedes sobrecargar el nombre del método?

void thing(paramA) { thing(paramA, THE_DEFAULT_B, THE_DEFAULT_C) } void thing(paramA, paramB, paramC) { // new method }


IntelliJ IDEA no debería tener ningún problema con esto.

No soy un experto en Java, pero algo como esto podría funcionar. No es una solución perfecta (incluso puede ser una solución muy mala), pero podría comenzar:

Cambie la firma del método con las herramientas de refactorización de IntelliJ y especifique los valores predeterminados para los 2 nuevos parámetros:

c: self.getClass() methodName: Thread.currentThread().getStackTrace()[1].getMethodName()

o mejor aún, simplemente especifique nulo como los valores predeterminados.


log(@class, @methodname, y reemplazaría el log( con el log(@class, @methodname,

Luego escribe un pequeño script en cualquier idioma (incluso en java) para encontrar el nombre de la clase y los nombres de los métodos y para reemplazar los tokens @class y @method ...

Buena suerte