Estoy tratando de encontrar algunos buenos ejemplos de utilidades semánticas de diferenciación / fusión. El paradigma tradicional de comparar archivos de código fuente funciona comparando líneas y caracteres ... pero ¿hay alguna utilidad (para cualquier idioma) que realmente considere la estructura del código al comparar archivos?
Por ejemplo, los programas diff existentes informarán "diferencia encontrada en el carácter 2 de la línea 125. El archivo x contiene vacío, donde el archivo y contiene bool". Una herramienta especializada debería poder informar "Tipo de retorno del método doSomething () cambiado de void a bool".
Yo diría que este tipo de información semántica es en realidad lo que el usuario busca al comparar código, y debería ser el objetivo de las herramientas de programación de próxima generación. ¿Hay ejemplos de esto en las herramientas disponibles?
fuente
Respuestas:
Hemos desarrollado una herramienta que es capaz de abordar con precisión este escenario. Consulte http://www.semanticmerge.com
Se fusiona (y diferencia) en función de la estructura del código y no utiliza algoritmos basados en texto, lo que básicamente le permite tratar casos como el siguiente, que implican una fuerte refactorización. También es capaz de representar tanto las diferencias como los conflictos de fusión, como puede ver a continuación:
Y en lugar de confundirse con los bloques de texto que se mueven, ya que analiza primero, puede mostrar los conflictos por método (por elemento de hecho). Un caso como el anterior ni siquiera tendrá conflictos manuales que resolver.
Es una herramienta de fusión consciente del idioma y ha sido genial poder finalmente responder a esta pregunta SO :-)
fuente
Eclipse ha tenido esta característica durante mucho tiempo. Se llama "Comparación de estructuras" y es muy agradable. Aquí hay una captura de pantalla de muestra para Java, seguida de otra para un archivo XML:
(Tenga en cuenta los iconos menos y más en los métodos en el panel superior).
fuente
Para hacer bien las "comparaciones semánticas", es necesario comparar los árboles de sintaxis de los idiomas y tener en cuenta el significado de los símbolos. Una diferencia semántica realmente buena entendería la semántica del lenguaje y se daría cuenta de cuándo un bloque de código es equivalente en función a otro. Llegar tan lejos requiere un demostrador de teoremas, y aunque sería extremadamente lindo, actualmente no es práctico para una herramienta real.
Una aproximación viable de esto es simplemente comparar árboles de sintaxis e informar cambios en términos de estructuras insertadas, eliminadas, movidas o modificadas. Acercándose un poco más a una "comparación semántica", se podría informar cuando un identificador se cambia consistentemente en un bloque de código.
Consulte nuestro http://www.semanticdesigns.com/Products/SmartDifferencer/index.html para obtener un motor de comparación basado en árbol de sintaxis que funciona con muchos idiomas, que hace la aproximación anterior.
EDITAR Enero de 2010: Versiones disponibles para C ++, C #, Java, PHP y COBOL. El sitio web muestra ejemplos específicos para la mayoría de ellos.
EDITAR Mayo de 2010: Python y JavaScript agregados.
EDITAR Oct 2010: EGL agregado.
EDITAR Nov 2010: VB6, VBScript, VB.net agregado
fuente
Lo que estás buscando es una "diferencia de árbol". Resulta que esto es mucho más difícil de hacer bien que una simple diferencia textual orientada a líneas, que en realidad es solo la comparación de dos secuencias planas.
" Un enfoque de comparación estructural XML detallado " concluye, en parte con:
(énfasis mío)
De hecho, si está buscando más ejemplos de diferenciación de árboles, le sugiero que se centre en XML, ya que ha impulsado desarrollos prácticos en esa área.
fuente
Enchufe descarado para mi propio proyecto:
HTML Tree Diff hace una comparación basada en la estructura de documentos xml y html, escritos en Python.
http://pypi.python.org/pypi/html-tree-diff/0.1.0
fuente
La solución a esto sería por idioma. Es decir, a menos que esté diseñado con una arquitectura de complemento que difiera gran parte del análisis del código en un árbol y la comparación semántica con un complemento específico de un idioma, será muy difícil admitir varios idiomas. Para qué idioma (s) está interesado en tener una herramienta de este tipo. Personalmente, me encantaría uno para C #.
Para C # hay un complemento diff de ensamblado para Reflector, pero solo hace una diferencia en el IL, no en el C #.
Puede descargar el complemento diff aquí [zip] o ir al proyecto en el sitio del codeplex aquí .
fuente
Una empresa llamada Zynamics ofrece una herramienta de diferencia semántica de nivel binario. Utiliza un lenguaje de metaensamblador llamado REIL para realizar un análisis teórico de gráficos de 2 versiones de un binario y produce un gráfico codificado por colores para ilustrar las diferencias entre ellos. No estoy seguro del precio, pero dudo que sea gratis.
fuente
http://prettydiff.com/
Pretty Diff minimiza cada entrada para eliminar comentarios y espacios en blanco innecesarios y luego embellece el código antes del algoritmo diff. De todos modos, no puedo pensar en convertirme en un código más semántico que esto. Y su JavaScript escrito para que se ejecute directamente en el navegador.
fuente