我怎样才能确保正确的字节码可用于我的自定义声纳插件规则,所以我不明白! 对于每一种类型?

我一直在试图为Sonarqube〜5.4编写一个自定义规则插件,虽然我已经实现了一些实现和工作的规则,但依赖于标准库之外的类型的规则依赖于各种杂技字符串匹配。

我正在使用sonar-packaging-maven-plugin来做包装:

 <plugin> <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> <artifactId>sonar-packaging-maven-plugin</artifactId> <version>1.16</version> <configuration> <pluginClass>${project.groupId}.sonar.BravuraRulesPlugin</pluginClass> <pluginKey>SonarPluginBravura</pluginKey> <skipDependenciesPackaging>false</skipDependenciesPackaging> <basePlugin>java</basePlugin> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>sonar-plugin</goal> </goals> </execution> </executions> </plugin> 

并且使用下面的助手扩展(kotlin)运行各种检查:

 fun <T : JavaFileScanner> T.verify() { val workDir = System.getProperty("user.dir"); val folder = Paths.get(workDir, "src/test/samples", this.javaClass.simpleName); Files.list(folder).forEach { sample -> try { if (sample.toString().endsWith(".clean.java")) { JavaCheckVerifier.verifyNoIssue(sample.toString(), this); } else { JavaCheckVerifier.verify(sample.toString(), this); } } catch (error: Exception) { throw VerificationFailedException(sample, error); } } }; class VerificationFailedException(path: Path, error: Exception) : Exception("Failed to verify $path.", error); 

我为该规则创建一个IssuableSubscriptionVisitor子类,并访问Tree.Kind.METHOD_INVOCATION ,查找使用传递AutoLongColumn的静态MAX,MIN,ASC或DESC sql builder方法。 这是为了停止用于订购目的的标识符字段。

不幸的是,即使我在maven“测试”类路径上有必要的库,当我尝试获取任何类型时,它们都显示为!unknown!

 override fun visitNode(tree: Tree) { if (tree !is MethodInvocationTree) { return; } val methodSelect = tree.methodSelect(); if (methodSelect !is IdentifierTree || methodSelect.name() !in setOf("MAX", "MIN", "ASC", "DESC")) { return; } val firstArg = statement.arguments().first(); if (firstArg !is MethodInvocationTree) { return; } val firstArgSelect = firstArg.methodSelect(); if (firstArgSelect !is MemberSelectExpressionTree) { return; } if (firstArgSelect.type is UnknownType) { throw TableFlipException("(ノಥ益ಥ)ノ ┻━┻"); } // It never gets here. } 

我确信我错过了一些重要的难题,如果有人能告诉我我哪里出错了,我会很感激。

编辑:我使用org.sonarsource.java:sonar-java-plugin:3.14分析仪,虽然我不能释放分析目标(商业IP和所有的)的所有代码,这里有一些结构相同关键部分:

 import static com.library.UtilClass.MAX; ... query.SELECT(biggestId = MAX(address._id())) // Noncompliant .FROM(address) .WHERE(address.user_id().EQ(userId) .AND(address.type_id().EQ(typeId))); ... 

address.id()的类型是一个包装long的com.library.Identifier 。 我想能够访问所有的方法调用,检查它们是否与com.library.UtilCLass.MAX匹配,如果是,请确保第一个参数不是com.library.Identifier 。 没有类型信息,我必须对_id方法引用进行正则表达式匹配,这很容易丢失。

所以,得到可用类型的方法是使用maven(或者你正在使用的任何工具)将需要的jar复制到一个目录中,然后把这个文件转换成一个文件列表,然后把它传递给测试验证。

例如,让我们假装我们正在试图找到joda-time的用法:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.10</version> <executions> <execution> <id>copy-libs</id> <phase>generate-test-resources</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.9.4</version> </artifactItem> </artifactItems> </configuration> </execution> <executions> </plugin> 

这个执行会把joda-time jar放到target/dependency目录中。 接下来,确保枚举该目录中的jar,并将其添加到您的测试验证中(我们假设您将验证者命名为“JodaCheck”):

 // Not at all necessary, but it makes the code later on a lot easier to read. fun <T> Stream<T>.toList(): List<T> = this.collect({ mutableListOf() }, { list, item -> list.add(item) }, { list, otherList -> list.addAll(otherList) }) ... val workDir = System.getProperty("user.dir") val sampleFile = Paths.get(workDir, "src/test/samples/JodaSample.java").toString() val dependencies = Files.list(Paths.get(workDir, "target/dependency")) .map { it.toFile() }.toList() JavaCheckVerifier.verify(sampleFile, JodaChecker(), dependencies) 

完成之后,通过测试进行调试将显示在分析过程中可用的joda时间类。