2011-11-20 4 views
7

Esta pregunta sigue: Why does Closure compiler rename properties of an extern type? La respuesta de John a esa pregunta trae a colación esta segunda pregunta.¿Puedo decirle al compilador Closure que, solo para tipos específicos, deje de cambiar el nombre de las propiedades?

Si declaro el tipo externo como se sugiere:

/** @interface */ 
function SpanishNoun() {} 
/** @type {string} */ 
SpanishNoun.prototype.english; 
/** @type {string} */ 
SpanishNoun.prototype.spanish; 

continuación Javascript como:

/** 
* @param {SpanishNoun} n 
*/ 
exp.foo = function (n) { 
    console.log(n.english, n.spanish, n['english'], n['spanish']); 
} 

compilará, según se desee, a:

function(a){console.log(a.english,a.spanish,a.english,a.spanish)}; 

Las propiedades no son renombrado como siempre Sin la declaración externa, el código compilado se vería así:

function(a){console.log(a.a,a.c,a.english,a.spanish) 

Eso es todo bien. El problema es que el compilador ha dejado de cambiar el nombre de 'inglés' y 'español' en todos los lugares. Incluso si no están en el tipo externo.

/** 
* @param {AnotherType} 
*/ 
exp.bar = function (c) { 
    c.other = c.english; 
} 

compila a ...

function(a){a.b=a.english}; 

¿Existe una manera de parar esto? Si no, ¿hay alguna razón para este comportamiento?

Quería usar tipos externos para manejar cosas como objetos JSON que se originan en el servidor y no tienen propiedades renombradas. Pero si cada vez que declaro un extern estoy consumiendo la capacidad del compilador para cambiar el nombre y reducir el código, encontraré otra manera. Tal vez tomaré el mapa de cambio de nombre de propiedad generado por el compilador (--property_map_output_file) y lo usaré en el servidor cuando genere respuestas JSON.

+0

Este es el comportamiento estándar de Closure para evitar errores (puede leer el sitio web de Closure para comprender por qué es necesario). El cierre siempre cambia el nombre de la misma propiedad por el mismo nombre. Por otro lado, no cambia el nombre de todas las propiedades (independientemente de dónde) del mismo nombre, porque en esencia, no cambiar el nombre es simplemente cambiar el nombre a sí mismo. Hay una bandera (llamada 'ambiguateProperties' o algo así) que puede activar para evitar esto, pero es solo experimental. –

+0

El motivo de este comportamiento estándar es que puede escribir una función que solo tome un objeto y usar la propiedad 'inglés' en ese objeto. El cierre no tiene manera de saber qué objeto está pasando y si la propiedad 'inglés 'de ese objeto ha sido renombrada o no. Como JavaScript es un lenguaje no tipado, puede hacer este tipo de cosas (pasando diferentes objetos de diferentes clases), por lo que el compilador debe cambiar el nombre del mismo nombre de propiedad por la misma cadena para evitar el no poder decidir qué versión de el nombre al que está asignado. –

Respuesta

3

El compilador de cierre puede cambiar el nombre en función de los tipos: https://github.com/google/closure-compiler/wiki/Type-Based-Property-Renaming Esto mejora otras optimizaciones, como la alineación y la eliminación de código inactivo también. Esto se usa internamente para Google pero tiene un costo, ya que puede presentar algunos escenarios de depuración difíciles si "miente" en sus declaraciones de tipo.

+0

Ese enlace ya no funciona. Tal vez este es un enlace nuevo (ya no es experimental): https://github.com/google/closure-compiler/wiki/Type-Based-Property-Renaming – ChrisW

+0

Gracias actualizó la URL. – John

Cuestiones relacionadas