1 / 30

Libraries as Languages: Typechecking jQuery Programs

Libraries as Languages: Typechecking jQuery Programs. Benjamin Lerner Liam Elberty Jincheng Li Shriram Krishnamurthi. Programming Web Pages in JavaScript. Myth 1 : HTML documents are trees of pointers Reality: much more tightly linked. body. div. div. p. div. p. span. span.

moya
Download Presentation

Libraries as Languages: Typechecking jQuery Programs

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Libraries as Languages:TypecheckingjQuery Programs Benjamin Lerner Liam Elberty Jincheng Li ShriramKrishnamurthi

  2. Programming Web Pages in JavaScript Myth 1: HTML documents are trees of pointers • Reality: much more tightly linked body div div p div p span span

  3. Programming Web Pages in JavaScript Assembly language for trees Myth 2: just walk pointers from node to node function findAllP() { results = []; q = [body]; while ((cur = q.pop()) !== null) { if (cur.elementName == “p”) results.push(cur); q.push(cur.childNodes); } } body div div p div p span span

  4. Programming Web Pages with Query Languages • We have higher-level languages to express these ideas! • Any intuitions you have from XQuery, CSS, XDuce/CDuce are appropriate here…

  5. Programming with jQuery • jQuery is a library for tree programming • E.g. “Find all <p> nodes and turn them green” $(“p”).css(“color”, “green”) Domain-specific language

  6. What does this jQuery code do? $(“.tweet span”).next().html() Depends on the shape of the page!

  7. $(“.tweet span”).next().html() <Body> <Div class=“header-bar”> <Div class=“main-content”> <Div class=“stream”> <Div class=“sidebar”> <Div class=“tweet”> <Span class=“Author”> Ben <Span class=“Time”> Now <Span class=“Content”> Hi <Div class=“tweet”> …

  8. $(“.tweet span”).next().html() <Body> <Div class=“header-bar”> <Div class=“main-content”> <Div class=“stream”> <Div class=“sidebar”> <Div class=“tweet”> <Span class=“Author”> Ben <Span class=“Time”> Now <Span class=“Content”> Hi <Div class=“tweet”> …

  9. $(“.tweet span”).next().html() <Body> <Div class=“header-bar”> <Div class=“main-content”> <Div class=“stream”> <Div class=“sidebar”> <Div class=“tweet”> <Span class=“Author”> Ben <Span class=“Time”> Now <Span class=“Content”> Hi <Div class=“tweet”> …

  10. $(“.tweet span”).next().html() <Body> <Div class=“header-bar”> <Div class=“main-content”> <Div class=“stream”> <Div class=“sidebar”> <Div class=“tweet”> <Span class=“Author”> Ben <Span class=“Time”> Now <Span class=“Content”> Hi <Div class=“tweet”> …

  11. $(“.tweet span”).next().html() <Body> <Div class=“header-bar”> <Div class=“main-content”> <Div class=“stream”> <Div class=“sidebar”> <Div class=“tweet”> “<Span class=“Time”> Now” <Span class=“Author”> Ben <Span class=“Time”> Now <Span class=“Content”> Hi <Div class=“tweet”> …

  12. $(“.tweet span”).next().text() <Body> <Div class=“header-bar”> <Div class=“main-content”> <Div class=“stream”> <Div class=“sidebar”> <Div class=“tweet”> “ Now Hi” <Span class=“Author”> Ben <Span class=“Time”> Now <Span class=“Content”> Hi <Div class=“tweet”> …

  13. What’s going on here? Query: Selects some nodes in the page Manipulate: Retrieve or modify data from node(s) $(“.tweet span”).next().html() Navigate: Move to new nodes, relative to existing ones

  14. How jQuery works $(“.tweet span”) .map() .html() .next() ... .map() .html() .next() ... .map() .html() .next() ... DOM nodes New DOM nodes New DOM nodes prev prev “<div>...</div>”

  15. So what can go wrong? • “Standard” type errors: • .map() a function over wrong types of elements • Ambiguity: • Getting the .html() of one node, but have many • Overshooting: • Asking for the .children() of a leaf node… • Wrong selection: • $(“div.mispleling”)

  16. How to catch these errors? Working backwards: • x.html() is ok if x has exactly 1 node • x.next() is ok if x has at least 1 node • The $() function returns some number of nodes, based on its argument… Need more than just simple types: Need to track sizes

  17. Catching “standard type errors” jq = A recursive, parametric type of ... html : [jq< 'e >] Str, text : [jq< 'e >] Str, ... next : [jq< 'e >]  ????

  18. Catching ambiguity errors jq = A recursive, parametric type of ... html : [jq< 'e >] Str, text : [jq< 'e >] Str, ... next : [jq< 'e >]  ????

  19. Catching ambiguity errors Multiplicities: Lightweight sizes for containers jq = A recursive, parametric type of ... html : [jq< 1<'e>>] Str, text : [jq<1+<'e>>] Str, ... next : [jq<1+<'e>>]  ????

  20. Multiplicities • New kind M Only allowed as arguments to type constructors No values have a type of kind M • Simple, finite set of constructors: 0, 1, 01, 1+, 0+ • Intuition: interval arithmetic Multiplication: 01<1+<τ>> = 0+<τ> Addition: 0<τ1> ++ 1<τ2> <: 01<τ1 + τ2>

  21. Catching ambiguity errors Intersection types + multiplicities = precise getter/setter types jq = A recursive, parametric type of ... html : [jq< 1<'e>>] Str, text : ([jq<1+<'e>>] Str) & ([jq[1+<'e>>] Strjq<1+<'e>>), ... next : [jq<1+<'e>>] ????

  22. Catching overshoot errors • Type-level functions to figure out structure jq = A recursive, parametric type of ... html : [jq< 1<'e>>] Str, text : ([jq<1+<'e>>] Str) & ([jq[1+<'e>>] Strjq<1+<'e>>), ... next : [jq<1+<'e>>]  jq<1+<@nextOf<'e>>>

  23. How to get structure information? • “Well, on this page, a Tweet is …” (Tweet : Div classes = {tweet} optional = {starred} (Author : Span classes = {span}) (Time : Span classes = {time}) (Content : Span classes = {content})) • Compute type functions from this local structure

  24. One last piece: matching selectors jq = A recursive, parametric type of ... html : [jq< 1<'e>>] Str, text : ([jq<1+<'e>>] Str) & ([jq[1+<'e>>] Strjq<1+<'e>>), ... next : [jq<1+<'e>>]  jq<1+<@nextOf<'e>>> $ : forall s <: String, s  @selector<'s>

  25. Matching selectors against local structure (Tweet : Div classes = {tweet} optional = {starred} (Author : Span classes = {span}) (Time : Span classes = {time}) (Content : Span classes = {content})) “*.tweet > *.time” 1+<Time> “*.tweet > *.content + *” 0<Element>

  26. Full recipe: • “Standard type errors”  standard types • Ambiguity errors  multiplicities • Overshooting errors  local structure • Wrong selection  local structure

  27. Evaluation • Examined 12 examples from Learning JQueryand its accompanying blog • Manually derived local structure from text descriptions • Type-checked example queries  All pass typechecking, with no extra annotations • Manually introduced bugs  All now fail

  28. Evaluation: Typical example $(“.tweet”).children().next().next().next().css(“color”) $(“.tweet”).children().next().next().css(“color”) $(“.tweet”).children().next().css(“color”) û‘css’ expects 1<Element>, got 0<Element> ü û‘css’ expects 1<Element>, got 1+<Author+Time>

  29. Subtleties • DOM Mutation $(“.tweet”).findClass(“starred”) .removeClass(“starred”) $(“.tweet”).findClass(“starred”)  how many?? • Overly broad queries What should $(“div > p”) match? • … See paper for more details

  30. Try it out! Implemented in TeJaS: Customizable, extensible type systems for JS https://github.com/brownplt/TeJaS http://www.jswebtools.org/

More Related