Open source
Algorithms
Compilers
Objective C
Swift
Comments 6
UFO landed and left these words here
+1
Спасибо! С трансляцией подобных макросов пока еще остается нерешенный вопрос, как методом дедукции получить type name (Double в примере в статье).
Планируем сделать примерно такой вариант:
func DEGREES_TO_RADIANS(degrees: Any) -> Any { return (.pi * Double(degrees))/180; }

но это еще в процессе :)
UFO landed and left these words here
+1

По поводу скобок вокруг аргумента — согласен, спасибо!
Правда, не всегда ж на входе конвертора попадается "правильный" код.
Конкретно этот макрос судя по всему взят отсюда:
http://stackoverflow.com/questions/29179692/how-can-i-convert-from-degrees-to-radians


Какой профит в данном случае будет от использования Any вместо Double если можно вывести тип аргумента?

Если рассматривать конвертацию любого макроса с параметрами, а не конкретный случай, то выходит примерно следующее:
1) Типы параметра (degrees) и возвращаемого значения не указаны, по-этому объявляем их как Any;
2) На этапе разбора M_PI * (degrees) конвертор знает, что M_PI имеет тип Double, соответственно выражение (degrees) должно иметь тип Double;
3) Ввиду того, что переменная degrees имеет тип Any, используется приведение типов.
(к сожалению, Swift очень строго относится к совместимости numeric data types).
4) Вывести тип аргумента и возвращаемого значения в приведенном примере можно,
а в общем случае — очень затруднительно. Ведь вместо (degrees) может идти вызов метода (известного нам, или нет), или же выражение любой сложности.


Не рассматривался вариант использования родного препроцессора (cpp)?

Рассматривался, но в контексте конвертации с Objective-C на Swift обычно это не совсем то, что нужно пользователю:
1) В Objective-C приложении нередко глобальные константы объявляются как #define.
Наиболее подходящая для этого конструкция в Swift — глобальная константа (let).
Если же заменить все использования макроса в коде на подставляемое значение, получится код в стиле copy&paste который мало кому понравится.
2) То же самое относится к #define с параметрами. В большинстве случаев, заменять такой макрос в коде на подставляемый результат — далеко не то, что ожидается в конечном результате.
Например, представьте себе развернутый в коде макрос UIColorToRGB() отсюда (далеко не самый сложный случай):
http://stackoverflow.com/questions/1243201/is-macro-better-than-uicolor-for-setting-rgb-color


Огромный плюс использования родного препроцессора в том, что он позволяет избежать ошибок парсинга в случае использования сложных макросов. Вероятно, в будующем мы добавим использование пепроцессора как опцию.


Как обрабатываются ситуации когда макрос нельзя преобразовать в функцию?
Макрос включается в результат в закомментированном виде.

В реальных проектах которые я рассматривал, имеет больше смысла дать пользователю возможность заменить объявление макроса вручную, чем заменить все использования макроса.
Даже если это поможет избежать некоторых ошибко конвертации, спагетти-код полученный в результате все равно придется переделывать.

UFO landed and left these words here
+1

Некоторые опции могли бы быть полезны.
К примеру, вряд ли нам пригодится препроцессорная обработка #if, #else, #endif, и включение в результат только участка кода, при котором условие вычисляется в true.
Вместо этого, мы включаем подобные директивы в Swift код, хоть их поддержка в Swift сильно ограничена.

Only those users with full accounts are able to leave comments. , please.