| MARBLE Mining for Boilerplate Code to Identify API Usability Problems Daye Nam Amber Horvath Andrew Macvean Brad Myers Bogdan Vesilescu
Code to write an XML document to a speci fi ed output stream? � 2
Code to write an XML document to a speci fi ed output stream? Expectation writeXMLDoc(Document doc, OutputStream out); � 3
Code to write an XML document to a speci fi ed output stream? Expectation writeXMLDoc(Document doc, OutputStream out); Reality static final void writeDoc(Document doc, OutputStream out) throws IOException { try { Transformer t = TransformerFactory.newInstance().newTransformer(); t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); t.transform(new DOMSource(doc), new StreamResult(out)); } catch(TransformerException e) { throw new AssertionError(e); //Can’t happen! } } � 4
static final void writeDoc(Document doc, OutputStream out) throws IOException { try { Transformer t = TransformerFactory.newInstance().newTransformer(); t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); t.transform(new DOMSource(doc), new StreamResult(out)); } catch(TransformerException e) { throw new AssertionError(e); //Can’t happen! } } Boilerplate Code � 5
static final void writeDoc(Document doc, OutputStream out) throws IOException { try { Transformer t = TransformerFactory.newInstance().newTransformer(); t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); t.transform(new DOMSource(doc), new StreamResult(out)); } catch(TransformerException e) { throw new AssertionError(e); //Can’t happen! } } Boilerplate Code Hard to understand Verbose Error-Prone � 6
API Design Guidelines suggest to reduce the need for boilerplate code. [Mosqueira-Rey et al. 2018, Reddy 2011] � 7
The existence of boilerplate client code may serve as an indicator of poor API design. � 8
API Designer I thought users will need the fl exibility, but most users do not… static final void writeDoc(Document doc, OutputStream out) throws IOException { static final void writeDoc(Document doc, OutputStream out) throws IOException { try { try { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) Transformer t = TransformerFactory.newInstance().newTransformer(); Transformer t = TransformerFactory.newInstance().newTransformer(); != PackageManager.PERMISSION_GRANTED) { t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); ActivityCompat.requestPermissions( t.transform(new DOMSource(doc), new StreamResult(out)); t.transform(new DOMSource(doc), new StreamResult(out)); this, } catch(TransformerException e) { } catch(TransformerException e) { new String[]{ Manifest.permission.ACCESS_FINE_LOCATION }, throw new AssertionError(e); //Can’t happen! throw new AssertionError(e); //Can’t happen! LOCATION_PERMISSION_REQUEST); } } return; } } } � 9
API Designer My API does not directly provide the methods that programmers need… static final void writeDoc(Document doc, OutputStream out) throws IOException { static final void writeDoc(Document doc, OutputStream out) throws IOException { try { try { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) Transformer t = TransformerFactory.newInstance().newTransformer(); Transformer t = TransformerFactory.newInstance().newTransformer(); != PackageManager.PERMISSION_GRANTED) { t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); ActivityCompat.requestPermissions( t.transform(new DOMSource(doc), new StreamResult(out)); t.transform(new DOMSource(doc), new StreamResult(out)); this, } catch(TransformerException e) { } catch(TransformerException e) { new String[]{ Manifest.permission.ACCESS_FINE_LOCATION }, throw new AssertionError(e); //Can’t happen! throw new AssertionError(e); //Can’t happen! LOCATION_PERMISSION_REQUEST); } } return; } } } � 10
MARBLE: API Boilerplate Code Miner My API does not directly provide the methods that programmers need… static final void writeDoc(Document doc, OutputStream out) throws IOException { static final void writeDoc(Document doc, OutputStream out) throws IOException { try { try { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) Transformer t = TransformerFactory.newInstance().newTransformer(); Transformer t = TransformerFactory.newInstance().newTransformer(); != PackageManager.PERMISSION_GRANTED) { t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); ActivityCompat.requestPermissions( t.transform(new DOMSource(doc), new StreamResult(out)); t.transform(new DOMSource(doc), new StreamResult(out)); this, } catch(TransformerException e) { } catch(TransformerException e) { new String[]{ Manifest.permission.ACCESS_FINE_LOCATION }, throw new AssertionError(e); //Can’t happen! throw new AssertionError(e); //Can’t happen! LOCATION_PERMISSION_REQUEST); } } return; } } } � 11
MARBLE: API Boilerplate Code Miner My API does not directly provide the methods that programmers need… static final void writeDoc(Document doc, OutputStream out) throws IOException { static final void writeDoc(Document doc, OutputStream out) throws IOException { try { try { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) Transformer t = TransformerFactory.newInstance().newTransformer(); Transformer t = TransformerFactory.newInstance().newTransformer(); != PackageManager.PERMISSION_GRANTED) { t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); ActivityCompat.requestPermissions( t.transform(new DOMSource(doc), new StreamResult(out)); t.transform(new DOMSource(doc), new StreamResult(out)); this, } catch(TransformerException e) { } catch(TransformerException e) { new String[]{ Manifest.permission.ACCESS_FINE_LOCATION }, throw new AssertionError(e); //Can’t happen! throw new AssertionError(e); //Can’t happen! LOCATION_PERMISSION_REQUEST); } } return; } MARBLE-found } } � 12
De fi ne Boilerplate Code
Study on Boilerplate Code Google Scholar Sources GitHub Commits the Web — Blog Posts, Stack Over fl ow/Quora Q&AA Survey on Twitter � 14
Study on Boilerplate Code Google Scholar Sources GitHub Commits the Web — Blog Posts, Stack Over fl ow/Quora Q&AA Survey on Twitter De fi nitions of boilerplate code Data Examples that are explicitly annotated as boilerplate code The rationale for the boilerplate designation � 15
Study on Boilerplate Code Google Scholar Sources GitHub Commits the Web — Blog Posts, Stack Over fl ow/Quora Q&AA Survey on Twitter De fi nitions of boilerplate code Data Examples that are explicitly annotated as boilerplate code The rationale for the boilerplate designation 4 Common Properties � 16
Common Properties of Boilerplate P1 Annoying!!! � 17
Common Properties of Boilerplate P1 Annoying!!! P2 Frequently Occurs in Client Code � 18
Common Properties of Boilerplate P1 Annoying!!! P2 Frequently Occurs in Client Code P3 Occurs Within a Relatively Condensed Area � 19
Common Properties of Boilerplate P1 Annoying!!! P2 Frequently Occurs in Client Code P3 Occurs Within a Relatively Condensed Area Used in Similar Forms Without Signi fi cant Variations P4 � 20
Common Properties of Boilerplate Subjective P1 Annoying!!! Automatable P2 Frequently Occurs in Client Code P3 Occurs Within a Relatively Condensed Area Used in Similar Forms Without Signi fi cant Variations P4 � 21
Mining Boilerplate Code
Overview of Mining Process Target API & Client Code Files Identifying patterns occurring High frequently among the client code javax.xml.transform Frequency .JAVA Annoying Condensed Identifying patterns occurring within condensed area API Designer Area Viewer Identifying patterns used Similar Generator Structure in similar forms among the client code � 23
Overview of Mining Process Ranked API Files Containing [Fowkes and Sutton, 2016] Target API & Client Code Files Usage Patterns & Each Pattern 1. API Pattern & API Usage Miner High .JAVA javax.xml.transform (PAM) Frequency 2. API Pattern & .JAVA .JAVA ⋮ ⋮ Annoying Condensed Identifying patterns occurring within condensed area API Designer Area Viewer Identifying patterns used Similar Generator Structure in similar forms among the client code � 24
API Usage Mining High Frequency ���Ranked�API��������������Files�Containing Target�API��������������&����Client�Code�Files [Fowkes�and�Sutton,�2016] Usage�Patterns������&�����Each�Pattern 1.������API�Pattern�����& API�Usage�Miner� .JAVA javax.xml.transform (PAM) 2.������API�Pattern�����& .JAVA .JAVA ⋮ ⋮ � 25
Recommend
More recommend