使用 IBM Rational Software Analyzer 进行静态分析,第 3 部分: 增强 Java 代码评审的规则

创建严重性的指示器、模板、用户帮助、通用变量,以及可配置的参数

这是关于 IBM Rational Software Analyzer 以及 Rational Application Developer 和 Rational Software Architect 中与它相关能力的四部分系列中的第三篇文章。它引导您浏览了创建您自定义规则以及规则集的整个过程,并使用其它扩展 Java 代码评审的高级能力。

Rational Software Analyzer 促进并简化了自动化代码质量改善的过程。它最初是用来创建和将静态分析工具整合到其它产品,比如 Rational Application Developer 和 Rational Software Architect 的一个 API 和用户界面。 它现在已经发展成为一个完整的,独立支撑的工具,使软件开发人员能够在他们的日常开发过程中轻松地使用自动化代码评审和结构分析。

Steve Gutz, 软件经理, IBM

Steve Gutz 是负责 IBM Rational 代码分析工具的开发经理。除了构架并管理 IBM 的商业产品以外,Steve 过去还致力于 Eclipse Test and Performance Tools project(TPTP),专注于基本的代码审查工具的实现和集成中的改进。在 2002 年加入 IBM 渥太华实验室之前,他在许多公共和私有的公司中担任高级管理和执行职位,包括两个他自己的成功创业。他还写过两本书和许多文章,并且经常在会议上演讲。



2008 年 11 月 06 日

在这个由四部分组成的系列中的 第 1 部分,我们从一个高的层次阐述了静态分析,并且为 IBM® Rational® Software Analyzer (还有 Rational® Software Architect 和 Rational® Application Developer) 和通过选择提供者,种类和规则 来创建分析配置中的普通用户而界面。我们还讨论了显示静态分析,以及内嵌在这些软件中 的一些基本报告能力的结果视图。

第 2 部分,您学习了如何编写规则来扩展当前的 Java 代码评审规则集。 Rational Software Analyzer 分析框架 (参阅代码中像 rsar) 包括几个扩展点以一个为添加分析和新规则的新形式的 API,但是正中的是这个目的,它还 提供了完整的功能分析供应者,从而执行 Java 源代码的自动化代码评审。

您在第 2 部分创建的规则是相当简单的,但是由于它的简化忽略了许多能力。 这篇文章描述了规则创建的一些更高级的特性。它描述了如何添加一个能够使用户添加 可配置参数的严重性指示器和普通规则变量。它还阐述了允许规则作者提供更多关于规则, 比如例子和解决方案的提供者工具的详情。

这篇文章和前面的文章为您理解和编写任何您想要的规则提供了充足的框架。

为规则和创建用户帮助

当您的规则构建过程完成之后,您需要告诉这个用户它为什么要存在以及如何它报告 的这个问题。您可以通过添加一个条目到这个 Eclipse Help 系统来执行,从而显示导致这 个与解决方案一起的规则起反应的代码例子。添加这种规则帮助实际上是一个相对简单的任 务,如果您按照这些基本步骤的话:

  1. 通过使用 HTML 编辑器来创建一个 Help 文档。
  2. 添加一个 help="my_help_id" 标签到 您的规则扩展中。
  3. 创建或者更新您插件的 help.xml 文件,为您的规则添加一个 Help 文本。

当创建 Help 文档时,采取简单的路径。为了保持一致性,最好使您规则中 的 Help 看起来与其它规则中的 Help 一样。最好的方法是从包含在 Rational Software Analyzer 中的规则克隆这个 HTML 文件。

  1. 按照惯例,是在您的名为 ruleinfo 的插件中创建一个文件夹, 并将您的 HTML 文件放进这个文件夹,如列表 1所示。

列表 1 是 Rational Software Analyzer 中一个规则的 Help 代码例子。

