variability aware code smells
play

Variability-Aware Code Smells Wolfram Fenske, 1 Sandro Schulze 2 - PowerPoint PPT Presentation

Variability-Aware Code Smells Wolfram Fenske, 1 Sandro Schulze 2 Monday 5 th May, 2014 1 University of Magdeburg, Germany 2 TU Braunschweig, Germany Code Smells (1) Code smell term introduced by Fowler, Beck, Brant, Opdyke & Roberts (1999)


  1. Variability-Aware Code Smells Wolfram Fenske, 1 Sandro Schulze 2 Monday 5 th May, 2014 1 University of Magdeburg, Germany 2 TU Braunschweig, Germany

  2. Code Smells (1) ◮ Code smell term introduced by Fowler, Beck, Brant, Opdyke & Roberts (1999) ◮ Hint at structural problem / design weakness of the code ◮ Smelly code � = buggy code, but ◮ Smelly code hinders . . . ◮ Program comprehension ◮ Bug fixing ◮ Extension ◮ Indicator that structure needs improvement Wolfram Fenske, Sandro Schulze Variability-Aware Code Smells 1

  3. Code Smells (2) ◮ So far focus on single systems ◮ Little systematic treatment of smells in SPL context ➥ Are code smells different in SPLs? If so, how? ◮ RQ 1: How does variability affect existing code smells? ◮ RQ 2: Can SPL entities, such as features, also be smelly? ◮ RQ 3: Are there code smells specific to SPLs? ➥ Variability-aware code smells Wolfram Fenske, Sandro Schulze Variability-Aware Code Smells 2

  4. Inter-Feature Code Clones Derived from: Duplicated Code Example: Graph Product Line (FOP) public class Graph { public class Graph { void search(Workspace w) { void search(Workspace w) { VertexIter itr = VertexIter itr = getVertices(); getVertices(); if (!itr.hasNext()) if (!itr.hasNext()) return ; return ; while (itr.hasNext()) { while (itr.hasNext()) { Vertex v = itr.next(); Vertex v = itr.next(); v.init_vertex(w); v.init_vertex(w); } } / ∗ More source code... ∗ / / ∗ More duplication... ∗ / } } / ∗ More source code... ∗ / / ∗ Other source code... ∗ / } } Feature BFS Feature DFS Wolfram Fenske, Sandro Schulze Variability-Aware Code Smells 3

  5. Switch Statements with Optional Cases Derived from: Switch Statements Example: Mozilla NSS Library static CK_RV NSSLOWKEYPublicKey ∗ pk11_handlePublicKeyObject(PK11Session ∗ pk11_GetPubKey(PK11Object ∗ object, session, PK11Object ∗ object, CK_KEY_TYPE key_type, CK_RV ∗ crvp) CK_KEY_TYPE key_type) { { / ∗ More code... ∗ / / ∗ More code... ∗ / switch (key_type) { switch (key_type) { / ∗ Other code for other cases... ∗ / / ∗ Handle other cases... ∗ / case CKK_DH: case CKK_DH: / ∗ Other code to handle CKK_DH... ∗ / / ∗ Handle CKK_DH... ∗ / break ; break ; #ifdef NSS_ENABLE_ECC #ifdef NSS_ENABLE_ECC case CKK_EC: case CKK_EC: / ∗ Start handling CKK_EC... ∗ / if (EC_FillParams(arena, &pubKey − / ∗ Start handling CKK_EC... ∗ / >u. pubKeyAttr = CKA_EC_POINT; ec.ecParams.DEREncoding, & derive = CK_TRUE; / ∗ for ECDH ∗ / pubKey − >u.ec.ecParams) != SECSuccess) break ; verify = CK_TRUE; / ∗ for ECDSA ∗ / encrypt = CK_FALSE; crv = pk11_Attribute2SSecItem(arena recover = CK_FALSE; ,&pubKey − >u.ec.publicValue, wrap = CK_FALSE; object, CKA_EC_POINT); break ; break ; #endif / ∗ NSS_ENABLE_ECC ∗ / #endif / ∗ NSS_ENABLE_ECC ∗ / default : default : / ∗ Handle default case... ∗ / / ∗ Other default code... ∗ / } } Wolfram Fenske, Sandro Schulze Variability-Aware Code Smells 4

  6. Annotation Bundle Derived from: Long Method Example: Firefox 28, memory/mozjemalloc/jemalloc.c / ∗ More code... ∗ / / ∗ ...continued from left ∗ / for (k = 0; k < nreps; k++) { #ifdef MALLOC_FILL switch (opts[j]) { # ifndef MALLOC_PRODUCTION case ’a’: case ’c’: opt_abort = false ; opt_poison = false ; break ; break ; case ’A’: case ’C’: opt_abort = true ; opt_poison = true ; break ; break ; case ’b’: # endif #ifdef MALLOC_BALANCE #endif case ’f’: opt_balance_threshold >>= 1; #endif opt_dirty_max >>= 1; break ; break ; case ’B’: case ’F’: #ifdef MALLOC_BALANCE if (opt_dirty_max == 0) if (opt_balance_threshold == 0) opt_dirty_max = 1; else if ((opt_dirty_max << 1) != 0) opt_balance_threshold = 1; else if ((opt_balance_threshold << opt_dirty_max <<= 1; break ; 1) > opt_balance_threshold) / ∗ More case clauses... ∗ / opt_balance_threshold <<= 1; #endif } break ; / ∗ Even more code... ∗ / Wolfram Fenske, Sandro Schulze Variability-Aware Code Smells 5

  7. Long Refinement Chain Derived from: Long Method Example: GUIDSL (FOP), method Main#process(Model) class Main { // Feature ’dmain’ public static void process(Model root) throws SemanticException { // layers extend this method for AST processing } }

  8. Long Refinement Chain Derived from: Long Method Example: GUIDSL (FOP), method Main#process(Model) class Main { // Feature ’dmain’ public static void process(Model root) throws SemanticException { // layers extend this method for AST processing class Main { // Feature ’fillgs’ } public static void process(Model root) throws SemanticException { } original (m); // harvest the tree m.harvest( new fillFPtable() ); if (Util.errorCount() != 0) throw new SemanticException("Error(s) in specification found"); m.harvest( new enterGspec() ); if (Util.errorCount() != 0) throw new SemanticException("Error(s) in specification found"); } }

  9. Long Refinement Chain Derived from: Long Method Example: GUIDSL (FOP), method Main#process(Model) class Main { // Feature ’dmain’ public static void process(Model root) throws SemanticException { // layers extend this method for AST processing class Main { // Feature ’fillgs’ } public static void process(Model root) throws SemanticException { } original (m); class Main { // Feature ’propgs’ // harvest the tree public static void process(Model root) throws SemanticException { m.harvest( new fillFPtable() ); original (m); if (Util.errorCount() != 0) grammar.current.visit( new propcons() ); throw new SemanticException("Error(s) in specification found"); if (Util.errorCount() !=0) m.harvest( new enterGspec() ); throw new SemanticException("Errors in propagating Constraints"); if (Util.errorCount() != 0) } throw new SemanticException("Error(s) in specification found"); } } }

  10. Long Refinement Chain Derived from: Long Method Example: GUIDSL (FOP), method Main#process(Model) class Main { // Feature ’dmain’ public static void process(Model root) throws SemanticException { // layers extend this method for AST processing class Main { // Feature ’fillgs’ } public static void process(Model root) throws SemanticException { } original (m); class Main { // Feature ’propgs’ // harvest the tree public static void process(Model root) throws SemanticException { m.harvest( new fillFPtable() ); original (m); class Main { // Feature ’formgs’ if (Util.errorCount() != 0) grammar.current.visit( new propcons() ); public static void process(Model root) throws SemanticException { throw new SemanticException("Error(s) in specification found"); if (Util.errorCount() !=0) original (m); m.harvest( new enterGspec() ); throw new SemanticException("Errors in propagating Constraints"); production.makeFormula(); if (Util.errorCount() != 0) } pattern.makeFormula(); throw new SemanticException("Error(s) in specification found"); } if (Util.errorCount() != 0) } throw new SemanticException("Errors in making propositional } formulas"); } }

  11. Long Refinement Chain Derived from: Long Method Example: GUIDSL (FOP), method Main#process(Model) class Main { // Feature ’dmain’ public static void process(Model root) throws SemanticException { // layers extend this method for AST processing class Main { // Feature ’fillgs’ } public static void process(Model root) throws SemanticException { } original (m); class Main { // Feature ’propgs’ // harvest the tree public static void process(Model root) throws SemanticException { m.harvest( new fillFPtable() ); original (m); class Main { // Feature ’formgs’ if (Util.errorCount() != 0) grammar.current.visit( new propcons() ); public static void process(Model root) throws SemanticException { throw new SemanticException("Error(s) in specification found"); if (Util.errorCount() !=0) original (m); m.harvest( new enterGspec() ); class Main { // Feature ’clauselist’ throw new SemanticException("Errors in propagating Constraints"); production.makeFormula(); if (Util.errorCount() != 0) public static void process(Model root) throws SemanticException { } pattern.makeFormula(); throw new SemanticException("Error(s) in specification found"); original (m); } if (Util.errorCount() != 0) } production.makeClauses(); throw new SemanticException("Errors in making propositional } pattern.makeClauses(); formulas"); ESList.makeClauses(); } grammar.makeClauses(); } if (Util.errorCount() != 0) throw new SemanticException("Errors in making conjunctive normal formulas"); } }

Recommend


More recommend