зеркало из https://github.com/github/codeql.git
Merge commit '7bfed6e517cbcabfe06cf614981baee8cbde5342' into attribute
This commit is contained in:
Коммит
7176b438c4
|
@ -15,4 +15,5 @@
|
|||
targets for `Object.toString()` calls. This affects all security queries and
|
||||
removes false positives that arose from paths through impossible `toString()`
|
||||
calls.
|
||||
* The library `VCS.qll` and all queries that imported it have been removed.
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
This metric measures the number of lines of text that have been added, deleted
|
||||
or modified in files below this location in the tree.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Code churn is known to be a good (if not the best) predictor of defects in a
|
||||
code component (see e.g. [Nagappan] or [Khoshgoftaar]). The intuition is that
|
||||
files, packages or projects that have experienced a disproportionately high
|
||||
amount of churn for the amount of code involved may have been harder to write,
|
||||
and are thus likely to contain more bugs.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
It is a fact of life that some code is going to be changed more than the rest,
|
||||
and little can be done to change this. However, bearing in mind code churn's
|
||||
effectiveness as a defect predictor, code that has been repeatedly changed
|
||||
should be subjected to vigorous testing and code review.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<references>
|
||||
|
||||
|
||||
<li>
|
||||
N. Nagappan et al. <em>Change Bursts as Defect Predictors</em>. In Proceedings of the 21st IEEE International Symposium on Software Reliability Engineering, 2010.
|
||||
</li>
|
||||
<li>
|
||||
T. M. Khoshgoftaar and R. M. Szabo. <em>Improving code churn predictions during the system test and maintenance phases</em>. In ICSM '94, 1994, pp. 58-67.
|
||||
</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
|
@ -1,22 +0,0 @@
|
|||
/**
|
||||
* @name Churned lines
|
||||
* @description The number of churned lines of a file (by version control history).
|
||||
* @kind treemap
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg sum max
|
||||
* @id java/vcs/churn-per-file
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import java
|
||||
import external.VCS
|
||||
|
||||
from File f, int n
|
||||
where
|
||||
n = sum(Commit entry, int churn |
|
||||
churn = entry.getRecentChurnForFile(f) and not artificialChange(entry)
|
||||
|
|
||||
churn
|
||||
)
|
||||
select f, n order by n desc
|
|
@ -1,6 +0,0 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<include src="HChurn.qhelp" />
|
||||
</qhelp>
|
|
@ -1,22 +0,0 @@
|
|||
/**
|
||||
* @name Added lines
|
||||
* @description The number of added lines of a file (by version control history).
|
||||
* @kind treemap
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg sum max
|
||||
* @id java/vcs/added-lines-per-file
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import java
|
||||
import external.VCS
|
||||
|
||||
from File f, int n
|
||||
where
|
||||
n = sum(Commit entry, int churn |
|
||||
churn = entry.getRecentAdditionsForFile(f) and not artificialChange(entry)
|
||||
|
|
||||
churn
|
||||
)
|
||||
select f, n order by n desc
|
|
@ -1,6 +0,0 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<include src="HChurn.qhelp" />
|
||||
</qhelp>
|
|
@ -1,22 +0,0 @@
|
|||
/**
|
||||
* @name Deleted lines
|
||||
* @description The number of deleted lines of a file (by version control history).
|
||||
* @kind treemap
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg sum max
|
||||
* @id java/vcs/deleted-lines-per-file
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import java
|
||||
import external.VCS
|
||||
|
||||
from File f, int n
|
||||
where
|
||||
n = sum(Commit entry, int churn |
|
||||
churn = entry.getRecentDeletionsForFile(f) and not artificialChange(entry)
|
||||
|
|
||||
churn
|
||||
)
|
||||
select f, n order by n desc
|
|
@ -1,48 +0,0 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
This metric measures the number of different authors (by examining the
|
||||
version control history)
|
||||
for files below this location in the tree. (This is a better version
|
||||
of the metric that counts the number of different authors using Javadoc
|
||||
tags.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Files that have been changed by a large number of different authors are
|
||||
by definition the product of many minds. New authors working on a file
|
||||
may be less familiar with the design and implementation of the code than
|
||||
the original authors, which can be a potential source of bugs. Furthermore,
|
||||
code that has been worked on by many people, if not carefully maintained,
|
||||
often ends up lacking conceptual integrity. For both of these reasons, any
|
||||
code that has been worked on by an unusually high number of different people
|
||||
merits careful inspection in code reviews.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
There is clearly no way to reduce the number of authors that have worked
|
||||
on a file - it is impossible to rewrite history. However, files highlighted
|
||||
by this metric should be given special attention in a code review, and may
|
||||
ultimately be good candidates for refactoring/rewriting by an individual,
|
||||
experienced developer.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</recommendation>
|
||||
<references>
|
||||
|
||||
|
||||
<li>
|
||||
F. P. Brooks Jr. <em>The Mythical Man-Month</em>, Chapter 4. Addison-Wesley, 1974.
|
||||
</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
|
@ -1,16 +0,0 @@
|
|||
/**
|
||||
* @name Number of authors (version control)
|
||||
* @description The number of distinct authors (by version control history) of a file.
|
||||
* @kind treemap
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max
|
||||
* @id java/vcs/authors-per-file
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import java
|
||||
import external.VCS
|
||||
|
||||
from File f
|
||||
select f, count(Author author | author.getAnEditedFile() = f)
|
|
@ -1,30 +0,0 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
This metric measures the total number of file-level changes made to files
|
||||
below this location in the tree. For an individual file, it measures the
|
||||
number of commits that have affected that file. For a directory of files, it
|
||||
measures the sum of the file-level changes for each of the files in the
|
||||
directory.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, suppose we have a directory containing two files, A and B. If the
|
||||
number of file-level changes to A is <code>100</code>, and the number of
|
||||
file-level changes to B is <code>80</code>, then the total number of
|
||||
file-level changes to the directory is <code>180</code>. Note that this is
|
||||
likely to be different (in some cases very different) from the number of
|
||||
commits that affected any file in the directory, since more than one file can
|
||||
be changed by a single commit. (Note what would happen if we performed
|
||||
<code>80</code> commits on A and B, followed by another <code>20</code>
|
||||
commits on A alone - the total number of file-level changes would be
|
||||
<code>180</code>, but the number of commits involved would be
|
||||
<code>100</code>.)
|
||||
</p>
|
||||
|
||||
|
||||
</overview>
|
||||
</qhelp>
|
|
@ -1,16 +0,0 @@
|
|||
/**
|
||||
* @name Number of file-level changes
|
||||
* @description The number of file-level changes made (by version control history).
|
||||
* @kind treemap
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max sum
|
||||
* @id java/vcs/commits-per-file
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import java
|
||||
import external.VCS
|
||||
|
||||
from File f
|
||||
select f, count(Commit svn | f = svn.getAnAffectedFile() and not artificialChange(svn))
|
|
@ -1,63 +0,0 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
This metric measures the number of recent changes to files that have occurred
|
||||
below this location in the tree. A recent change is taken to mean a change
|
||||
that has occurred in the last <code>180</code> days.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
All code that has changed a great deal may be more than usually prone to
|
||||
defects, but this is particularly true of code that has been changing
|
||||
dramatically in the recent past, because it has not yet had a chance to be
|
||||
properly field-tested in order to iron out the bugs.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
There is more than one reason why a file may have been changing a lot
|
||||
recently:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The file may be part of a new subsystem that is being written. New code is
|
||||
always going to change a lot in a short period of time, but it is important
|
||||
to ensure that it is properly code reviewed and unit tested before integrating
|
||||
it into a working product.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The file may be being heavily refactored. Large refactorings are sometimes
|
||||
essential, but they are also quite risky. You should write proper regression
|
||||
tests before starting on a major refactoring, and check that they still pass
|
||||
once you're done.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The same bit of code may be being changed repeatedly because it is difficult
|
||||
to get right. Aside from vigorous code reviewing and testing, it may be a good
|
||||
idea to rethink the system design - if something is that hard
|
||||
to get right (and it's not an inherently difficult concept), you might be making life unnecessarily hard for yourself and
|
||||
risking introducing insidious defects.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</recommendation>
|
||||
<references>
|
||||
|
||||
|
||||
<li>
|
||||
N. Nagappan et al. <em>Change Bursts as Defect Predictors</em>. In Proceedings of the 21st IEEE International Symposium on Software Reliability Engineering, 2010.
|
||||
</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
|
@ -1,22 +0,0 @@
|
|||
/**
|
||||
* @name Number of recent file changes
|
||||
* @description Number of recent commits to a file (by version control history).
|
||||
* @kind treemap
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max sum
|
||||
* @id java/vcs/recent-commits-per-file
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import java
|
||||
import external.VCS
|
||||
|
||||
from File f, int n
|
||||
where
|
||||
n = count(Commit e |
|
||||
e.getAnAffectedFile() = f and
|
||||
e.daysToNow() <= 180 and
|
||||
not artificialChange(e)
|
||||
)
|
||||
select f, n order by n desc
|
|
@ -171,36 +171,6 @@ tokens(
|
|||
int endColumn : int ref
|
||||
);
|
||||
|
||||
/*
|
||||
* Version history
|
||||
*/
|
||||
|
||||
svnentries(
|
||||
int id : @svnentry,
|
||||
string revision : string ref,
|
||||
string author : string ref,
|
||||
date revisionDate : date ref,
|
||||
int changeSize : int ref
|
||||
)
|
||||
|
||||
svnaffectedfiles(
|
||||
int id : @svnentry ref,
|
||||
int file : @file ref,
|
||||
string action : string ref
|
||||
)
|
||||
|
||||
svnentrymsg(
|
||||
int id : @svnentry ref,
|
||||
string message : string ref
|
||||
)
|
||||
|
||||
svnchurn(
|
||||
int commit : @svnentry ref,
|
||||
int file : @file ref,
|
||||
int addedLines : int ref,
|
||||
int deletedLines : int ref
|
||||
)
|
||||
|
||||
/*
|
||||
* Locations and files
|
||||
*/
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,78 +0,0 @@
|
|||
import java
|
||||
|
||||
class Commit extends @svnentry {
|
||||
Commit() {
|
||||
svnaffectedfiles(this, _, _) and
|
||||
exists(date svnDate, date snapshotDate |
|
||||
svnentries(this, _, _, svnDate, _) and
|
||||
snapshotDate(snapshotDate) and
|
||||
svnDate <= snapshotDate
|
||||
)
|
||||
}
|
||||
|
||||
string toString() { result = this.getRevisionName() }
|
||||
|
||||
string getRevisionName() { svnentries(this, result, _, _, _) }
|
||||
|
||||
string getAuthor() { svnentries(this, _, result, _, _) }
|
||||
|
||||
date getDate() { svnentries(this, _, _, result, _) }
|
||||
|
||||
int getChangeSize() { svnentries(this, _, _, _, result) }
|
||||
|
||||
string getMessage() { svnentrymsg(this, result) }
|
||||
|
||||
string getAnAffectedFilePath(string action) {
|
||||
exists(File rawFile | svnaffectedfiles(this, rawFile, action) |
|
||||
result = rawFile.getAbsolutePath()
|
||||
)
|
||||
}
|
||||
|
||||
string getAnAffectedFilePath() { result = getAnAffectedFilePath(_) }
|
||||
|
||||
File getAnAffectedFile(string action) { svnaffectedfiles(this, result, action) }
|
||||
|
||||
File getAnAffectedFile() { exists(string action | result = this.getAnAffectedFile(action)) }
|
||||
|
||||
predicate isRecent() { recentCommit(this) }
|
||||
|
||||
int daysToNow() {
|
||||
exists(date now | snapshotDate(now) | result = getDate().daysTo(now) and result >= 0)
|
||||
}
|
||||
|
||||
int getRecentAdditionsForFile(File f) { svnchurn(this, f, result, _) }
|
||||
|
||||
int getRecentDeletionsForFile(File f) { svnchurn(this, f, _, result) }
|
||||
|
||||
int getRecentChurnForFile(File f) {
|
||||
exists(int added, int deleted | svnchurn(this, f, added, deleted) and result = added + deleted)
|
||||
}
|
||||
}
|
||||
|
||||
class Author extends string {
|
||||
Author() { exists(Commit e | this = e.getAuthor()) }
|
||||
|
||||
Commit getACommit() { result.getAuthor() = this }
|
||||
|
||||
File getAnEditedFile() { result = this.getACommit().getAnAffectedFile() }
|
||||
}
|
||||
|
||||
predicate recentCommit(Commit e) {
|
||||
exists(date snapshotDate, date commitDate, int days |
|
||||
snapshotDate(snapshotDate) and
|
||||
e.getDate() = commitDate and
|
||||
days = commitDate.daysTo(snapshotDate) and
|
||||
days >= 0 and
|
||||
days <= 60
|
||||
)
|
||||
}
|
||||
|
||||
date firstChange(File f) {
|
||||
result = min(Commit e, date toMin | f = e.getAnAffectedFile() and toMin = e.getDate() | toMin)
|
||||
}
|
||||
|
||||
predicate firstCommit(Commit e) {
|
||||
not exists(File f | f = e.getAnAffectedFile() | firstChange(f) < e.getDate())
|
||||
}
|
||||
|
||||
predicate artificialChange(Commit e) { firstCommit(e) or e.getChangeSize() >= 50000 }
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* @name Filter: only files recently edited
|
||||
* @description Filter a defect query to only include results in files that have been changed recently, and modify the message.
|
||||
* @kind problem
|
||||
* @id java/recently-changed-file-filter
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import java
|
||||
import external.DefectFilter
|
||||
import external.VCS
|
||||
|
||||
pragma[noopt]
|
||||
private predicate recent(File file) {
|
||||
exists(Commit e | file = e.getAnAffectedFile() | e.isRecent() and not artificialChange(e)) and
|
||||
exists(file.getLocation())
|
||||
}
|
||||
|
||||
from DefectResult res
|
||||
where recent(res.getFile())
|
||||
select res, res.getMessage()
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* @name Metric filter: only files recently edited
|
||||
* @description Filter a metric query to only include results in files that have been changed recently, and modify the message.
|
||||
* @kind treemap
|
||||
* @id java/recently-changed-file-metric-filter
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import java
|
||||
import external.MetricFilter
|
||||
import external.VCS
|
||||
|
||||
pragma[noopt]
|
||||
private predicate recent(File file) {
|
||||
exists(Commit e | file = e.getAnAffectedFile() | e.isRecent() and not artificialChange(e)) and
|
||||
exists(file.getLocation())
|
||||
}
|
||||
|
||||
from MetricResult res
|
||||
where recent(res.getFile())
|
||||
select res, res.getValue()
|
Загрузка…
Ссылка в новой задаче