Type-Directed Completion of Partial Expressions Daniel Perelman † Sumit Gulwani ‡ Thomas Ball ‡ Dan Grossman † † University of Washington ‡ Microsoft Research Redmond June 12, 2012
I want to shrink an image... Document image = ...; Size newSize = ...; image. ✿✿✿✿✿✿✿ Shrink(newSize) 2 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; image. 3 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; image. 4 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; image. 5 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; image. 6 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet. 7 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet. 8 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet. 9 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet. 10 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Document. 11 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Document. 12 / 54
I want to shrink an image... 13 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Data. 14 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Actions. 15 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Actions. 16 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Actions. 17 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Actions. 18 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Actions.ResizeAction. 19 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Actions. 20 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Actions.CanvasSizeAction. 21 / 54
I want to shrink an image... Document image = ...; Size newSize = ...; PaintDotNet.Actions.CanvasSizeAction. .ResizeDocument( /* PaintDotNet.Document image */, /* System.Drawing.Size size */, /* PaintDotNet.AnchorEdge edge */, /* PointDotNet.ColorBgra bgColor */); 22 / 54
Programmer thought process ◮ I have a Document and a Size ◮ I want to shrink the Document ◮ There must be a method 23 / 54
Programmer thought process ◮ I have a Document and a Size ◮ I want to shrink the Document ◮ There must be a method ◮ Current code completion ◮ Left-to-right ◮ Complete, alphabetic list of just next token ◮ Very limited filtering 24 / 54
Proposed workflow Document image = ...; Size newSize = ...; ❄ ( { image, newSize } ) var newImage = ✿ 25 / 54
Proposed workflow Document image = ...; Size newSize = ...; ❄ ( { image, newSize } ) var newImage = ✿ 26 / 54
Programmer thought process ◮ I have a Document and a Size ◮ I want to shrink the Document ◮ There must be a method ◮ Query should contain what the programmer knows ◮ Some values and types the expression should involve ◮ Loose syntactic structure ◮ Query shouldn’t require what the programmer doesn’t know ◮ Names ◮ Argument order ◮ Other arguments ◮ Show “best” results first ◮ Similar in spirit to Prospector [Mandelin et. al., PLDI’05] 27 / 54
Overview ◮ Expression of API queries as partial expressions ◮ Algorithm to generate results quickly in ranked order ◮ Experiment showing simple queries represent real code well 28 / 54
Unknown method queries ◮ Ex. ✿✿ ❄ ( { image, size } ) ◮ ⇒ PaintDotNet.Actions.CanvasSizeAction .ResizeDocument(img, size, ⋄ , ⋄ ) ◮ ⇒ PaintDotNet.Functional.Func.Bind( ⋄ , size, img) ◮ ⇒ PaintDotNet.Pair.Create(size, img) ◮ ⇒ PaintDotNet.Quadruple.Create(size, img, ⋄ , ⋄ ) ◮ ⇒ PaintDotNet.Triple.Create(size, img, ⋄ ) ◮ ⇒ PaintDotNet.PropertySystem .StaticListChoiceProperty .CreateForEnum(img, size, ⋄ ) ◮ ⇒ System.Drawing.Size.Equals(size, img) ◮ ⇒ System.Object.ReferenceEquals(size, img) 29 / 54
Unknown lookup queries ◮ Ex. float f = pointPair. ✯ ✿✿ ◮ ⇒ pointPair.P1.X ◮ ⇒ pointPair.P1.Y ◮ ⇒ pointPair.P2.X ◮ ⇒ pointPair.P2.Y ◮ ⇒ pointPair.Midpoint.X ◮ ⇒ pointPair.Midpoint.Y ◮ ⇒ pointPair.FirstValidValue().X ◮ ⇒ pointPair.Length 30 / 54
Unknown expression queries ◮ Ex. XmlReader xr = ❄ ✿ ◮ ⇒ System.Xml.XmlReader.Create( ⋄ ) ◮ ⇒ new System.Xml.XmlNodeReader( ⋄ ) ◮ ⇒ System.Data.SqlTypes.SqlXml.Null.CreateReader() ◮ ⇒ new System.Xml.XmlNodeReader( ⋄ ).ReadSubtree() ◮ ⇒ new System.Xml.XmlValidatingReader( ⋄ ).Reader ◮ ⇒ Microsoft.SqlServer.Server.SqlContext .TriggerContext.EventData.CreateReader() ◮ ⇒ new System.Xml.XmlValidatingReader( ⋄ ) .Reader.ReadSubtree() 31 / 54
❄ ✯ ✯ ❄ Partial expression language (a) e ::= call | varName | e . fieldName | e := e | e < e ::= call methodName ( e 1 , . . . , e n ) (b) e � ::= � a | ✿ ❄ | ⋄ ✯ | � � a ::= e | � a . ✿ call | � e := � e | � e < � e � call ::= ❄ ( { � e 1 , . . . , � e n } ) | methodName ( � e 1 , . . . , � e n ) ✿ 32 / 54
Partial expression language (a) e ::= call | varName | e . fieldName | e := e | e < e ::= call methodName ( e 1 , . . . , e n ) (b) � e ::= � a | ✿ ❄ | ⋄ ✯ | � � a ::= e | � a . ✿ call | � e := � e | � e < � e � call ::= ❄ ( { � e 1 , . . . , � e n } ) | methodName ( � e 1 , . . . , � e n ) ✿ ◮ Ex. ✿✿ ❄ ( { strBuilder. ✿ ✯ } ) ✯ , e. ✿ ⇒ ✿✿ ❄ ( { strBuilder, e.StackTrace } ) ⇒ strBuilder.Append(e.StackTrace) 33 / 54
Algorithm ◮ Problem: given query, generate completions 34 / 54
Method index by parameter type ArrayList ICloneable Object 2299 methods 2211 methods 2210 methods BinarySearch Clone Equals Reverse GetHashCode IList ... Registry .SetValue 2257 methods Array .IndexOf Add IList.Add Remove Console.WriteLine ... ... 35 / 54
Infinite results ◮ Problem: too many results ◮ inefficient to generate thousands of results to show only 20 to the programmer ◮ programmer does not want to look at every result ◮ result set is often infinite ◮ Ex. var res = foo. ✿ ✯ ; ◮ ⇒ foo ◮ ⇒ foo.GetType() ◮ ⇒ foo.GetType().GetType() ◮ ⇒ foo.GetType().GetType().GetType() ◮ ⇒ foo.GetType().GetType().GetType().GetType() ◮ ⇒ . . . ◮ Solution: generate in ranked order 36 / 54
Algorithm ◮ Simple structually recursive algorithm ◮ Group by type to minimize redundant work ◮ Generate results in ranking order ◮ Allows determination of top n without computing all results 37 / 54
Heuristics: Type distance Object IDrawingElement 2 Shape 2 1 Rectangle 38 / 54
Heuristics: Type distance Object IDrawingElement 2 Shape 2 1 Rectangle 0 39 / 54
❄ ✯ ✯ Heuristics: Length ◮ Number of field/property lookups or method calls added 40 / 54
Heuristics: Length ◮ Number of field/property lookups or method calls added ❄ ( { strBuilder. ✿ ✯ ,e. ✿ ✯ } ) ◮ ✿ Good (1): ⇒ strBuilder.Append(e.StackTrace) Bad (3): ⇒ strBuilder.Clear().Append(e.Data.Count) 41 / 54
Heuristics: Inferred abstract types Example usages elsewhere in codebase: string f = Path.GetTempFileName(); ...; File.Delete(f); File.Delete(Path.Combine(dir, filename)); if(File.Exists(Path.Combine(otherDir, file))) { ... } Query: string p = Path.GetTempFileName(); ❄ ( { p } ) ✿ ⇒ GetCursor(p) ⇒ File.Delete(p) ⇒ File.Exists(p) 42 / 54
Ranking function ◮ Linear combination of these and other heuristics ◮ Sensitivity analysis showed these are most important and coefficients do not matter much 43 / 54
Outline Motivation Approach Language Algorithm Ranking Experiment Results Related work Conclusion 44 / 54
Experiment ◮ Automated test of expressiveness of partial expressions ◮ Generated queries for each call and looked at rank of actual call in query results ◮ Advantage: able to do many queries ◮ Disadvantage: many of the method calls are not ones a programmer would need API discovery for 45 / 54
Experiment ◮ Used Microsoft CCI to disassemble mature C# projects ◮ Converted every call with at least 3 arguments (including receiver) to a query with 1 or 2 arguments (including receiver) ◮ For ResizeDocument(document, size, anchorEdge, background) 16 queries would be generated: ⇒ ✿ ❄ (document) ⇒ ✿ ❄ (size) ⇒ ✿ ❄ (anchorEdge) ⇒ ✿ ❄ (background) ⇒ ✿ ❄ (document, size) ⇒ ✿ ❄ (document, background) ⇒ . . . ◮ Report rank for best-performing query for each call 46 / 54
Recommend
More recommend