Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Hunt for dead code

332 views

Published on

Dead code happens when it can never be executed, or if it has no effect on the output. Dead code tends to appear in long-winded projects, and grows over time. It is a significant part of the technical debt, leading to lost time in understanding code, fixing it (sic) and ultimately, removing it. It takes various shapes, such as unreachable code, unused functions, redundant conditions. It may also be conditional, depending on environnement, even if the latter doesn't exist anymore. During the session, we'll track dead code, discuss how it may be removed or sidelined. We'll feel a lot cleaner and leaner afterward.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Hunt for dead code

  1. 1. Lorem Ipsum Dolor The hunt for dead code PHP South Africa
  2. 2. Agenda ❖ What is dead code ❖ Classic/PHP dead code ❖ Removing dead structures
  3. 3. Speaker ❖ CTO Exakat ❖ Doing PHP on every continents ❖ Static code analysis for PHP
  4. 4. Dead code ❖ Code that is never used ❖ Data never delivered to the user ❖ Opposite to : PHP Fatal error: Uncaught Error: Call to undefined function foo()
  5. 5. Dead code <?php function foo() {} $y = rand(0, 12); echo 'two'; ?> if ($y == 2) {    echo 'two'; }  ?>
  6. 6. Dead code <?php  class A implements B {} interface B {} ?> <?php interface B implementedBy A,B,C {} class A {} ?> Wouldn't it be better to hunt dead code to write this?
  7. 7. Dead code ❖ PHP base install ❖ 766 functions ❖ 92 classes ❖ 1024 constants ❖ Avoid compiling too 
 many PHP extensions ❖ Use disable_functions
  8. 8. Why remove? ❖ Larger code source ❖ Less maintainable code ❖ Dead code is often maintained ❖ Slower code ❖ Dead code grows over time
  9. 9. Why keep dead code? ❖ No one was ever fired to keep dead code ❖ Why fix something that isn't broken ❖ All tests for this feature are OK ❖ Other part of the code depends on it ❖ Code base always grows organically ❖ No time for that!
  10. 10. How to remove dead code ❖ Spot the original code ❖ Check for its usage ❖ Remove usages one by one ❖ Remove the original code
  11. 11. 3 types of dead code ❖ Classic dead code ❖ PHP stealth dead code ❖ Structural dead code
  12. 12. Classic dead code Dead code in any language
  13. 13. Unreachable code <?php if (false) {    print_r($variable); } if (0) {     // Huge piece of code with bug    // or unfinished new feature }  ?> ❖ Classic debug
  14. 14. Unreachable code <?php function foo($bar) {    for($i = 0; $i < 10; $i++) {      $bar *= 2;             exit; // or die      $bar += 1;    } } ?> ❖ Classic unreachable
  15. 15. Unreachable code <?php function foo($bar) {    for($i = 0; $i < 10; $i++) {     $bar *= 2;             continue;      $bar += 1;    } } ?> ❖ Classic unreachable
  16. 16. Unreachable code <?php function foo($bar) {    for($i = 0; $i < 10; $i++) {      $bar *= 2;             break 1;      $bar += 1;    } } ?> ❖ Classic unreachable
  17. 17. Unreachable code <?php function foo($bar) {    $bar *= 2;        return $bar;    $bar += 1;    return $bar; } ?> ❖ Classic unreachable
  18. 18. Unreachable code <?php $bar *= 2; goto END: $bar += 1;        exit;  end: print $bar; ?> ❖ Classic unreachable
  19. 19. Unreachable code <?php $bar = 2; goto END;   class X {    const ONE = 1; } exit;  END: print $bar . X::ONE; ?> ❖ Classic unreachable ❖ But definitions are 
 still accessible
  20. 20. Useless variables <?php  $usedOnce = "Hello world"; ?> ❖ The mythical 'used once' variable ❖ 75% repo has this kind of variable ❖ Global or local to functions ❖ Mass import
 $_GET/_POST <?php  echo $alsoUsedOnce; ?>
  21. 21. Useless variables <?php   function foo() {   $a = "Hello world";    //more code    $a = "Hello universe";    //more code   $a .= " and the world";  } ?> ❖ Written only variables ❖ Inside a scope ❖ Read-only is better but worth a check
  22. 22. PHP skeletons in the closet
  23. 23. Default clause in switch() <?php    switch($x) {        case '1' :             break;        default :             break;        default :             break;        case '2' :             break;    }    ❖ PHP 7.0+ : Fatal error ❖ 'case' order is "not"
 important
  24. 24. Multiple cases ? ❖ Switch() uses == ❖ Transtyping happens switch($x) {        case 1 :             break;        case 0+1 :             break;        case '1' :             break;        case true :             break;        case 1.0 :             break;        case $y :             break;    }   
  25. 25. Arrays index <?php $a = [ true  => 1,         1.0  => 2,         1.1  => 3,         4,        "1.4" => 5,        2  => 6];         print_r($a); ?> ❖ are int or strings ❖ Beware of mix between 
 auto-indexing and
 fixed values Array ( [1] => 3 [2] => 6 [1.4] => 5 )
  26. 26. Dead code in plain sight <?php try {    doSomething(); } catch (NotAnException $e) { } catch (MyExxeption $e) { } catch (Exception $e) { } catch (MyException $e) { } ❖ Non Existing classes ❖ Non-Exceptions ❖ Specific to general ❖ Simply ignored
  27. 27. Instanceof ❖ The target class 
 is in the current
 namespace <?php class MyClass {} $o = new MyClass(); if ($o instanceof MyClass) {    print "Found MyClassn"; } ?>
  28. 28. Instanceof ❖ The target class 
 is in the current
 namespace ❖ Beware of moving
 classes and 
 instanceof around <?php namespace { class MyClass {} } namespace X { $o = new MyClass(); if ($o instanceof MyClass) {     print "Found MyClassn"; } } ?>
  29. 29. Instanceof ❖ Hardcoded names
 vs
 strings classnames namespace { class MyClass {} } namespace X { $o = new MyClass(); $a = 'XMyClass'; if ($o instanceof $a) {     print "Found MyClass with $a } }
  30. 30. Typehint ❖ Typehint are not checked either ❖ You can check type hint at execution time <?php class foo {} $o = new foo(); function bar(fooo $a) {} bar($o); ?> PHP Fatal error: Uncaught TypeError: Argument 1 passed to bar() must be an instance of fooo, instance of foo given,
  31. 31. Structural dead code Files Constants Variables Functions Classes Interfaces Traits
  32. 32. Synopsis ❖ Definitions ❖ Usage ❖ Unreviewable pitfalls ❖ Dynamical calls
  33. 33. Structural dead code Traits Interfaces Classes Functions Constants Files
  34. 34. Traits <?php trait t1 {    use t2; } class c {    use t1; } ?>
  35. 35. Traits ❖ Used in class-'use' expression ❖ Depends on 'use' expression ❖ Used in static method call, static properties <?php trait t1 {    use t2; } class c {    use t1; } ?>
  36. 36. Traits ❖ Easy to spot : only static calls ❖ Namespaced, aliased ❖ Trait local dependencies leads to 
 more dead code <?php  use t1 as t3; trait t1 {     use t2;  }  class c {     use t3;  }  ?>
  37. 37. Traits <?php trait t {    function setName($name) {      $this->name = $this->normalize($name);   } } class bar {    use t;    private $name = 'none';    function normalize($string) {} } ?>
  38. 38. Interfaces <?php interface i2 { } interface i1 implements i2 { } class c implements i1 { } ?>
  39. 39. Interfaces ❖ Used in classes ❖ Used in interfaces ❖ Used in static constants ❖ Used in instanceof, catch and type hint <?php  interface i2 { const konst =  interface i1 implements i2 {  class c implements i1 { }  echo i2::konst; ?>
  40. 40. Interfaces ❖ It may end up in variables/literals ❖ It inherits from parents <?php  interface i2 { const konst = 3;  interface i1 implements i2 { }  $interfaceName = 'i2'; if ($object instanceof $interfac echo i1::konst; ?>
  41. 41. Classes <?php classes c1  { } class c2 extends c1 { } new c2(); ?>
  42. 42. Classes ❖ Used in other classes ❖ Used in all static calls ❖ constants, properties, methods ❖ Normal calls -> ❖ Used in instanceof, catch, typehint ❖ Used in new <?php class c1  { } class c2 extends c1 new c2(); ?>
  43. 43. Classes ❖ new a / new a() ❖ Dynamic calls all over the place ❖ It has special keywords : parent, self, static <?php class foo {    const ONE = 1;    const TWO = self::ONE + 1; } class bar extends foo {    const THREE = parent::TWO + s } $class = 'bar'; $o = new bar; ?>
  44. 44. Classes ❖ Circular dependencies ❖ Actually applies to traits and interfaces as well <?php  class foo extends bar {     const TWO = bar::ONE + 1;  }  class bar extends foo {     const ONE = bar::ONE; }  ?> PHP Fatal error: Class 'bar' not found
  45. 45. Classes ❖ Vicious 
 circular dependencies <?php  class foo {     const ONE = 1;     const TWO = bar::ONE + 1;  }  class bar {     const ONE = foo::TWO; }  echo bar::ONE; PHP Fatal error: Uncaught Error: Cannot declare self- referencing constant 'foo::TWO' on line 12
  46. 46. ❖ Interfaces, traits then classes ❖ Start with lowest positions, then least used
  47. 47. Functions ❖ Used in function calls ❖ Depends on namespaces
 and aliases ❖ Used in native functions
 like array_map() <?php function foo() {} array_map('foo', $array); ?>
  48. 48. Constants ❖ Defined with const, define ❖ May be case-insensitive ❖ Dynamic constant() ❖ Namespaced, aliased ❖ Used in static expressions ❖ This leads to inclusion hells <?php  define(ONE, 1, true); const TWO = ONE + 1;  $constant = 'TWO'; echo constant($constant ?>
  49. 49. Inclusion ❖ include/require, /_once ❖ new() because autoload ❖ Static constant, static methods calls, static property ❖ Order is important, as include also execute… <?php  include 'file.php'; ?>
  50. 50. How to spot issues? ❖ Code knowledge ❖ lint ❖ Grep / Search ❖ Static analysis ❖ Logs / error_reporting ❖ Unit Tests
  51. 51. When to hunt dead code? ❖ An every day relaxation ❖ My most productive day saw 200 classes removed ❖ trigger_error($msg, E_USER_DEPRECATED) and 
 debug_backtrace() ❖ Bath in the energy of live code
  52. 52. Lorem Ipsum Dolor Thanks! @exakat http://www.exakat.io/ http://slideshare.net/dseguy/
  53. 53. Dynamic variables <?php  $a = 'b'; $b = 'c'; $c = 'd'; $$${$a} = '3'; echo $d; ?> ❖ Variable variables ❖ Extract() ❖ parse_str(), one arg
  54. 54. Unreachable code <?php if ($sale_price === $regular_price || 
 $sale_price !== $price) {    print_r($variable); } ?>
  55. 55. Unreachable code $sale_price $regular $price results $regular 1 1 1 $price 0 0 0 All other values 0 1 1 ($sale_price === $regular_price|| $sale_price !== $price)
  56. 56. Constant Property Method Class X X X Interface X X Traits X X

×