33import python
44
55/** Gets the relative path of `file`, with backslashes replaced by forward slashes. */
6- private
7- string relativePath ( File file ) {
8- result = file .getRelativePath ( ) .replaceAll ( "\\" , "/" )
9- }
6+ private string relativePath ( File file ) { result = file .getRelativePath ( ) .replaceAll ( "\\" , "/" ) }
107
118/**
129 * Holds if the `index`-th token of block `copy` is in file `file`, spanning
@@ -21,60 +18,42 @@ private predicate tokenLocation(File file, int sl, int sc, int ec, int el, Copy
2118}
2219
2320/** A token block used for detection of duplicate and similar code. */
24- class Copy extends @duplication_or_similarity
25- {
26- private
27- int lastToken ( ) {
28- result = max ( int i | tokens ( this , i , _, _, _, _) | i )
29- }
21+ class Copy extends @duplication_or_similarity {
22+ private int lastToken ( ) { result = max ( int i | tokens ( this , i , _, _, _, _) | i ) }
3023
3124 /** Gets the index of the token in this block starting at the location `loc`, if any. */
3225 int tokenStartingAt ( Location loc ) {
33- tokenLocation ( loc .getFile ( ) , loc .getStartLine ( ) , loc .getStartColumn ( ) ,
34- _, _, this , result )
26+ tokenLocation ( loc .getFile ( ) , loc .getStartLine ( ) , loc .getStartColumn ( ) , _, _, this , result )
3527 }
3628
3729 /** Gets the index of the token in this block ending at the location `loc`, if any. */
3830 int tokenEndingAt ( Location loc ) {
39- tokenLocation ( loc .getFile ( ) , _, _,
40- loc .getEndLine ( ) , loc .getEndColumn ( ) , this , result )
31+ tokenLocation ( loc .getFile ( ) , _, _, loc .getEndLine ( ) , loc .getEndColumn ( ) , this , result )
4132 }
4233
4334 /** Gets the line on which the first token in this block starts. */
44- int sourceStartLine ( ) {
45- tokens ( this , 0 , result , _, _, _)
46- }
35+ int sourceStartLine ( ) { tokens ( this , 0 , result , _, _, _) }
4736
4837 /** Gets the column on which the first token in this block starts. */
49- int sourceStartColumn ( ) {
50- tokens ( this , 0 , _, result , _, _)
51- }
38+ int sourceStartColumn ( ) { tokens ( this , 0 , _, result , _, _) }
5239
5340 /** Gets the line on which the last token in this block ends. */
54- int sourceEndLine ( ) {
55- tokens ( this , this .lastToken ( ) , _, _, result , _)
56- }
41+ int sourceEndLine ( ) { tokens ( this , this .lastToken ( ) , _, _, result , _) }
5742
5843 /** Gets the column on which the last token in this block ends. */
59- int sourceEndColumn ( ) {
60- tokens ( this , this .lastToken ( ) , _, _, _, result )
61- }
44+ int sourceEndColumn ( ) { tokens ( this , this .lastToken ( ) , _, _, _, result ) }
6245
6346 /** Gets the number of lines containing at least (part of) one token in this block. */
64- int sourceLines ( ) {
65- result = this .sourceEndLine ( ) + 1 - this .sourceStartLine ( )
66- }
47+ int sourceLines ( ) { result = this .sourceEndLine ( ) + 1 - this .sourceStartLine ( ) }
6748
6849 /** Gets an opaque identifier for the equivalence class of this block. */
69- int getEquivalenceClass ( ) {
70- duplicateCode ( this , _, result ) or similarCode ( this , _, result )
71- }
50+ int getEquivalenceClass ( ) { duplicateCode ( this , _, result ) or similarCode ( this , _, result ) }
7251
7352 /** Gets the source file in which this block appears. */
7453 File sourceFile ( ) {
75- exists ( string name |
76- duplicateCode ( this , name , _ ) or similarCode ( this , name , _ ) |
77- name . replaceAll ( "\\" , "/" ) = relativePath ( result ) )
54+ exists ( string name | duplicateCode ( this , name , _ ) or similarCode ( this , name , _ ) |
55+ name . replaceAll ( "\\" , "/" ) = relativePath ( result )
56+ )
7857 }
7958
8059 /**
@@ -84,7 +63,9 @@ class Copy extends @duplication_or_similarity
8463 * For more information, see
8564 * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
8665 */
87- predicate hasLocationInfo ( string filepath , int startline , int startcolumn , int endline , int endcolumn ) {
66+ predicate hasLocationInfo (
67+ string filepath , int startline , int startcolumn , int endline , int endcolumn
68+ ) {
8869 sourceFile ( ) .getName ( ) = filepath and
8970 startline = sourceStartLine ( ) and
9071 startcolumn = sourceStartColumn ( ) and
@@ -102,7 +83,8 @@ class Copy extends @duplication_or_similarity
10283 Copy extendingBlock ( ) {
10384 exists ( File file , int sl , int sc , int ec , int el |
10485 tokenLocation ( file , sl , sc , ec , el , this , _) and
105- tokenLocation ( file , sl , sc , ec , el , result , 0 ) ) and
86+ tokenLocation ( file , sl , sc , ec , el , result , 0 )
87+ ) and
10688 this != result
10789 }
10890}
@@ -113,13 +95,17 @@ class Copy extends @duplication_or_similarity
11395 * have the same equivalence class, with `start` being the equivalence class of `start1` and
11496 * `start2`, and `end` the equivalence class of `end1` and `end2`.
11597 */
116- predicate similar_extension ( SimilarBlock start1 , SimilarBlock start2 , SimilarBlock ext1 , SimilarBlock ext2 , int start , int ext ) {
98+ predicate similar_extension (
99+ SimilarBlock start1 , SimilarBlock start2 , SimilarBlock ext1 , SimilarBlock ext2 , int start , int ext
100+ ) {
117101 start1 .getEquivalenceClass ( ) = start and
118102 start2 .getEquivalenceClass ( ) = start and
119103 ext1 .getEquivalenceClass ( ) = ext and
120104 ext2 .getEquivalenceClass ( ) = ext and
121105 start1 != start2 and
122- ( ext1 = start1 and ext2 = start2 or
106+ (
107+ ext1 = start1 and ext2 = start2
108+ or
123109 similar_extension ( start1 .extendingBlock ( ) , start2 .extendingBlock ( ) , ext1 , ext2 , _, ext )
124110 )
125111}
@@ -130,28 +116,29 @@ predicate similar_extension(SimilarBlock start1, SimilarBlock start2, SimilarBlo
130116 * have the same equivalence class, with `start` being the equivalence class of `start1` and
131117 * `start2`, and `end` the equivalence class of `end1` and `end2`.
132118 */
133- predicate duplicate_extension ( DuplicateBlock start1 , DuplicateBlock start2 , DuplicateBlock ext1 , DuplicateBlock ext2 , int start , int ext ) {
119+ predicate duplicate_extension (
120+ DuplicateBlock start1 , DuplicateBlock start2 , DuplicateBlock ext1 , DuplicateBlock ext2 , int start ,
121+ int ext
122+ ) {
134123 start1 .getEquivalenceClass ( ) = start and
135124 start2 .getEquivalenceClass ( ) = start and
136125 ext1 .getEquivalenceClass ( ) = ext and
137126 ext2 .getEquivalenceClass ( ) = ext and
138127 start1 != start2 and
139- ( ext1 = start1 and ext2 = start2 or
128+ (
129+ ext1 = start1 and ext2 = start2
130+ or
140131 duplicate_extension ( start1 .extendingBlock ( ) , start2 .extendingBlock ( ) , ext1 , ext2 , _, ext )
141132 )
142133}
143134
144135/** A block of duplicated code. */
145- class DuplicateBlock extends Copy , @duplication
146- {
147- override string toString ( ) {
148- result = "Duplicate code: " + sourceLines ( ) + " duplicated lines."
149- }
136+ class DuplicateBlock extends Copy , @duplication {
137+ override string toString ( ) { result = "Duplicate code: " + sourceLines ( ) + " duplicated lines." }
150138}
151139
152140/** A block of similar code. */
153- class SimilarBlock extends Copy , @similarity
154- {
141+ class SimilarBlock extends Copy , @similarity {
155142 override string toString ( ) {
156143 result = "Similar code: " + sourceLines ( ) + " almost duplicated lines."
157144 }
@@ -167,8 +154,9 @@ predicate duplicateStatement(Scope scope1, Scope scope2, Stmt stmt1, Stmt stmt2)
167154 scope2 .contains ( stmt2 ) and
168155 duplicateCoversStatement ( equivstart , equivend , first , last , stmt1 ) and
169156 duplicateCoversStatement ( equivstart , equivend , first , last , stmt2 ) and
170- stmt1 != stmt2 and scope1 != scope2
171- )
157+ stmt1 != stmt2 and
158+ scope1 != scope2
159+ )
172160}
173161
174162/**
@@ -178,8 +166,9 @@ predicate duplicateStatement(Scope scope1, Scope scope2, Stmt stmt1, Stmt stmt2)
178166 * and `equivstart` and `equivend` are the equivalence classes of the first and the last
179167 * block, respectively.
180168 */
181- private
182- predicate duplicateCoversStatement ( int equivstart , int equivend , int first , int last , Stmt stmt ) {
169+ private predicate duplicateCoversStatement (
170+ int equivstart , int equivend , int first , int last , Stmt stmt
171+ ) {
183172 exists ( DuplicateBlock b1 , DuplicateBlock b2 , Location startloc , Location endloc |
184173 stmt .getLocation ( ) = startloc and
185174 stmt .getLastStatement ( ) .getLocation ( ) = endloc and
@@ -204,13 +193,14 @@ predicate duplicateStatements(Scope scope1, Scope scope2, int duplicate, int tot
204193 * Find pairs of scopes that are identical or almost identical
205194 */
206195predicate duplicateScopes ( Scope s , Scope other , float percent , string message ) {
207- exists ( int total , int duplicate |
208- duplicateStatements ( s , other , duplicate , total ) |
209- percent = 100.0 * duplicate / total and percent >= 80.0 and
210- if duplicate = total then
211- message = "All " + total + " statements in " + s .getName ( ) + " are identical in $@."
196+ exists ( int total , int duplicate | duplicateStatements ( s , other , duplicate , total ) |
197+ percent = 100.0 * duplicate / total and
198+ percent >= 80.0 and
199+ if duplicate = total
200+ then message = "All " + total + " statements in " + s .getName ( ) + " are identical in $@."
212201 else
213- message = duplicate + " out of " + total + " statements in " + s .getName ( ) + " are duplicated in $@."
202+ message =
203+ duplicate + " out of " + total + " statements in " + s .getName ( ) + " are duplicated in $@."
214204 )
215205}
216206
@@ -219,12 +209,13 @@ predicate duplicateScopes(Scope s, Scope other, float percent, string message) {
219209 * respectively, where `scope1` and `scope2` are not the same.
220210 */
221211private predicate similarStatement ( Scope scope1 , Scope scope2 , Stmt stmt1 , Stmt stmt2 ) {
222- exists ( int start , int end , int first , int last |
212+ exists ( int start , int end , int first , int last |
223213 scope1 .contains ( stmt1 ) and
224214 scope2 .contains ( stmt2 ) and
225215 similarCoversStatement ( start , end , first , last , stmt1 ) and
226216 similarCoversStatement ( start , end , first , last , stmt2 ) and
227- stmt1 != stmt2 and scope1 != scope2
217+ stmt1 != stmt2 and
218+ scope1 != scope2
228219 )
229220}
230221
@@ -235,7 +226,9 @@ private predicate similarStatement(Scope scope1, Scope scope2, Stmt stmt1, Stmt
235226 * and `equivstart` and `equivend` are the equivalence classes of the first and the last
236227 * block, respectively.
237228 */
238- private predicate similarCoversStatement ( int equivstart , int equivend , int first , int last , Stmt stmt ) {
229+ private predicate similarCoversStatement (
230+ int equivstart , int equivend , int first , int last , Stmt stmt
231+ ) {
239232 exists ( SimilarBlock b1 , SimilarBlock b2 , Location startloc , Location endloc |
240233 stmt .getLocation ( ) = startloc and
241234 stmt .getLastStatement ( ) .getLocation ( ) = endloc and
@@ -260,13 +253,14 @@ private predicate similarStatements(Scope scope1, Scope scope2, int similar, int
260253 * Find pairs of scopes that are similar
261254 */
262255predicate similarScopes ( Scope s , Scope other , float percent , string message ) {
263- exists ( int total , int similar |
264- similarStatements ( s , other , similar , total ) |
265- percent = 100.0 * similar / total and percent >= 80.0 and
266- if similar = total then
267- message = "All statements in " + s .getName ( ) + " are similar in $@."
256+ exists ( int total , int similar | similarStatements ( s , other , similar , total ) |
257+ percent = 100.0 * similar / total and
258+ percent >= 80.0 and
259+ if similar = total
260+ then message = "All statements in " + s .getName ( ) + " are similar in $@."
268261 else
269- message = similar + " out of " + total + " statements in " + s .getName ( ) + " are similar in $@."
262+ message =
263+ similar + " out of " + total + " statements in " + s .getName ( ) + " are similar in $@."
270264 )
271265}
272266
@@ -275,7 +269,5 @@ predicate similarScopes(Scope s, Scope other, float percent, string message) {
275269 * This is true for blocks of import statements.
276270 */
277271predicate whitelistedLineForDuplication ( File f , int line ) {
278- exists ( ImportingStmt i |
279- i .getLocation ( ) .getFile ( ) = f and i .getLocation ( ) .getStartLine ( ) = line
280- )
272+ exists ( ImportingStmt i | i .getLocation ( ) .getFile ( ) = f and i .getLocation ( ) .getStartLine ( ) = line )
281273}
0 commit comments