404 | | In large program systems often occure duplicated code, which is a computer programming term for a sequence of source code that occurs more than once. There are two ways in which two code sequences can be duplicates of each other: syntactically and functionally. This new feature can detect the syntactically similar duplicates. You can learn more about this topic and about the usage, especially about the command-line usage, on [[DuplicateCodeAnalysis| Duplicate code analysis]] page. |
| 404 | In large program systems often occure duplicated code, which is a computer programming term for a sequence of source code that occurs more than once. There are two ways in which two code sequences can be duplicates of each other: syntactically and functionally. This new feature can detect the syntactically similar duplicates. You can learn more about this topic and about the usage on CloneIdentifiErl page, whilst the services provided by this interface are detailed below. |
| 405 | ==== Functions ==== |
| 406 | * clone_identifierl/0: uses the default values of properties |
| 407 | * clone_identifierl/1: takes a proplist as described above |
| 408 | |
| 409 | Regardless of the chosen algorithm all output format, which are illustrated below, can be requested. |
| 410 | * prettyprint: Returns the textual representation of the clones. |
| 411 | Command: {{{ri:clone_identifierl([{algorithm,sw_metrics}, {files,[ucl_alg_dm]}, {format,prettyprint}]).}}} |
| 412 | {{{ |
| 413 | -------------------------------------------------------------------------------- |
| 414 | Clone element: (found in ucl_alg_dm): |
| 415 | q_gen(QueryETS) -> |
| 416 | fun(F, Ps) -> |
| 417 | [{F, Ps1}] = ets:lookup(QueryETS, F), |
| 418 | length(list_sort_intersect(Ps1, Ps)) |
| 419 | end. |
| 420 | |
| 421 | -------------------------------------------------------------------------------- |
| 422 | -------------------------------------------------------------------------------- |
| 423 | Clone element: (found in ucl_alg_dm): |
| 424 | u_gen(UseETS) -> |
| 425 | fun(P, Fs) -> |
| 426 | [{P, Fs1}] = ets:lookup(UseETS, P), |
| 427 | length(list_sort_intersect(Fs1, Fs)) |
| 428 | end. |
| 429 | -------------------------------------------------------------------------------- |
| 430 | }}} |
| 431 | |
| 432 | * file_and_loc: Returns file and position information related to the clones. When using this output format it is possible to set the position type. |
| 433 | The {{{linecol}}} position type returns the row and column where the found clone starts and ends. The scalar position type returns the character position where the clone starts and ends. |
| 434 | |
| 435 | Command:[[BR]] |
| 436 | {{{ri:clone_identifierl([{algorithm,sw_metrics}, {files,[ucl_alg_dm]}, {format,file_and_loc}, {postype,linecol]).}}} |
| 437 | |
| 438 | |
| 439 | {{{ |
| 440 | [[[{filepath,"/home/laptop/refactorerl/src/ucl_alg_dm.erl"}, |
| 441 | {startpos,{12,1}}, |
| 442 | {endpos,{16,8}}], |
| 443 | [{filepath,"/home/laptop/refactorerl/src/ucl_alg_dm.erl"}, |
| 444 | {startpos,{41,1}}, |
| 445 | {endpos,{45,8}}]]] |
| 446 | }}} |
| 447 | |
| 448 | Command: [[BR]] |
| 449 | {{{ri:clone_identifierl([{algorithm,sw_metrics}, {files,[ucl_alg_dm]}, {format,file_and_loc}, {postype,scalar]).}}} |
| 450 | |
| 451 | {{{ |
| 452 | [[[{filepath,"/home/laptop/refactorerl/src/ucl_alg_dm.erl"}, |
| 453 | {startpos,{47}}, |
| 454 | {endpos,{121}}], |
| 455 | [{filepath,"/home/laptop/refactorerl/src/ucl_alg_dm.erl"}, |
| 456 | {startpos,{520}}, |
| 457 | {endpos,{576}}]]] |
| 458 | }}} |
| 459 | |
| 460 | * nodes: Returns the internal identifiers of the found clone groups. It is a good choice if you wish to further process the result by scripting using the ris interface. |
| 461 | Command: {{{ri:clone_identifierl([{algorithm,sw_metrics}, {files,[ucl_alg_dm]}, {format,nodes}]).}}} |
| 462 | {{{ |
| 463 | [[[{'$gn',form,2}],[{'$gn',form,3}]]] |
| 464 | }}} |
| 465 | |
| 466 | |
| 467 | ==== Result query functions ==== |
| 468 | ||=Function=||=Parameters=||=Description=||=Example=|| |
| 469 | || stored_dupcode_results/0 || - || Returns the list of all saved results (name and information about the parameters of the analysis) || ri:stored_dupcode_results() || |
| 470 | || show_dupcode/1 || Name::atom() - Name associated with the result ||Displays the selected result using the default output format. || ri:show_dupcode(mydups) || |
| 471 | || show_dupcode/2 || Name::atom() - name associated with the result, Format::atom() - requested output format || Displays the selected result using the requested format. || ri:show_dupcode(mysearch,file_and_loc) || |
| 472 | || show_dupcode_group/2 || Name::atom() - name associated with the result, GroupNumber::integer() - the required ID of the clone group belonging to the requested result || Displays the given clone group of the result using the default output format. || ri:show_dupcode_group(mysearch,2) || |
| 473 | || show_dupcode_group/3 || Name::atom() - name associated with the result, GroupNumber::integer() - the required ID of the clone group belonging to the requested result, Format::atom() - requested output format || Displays the given clone group of the result using the default output format using the requested format. || ri:show_dupcode_group(mysearch,2,file_and_loc) || |
| 474 | || save_dupcode_result/2 || Name::atom() - name associated with the result, FilePath::string() - absolute file path || Saves the result to !FilePath using the default output format. || ri:save_dupcode_result(mysearch,"/home/laptop/Desktop/result.txt") |
| 475 | || save_dupcode_result/3 || Name::atom() - name associated with the result, FilePath::string() - absolute file path, Format::atom() - requested output format || Saves the result to !FilePath using the specified output format. || ri:save_dupcode_result(mysearch,"/home/laptop/Desktop/result.txt", file_and_loc) || |
| 476 | |
| 477 | |
| 478 | ==== Exemplars ==== |
| 479 | In this section, we show some illustrative examples to get familiar with this feature. |
| 480 | * Simpliest case. |
| 481 | {{{#!erlang |
| 482 | ri:clone_identifierl(). |
| 483 | }}} |
| 484 | * We are looking for all of the clones can be found in the database. We have much memory and a wide interest in any detectable clones, and we also allow a greater deviation of clones. |
| 485 | {{{#!erlang |
| 486 | ri:clone_identifierl([{algorithm, matrix}, {caching, true}, {max_invalid_seq_length, 3}, {diff_limit, 0.2}]). |
| 487 | }}} |
| 488 | |
| 489 | * We want to find the duplicates of a specific, newly introduced library function (lib_module:new_fun/2). |
| 490 | {{{#!erlang |
| 491 | ri:clone_identifierl([{func_list, [{lib_module, new_fun, 2}]}]). |
| 492 | }}} |
| 493 | |
| 494 | * We want to find either the whole function or even its subsequences as duplicates of a specific, newly introduced library function (lib_module:new_fun/2). |
| 495 | {{{#!erlang |
| 496 | ri:clone_identifierl([{algorithm, matrix}, {func_list, [{lib_module, new_fun, 2}]}]). |
| 497 | }}} |
| 498 | |
| 499 | * We want to find the duplicates of every function located in a library module (lib_module). |
| 500 | {{{#!erlang |
| 501 | ri:clone_identifierl([{files, [lib_module]}]). |
| 502 | }}} |
| 503 | |
| 504 | * We want to find either the whole function or even its subsequences as duplicates of every function located in a library module (lib_module). |
| 505 | {{{#!erlang |
| 506 | ri:clone_identifierl([{algorithm, matrix},{files, [lib_module]}]). |
| 507 | }}} |
| 508 | |
| 509 | * We want to find fully syntactically similar clones only in the dups and lib_module module. |
| 510 | {{{#!erlang |
| 511 | ri:clone_identifierl([{algorithm, suffix_tree},{files, [dups,lib_module]}]). |
| 512 | }}} |
| 513 | |
| 514 | * We want to find long, fully syntactically similar clones that are straightforward to be eliminated. |
| 515 | {{{#!erlang |
| 516 | ri:clone_identifierl([{algorithm, filtered_suffix_tree},{minlen,80}]). |
| 517 | }}} |
| 518 | |