列表 1. Help 的 HTML 代码示范
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<!-- 
********************************************************************************
* Licensed Materials - Property of IBM                                         *
* (C) Copyright IBM Corp. 2006.  All Rights Reserved.                          *
*                                                                              *
* US Government Users Restricted Rights - Use, duplication or disclosure       *
* restricted by GSA ADP Schedule Contract with IBM Corp.                       *
********************************************************************************
-->
<html xmlns="http://www.w3.org/1999/xhtml" 
xmlns:xmi="http://www.omg.org/XMI" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<head>
<meta HTTP-EQUIV="Content-Type" 
CONTENT="text/html; charset=iso-8859-1"></meta>
<link rel="stylesheet" type="text/css" href="../ruleinfo.css" >
</head>
<body>
<span class="Text">
<table border="0">
<tr><td><span class="SubHeader">Example</span></td></tr>

<tr><td>
	<table	bgcolor="#F7F8F9" border="1">
	<tr><td>
		<span class="JavaKeyword">package</span> default;<br>
		<br>
		<span class=
              "indent"></span><span class="Javadoc">/**<br>
		<span class="indent"></span> *Javadoc<br>
		<span class="indent"></span> */<br></span>
		<span class=
              "indent"></span><span class="JavaComment">/* <br>
		<span class="indent"></span>*Non-Javadoc<br>
		<span class="indent"></span>*/<br></span>
		<span class="indent"></span>
		<span class="JavaKeyword">public class</span> ClassA {<br>
		<span class="indent2"></span>
		<span class="JavaKeyword">public</span> ClassA () { <br>
		<span class="indent2"></span>}<br>
		<span class="indent"></span>}<br>
		<br>
		
	</td></tr>
	</table>
		
</td></tr>
</table>

<br>
<table border="0">
<tr><td>
	<span class="SubHeader">Solution</span></td></tr>
	<tr><td>
		Place the non-Javadoc in a proper spot, preferably inside the 
		body of the declaration.
		<br>
	
		<table bgcolor="#F7F8F9" border="1">
		<tr><td>
			<span class="JavaKeyword">package</span> default;<br>
			<br>
			<span class=
                      "indent"></span><span class="Javadoc">/**<br>
			<span class="indent"></span> * Javadoc<br>
			<span class="indent"></span> */<br></span>
					
			<span class="indent"></span>
			<span class="JavaKeyword">public class</span> ClassA {<br>
			<span class=
                      "indent2
                      "></span><span class="JavaComment">/*<br>
			<span class="indent2"></span>*Non-Javadoc<br>
			<span class="indent2"></span>*/<br></span>
			 		
			<span class="indent2"></span>
			<span class="JavaKeyword">public </span> ClassA () { <br>
			<span class="indent2"></span>}<br>
			<span class="indent"></span>}
		</td></tr>
		</table>
	</td></tr>
</table>
</span>
</body>
</html>

注意这个规则样例参考了名为 ruleinfo.css 的层叠式样式表。要简化您的规则帮助中的 HTML,您将很可能还想您的 ruleinfo 文件夹中由一个 CSS 文件。它看起来跟列表 2差不多。

