Flex Code Analyzer

2011-03-09 17:13 by hackerzhou

最近做了一个检查flex代码,找出没有用到的properties资源(主要用来保存一些设置和提供多语言支持)以及as和mxml文件的工具。对于一个多人合作或者需求经常更改的大项目来说,很容易出现这种问题,需要定期的做code clean up来保证源代码条理清晰。那么,问题也就产生了,如何有效率的找出没有用到的项目,本文的目的也就在于解决这类的问题。

Properties主要有如下几点问题:

1.重复的项:重复定义的项可能会导致不可预料的后果,比如定义了a=1和a=2两条矛盾的记录,那么很有可能造成混淆。

2.用到了未定义的项:代码中使用到了,但是却没有在properties中定义,同样会造成问题。

3.定义了但从未用到的项:这类的多余的项会影响整个项目代码的review,clean up的时候应当将这些项目删除。

解决方法:

1.使用HashMap读入properties文件(处理注释以及空白),其实用Java的Properties类来读取更加方便,但是用Properties类的话就不能发现重复项了,问题1解决。

2.读取所有可能用到properties的文件(*.as,*.mxml,*.xml),用正则提取所有双引号和单引号中的内容,放到另一个HashMap中,这个Map就是潜在的可能匹配项,因为需要用到properties的地方都是需要用引号来调用值。但是这个Map会很大,因为比如width=”1″,这里的1都会被提取出来。

3.出现在第一个HashMap中却没有出现在第二个HashMap中的,是定义了但从未用到的项,问题3解决。这种方法比建立一个正则的filter,然后接受一个一个文件来过滤有效率的多,而且效果是一样的。

4.用另一个比较通用的调用方式建立正则,比如“ResourceUtil.getString(…”之类的,匹配出肯定是调用properties的地方,检查是否存在于第一个HashMap中,要是不存在,就是未定义的项,问题2解决。不过这地方很难做到完美,因为不一定所有的地方调用properties的方法都一样,要是别人把ResourceUtil封装了一下上面的那个例子就检测不出来了。只能在相当程度上检查出这类的问题。

Unreferenced Code Check:

这个问题的处理难度比第一个复杂多了,开头想过直接通过从Application入口点开始构造一整颗引用树,太复杂了,想了一个比较方便的方法:使用Flex的编译器来帮我们分析Reference,因为编译器不会把未用到的源代码编译进去。

1.通过命令行编译Flex项目,增加编译参数-keep-generated-actionscript=true,这个参数的意思是保留产生的中间as代码。由于mxml也会由编译器编译,然后产生中间actionscript代码,这些中间代码被保存在generated文件夹下。
这些产生的代码都会以-generated或者-interface结尾,有些则是编译出的InnerClass,分析这些代码后发现有可能出现外部引用的地方是:头部的import,编译器自动添加的include,以及定义变量或者用as转换类型时。那么接下来就可以通过这些规则来解决问题。

2.定义两个Map,一个是AllCodeMap,即所有的MXML和AS类的类名都在这个Map中,Value是具体的File;另一个是UsedCodeMap,将产生的中间代码去掉generated等后缀,Value也是具体的File。

3.遍历UsedCodeMap,检查代码文件的import和include,如果import/include的内容不在UsedCodeMap中,从AllCodeMap查询出对应的项,插入UsedCodeMap中。

4.接着遍历UsedCodeMap,检查类型的使用(new,as,extends,var等),如果使用的类不在UsedCodeMap中,从AllCodeMap查询出对应的项,插入UsedCodeMap中。

5.重复3和4两个步骤,直到没有更多的项被加入UsedCodeMap。

6.遍历AllCodeMap,如果在UsedCodeMap中没有,则为没有用到的代码。至此,问题解决。

 

本文基于 署名 2.5 中国大陆 许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 hackerzhou 并包含 原文链接
发表评论

本文有 8 条评论

  1. God Bless You
    2011-12-01 13:09

    shell脚本就能轻松解决这个问题,写代码的话就相对累了

    检查类型的使用(new,as,extends,var等)意义不是太大,大多数类型检查或转换还是会用到import的

    • hackerzhou
      2011-12-01 18:37

      问一下用shell脚本怎么解决呢,当时没想到

      • God Bless You
        2011-12-02 09:25

        1.mxml和as文件中find 含”import” “include”等字符串的行,保存到res.txt文件中
        2.awk、sort、uniq 命令处理res.txt文件,格式化数据
        3.find 代码的src目录,保存代码的文件名列表到code.txt
        4.同2,格式化代码文件名列表code.txt
        5.比较code和res文件,code中多余的行即为无用代码

        注:不考虑 检查类型,import的Class在代码中被注释、同包的引用等问题。。。
        故5中可能会多删,编译时看到误删的补回来即可

        • hackerzhou
          2011-12-02 20:58

          你不考虑的东西太多了。。。因为是产品应用,不敢乱动啊。其实我想到的标准做法应该是模拟编译器进行词法和语法分析,形成语法树之后做code cleanup。我当时就是考虑尽量不要自己做词法分析,还是依赖flex编译器来做这种事情。这是实习的时候帮UI team做的活儿。

          • God Bless You
            2011-12-05 11:43

            如果考虑那些问题的话,shell会稍复杂些,可能得写个小脚本。我们也是产品应用。
            光文本处理的话,还是shell强大和简单的

          • hackerzhou
            2011-12-05 20:26

            嗯,确实~

  2. diytz
    2011-11-23 14:52

    hi,兄弟

    能否分享下你的工具?

    • hackerzhou
      2011-11-23 18:38

      由于代码牵涉到公司的版权,所以不能公开,按照我的思路来做的话不难做出来的

发表评论