Here are the tweets you likely missed last month!
— SonarQube (@SonarQube) June 8, 2016
— SonarQube (@SonarQube) June 14, 2016
— SonarQube (@SonarQube) June 15, 2016
The latest rule we implemented based on execution flow aims at no less than detecting when a property is accessed on a value which might be null or undefined. In such a case, a TypeError may be thrown at runtime, and the application may crash. That rule catches obvious bugs in poor quality code, but it can also find more subtle issues, such as when a value is sometimes tested for nullability and sometimes not. That’s the case in the following code in the React project:
Conditions which are either always true or always false represent another bug pattern for which we have a relatively new rule. Sometimes, such a condition is simply redundant with the rest of the code as in in the following example in the Closure Library:
In other cases, a condition which is always true or false may be the visible part of a real bug, especially when it means that a full block of code will never be executed. Here’s an example from the Ionic framework which looks like a serious bug:
Detecting dead stores is another rule we added recently and that is based on execution flow. A dead store is a useless assignment to a variable, where the variable that’s assigned is never read after the assignment. Most often, this is not a bug, just useless and potentially confusing code. However, it’s so common that thousands of dead stores can be found in open-source projects. Here’s a very simple example in the AngularJS project:
Now, we’ve said all of these rules are based on execution flow, but some curious readers may ask: how do we describe execution flow? Except in the simplest cases, execution flow is rarely linear. As soon as a piece of code contains an if statement, its execution flow has to be described with alternatives branches: either the condition of the if statement is true and we execute the associated block, or it’s false and we don’t execute the block. Moreover, execution flow may go back to a point which was already executed thanks to loops. In the end, in order to represent all the possible paths, we use a graph structure which is known as a control flow graph (CFG).
Based on a control flow graph, it’s rather easy to identify dead stores by checking all paths which come out of an assignment. However, a CFG is certainly not enough to detect potential TypeErrors or conditions which are always true or false. To do that, we need symbolic execution. That is, we need to track the values which are referenced by variables. We can walk through the CFG and evaluate some parts of the code:
- Based on assignments, we may know the precise value of a variable at a given point.
- Based on conditions in if statements or loops, we may know which constraints are met by the value of a variable inside a given block.
Running symbolic execution means that we explore the possible execution paths based on the CFG and the possible constraints on variables.
- When looking for possible TypeErrors, we raise an issue as soon as one of the execution paths leads to a property access on a value which is constrained to null or undefined.
- When looking for conditions which are always true or false, we have to check all of the execution paths which go through a condition.
We’re excited to announce that we’ve finally determined where and when Selenium Conf will be happening this Fall.
Our initial goal was to bring the event to a new country, but for a number of reasons that proved more challenging than we’d hoped. But in 2012 we had the 2nd annual Selenium Conf in London, and we’re pleased to be bringing it back there this year!
The conference will be held at The Mermaid in downtown London on November 14-16:
- The 14th will be all-day pre-conference workshops
- The 15th-16th will be the conference
Go here to sign up for the email list for conference updates (e.g., when tickets go on sale) as well as submit a talk. Call for speakers are open from now until July 29th.
SonarAnalyzers are fundamental pillars of our ecosystem. The language analyzers play a central role, but the value they bring isn’t always obvious. The aim of this post is to highlight the ins and outs of SonarAnalyzers.
The goal of the SonarAnalyzers (packaged either as SonarQube plugins or in SonarLint) is to raise issues on problems detected in source code written in a given programming language. The detection of issues relies on the static analysis of source code and the analyzer’s rule implementations. Each programming language requires a specific SonarAnalyzer implementation.The analyzer
The SonarAnalyzer’s static analysis engine is at the core of source code interpretation. The scope of the analysis engine is quite large. It goes from basic syntax parsing to the advanced determination of the potential states of a piece of code. At minimum, it provides the bare features required for the analysis: basic recognition of the language’s syntax. The better the analyzer is, the more advanced it’s analysis can be, and the trickier the bugs it can find.
Driven by the will to perform more and more advanced analyses, the analyzers are continuously improved. New ambitions in terms of validation require constant efforts in the development of the SonarAnalyzers. In addition, to be able to handle updates to each programming language, regular updates are required in the analyzers to keep up with each language’s evolution.The rules
The genesis of a rule starts with the writing of its specification. The specification of each rule is an important step. The description should be clear and unequivocal in order to be explicit about what issue is being detected. Not only must the description of the rule be clear and accurate, but code snippets must also be supplied to demonstrate both the bad practice and it’s fix. The specification is available from each issue raised by the rule to help users understand why the issue was raised.
Rules also have tags. The issues raised by a rule inherit the rule’s tags, so that both rules and issues are more searchable in SonarQube.
Once the specification of a rule is complete, next comes the implementation. Based on the capabilities offered by the analyzer, rule implementations detect increasingly tricky patterns of maintainability issues, bugs, and security vulnerabilities.Continuous Improvement
The analysis of other languages can be enabled by the installation of additional SonarAnalyzer plugins.
SonarQube community officially supports 24 language analyzers. Currently about 3500 rules are implemented across all SonarAnalyzers.
More than half of SonarSource developers work on SonarAnalyzers. Thanks to the efforts of our SonarAnalyzer developers, there are new SonarAnalyzer versions nearly every week.
In 2015, we delivered a total of 61 new SonarAnalyser releases, and so far this year, another 30 versions have been released.What it means for you
You can easily benefit from the regular delivery of SonarAnalyzers. At each release, analyzer enhancements and new rules are provided. But, you don’t need to upgrade SonarQube to upgrade your analysis; as a rule, new releases of each analyzers are compatible with the latest LTS.
When you update a SonarAnalyzer, the static analysis engine is replaced and new rules are made available. But at this step, you’re not yet benefiting from those new rules. During the update of your SonarAnalyzer, the quality profile remains unchanged. The rules executed during the analysis are the same ones you previously configured in your quality profile.
It means that if you want to benefit from new rules you must update your quality profile to add them.
With the release of SonarQube version 5.6, the entire Sonar ecosystem will drop support for Java 7. This means you won’t be able to run new versions of the SonarQube server, execute an analysis, or use SonarLint with a JVM < 8.
Why? Well, its been over two years since Java 8′s initial release, and a year since Oracle stopped supporting Java 7, so we figured it was time for us to stop to. Doing so allows us to simplify our development processes and begin using the spiffy new features in Java 8. Plus, performance is up to 20% better with Java 8!
Of course, we’ll still support running older versions of ecosystem products, e.g. SonarQube 4.5, with Java 7, and you’ll still be able to compile your project with a lower version of Java. You’ll just have to bump up the JVM version to run the analysis.