列表 2. RuleInfo 层叠式样式表 (ruleinfo.css)
A:link  
{ color: #000099; text-decoration: underline; font-size: 11px; font-family: tahoma }
A:active 
{ color: #000099; text-decoration: underline; font-size: 11px; font-family: tahoma }
A:visited 
{ color: #000099; text-decoration: underline; font-size: 11px; font-family: tahoma }
A:hover 
{ color: #000099; text-decoration: underline; font-size: 11px; font-family: tahoma }

.Text 
{font-family: tahoma; font-size: 11px; color: black} 
.Italic 
{font-family: tahoma; font-size: 11px; font-style: italic}
.Strong  
{font-family: tahoma; font-size: 11px; font-weight: bold}
.Header  
{font-family: tahoma; font-size: 16px; color: black; font-weight: bold; }
.SubHeader 
{font-family: tahoma; font-size: 11px; color: black; font-weight: bold; }
.Code 
      {font-family: tahoma; font-size: 11px; 
      color: black; font-weight: bold; background: #F7F8F9; } 
.JavaType 
{font-family: tahoma; font-size: 11px; color: black; font-weight: bold; } 		
.JavaKeyword 
{font-family: tahoma; font-size: 11px; color: #7F0055; font-weight: bold; } 		
.JavaConst 
{font-family: tahoma; font-size: 11px; color: #2A00FF; font-weight: bold; } 		
.JavaComment 
{font-family: tahoma; font-size: 11px; color: #3F7F5F  } 		
.XmlDefinition {font-family: tahoma; font-size: 11px; color: black; 
text-decoration: italic } 		
.indent {padding-left: 10px;} 
.indent2 {padding-left: 30px;} 
.indent3 {padding-left: 50px;} 
.indent4 {padding-left: 70px;}
  1. 下一步需要添加帮助您的规则来为它们创建唯一的 Help ID。 当您确定您的 ID 后,您可以添加一个 Help 属性到您的规则中。 比如:
      <analysisRule
            category="analysis.codereview.java.examples"
            class="com.ibm.rsar.codereview.java.examples.RuleFinalizerSuper"
            help="com.ibm.rsar.codereview.java.examples.finalSuper"
            id="codereview.java.example.finalSuper"
            label="Avoid finalize() methods that call only super">
      </analysisRule>
  1. 最后,您需要将这个 ID 与一个 Help 上下文联合起来。可以通过 为您的插件创建或者更新 help.xml 文件来实现。

列表 3 是一个简单 help.xml 文件的例子。

列表 3. 简单的 help.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<contexts>
  <context id="examples" title="Examples">
      <description>This category contains example rules for Java code review.
	</description>
  </context>
  <context id="finalSuper" title="Avoid finalize() methods that call only super">
	<description>Providing finalize() methods that call only super is a waste of time
	</description>
	<topic href=
        ".\ruleinfo\examples\finalsuper.html" label="Examples and Solutions"/>
  </context>
</contexts>

在这个文件中有一些值得关注的特性。

  • 首先,注意第一个上下文描述了一个目录。当然,这些目录也可以用有 Help,并且它是通过相同的方法实现的:通过使用这个扩展中的一个 Help 属性。
  • 其次,注意所有的 Help 上下文 ID 的命名都与这个插件相关。 这就是为什么这个 help.xml 文件中的 ID 是 finalsuper 的原因,但是完整的具属名称在 规则定义中使用。
  • 最后,确保这个主题包含到这个 HTML 文件的相关路径,当这个用 户点击最高阶层 Help 页面上的链接时它将会显示(在这种情形下是 Examples 和 Solutions)。

这个例子中的 HTML Help 文件显示在列表 4 中。注意,在这种情形下, 唯一的解决方案是清除 这个 finalize() 方法method;因此,不包 含解决方案例子。然而,绝大多数规则都包含一个修正的代码框架来显示这个 解决方案。

列表 4. HTML Help 文件
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<!-- 
********************************************************************************
* Licensed Materials - Property of IBM                                         *
* (C) Copyright IBM Corp. 2006.  All Rights Reserved.                          *
*                                                                              *
* US Government Users Restricted Rights - Use, duplication or disclosure       *
* restricted by GSA ADP Schedule Contract with IBM Corp.                       *
********************************************************************************
-->
<html xmlns="http://www.w3.org/1999/xhtml" 
xmlns:xmi="http://www.omg.org/XMI" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<head>
<meta HTTP-EQUIV="Content-Type" 
CONTENT="text/html; charset=iso-8859-1"></meta>
<link rel="stylesheet" 
type="text/css" href="../ruleinfo.css" >
</head>
<body>
<span class="Text">
<table border="0">
<tr><td><span class=
"SubHeader">Example</span></td></tr>

<tr><td>
	<table	bgcolor="#F7F8F9" border="1">
	<tr><td>
		<span class="indent"></span>
		<span class="JavaKeyword">public class</span> ClassA {<br>
		<span class="indent2"></span>
		<span class="JavaKeyword">public</span> finalize() { <br>
		<span class="indent3"></span>super.finalize();<br>
		<span class="indent2"></span>}<br>
		<span class="indent"></span>}<br>
		<br>
		
	</td></tr>
	</table>
		
</td></tr></table></span>

<br>
<span class="Text">
<table border="0">
<tr><td>
	<span class=
        "SubHeader">Solution</span></td></tr>
	<tr><td>
		Remove the superfluous finalize method
	</td></tr>
</table>
</span>
</body>
</html>

还需要最后的步骤来激活您规则的上下文相关 Help。您需要将通过一个扩展点这个 help.xml 文件连接到 Eclipse 引擎。添加下面这些到您的 plugin.xml 文件中:

   <extension
         name="Context-Sensitive Help"
         point="org.eclipse.help.contexts">
      <contexts
            file="help.xml"/>
   </extension>

提示:
不要忘记将这个 ruleinfo 文件夹和 help.xml 文件与您的插件一起输出。打开这个 plugin.xml 文件并选择 Build 标签,然后选择 UI (用户界面)中的这些资源。

当您的 Help 已经完成并正确地整合之后,这个用户将能够利用 F1 键在 Analysis Configuration 对话框或者这个分析结果视图中显示它(图 1)。

图 1. 分析结果视图
工作空间视图

指示规则严重性

这个 Rational Software Analyzer 配置configuration 对话框提供了一个保留的区域,允许用户显示和更改任何与这个规则和联合在一起的属性。这个规则作者除了提供任何自定义的细节之外,这个属性面板还提供了一个下拉菜单,这样用户就可以更改这个规则的默认严重性,如图 2所示。这个属性的值控制着与它的规则相联系的图标和它的结果,可以指示它的重要性。下面是严重性的三个基本模式:

  • 建议
  • 警告
  • 严重的

您可以利用这些水平来向用户指示,处理这些产生的结果到底有多重要。对它们 的使用并不是强制性的,但是您应该为您创建的所有规则都详细说明它们默认的严重性。当您的规则结果被报告后,这将有助于指导用户(请参见图 2)。

图 2. 用严重性下来菜单 来更改一个规则的严重性
菜单

利用 Eclipse 中的向导来编辑 analysisRule 并通过这个下拉列表 来设置严重性:

  • 0 = 建议
  • 1 = 警告
  • 2 = 严重的

这些代码碎片显示了这个作为结果的 XML 文本:

      <analysisRule
            category="analysis.codereview.java.examples"
            class="com.ibm.rsar.codereview.java.examples.RuleFinalizerSuper"
            help="com.ibm.rsar.codereview.java.examples.finalSuper"
            id="codereview.java.example.finalSuper"
            label="Avoid finalize() methods that call only super"
            severity="2">
      </analysisRule>

包括普通分析元素参数

当您需要允许用户存储一个规则,目录,或者供应者(分析元素)时会出现一些情形。这个分析规则 API 能让您创建变量,以及在选择这个分析元素时在 Properties 键符上呈现它们。

  1. 利用这个 Eclipse 扩展编辑器添加一个新 analysisParameter,如图 3所示。
图 3. 添加一个新参数
菜单

参数 命名 为(testParameter 在这个例子中)和 (这里是: Hello) ,与这些额外的信息一起(请参见图 4):

  • 这个 Label 区域包括用户在浏览用户界面中的参数区域时可以看到的文本 (这里是: Test)。
  • 这个 Type 区域决定了这个值的数据类型,并且它被用来提供正确的区域编辑器,还有区域确认。这个区域有效的值为 string 或者 integer
  • 这个控制 UI 控制类型的 Style 区域是用来显示这个参数的。例如,数据可以代表一个标准的文本,一个组合框,或者一个复选框。
图 4. 扩展元素细节
对话框

如果这个类型是一个组合框,如前面的图 4所示,那么它的值也必须被添加。

  1. 添加一个新的 comboValue 扩展到每个您想要包含在这个列表中的值的 analysisParameter,如图 5所示。ComboValue 扩展z只有一个值域,它包含这个组合框展开时用户将看到的文本。
图 5. 添加一个 comboValue 扩展
菜单项

您既然已经了解了如何添加一个数据参数到一个规则扩展中,那么您就已经准备好学习如何在您的代码中使用那些值了。

  1. 要在您的规则的 analyze() 方法中中访问一个规则参数,您可以使用下面的代码碎片:
// Extract required parameters
AnalysisParameter rv = this.getParameter( "parameterName" );
String value = rv.getValue();

创建规则模板

正如您刚开始编写规则一样,您将快速意识到许多规则都十分类似。例如,您 可能想要代码扩展各种 Java™ 类时产生结果的规则。假设它们之间唯一的 根本差别是类名称,那么它将有助于利用一个简单的方法来为能够操作所有类的唯 一的规则创建模板。幸运的是,这个分析 API 提供了一个工具使您能够实现。

按照开拓性规则参数,您可以为规则创建简单的,灵活的模板。如果您仔细核查这个 Java 代码评审,您将看到几个模板。 列表 5 显示了为扩展类而产生结果的模板样例。

列表 5. Template example
/*
 *+------------------------------------------------------------------------+
 *| Licensed Materials - Property of IBM                                   |
 *| (C) Copyright IBM Corp. 2005,2007.  All Rights Reserved.               |
 *|                                                                        |
 *| US Government Users Restricted Rights - Use, duplication or disclosure |
 *| restricted by GSA ADP Schedule Contract with IBM Corp.                 |
 *+------------------------------------------------------------------------+
 */
package com.ibm.rsaz.analysis.codereview.java.rules.base.templates;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.TypeDeclaration;

import com.ibm.rsaz.analysis.codereview.java.AbstractCodeReviewRule;
import com.ibm.rsaz.analysis.codereview.java.CodeReviewResource;
import com.ibm.rsaz.analysis.codereview.java.ast.ASTHelper;
import com.ibm.rsaz.analysis.codereview.java.rulefilter.SuperClassRuleFilter;
import com.ibm.rsaz.analysis.core.history.AnalysisHistory;

public class Template_Avoid_Extending_Class
	extends AbstractCodeReviewRule
{
	private static final String CLASS = "CLASS"; //$NON-NLS-1$

	private String	className;

	
	/**
	 * Analyze this rule
	 * 
	 * @param history	A reference to the history record for this analysis
	 */
	public void analyze(AnalysisHistory history, CodeReviewResource resource ) {
		// Extract required variables
		className = getParameter( CLASS ).getValue();

		// Obtain a list of string literals
		List list = resource.getTypedNodeList( resource.getResourceCompUnit(), 
                ASTNode.TYPE_DECLARATION );
		ASTHelper.satisfy( list, new SuperClassRuleFilter( className, true ) );
		for( Iterator it = list.iterator(); it.hasNext(); ) {
			TypeDeclaration td = (TypeDeclaration)it.next();
			resource.generateResultsForASTNode( this, history.getHistoryId(), 
                td.getSuperclassType() );
		}
	}
}

注意这个代码使用了一个叫做 CLASS 的规则参数,并使用它的值核查超类。这个 analysisRule 的扩展使用了类似这个代码的模板:

      <analysisRule
            category="codereview.java.category.exceptions"
            class="com.ibm.rsaz.analysis.templates.Template_Avoid_Extending_Class"
            id="codereview.java.rules.exceptions.RuleExceptionsExtendError"
            label="%label.template.avoid.extending.class"
            severity="0"
            <analysisParameter name="CLASS" value="java.lang.Error" />
      </analysisRule>

注意 analysisParameter 行,它定义了这个 CLASS 参数并分配了一个值,java.lang.Error,给它。因为这个参数还没有一个标签,所以它将不会在这个规则的 Properties 标签页中出现。这就是可视化参数创建的过程。

这个测试中另一个值得注意的行是这个类定义,它指向这个模板的类,而不是您可能创建的模板。

编写自定义规则

模板还可以被终端用户采用,在没有任何代码的请参见下定义新的规则。如果您现在 已经定义了可以用来作为模板的规则类,您可以利用 analysisRuleTemplate 扩展点,使它被终端用户利用。在列表 6中 考虑这个扩展例子。

列表 6. 扩展例子
<extension
  point="com.ibm.rsaz.analysis.core.analysisRuleTemplate">
    <ruleTemplate
       provider="codereview.java.analysisProvider"
	class="com.ibm.rsaz.analysis.templates.Template_Avoid_Extending_Class"
       id=" codereview.java.templates.Template_Avoid_Extending_Class"
       label="Avoid extending <CLASS>">
       <ruleParameter
              label="Class Name:"
              description="Enter a qualified Class Name"
              name="CLASS"
              style="text"
              type="string"/>
	</ruleTemplate>
</extension>

这个例子创建了一个允许用户来定义新的规则来报告以及为特定的类编码扩展的模板。 它使用一个规则参数来声明和描述一个用户可以键入一个合格的类名称的域。

正如这个系列中的第 1 部分,您所定义的任何规则模板都将显示在 Eclipse Preferences 中的 New Rule 向导中。可以这样进行查找:

  1. 从主要的 Eclipse 菜单中选择 Window > Preference
  2. 然,在这个 Preferences 树中,选择 Analysis > Custom Rules and Categories

添加 QuickFix 支持

有时候,一个规则的结果太容易确定,以至于您可以为用户提供一个简单的修正程序。这篇文章没有涉及使用 Java 工具来模拟一个源文件的复杂问题,但是讨论了基本的界面需求。这个 analysisRule 扩展提供了一个 quickfix 次级扩展点,这样您可以为您的 QuickFix 设置一个唯一的标识符,如这个例子中所示:

      <analysisRule
            category="analysis.codereview.java.examples"
            class="com.ibm.RSAR.codereview.java.examples.RuleFinalizeSuper"
            icon="analysis.codereview.java.examples"
            id="codereview.java.example.finalSuper"
            label="Avoid finalize() methods that call only super"
            severity="2">
     	     <quickfix id=
            "com.ibm.rsar.codereview.java.examples.quickfix.FixFinalSuper" />
</analysisRule>

提示:
如果您的规则违背可以用更多的方法来解决,那么您可以在这个规则定义中设置更多的 quickfix 扩展。在这个结果视图中,您具体说明的每个快速确定都将显示在这个结果下拉菜单中。

QuickFix 其实就是一个来自分析 API 的了利用扩展点。要定义一个新扩展点,可以用这个 analysisRuleQuickFix 扩展点。这个扩展需要您定义一个唯一的 ID,一个类来执行这个 QuickFix,一个标签。定义完成之后,它将与这个 plugin.xml 文件片段十分相似:

<extension
     point="com.ibm.rsaz.analysis.core.analysisRuleQuickFix">     
  <analysisRuleQuickFix        	
	class="com.ibm.rsar.codereview.java.examples.quickfix.FixFinalSuper"
	label="%label.stringLiteral.quickfix"
	id=
      " com.ibm.RSAR.codereview.java.examples.quickfix.FixFinalSuper "/>

这个扩展中的标签域是可选择的。如果您省略这个值,这个分析框架将自动设置这个 QuickFix 标签来 “QuickFix。”唯一您需要指定一个标签的实际时间是为了以防万一您的一个规则有多个 QuickFix 的时间。

您执行的这个 quickfix 类必须扩展由 API 所提供的这个 AbstractAnalysisQuickFix 类。严格地说,这样只需要执行一个接受被确定分析结果的 quickfix() 方法。在这个 quickfix 方法中,您可以利用 Java 工具来执行任何需要的修正。为了帮助 Java 代码评审 QuickFix 的实现,分析 API 提供了 JavaCodeReviewQuickFix 基本类。这个类处理所有需要确定问题的重要提升问题,您应该对它进行扩展。

列表 7中的代码执行由 Rational Software Analyzer 提供的规则之一的一个简单的 QuickFix:

列表 7. 规则之一的 QuickFix 包含在 Rational Software Analyzer 之中
public class RuleComparisonReferenceEqualityQuickFix extends
		JavaCodeReviewQuickFix {

	private static final String NOT = &quot;!&quot;; //$NON-NLS-1$
	private static final String CLOSE_PAREN = &quot; )&quot;; //$NON-NLS-1$
	private static final String EQUALS = &quot;.equals( &quot;; //$NON-NLS-1$
	private InfixExpression infixExpr = null;
	
	public TextEdit fixCodeReviewResult 
        ( ASTNode theNode, IDocument docToChange ) {
		
		// reset
		infixExpr = null;
		
		if(theNode instanceof InfixExpression) {
			infixExpr = (InfixExpression)theNode;
		}
		
     if(infixExpr != null) {
	ASTNode enclosingClass = this.getEnclosingClass(infixExpr);
	AST ast = enclosingClass.getAST();
	ASTRewrite rewriter = ASTRewrite.create( ast );
			
        Expression left = infixExpr.getLeftOperand();
	 Expression right = infixExpr.getRightOperand();
	 Operator op = infixExpr.getOperator();			
			
	 StringBuffer replaceString = new StringBuffer(left.toString());
	 replaceString.append(EQUALS); 
	 replaceString.append(right.toString());
	 replaceString.append(CLOSE_PAREN); 
			
	 ASTNode methodInv = (Operator.NOT_EQUALS.equals( op )) ? 
	 rewriter.createStringPlaceholder(NOT + replaceString.toString(),
	 ASTNode.METHOD_INVOCATION) : 
	 rewriter.createStringPlaceholder(replaceString.toString(), 
	 ASTNode.METHOD_INVOCATION);	
			
	 rewriter.replace(infixExpr, methodInv, null);
			
	 TextEdit edits = new MultiTextEdit();			
	 edits.addChild(rewriter.rewriteAST(docToChange, null));

       return edits;
	}
		
	return null;
	}
	
	/*
	 * Returns the ASTNode of type 
          TYPE_DECLARATION or ANONYMOUS_CLASS_DECLARATION
	 * that encloses the given node.
	 * It returns null if there is not enclosing node of those types
	 */
	private ASTNode getEnclosingClass( ASTNode node ) {
		
		ASTNode currentNode = node;
		
		while ( currentNode != null && 
		currentNode.getNodeType() != ASTNode.TYPE_DECLARATION &&
		currentNode.getNodeType() != ASTNode.ANONYMOUS_CLASS_DECLARATION ) {
		currentNode = currentNode.getParent();
		}
		
		return currentNode;
	}	

}

添加规则集支持

假设您已经创建了您自己的许多规则,并且将它们分散在几个不同目录之下。如果您的规则适合一个特定的主题 (比如,安全),它可能会允许这个用户在没有浏览这个规则树的情况下快速选择它们。

幸运的是,您可以通过使用由静态分析框架提供的扩展点来轻松地实现它,而且不需要编写任何代码。这就是著名的规则集。可以通过添加 analysisRuleSet 扩展到您的 plugin.xml 文件来实现它,如这个例子所示:

   <extension
         point="com.ibm.rsaz.analysis.core.analysisRuleSet">
      <analysisRuleSet
            id="analysis.codereview.java.ruleset.quick"
            label="MyRuleSet">
         <analysisRuleSetRule id="codereview.java.rules.awt.RuleAwtPeer"/>
         <analysisRuleSetRule id="codereview.java.threads.whilesleep"/>
         <analysisRuleSetCategory id="codereview.java.j2sebestpractices.loops"/>
      </analysisRuleSet>
   </extension>

在这个例子中,这个定义的规则集包含两个分离的规则和一个一个整体目录。注意包含一个目录将会自动包含这个目录所包含的任何规则和目录。analysisRuleSetRule analysisRuleSetCategory 条目中使用的 ID 是分别为规则和目录而定义的唯一标识符。

规则集是附加的。如果您定义两个规则集 扩展有着相同的 ID,那么这个规则集 将包含这两个扩展中定义的所有元素。在这种情况下,扩展点中只有一个可以为这个标签定义一个值。

规则集将显示在这个分析输入对话框中的 Rules 标签页中。这个用户可以通过使用这个下拉菜单和选择想要的条目(请参见图 6),来浏览这个著名的规则集。当点击这个 Set 按钮之后,规则集中所有的规则和目录在这个规则树中都将会被选择。

图 6. Rules 标签页下的规则集
下拉

总结和下一篇的概要

这篇文章涉及了规则严重性,自定义规则模板,以及常见规则模板的概念。掌握了这些信息以及第 2 部分中所涉及的内容,您现在就已经足够编写您自己规则的知识了。

在这个系列的第 4 部分,我们将进入分析 API 的更深层次研究,并利用它来创建新的分析提供者,自定义目录,以及结果视图。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=350398
ArticleTitle=使用 IBM Rational Software Analyzer 进行静态分析,第 3 部分: 增强 Java 代码评审的规则
publish-date=11062008