Flash, Ant и множество регулярных выражений заменяют

#ant #flash-builder

#ant #flash-builder

Вопрос:

У меня есть проект flash, в котором в целях оптимизации постоянные ссылки должны быть заменены литералами во время сборки релиза.

Есть сотни констант, которые я хочу заменить. Все они хранятся в одном файле в этом формате:

 FILE: Constants.as
public static const CONST_1         :uint = 0;
public static const CONST_LOLO      :int = -1;
public static const CONST_WHEE      :Number = 2.55;
public static const OTHER_CONST     :String = "La string!";
public static const ITSAMEMARIO     :String = "O, HAI!";
public static const MAGE_WALL       :uint = 15;
 

Я полагаю, что мог бы сделать это вручную, вот так:

 <replaceregexp match="CONST_1" replace="0">
    <fileset dir="${project.sourcePath}" includes="**/*.as" />
</replaceregexp>
<replaceregexp match="CONST_LOLO" replace="-1">
    <fileset dir="${project.sourcePath}" includes="**/*.as" />
</replaceregexp>
 

И так далее, для всех других переменных. Проблема двоякая — во-первых, это довольно много работы. Но большая проблема в том, что эти константы могут меняться, и мне нужно не забыть внести изменения в двух местах.

Обычно я использую Ant (который я тоже только начал изучать) для выполнения этой задачи, но если вы считаете, что есть лучший способ, я весь внимание. Я могу придумать два решения, ни одно из которых я не знаю, как выполнить:

  1. Напишите какой-нибудь умный фрагмент кода Ant, который проанализировал бы этот файл констант и с радостью выполнил замену, сохранив все в памяти.
  2. Сделайте задачу сначала проанализировать Constants.as , выведите новый Ant-скрипт, который затем будет выполнен первой задачей.

Я использую Flash Builder 4.5 для всех своих потребностей Ant.

РЕДАКТИРОВАТЬ: некоторые пояснения. В проекте я использую константы, например LEVEL_WIDTH . Все эти константы объявлены в вышеупомянутом Constants.as . Теперь я хочу заменить все экземпляры этих констант во всем проекте их фактическим значением. Итак, такая строка:

 return (x >= 0 amp;amp; x < Constants.LEVEL_WIDTH);
 

будет заменен на:

 return (x >= 0 amp;amp; x < 20);
 

Комментарии:

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

2. @FailedDev, я отредактировал сообщение, теперь понятно, что я ищу?

Ответ №1:

Хорошо, это не самая простая вещь, которую можно сделать с ant. Сначала вам нужно знать, что вы можете изменить. Это означает все имена ваших констант, а также соответствующие значения. Уникальны ли имена констант? Если да, то для меня это звучит как структура карты. Затем вам нужно повторно выразить все ваши исходные файлы, которые содержат одну или несколько из этих переменных, чтобы каждая константа была заменена фактическим значением. Это не то, для чего предназначен ant, но вы можете сделать это с помощью script def.

Я бы сделал это с Java следующим образом :

Сохраните все константы / значения в map (если константы уникальны), иначе используйте другую структуру.

Пример кода :

 <project name="test" default="build">
  <property name="constants" value="constants.txt"/>

  <scriptdef name="replaceConstants" language="java">
    <attribute name="constants" />
    <attribute name="srcFile" />
    <![CDATA[
      import java.util.*;
      import java.util.regex.*;
      ArrayList constantNameList = new ArrayList();
      ArrayList constantValueList = new ArrayList();

      var constantFile = attributes.get("constants");
      Pattern regex = Pattern.compile("(?<=const)\s (\b\w \b).*?=\s*(.*?)\s*;");
        Matcher regexMatcher = regex.matcher(constantFile);
        while (regexMatcher.find()) {
            constantNameList.add(regexMatcher.group(1));
        constantValueList.add(regexMatcher.group(2));
        }
      for(int i = 0; i < constantNameList.size();   i)
      {
        //debugging
        System.out.print("key : ");
        System.out.print(constantNameList.get(i));
        System.out.print(" value : ");
        System.out.println(constantValueList.get(i));
        //do the actual replacement here
      }
     ]]>
  </scriptdef>

  <target name="build">
    <loadfile property="constants.file" srcFile="${constants}"/>
    <loadfile property="source.file" srcFile="sourceFile.txt"/>
    <echo message="${constants.file}"/>
    <replaceConstants constants="${constants.file}" srcFile="${source.file}"/>
  </target>
</project>
 

Для запуска этого, а также http://www.java2s.com/Code/Jar/ABC/bsh-2.0b5.jar.htm

Этот jar для его запуска.

Вывод :

 [replaceConstants] key : CONST_1 value : 0
[replaceConstants] key : CONST_LOLO value : -1
[replaceConstants] key : CONST_WHEE value : 2.55
[replaceConstants] key : OTHER_CONST value : "La string!"
[replaceConstants] key : ITSAMEMARIO value : "O, HAI!"
[replaceConstants] key : MAGE_WALL value : 15
 

Итак, что я сделал, это сохранил все имена / значения констант в два массива. Вам нужно перебирать массивы и заменять регулярные выражения для каждого из ваших исходных файлов. Все это может быть macrodef, который вы можете вызывать несколько раз.

Комментарии:

1. Потрясающе! Теперь мне нужно только выяснить, как использовать его с набором файлов, затем читать из / записывать в файлы, и все готово!

2. У вас установлен ant contrib? Вы можете использовать это для перебора файлов набора файлов и вызова целевого объекта для каждого файла. Вот как я бы это сделал 🙂

3. Хотел бы я знать. Я использую возможности Flash Builder (который представляет собой afaik eclipse со встроенным плагином flash) для выполнения Ant, и я начал с этого только сегодня. Тем не менее, я не думаю, что он установлен.