'
13 |
14 | hr_faded: '
'
15 | hr_shaded: '
'
--------------------------------------------------------------------------------
/docs/_data/definitions.yml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/_data/glossary.yml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/_data/sidebars/home_sidebar.yml:
--------------------------------------------------------------------------------
1 |
2 | #################################################
3 | ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
4 | #################################################
5 | # Instead edit ../../sidebar.json
6 | entries:
7 | - folders:
8 | - folderitems:
9 | - output: web,pdf
10 | title: Overview
11 | url: /
12 | - output: web,pdf
13 | title: module name here
14 | url: core.html
15 | - output: web,pdf
16 | title: 'Download Grammars:'
17 | url: build_grammars.html
18 | - output: web,pdf
19 | title: Title
20 | url: demo.html
21 | output: web
22 | title: function_parser
23 | output: web
24 | title: Sidebar
25 |
--------------------------------------------------------------------------------
/docs/_data/tags.yml:
--------------------------------------------------------------------------------
1 | allowed-tags:
2 | - getting_started
3 | - navigation
4 |
--------------------------------------------------------------------------------
/docs/_data/terms.yml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/_data/topnav.yml:
--------------------------------------------------------------------------------
1 | topnav:
2 | - title: Topnav
3 | items:
4 | - title: github
5 | external_url: https://github.com/ncoop57/function_parser/tree/main/
6 |
7 | #Topnav dropdowns
8 | topnav_dropdowns:
9 | - title: Topnav dropdowns
10 | folders:
--------------------------------------------------------------------------------
/docs/_includes/archive.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | type: archive
4 | ---
5 |
6 |
9 |
10 |
11 | {{ content }}
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/docs/_includes/callout.html:
--------------------------------------------------------------------------------
1 |
{{include.content}}
2 |
--------------------------------------------------------------------------------
/docs/_includes/footer.html:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/docs/_includes/google_analytics.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% if site.google_analytics %}
4 |
5 |
6 | {% endif %}
--------------------------------------------------------------------------------
/docs/_includes/head.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{ page.title }} | {{ site.site_title }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | {% if site.use_math %}
25 |
26 |
27 |
28 |
39 | {% endif %}
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
56 |
57 |
58 |
59 |
60 | {% if site.twitter_username %}
61 |
62 |
63 |
64 | {% endif %}
65 |
66 | {% if page.summary %}
67 |
68 | {% else %}
69 |
70 | {% endif %}
71 |
72 | {% if page.image %}
73 |
74 |
75 | {% else %}
76 |
77 |
78 | {% endif %}
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/docs/_includes/head_print.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{% if page.homepage == true %} {{site.homepage_title}} {% elsif page.title %}{{ page.title }}{% endif %} | {{ site.site_title }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
29 |
--------------------------------------------------------------------------------
/docs/_includes/image.html:
--------------------------------------------------------------------------------
1 |
{% if {{include.url}} %}{% endif %} {% if {{include.url}} %} {% endif %}{% if {{include.caption}} %}{{include.caption}} {% endif %}
2 |
--------------------------------------------------------------------------------
/docs/_includes/important.html:
--------------------------------------------------------------------------------
1 |
Important: {{include.content}}
--------------------------------------------------------------------------------
/docs/_includes/initialize_shuffle.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
100 |
101 |
102 |
103 |
114 |
115 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/docs/_includes/inline_image.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/_includes/links.html:
--------------------------------------------------------------------------------
1 | {% comment %}Get links from each sidebar, as listed in the _config.yml file under sidebars{% endcomment %}
2 |
3 | {% for sidebar in site.sidebars %}
4 | {% for entry in site.data.sidebars[sidebar].entries %}
5 | {% for folder in entry.folders %}
6 | {% for folderitem in folder.folderitems %}
7 | {% if folderitem.url contains "html#" %}
8 | [{{folderitem.url | remove: "/" }}]: {{folderitem.url | remove: "/"}}
9 | {% else %}
10 | [{{folderitem.url | remove: "/" | remove: ".html"}}]: {{folderitem.url | remove: "/"}}
11 | {% endif %}
12 | {% for subfolders in folderitem.subfolders %}
13 | {% for subfolderitem in subfolders.subfolderitems %}
14 | [{{subfolderitem.url | remove: "/" | remove: ".html"}}]: {{subfolderitem.url | remove: "/"}}
15 | {% endfor %}
16 | {% endfor %}
17 | {% endfor %}
18 | {% endfor %}
19 | {% endfor %}
20 | {% endfor %}
21 |
22 |
23 | {% comment %} Get links from topnav {% endcomment %}
24 |
25 | {% for entry in site.data.topnav.topnav %}
26 | {% for item in entry.items %}
27 | {% if item.external_url == null %}
28 | [{{item.url | remove: "/" | remove: ".html"}}]: {{item.url | remove: "/"}}
29 | {% endif %}
30 | {% endfor %}
31 | {% endfor %}
32 |
33 | {% comment %}Get links from topnav dropdowns {% endcomment %}
34 |
35 | {% for entry in site.data.topnav.topnav_dropdowns %}
36 | {% for folder in entry.folders %}
37 | {% for folderitem in folder.folderitems %}
38 | {% if folderitem.external_url == null %}
39 | [{{folderitem.url | remove: "/" | remove: ".html"}}]: {{folderitem.url | remove: "/"}}
40 | {% endif %}
41 | {% endfor %}
42 | {% endfor %}
43 | {% endfor %}
44 |
45 |
--------------------------------------------------------------------------------
/docs/_includes/note.html:
--------------------------------------------------------------------------------
1 |
Note: {{include.content}}
2 |
--------------------------------------------------------------------------------
/docs/_includes/notebook_colab_link.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/docs/_includes/search_google_custom.html:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/_includes/search_simple_jekyll.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
17 |
--------------------------------------------------------------------------------
/docs/_includes/sidebar.html:
--------------------------------------------------------------------------------
1 | {% assign sidebar = site.data.sidebars[page.sidebar].entries %}
2 | {% assign pageurl = page.url | remove: ".html" %}
3 |
4 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/docs/_includes/tip.html:
--------------------------------------------------------------------------------
1 |
Tip: {{include.content}}
--------------------------------------------------------------------------------
/docs/_includes/toc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/_includes/topnav.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
15 |
16 | Nav
17 |
18 |
19 | {% assign topnav = site.data[page.topnav] %}
20 | {% assign topnav_dropdowns = site.data[page.topnav].topnav_dropdowns %}
21 |
22 | {% for entry in topnav.topnav %}
23 | {% for item in entry.items %}
24 | {% if item.external_url %}
25 | {{item.title}}
26 | {% elsif page.url contains item.url %}
27 | {{item.title}}
28 | {% else %}
29 | {{item.title}}
30 | {% endif %}
31 | {% endfor %}
32 | {% endfor %}
33 |
34 |
35 | {% for entry in topnav_dropdowns %}
36 | {% for folder in entry.folders %}
37 |
38 | {{ folder.title }}
39 |
50 |
51 | {% endfor %}
52 | {% endfor %}
53 | {% if site.google_search %}
54 |
55 | {% include search_google_custom.html %}
56 |
57 | {% endif %}
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/docs/_includes/warning.html:
--------------------------------------------------------------------------------
1 |
Warning: {{include.content}}
--------------------------------------------------------------------------------
/docs/_layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% include head.html %}
5 |
41 |
46 |
57 | {% if page.datatable == true %}
58 |
59 |
60 |
61 |
66 |
76 | {% endif %}
77 |
78 |
79 |
80 | {% include topnav.html %}
81 |
82 |
83 |
84 |
85 |
86 | {% assign content_col_size = "col-md-12" %}
87 | {% unless page.hide_sidebar %}
88 |
89 |
92 | {% assign content_col_size = "col-md-9" %}
93 | {% endunless %}
94 |
95 |
96 |
97 | {{content}}
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | {% if site.google_analytics %}
108 | {% include google_analytics.html %}
109 | {% endif %}
110 |
111 |
--------------------------------------------------------------------------------
/docs/_layouts/default_print.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {% include head_print.html %}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | {{content}}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/docs/_layouts/none.html:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 | {{content}}
--------------------------------------------------------------------------------
/docs/_layouts/page.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 |
12 |
13 | {% if page.simple_map == true %}
14 |
15 |
20 |
21 | {% include custom/{{page.map_name}}.html %}
22 |
23 | {% elsif page.complex_map == true %}
24 |
25 |
30 |
31 | {% include custom/{{page.map_name}}.html %}
32 |
33 | {% endif %}
34 |
35 |
36 |
37 | {% if page.summary %}
38 |
{{page.summary}}
39 | {% endif %}
40 |
41 | {% unless page.toc == false %}
42 | {% include toc.html %}
43 | {% endunless %}
44 |
45 |
46 | {% if site.github_editme_path %}
47 |
48 |
Edit me
49 |
50 | {% endif %}
51 |
52 | {{content}}
53 |
54 |
65 |
66 |
67 |
68 | {{site.data.alerts.hr_shaded}}
69 |
70 | {% include footer.html %}
71 |
--------------------------------------------------------------------------------
/docs/_layouts/page_print.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default_print
3 | comments: true
4 | ---
5 |
8 |
9 |
10 |
11 | {% if page.summary %}
12 |
{{page.summary}}
13 | {% endif %}
14 | {{ content }}
15 |
16 |
--------------------------------------------------------------------------------
/docs/build_grammars.html:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: Download Grammars:
4 |
5 |
6 | keywords: fastai
7 | sidebar: home_sidebar
8 |
9 |
10 |
11 | nb_path: "nbs/build_grammars.ipynb"
12 | ---
13 |
22 |
23 |
24 |
25 | {% raw %}
26 |
27 |
28 |
29 |
30 | {% endraw %}
31 |
32 |
33 |
34 |
from tree_sitter import Language
35 |
36 | Language . build_library (
37 | # Store the library in the directory
38 | '<out_dir>/tree-sitter-languages.so' ,
39 | # Include one or more languages
40 | [
41 | '<path/to/repo>/tree-sitter-python' ,
42 | '<path/to/repo>/tree-sitter-go' ,
43 | '<path/to/repo>/tree-sitter-java'
44 | ]
45 | )
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/docs/core.html:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: module name here
4 |
5 |
6 | keywords: fastai
7 | sidebar: home_sidebar
8 |
9 | summary: "API details."
10 | description: "API details."
11 | nb_path: "nbs/00_core.ipynb"
12 | ---
13 |
22 |
23 |
24 |
25 | {% raw %}
26 |
27 |
28 |
29 |
30 | {% endraw %}
31 |
32 | {% raw %}
33 |
34 |
47 | {% endraw %}
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/docs/css/boxshadowproperties.css:
--------------------------------------------------------------------------------
1 | /* box-shadow fonts return errors with prince, so extracting here to put in web output only */
2 |
3 | #search-demo-container ul#results-container {
4 | box-shadow: 2px 3px 2px #dedede;
5 | }
6 |
7 |
8 | hr.shaded {
9 | box-shadow: inset 0 6px 6px -6px rgba(0,0,0,0.5);
10 | }
11 |
12 | .videoThumbs img {
13 | box-shadow: 2px 2px 1px #f0f0f0;
14 | }
15 |
16 | .box {
17 | box-shadow: 2px 2px 4px #dedede;
18 | }
19 |
20 | @media (max-width: 1200px) {
21 | .navbar-collapse {
22 | box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/docs/css/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/css/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/docs/css/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/css/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/docs/css/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/css/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/docs/css/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/css/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/docs/css/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/css/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/docs/css/modern-business.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Start Bootstrap - Modern Business HTML Template (http://startbootstrap.com)
3 | * Code licensed under the Apache License v2.0.
4 | * For details, see http://www.apache.org/licenses/LICENSE-2.0.
5 | */
6 |
7 | /* Global Styles */
8 |
9 | html,
10 | body {
11 | height: 100%;
12 | }
13 |
14 | .img-portfolio {
15 | margin-bottom: 30px;
16 | }
17 |
18 | .img-hover:hover {
19 | opacity: 0.8;
20 | }
21 |
22 | /* Home Page Carousel */
23 |
24 | header.carousel {
25 | height: 50%;
26 | }
27 |
28 | header.carousel .item,
29 | header.carousel .item.active,
30 | header.carousel .carousel-inner {
31 | height: 100%;
32 | }
33 |
34 | header.carousel .fill {
35 | width: 100%;
36 | height: 100%;
37 | background-position: center;
38 | background-size: cover;
39 | }
40 |
41 | /* 404 Page Styles */
42 |
43 | .error-404 {
44 | font-size: 100px;
45 | }
46 |
47 | /* Pricing Page Styles */
48 |
49 | .price {
50 | display: block;
51 | font-size: 50px;
52 | line-height: 50px;
53 | }
54 |
55 | .price sup {
56 | top: -20px;
57 | left: 2px;
58 | font-size: 20px;
59 | }
60 |
61 | .period {
62 | display: block;
63 | font-style: italic;
64 | }
65 |
66 | /* Footer Styles */
67 |
68 | footer {
69 | margin: 50px 0;
70 | }
71 |
72 | /* Responsive Styles */
73 |
74 | @media(max-width:991px) {
75 | .client-img,
76 | .img-related {
77 | margin-bottom: 30px;
78 | }
79 | }
80 |
81 | @media(max-width:767px) {
82 | .img-portfolio {
83 | margin-bottom: 15px;
84 | }
85 |
86 | header.carousel .carousel {
87 | height: 70%;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/docs/css/printstyles.css:
--------------------------------------------------------------------------------
1 |
2 | /*body.print .container {max-width: 650px;}*/
3 |
4 | body {
5 | font-size:14px;
6 | }
7 | .nav ul li a {border-top:0px; background-color:transparent; color: #808080; }
8 | #navig a[href] {color: #595959 !important;}
9 | table .table {max-width:650px;}
10 |
11 | #navig li.sectionHead {font-weight: bold; font-size: 18px; color: #595959 !important; }
12 | #navig li {font-weight: normal; }
13 |
14 | #navig a[href]::after { content: leader(".") target-counter(attr(href), page); }
15 |
16 | a[href]::after {
17 | content: " (page " target-counter(attr(href), page) ")"
18 | }
19 |
20 | a[href^="http:"]::after, a[href^="https:"]::after {
21 | content: "";
22 | }
23 |
24 | a[href] {
25 | color: blue !important;
26 | }
27 | a[href*="mailto"]::after, a[data-toggle="tooltip"]::after, a[href].noCrossRef::after {
28 | content: "";
29 | }
30 |
31 |
32 | @page {
33 | margin: 60pt 90pt 60pt 90pt;
34 | font-family: sans-serif;
35 | font-style:none;
36 | color: gray;
37 |
38 | }
39 |
40 | .printTitle {
41 | line-height:30pt;
42 | font-size:27pt;
43 | font-weight: bold;
44 | letter-spacing: -.5px;
45 | margin-bottom:25px;
46 | }
47 |
48 | .printSubtitle {
49 | font-size: 19pt;
50 | color: #cccccc !important;
51 | font-family: "Grotesque MT Light";
52 | line-height: 22pt;
53 | letter-spacing: -.5px;
54 | margin-bottom:20px;
55 | }
56 | .printTitleArea hr {
57 | color: #999999 !important;
58 | height: 2px;
59 | width: 100%;
60 | }
61 |
62 | .printTitleImage {
63 | max-width:300px;
64 | margin-bottom:200px;
65 | }
66 |
67 |
68 | .printTitleImage {
69 | max-width: 250px;
70 | }
71 |
72 | #navig {
73 | /*page-break-before: always;*/
74 | }
75 |
76 | .copyrightBoilerplate {
77 | page-break-before:always;
78 | font-size:14px;
79 | }
80 |
81 | .lastGeneratedDate {
82 | font-style: italic;
83 | font-size:14px;
84 | color: gray;
85 | }
86 |
87 | .alert a {
88 | text-decoration: none !important;
89 | }
90 |
91 |
92 | body.title { page: title }
93 |
94 | @page title {
95 | @top-left {
96 | content: " ";
97 | }
98 | @top-right {
99 | content: " "
100 | }
101 | @bottom-right {
102 | content: " ";
103 | }
104 | @bottom-left {
105 | content: " ";
106 | }
107 | }
108 |
109 | body.frontmatter { page: frontmatter }
110 | body.frontmatter {counter-reset: page 1}
111 |
112 |
113 | @page frontmatter {
114 | @top-left {
115 | content: prince-script(guideName);
116 | }
117 | @top-right {
118 | content: prince-script(datestamp);
119 | }
120 | @bottom-right {
121 | content: counter(page, lower-roman);
122 | }
123 | @bottom-left {
124 | content: "youremail@domain.com"; }
125 | }
126 |
127 | body.first_page {counter-reset: page 1}
128 |
129 | h1 { string-set: doctitle content() }
130 |
131 | @page {
132 | @top-left {
133 | content: string(doctitle);
134 | font-size: 11px;
135 | font-style: italic;
136 | }
137 | @top-right {
138 | content: prince-script(datestamp);
139 | font-size: 11px;
140 | }
141 |
142 | @bottom-right {
143 | content: "Page " counter(page);
144 | font-size: 11px;
145 | }
146 | @bottom-left {
147 | content: prince-script(guideName);
148 | font-size: 11px;
149 | }
150 | }
151 | .alert {
152 | background-color: #fafafa !important;
153 | border-color: #dedede !important;
154 | color: black;
155 | }
156 |
157 | pre {
158 | background-color: #fafafa;
159 | }
160 |
--------------------------------------------------------------------------------
/docs/css/syntax.css:
--------------------------------------------------------------------------------
1 | .highlight { background: #ffffff; }
2 | .highlight .c { color: #999988; font-style: italic } /* Comment */
3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
4 | .highlight .k { font-weight: bold } /* Keyword */
5 | .highlight .o { font-weight: bold } /* Operator */
6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
7 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
12 | .highlight .ge { font-style: italic } /* Generic.Emph */
13 | .highlight .gr { color: #aa0000 } /* Generic.Error */
14 | .highlight .gh { color: #999999 } /* Generic.Heading */
15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
17 | .highlight .go { color: #888888 } /* Generic.Output */
18 | .highlight .gp { color: #555555 } /* Generic.Prompt */
19 | .highlight .gs { font-weight: bold } /* Generic.Strong */
20 | .highlight .gu { color: #aaaaaa } /* Generic.Subheading */
21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */
22 | .highlight .kc { font-weight: bold } /* Keyword.Constant */
23 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */
24 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */
25 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */
26 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
27 | .highlight .m { color: #009999 } /* Literal.Number */
28 | .highlight .s { color: #d14 } /* Literal.String */
29 | .highlight .na { color: #008080 } /* Name.Attribute */
30 | .highlight .nb { color: #0086B3 } /* Name.Builtin */
31 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
32 | .highlight .no { color: #008080 } /* Name.Constant */
33 | .highlight .ni { color: #800080 } /* Name.Entity */
34 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
35 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
36 | .highlight .nn { color: #555555 } /* Name.Namespace */
37 | .highlight .nt { color: #000080 } /* Name.Tag */
38 | .highlight .nv { color: #008080 } /* Name.Variable */
39 | .highlight .ow { font-weight: bold } /* Operator.Word */
40 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
41 | .highlight .mf { color: #009999 } /* Literal.Number.Float */
42 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */
43 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */
44 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */
45 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */
46 | .highlight .sc { color: #d14 } /* Literal.String.Char */
47 | .highlight .sd { color: #d14 } /* Literal.String.Doc */
48 | .highlight .s2 { color: #d14 } /* Literal.String.Double */
49 | .highlight .se { color: #d14 } /* Literal.String.Escape */
50 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */
51 | .highlight .si { color: #d14 } /* Literal.String.Interpol */
52 | .highlight .sx { color: #d14 } /* Literal.String.Other */
53 | .highlight .sr { color: #009926 } /* Literal.String.Regex */
54 | .highlight .s1 { color: #d14 } /* Literal.String.Single */
55 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */
56 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
57 | .highlight .vc { color: #008080 } /* Name.Variable.Class */
58 | .highlight .vg { color: #008080 } /* Name.Variable.Global */
59 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */
60 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
--------------------------------------------------------------------------------
/docs/css/theme-blue.css:
--------------------------------------------------------------------------------
1 | .summary {
2 | color: #808080;
3 | border-left: 5px solid #ED1951;
4 | font-size:16px;
5 | }
6 |
7 |
8 | h3 {color: #000000; }
9 | h4 {color: #000000; }
10 |
11 | .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
12 | background-color: #248ec2;
13 | color: white;
14 | }
15 |
16 | .nav > li.active > a {
17 | background-color: #347DBE;
18 | }
19 |
20 | .nav > li > a:hover {
21 | background-color: #248ec2;
22 | }
23 |
24 | div.navbar-collapse .dropdown-menu > li > a:hover {
25 | background-color: #347DBE;
26 | }
27 |
28 | .nav li.thirdlevel > a {
29 | background-color: #FAFAFA !important;
30 | color: #248EC2;
31 | font-weight: bold;
32 | }
33 |
34 | a[data-toggle="tooltip"] {
35 | color: #649345;
36 | font-style: italic;
37 | cursor: default;
38 | }
39 |
40 | .navbar-inverse {
41 | background-color: #347DBE;
42 | border-color: #015CAE;
43 | }
44 | .navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-brand {
45 | color: white;
46 | }
47 |
48 | .navbar-inverse .navbar-nav>li>a:hover, a.fa.fa-home.fa-lg.navbar-brand:hover {
49 | color: #f0f0f0;
50 | }
51 |
52 | a.navbar-brand:hover {
53 | color: #f0f0f0;
54 | }
55 |
56 | .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus {
57 | color: #015CAE;
58 | }
59 |
60 | .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus {
61 | background-color: #015CAE;
62 | color: #ffffff;
63 | }
64 |
65 | .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form {
66 | border-color: #248ec2 !important;
67 | }
68 |
69 | .btn-primary {
70 | color: #ffffff;
71 | background-color: #347DBE;
72 | border-color: #347DBE;
73 | }
74 |
75 | .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus {
76 | background-color: #347DBE;
77 | }
78 |
79 | .btn-primary:hover,
80 | .btn-primary:focus,
81 | .btn-primary:active,
82 | .btn-primary.active,
83 | .open .dropdown-toggle.btn-primary {
84 | background-color: #248ec2;
85 | border-color: #347DBE;
86 | }
87 |
88 | .printTitle {
89 | color: #015CAE !important;
90 | }
91 |
92 | body.print h1 {color: #015CAE !important; font-size:28px !important;}
93 | body.print h2 {color: #595959 !important; font-size:20px !important;}
94 | body.print h3 {color: #E50E51 !important; font-size:14px !important;}
95 | body.print h4 {color: #679DCE !important; font-size:14px; font-style: italic !important;}
96 |
97 | .anchorjs-link:hover {
98 | color: #216f9b;
99 | }
100 |
101 | div.sidebarTitle {
102 | color: #015CAE;
103 | }
104 |
105 | li.sidebarTitle {
106 | margin-top:20px;
107 | font-weight:normal;
108 | font-size:130%;
109 | color: #ED1951;
110 | margin-bottom:10px;
111 | margin-left: 5px;
112 |
113 | }
114 |
115 | .navbar-inverse .navbar-toggle:focus, .navbar-inverse .navbar-toggle:hover {
116 | background-color: #015CAE;
117 | }
118 |
119 | .navbar-inverse .navbar-toggle {
120 | border-color: #015CAE;
121 | }
122 |
--------------------------------------------------------------------------------
/docs/css/theme-green.css:
--------------------------------------------------------------------------------
1 | .summary {
2 | color: #808080;
3 | border-left: 5px solid #E50E51;
4 | font-size:16px;
5 | }
6 |
7 |
8 | h3 {color: #E50E51; }
9 | h4 {color: #808080; }
10 |
11 | .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
12 | background-color: #248ec2;
13 | color: white;
14 | }
15 |
16 | .nav > li.active > a {
17 | background-color: #72ac4a;
18 | }
19 |
20 | .nav > li > a:hover {
21 | background-color: #72ac4a;
22 | }
23 |
24 | div.navbar-collapse .dropdown-menu > li > a:hover {
25 | background-color: #72ac4a;
26 | }
27 |
28 | .navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-brand {
29 | color: white;
30 | }
31 |
32 | .navbar-inverse .navbar-nav>li>a:hover, a.fa.fa-home.fa-lg.navbar-brand:hover {
33 | color: #f0f0f0;
34 | }
35 |
36 | .nav li.thirdlevel > a {
37 | background-color: #FAFAFA !important;
38 | color: #72ac4a;
39 | font-weight: bold;
40 | }
41 |
42 | a[data-toggle="tooltip"] {
43 | color: #649345;
44 | font-style: italic;
45 | cursor: default;
46 | }
47 |
48 | .navbar-inverse {
49 | background-color: #72ac4a;
50 | border-color: #5b893c;
51 | }
52 |
53 | .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus {
54 | color: #5b893c;
55 | }
56 |
57 | .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus {
58 | background-color: #5b893c;
59 | color: #ffffff;
60 | }
61 |
62 | /* not sure if using this ...*/
63 | .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form {
64 | border-color: #72ac4a !important;
65 | }
66 |
67 | .btn-primary {
68 | color: #ffffff;
69 | background-color: #5b893c;
70 | border-color: #5b893c;
71 | }
72 |
73 | .btn-primary:hover,
74 | .btn-primary:focus,
75 | .btn-primary:active,
76 | .btn-primary.active,
77 | .open .dropdown-toggle.btn-primary {
78 | background-color: #72ac4a;
79 | border-color: #5b893c;
80 | }
81 |
82 | .printTitle {
83 | color: #5b893c !important;
84 | }
85 |
86 | body.print h1 {color: #5b893c !important; font-size:28px;}
87 | body.print h2 {color: #595959 !important; font-size:24px;}
88 | body.print h3 {color: #E50E51 !important; font-size:14px;}
89 | body.print h4 {color: #679DCE !important; font-size:14px; font-style: italic;}
90 |
91 | .anchorjs-link:hover {
92 | color: #4f7233;
93 | }
94 |
95 | div.sidebarTitle {
96 | color: #E50E51;
97 | }
98 |
99 | li.sidebarTitle {
100 | margin-top:20px;
101 | font-weight:normal;
102 | font-size:130%;
103 | color: #ED1951;
104 | margin-bottom:10px;
105 | margin-left: 5px;
106 | }
107 |
108 | .navbar-inverse .navbar-toggle:focus, .navbar-inverse .navbar-toggle:hover {
109 | background-color: #E50E51;
110 | }
111 |
--------------------------------------------------------------------------------
/docs/demo.html:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: Title
4 |
5 |
6 | keywords: fastai
7 | sidebar: home_sidebar
8 |
9 |
10 |
11 | nb_path: "nbs/demo.ipynb"
12 | ---
13 |
22 |
23 |
24 |
25 | {% raw %}
26 |
27 |
28 |
29 |
30 | {% endraw %}
31 |
32 | {% raw %}
33 |
34 |
47 | {% endraw %}
48 |
49 | {% raw %}
50 |
51 |
70 | {% endraw %}
71 |
72 | {% raw %}
73 |
74 |
87 | {% endraw %}
88 |
89 | {% raw %}
90 |
91 |
107 | {% endraw %}
108 |
109 | {% raw %}
110 |
111 |
124 | {% endraw %}
125 |
126 | {% raw %}
127 |
128 |
141 | {% endraw %}
142 |
143 | {% raw %}
144 |
145 |
146 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
178 |
179 |
180 |
181 |
182 | nwo
183 | sha
184 | path
185 | language
186 | identifier
187 | parameters
188 | argument_list
189 | return_statement
190 | docstring
191 | docstring_summary
192 | docstring_tokens
193 | function
194 | function_tokens
195 | url
196 |
197 |
198 |
199 |
200 | 0
201 | keras-team/keras
202 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
203 | keras/backend.py
204 | python
205 | backend
206 | ()
207 |
208 | return 'tensorflow'
209 | Publicly accessible method for determining the...
210 | Publicly accessible method for determining the...
211 | [Publicly, accessible, method, for, determinin...
212 | def backend():\n """Publicly accessible metho...
213 | [def, backend, (, ), :, return, 'tensorflow']
214 | https://github.com/keras-team/keras/blob/e43af...
215 |
216 |
217 | 1
218 | keras-team/keras
219 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
220 | keras/backend.py
221 | python
222 | cast_to_floatx
223 | (x)
224 |
225 | return np.asarray(x, dtype=floatx())
226 | Cast a Numpy array to the default Keras float ...
227 | Cast a Numpy array to the default Keras float ...
228 | [Cast, a, Numpy, array, to, the, default, Kera...
229 | def cast_to_floatx(x):\n """Cast a Numpy arra...
230 | [def, cast_to_floatx, (, x, ), :, if, isinstan...
231 | https://github.com/keras-team/keras/blob/e43af...
232 |
233 |
234 | 2
235 | keras-team/keras
236 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
237 | keras/backend.py
238 | python
239 | get_uid
240 | (prefix='')
241 |
242 | return layer_name_uids[prefix]
243 | Associates a string prefix with an integer cou...
244 | Associates a string prefix with an integer cou...
245 | [Associates, a, string, prefix, with, an, inte...
246 | def get_uid(prefix=''):\n """Associates a str...
247 | [def, get_uid, (, prefix, =, '', ), :, graph, ...
248 | https://github.com/keras-team/keras/blob/e43af...
249 |
250 |
251 | 3
252 | keras-team/keras
253 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
254 | keras/backend.py
255 | python
256 | reset_uids
257 | ()
258 |
259 |
260 | Resets graph identifiers.
261 | Resets graph identifiers.
262 | [Resets, graph, identifiers, .]
263 | def reset_uids():\n """Resets graph identifie...
264 | [def, reset_uids, (, ), :, PER_GRAPH_OBJECT_NA...
265 | https://github.com/keras-team/keras/blob/e43af...
266 |
267 |
268 | 4
269 | keras-team/keras
270 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
271 | keras/backend.py
272 | python
273 | clear_session
274 | ()
275 |
276 |
277 | Resets all state generated by Keras.\n\n Kera...
278 | Resets all state generated by Keras.
279 | [Resets, all, state, generated, by, Keras, .]
280 | def clear_session():\n """Resets all state ge...
281 | [def, clear_session, (, ), :, global, _SESSION...
282 | https://github.com/keras-team/keras/blob/e43af...
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 | {% endraw %}
296 |
297 | {% raw %}
298 |
299 |
313 | {% endraw %}
314 |
315 | {% raw %}
316 |
317 |
330 | {% endraw %}
331 |
332 | {% raw %}
333 |
334 |
347 | {% endraw %}
348 |
349 | {% raw %}
350 |
351 |
352 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
[('https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/wrappers/scikit_learn.py#L102-L102',
372 | 'https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/utils/generic_utils.py#L474-L489'),
373 | ('https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/wrappers/scikit_learn.py#L159-L159',
374 | 'https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/losses.py#L1821-L1828'),
375 | ('https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/wrappers/scikit_learn.py#L161-L161',
376 | 'https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/utils/np_utils.py#L25-L81'),
377 | ('https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/wrappers/scikit_learn.py#L184-L184',
378 | 'https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/utils/generic_utils.py#L474-L489'),
379 | ('https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/wrappers/scikit_learn.py#L300-L300',
380 | 'https://github.com/keras-team/keras/blob/e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b/keras/utils/np_utils.py#L25-L81')]
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 | {% endraw %}
390 |
391 | {% raw %}
392 |
393 |
394 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
426 |
427 |
428 |
429 |
430 | nwo
431 | sha
432 | path
433 | language
434 | identifier
435 | argument_list
436 | url
437 |
438 |
439 |
440 |
441 | 0
442 | keras-team/keras
443 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
444 | keras/backend.py
445 | python
446 | _DummyEagerGraph
447 | ()
448 | https://github.com/keras-team/keras/blob/e43af...
449 |
450 |
451 | 1
452 | keras-team/keras
453 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
454 | keras/backend.py
455 | python
456 | get_graph
457 | ()
458 | https://github.com/keras-team/keras/blob/e43af...
459 |
460 |
461 | 2
462 | keras-team/keras
463 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
464 | keras/backend.py
465 | python
466 | reset_uids
467 | ()
468 | https://github.com/keras-team/keras/blob/e43af...
469 |
470 |
471 | 3
472 | keras-team/keras
473 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
474 | keras/backend.py
475 | python
476 | get_graph
477 | ()
478 | https://github.com/keras-team/keras/blob/e43af...
479 |
480 |
481 | 4
482 | keras-team/keras
483 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
484 | keras/backend.py
485 | python
486 | symbolic_learning_phase
487 | ()
488 | https://github.com/keras-team/keras/blob/e43af...
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 | {% endraw %}
502 |
503 | {% raw %}
504 |
505 |
518 | {% endraw %}
519 |
520 |
521 |
522 |
523 |
--------------------------------------------------------------------------------
/docs/feed.xml:
--------------------------------------------------------------------------------
1 | ---
2 | search: exclude
3 | layout: none
4 | ---
5 |
6 |
7 |
8 |
9 | {{ site.title | xml_escape }}
10 | {{ site.description | xml_escape }}
11 | {{ site.url }}/
12 |
13 | {{ site.time | date_to_rfc822 }}
14 | {{ site.time | date_to_rfc822 }}
15 | Jekyll v{{ jekyll.version }}
16 | {% for post in site.posts limit:10 %}
17 | -
18 |
{{ post.title | xml_escape }}
19 | {{ post.content | xml_escape }}
20 | {{ post.date | date_to_rfc822 }}
21 | {{ post.url | prepend: site.url }}
22 | {{ post.url | prepend: site.url }}
23 | {% for tag in post.tags %}
24 | {{ tag | xml_escape }}
25 | {% endfor %}
26 | {% for tag in page.tags %}
27 | {{ cat | xml_escape }}
28 | {% endfor %}
29 |
30 | {% endfor %}
31 |
32 |
33 |
--------------------------------------------------------------------------------
/docs/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/docs/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/docs/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/docs/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/docs/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/docs/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/docs/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/docs/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/docs/images/colab.svg:
--------------------------------------------------------------------------------
1 |
Open in Colab Open in Colab
2 |
--------------------------------------------------------------------------------
/docs/images/company_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/images/company_logo.png
--------------------------------------------------------------------------------
/docs/images/company_logo_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/images/company_logo_big.png
--------------------------------------------------------------------------------
/docs/images/doc_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/images/doc_example.png
--------------------------------------------------------------------------------
/docs/images/export_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/images/export_example.png
--------------------------------------------------------------------------------
/docs/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/images/favicon.ico
--------------------------------------------------------------------------------
/docs/images/workflowarrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncoop57/function_parser/HEAD/docs/images/workflowarrow.png
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: function_parser
4 |
5 |
6 | keywords: fastai
7 | sidebar: home_sidebar
8 |
9 | summary: "This library contains various utils to parse GitHub repositories into function definition and docstring pairs. It is based on tree-sitter to parse code into ASTs and apply heuristics to parse metadata in more details. Currently, it supports 6 languages: Python, Java, Go, Php, Ruby, and Javascript. It also parses function calls and links them with their definitions for Python."
10 | description: "This library contains various utils to parse GitHub repositories into function definition and docstring pairs. It is based on tree-sitter to parse code into ASTs and apply heuristics to parse metadata in more details. Currently, it supports 6 languages: Python, Java, Go, Php, Ruby, and Javascript. It also parses function calls and links them with their definitions for Python."
11 | nb_path: "nbs/index.ipynb"
12 | ---
13 |
22 |
23 |
24 |
25 | {% raw %}
26 |
27 |
28 |
29 |
30 | {% endraw %}
31 |
32 |
38 |
39 |
40 |
pip install function-parser
41 |
42 |
43 |
44 |
45 |
51 |
52 |
53 |
In order to use the library you must download and build the language grammars for tree-sitter to parser source code with. Included in the library is a handy CLI tool for setting this up.
54 |
To download and build grammars: build_grammars
55 |
This command will download and build the grammars in the same location this python library was installed on your computer after pip installing.
56 |
57 |
58 |
59 |
60 | {% raw %}
61 |
62 |
63 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
114 |
115 |
116 |
117 |
118 | nwo
119 | sha
120 | path
121 | language
122 | identifier
123 | parameters
124 | argument_list
125 | return_statement
126 | docstring
127 | docstring_summary
128 | docstring_tokens
129 | function
130 | function_tokens
131 | url
132 |
133 |
134 |
135 |
136 | 0
137 | keras-team/keras
138 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
139 | keras/backend.py
140 | python
141 | backend
142 | ()
143 |
144 | return 'tensorflow'
145 | Publicly accessible method for determining the...
146 | Publicly accessible method for determining the...
147 | [Publicly, accessible, method, for, determinin...
148 | def backend():\n """Publicly accessible metho...
149 | [def, backend, (, ), :, return, 'tensorflow']
150 | https://github.com/keras-team/keras/blob/e43af...
151 |
152 |
153 | 1
154 | keras-team/keras
155 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
156 | keras/backend.py
157 | python
158 | cast_to_floatx
159 | (x)
160 |
161 | return np.asarray(x, dtype=floatx())
162 | Cast a Numpy array to the default Keras float ...
163 | Cast a Numpy array to the default Keras float ...
164 | [Cast, a, Numpy, array, to, the, default, Kera...
165 | def cast_to_floatx(x):\n """Cast a Numpy arra...
166 | [def, cast_to_floatx, (, x, ), :, if, isinstan...
167 | https://github.com/keras-team/keras/blob/e43af...
168 |
169 |
170 | 2
171 | keras-team/keras
172 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
173 | keras/backend.py
174 | python
175 | get_uid
176 | (prefix='')
177 |
178 | return layer_name_uids[prefix]
179 | Associates a string prefix with an integer cou...
180 | Associates a string prefix with an integer cou...
181 | [Associates, a, string, prefix, with, an, inte...
182 | def get_uid(prefix=''):\n """Associates a str...
183 | [def, get_uid, (, prefix, =, '', ), :, graph, ...
184 | https://github.com/keras-team/keras/blob/e43af...
185 |
186 |
187 | 3
188 | keras-team/keras
189 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
190 | keras/backend.py
191 | python
192 | reset_uids
193 | ()
194 |
195 |
196 | Resets graph identifiers.
197 | Resets graph identifiers.
198 | [Resets, graph, identifiers, .]
199 | def reset_uids():\n """Resets graph identifie...
200 | [def, reset_uids, (, ), :, PER_GRAPH_OBJECT_NA...
201 | https://github.com/keras-team/keras/blob/e43af...
202 |
203 |
204 | 4
205 | keras-team/keras
206 | e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b
207 | keras/backend.py
208 | python
209 | clear_session
210 | ()
211 |
212 |
213 | Resets all state generated by Keras.\n\n Kera...
214 | Resets all state generated by Keras.
215 | [Resets, all, state, generated, by, Keras, .]
216 | def clear_session():\n """Resets all state ge...
217 | [def, clear_session, (, ), :, global, _SESSION...
218 | https://github.com/keras-team/keras/blob/e43af...
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | {% endraw %}
232 |
233 |
234 |
235 |
236 |
--------------------------------------------------------------------------------
/docs/js/customscripts.js:
--------------------------------------------------------------------------------
1 | $('#mysidebar').height($(".nav").height());
2 |
3 |
4 | $( document ).ready(function() {
5 |
6 | //this script says, if the height of the viewport is greater than 800px, then insert affix class, which makes the nav bar float in a fixed
7 | // position as your scroll. if you have a lot of nav items, this height may not work for you.
8 | var h = $(window).height();
9 | //console.log (h);
10 | if (h > 800) {
11 | $( "#mysidebar" ).attr("class", "nav affix");
12 | }
13 | // activate tooltips. although this is a bootstrap js function, it must be activated this way in your theme.
14 | $('[data-toggle="tooltip"]').tooltip({
15 | placement : 'top'
16 | });
17 |
18 | /**
19 | * AnchorJS
20 | */
21 | anchors.add('h2,h3,h4,h5');
22 |
23 | });
24 |
25 | // needed for nav tabs on pages. See Formatting > Nav tabs for more details.
26 | // script from http://stackoverflow.com/questions/10523433/how-do-i-keep-the-current-tab-active-with-twitter-bootstrap-after-a-page-reload
27 | $(function() {
28 | var json, tabsState;
29 | $('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
30 | var href, json, parentId, tabsState;
31 |
32 | tabsState = localStorage.getItem("tabs-state");
33 | json = JSON.parse(tabsState || "{}");
34 | parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id");
35 | href = $(e.target).attr('href');
36 | json[parentId] = href;
37 |
38 | return localStorage.setItem("tabs-state", JSON.stringify(json));
39 | });
40 |
41 | tabsState = localStorage.getItem("tabs-state");
42 | json = JSON.parse(tabsState || "{}");
43 |
44 | $.each(json, function(containerId, href) {
45 | return $("#" + containerId + " a[href=" + href + "]").tab('show');
46 | });
47 |
48 | $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() {
49 | var $this = $(this);
50 | if (!json[$this.attr("id")]) {
51 | return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show");
52 | }
53 | });
54 | });
55 |
--------------------------------------------------------------------------------
/docs/js/jekyll-search.js:
--------------------------------------------------------------------------------
1 | !function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o
=0}var self=this;self.matches=function(string,crit){return"string"!=typeof string?!1:(string=string.trim(),doMatch(string,crit))}}module.exports=new LiteralSearchStrategy},{}],4:[function(require,module){module.exports=function(){function findMatches(store,crit,strategy){for(var data=store.get(),i=0;i{title} ',noResultsText:"No results found",limit:10,fuzzy:!1};self.init=function(_opt){validateOptions(_opt),assignOptions(_opt),isJSON(opt.dataSource)?initWithJSON(opt.dataSource):initWithURL(opt.dataSource)}}var Searcher=require("./Searcher"),Templater=require("./Templater"),Store=require("./Store"),JSONLoader=require("./JSONLoader"),searcher=new Searcher,templater=new Templater,store=new Store,jsonLoader=new JSONLoader;window.SimpleJekyllSearch=new SimpleJekyllSearch}(window,document)},{"./JSONLoader":1,"./Searcher":4,"./Store":5,"./Templater":6}]},{},[7]);
2 |
--------------------------------------------------------------------------------
/docs/js/jquery.ba-throttle-debounce.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery throttle / debounce - v1.1 - 3/7/2010
3 | * http://benalman.com/projects/jquery-throttle-debounce-plugin/
4 | *
5 | * Copyright (c) 2010 "Cowboy" Ben Alman
6 | * Dual licensed under the MIT and GPL licenses.
7 | * http://benalman.com/about/license/
8 | */
9 | (function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);
--------------------------------------------------------------------------------
/docs/js/jquery.navgoco.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Navgoco Menus Plugin v0.2.1 (2014-04-11)
3 | * https://github.com/tefra/navgoco
4 | *
5 | * Copyright (c) 2014 Chris T (@tefra)
6 | * BSD - https://github.com/tefra/navgoco/blob/master/LICENSE-BSD
7 | */
8 | !function(a){"use strict";var b=function(b,c,d){return this.el=b,this.$el=a(b),this.options=c,this.uuid=this.$el.attr("id")?this.$el.attr("id"):d,this.state={},this.init(),this};b.prototype={init:function(){var b=this;b._load(),b.$el.find("ul").each(function(c){var d=a(this);d.attr("data-index",c),b.options.save&&b.state.hasOwnProperty(c)?(d.parent().addClass(b.options.openClass),d.show()):d.parent().hasClass(b.options.openClass)?(d.show(),b.state[c]=1):d.hide()});var c=a(" ").prepend(b.options.caretHtml),d=b.$el.find("li > a");b._trigger(c,!1),b._trigger(d,!0),b.$el.find("li:has(ul) > a").prepend(c)},_trigger:function(b,c){var d=this;b.on("click",function(b){b.stopPropagation();var e=c?a(this).next():a(this).parent().next(),f=!1;if(c){var g=a(this).attr("href");f=void 0===g||""===g||"#"===g}if(e=e.length>0?e:!1,d.options.onClickBefore.call(this,b,e),!c||e&&f)b.preventDefault(),d._toggle(e,e.is(":hidden")),d._save();else if(d.options.accordion){var h=d.state=d._parents(a(this));d.$el.find("ul").filter(":visible").each(function(){var b=a(this),c=b.attr("data-index");h.hasOwnProperty(c)||d._toggle(b,!1)}),d._save()}d.options.onClickAfter.call(this,b,e)})},_toggle:function(b,c){var d=this,e=b.attr("data-index"),f=b.parent();if(d.options.onToggleBefore.call(this,b,c),c){if(f.addClass(d.options.openClass),b.slideDown(d.options.slide),d.state[e]=1,d.options.accordion){var g=d.state=d._parents(b);g[e]=d.state[e]=1,d.$el.find("ul").filter(":visible").each(function(){var b=a(this),c=b.attr("data-index");g.hasOwnProperty(c)||d._toggle(b,!1)})}}else f.removeClass(d.options.openClass),b.slideUp(d.options.slide),d.state[e]=0;d.options.onToggleAfter.call(this,b,c)},_parents:function(b,c){var d={},e=b.parent(),f=e.parents("ul");return f.each(function(){var b=a(this),e=b.attr("data-index");return e?void(d[e]=c?b:1):!1}),d},_save:function(){if(this.options.save){var b={};for(var d in this.state)1===this.state[d]&&(b[d]=1);c[this.uuid]=this.state=b,a.cookie(this.options.cookie.name,JSON.stringify(c),this.options.cookie)}},_load:function(){if(this.options.save){if(null===c){var b=a.cookie(this.options.cookie.name);c=b?JSON.parse(b):{}}this.state=c.hasOwnProperty(this.uuid)?c[this.uuid]:{}}},toggle:function(b){var c=this,d=arguments.length;if(1>=d)c.$el.find("ul").each(function(){var d=a(this);c._toggle(d,b)});else{var e,f={},g=Array.prototype.slice.call(arguments,1);d--;for(var h=0;d>h;h++){e=g[h];var i=c.$el.find('ul[data-index="'+e+'"]').first();if(i&&(f[e]=i,b)){var j=c._parents(i,!0);for(var k in j)f.hasOwnProperty(k)||(f[k]=j[k])}}for(e in f)c._toggle(f[e],b)}c._save()},destroy:function(){a.removeData(this.$el),this.$el.find("li:has(ul) > a").unbind("click"),this.$el.find("li:has(ul) > a > span").unbind("click")}},a.fn.navgoco=function(c){if("string"==typeof c&&"_"!==c.charAt(0)&&"init"!==c)var d=!0,e=Array.prototype.slice.call(arguments,1);else c=a.extend({},a.fn.navgoco.defaults,c||{}),a.cookie||(c.save=!1);return this.each(function(f){var g=a(this),h=g.data("navgoco");h||(h=new b(this,d?a.fn.navgoco.defaults:c,f),g.data("navgoco",h)),d&&h[c].apply(h,e)})};var c=null;a.fn.navgoco.defaults={caretHtml:"",accordion:!1,openClass:"open",save:!0,cookie:{name:"navgoco",expires:!1,path:"/"},slide:{duration:400,easing:"swing"},onClickBefore:a.noop,onClickAfter:a.noop,onToggleBefore:a.noop,onToggleAfter:a.noop}}(jQuery);
--------------------------------------------------------------------------------
/docs/js/toc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/ghiculescu/jekyll-table-of-contents
2 | // this library modified by fastai to:
3 | // - update the location.href with the correct anchor when a toc item is clicked on
4 | (function($){
5 | $.fn.toc = function(options) {
6 | var defaults = {
7 | noBackToTopLinks: false,
8 | title: '',
9 | minimumHeaders: 3,
10 | headers: 'h1, h2, h3, h4',
11 | listType: 'ol', // values: [ol|ul]
12 | showEffect: 'show', // values: [show|slideDown|fadeIn|none]
13 | showSpeed: 'slow' // set to 0 to deactivate effect
14 | },
15 | settings = $.extend(defaults, options);
16 |
17 | var headers = $(settings.headers).filter(function() {
18 | // get all headers with an ID
19 | var previousSiblingName = $(this).prev().attr( "name" );
20 | if (!this.id && previousSiblingName) {
21 | this.id = $(this).attr( "id", previousSiblingName.replace(/\./g, "-") );
22 | }
23 | return this.id;
24 | }), output = $(this);
25 | if (!headers.length || headers.length < settings.minimumHeaders || !output.length) {
26 | return;
27 | }
28 |
29 | if (0 === settings.showSpeed) {
30 | settings.showEffect = 'none';
31 | }
32 |
33 | var render = {
34 | show: function() { output.hide().html(html).show(settings.showSpeed); },
35 | slideDown: function() { output.hide().html(html).slideDown(settings.showSpeed); },
36 | fadeIn: function() { output.hide().html(html).fadeIn(settings.showSpeed); },
37 | none: function() { output.html(html); }
38 | };
39 |
40 | var get_level = function(ele) { return parseInt(ele.nodeName.replace("H", ""), 10); }
41 | var highest_level = headers.map(function(_, ele) { return get_level(ele); }).get().sort()[0];
42 | //var return_to_top = ' ';
43 | // other nice icons that can be used instead: glyphicon-upload glyphicon-hand-up glyphicon-chevron-up glyphicon-menu-up glyphicon-triangle-top
44 | var level = get_level(headers[0]),
45 | this_level,
46 | html = settings.title + " <"+settings.listType+">";
47 | headers.on('click', function() {
48 | if (!settings.noBackToTopLinks) {
49 | var pos = $(window).scrollTop();
50 | window.location.hash = this.id;
51 | $(window).scrollTop(pos);
52 | }
53 | })
54 | .addClass('clickable-header')
55 | .each(function(_, header) {
56 | base_url = window.location.href;
57 | base_url = base_url.replace(/#.*$/, "");
58 | this_level = get_level(header);
59 | //if (!settings.noBackToTopLinks && this_level > 1) {
60 | // $(header).addClass('top-level-header').before(return_to_top);
61 | //}
62 | txt = header.textContent.split('¶')[0].split(/\[(test|source)\]/)[0];
63 | if (!txt) {return;}
64 | if (this_level === level) // same level as before; same indenting
65 | html += "" + txt + " ";
66 | else if (this_level <= level){ // higher level than before; end parent ol
67 | for(i = this_level; i < level; i++) {
68 | html += " "+settings.listType+">"
69 | }
70 | html += "" + txt + " ";
71 | }
72 | else if (this_level > level) { // lower level than before; expand the previous to contain a ol
73 | for(i = this_level; i > level; i--) {
74 | html += "<"+settings.listType+">"+((i-level == 2) ? "" : " ")
75 | }
76 | html += "" + txt + " ";
77 | }
78 | level = this_level; // update for the next one
79 | });
80 | html += ""+settings.listType+">";
81 | if (!settings.noBackToTopLinks) {
82 | $(document).on('click', '.back-to-top', function() {
83 | $(window).scrollTop(0);
84 | window.location.hash = '';
85 | });
86 | }
87 |
88 | render[settings.showEffect]();
89 | };
90 | })(jQuery);
91 |
--------------------------------------------------------------------------------
/docs/licenses/LICENSE:
--------------------------------------------------------------------------------
1 | /* This license pertains to the docs template, except for the Navgoco jQuery component. */
2 |
3 | The MIT License (MIT)
4 |
5 | Original theme: Copyright (c) 2016 Tom Johnson
6 | Modifications: Copyright (c) 2017 onwards fast.ai, Inc
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all
16 | copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | SOFTWARE.
25 |
--------------------------------------------------------------------------------
/docs/licenses/LICENSE-BSD-NAVGOCO.txt:
--------------------------------------------------------------------------------
1 | /* This license pertains to the Navgoco jQuery component used for the sidebar. */
2 |
3 | Copyright (c) 2013, Christodoulos Tsoulloftas, http://www.komposta.net
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without modification,
7 | are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice,
10 | this list of conditions and the following disclaimer.
11 | * Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 | * Neither the name of the nor the names of its
15 | contributors may be used to endorse or promote products derived from this
16 | software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 | OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/docs/sidebar.json:
--------------------------------------------------------------------------------
1 | {
2 | "function_parser": {
3 | "Overview": "/",
4 | "module name here": "core.html",
5 | "Download Grammars:": "build_grammars.html",
6 | "Title": "demo.html"
7 | }
8 | }
--------------------------------------------------------------------------------
/docs/sitemap.xml:
--------------------------------------------------------------------------------
1 | ---
2 | layout: none
3 | search: exclude
4 | ---
5 |
6 |
7 |
8 | {% for post in site.posts %}
9 | {% unless post.search == "exclude" %}
10 |
11 | {{site.url}}{{post.url}}
12 |
13 | {% endunless %}
14 | {% endfor %}
15 |
16 |
17 | {% for page in site.pages %}
18 | {% unless page.search == "exclude" %}
19 |
20 | {{site.url}}{{ page.url}}
21 |
22 | {% endunless %}
23 | {% endfor %}
24 |
--------------------------------------------------------------------------------
/docs/tooltips.json:
--------------------------------------------------------------------------------
1 | ---
2 | layout: null
3 | search: exclude
4 | ---
5 |
6 | {
7 | "entries":
8 | [
9 | {% for page in site.tooltips %}
10 | {
11 | "doc_id": "{{ page.doc_id }}",
12 | "body": "{{ page.content | strip_newlines | replace: '\', '\\\\' | replace: '"', '\\"' }}"
13 | } {% unless forloop.last %},{% endunless %}
14 | {% endfor %}
15 | ]
16 | }
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/function_parser/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = "0.0.4"
--------------------------------------------------------------------------------
/function_parser/_nbdev.py:
--------------------------------------------------------------------------------
1 | # AUTOGENERATED BY NBDEV! DO NOT EDIT!
2 |
3 | __all__ = ["index", "modules", "custom_doc_links", "git_url"]
4 |
5 | index = {}
6 |
7 | modules = []
8 |
9 | doc_url = "https://ncoop57.github.io/function_parser/"
10 |
11 | git_url = "https://github.com/ncoop57/function_parser/tree/main/"
12 |
13 | def custom_doc_links(name): return None
14 |
--------------------------------------------------------------------------------
/function_parser/build_grammars.py:
--------------------------------------------------------------------------------
1 | import function_parser
2 |
3 | from git import Git, Repo
4 | from pathlib import Path
5 | from tree_sitter import Language
6 |
7 | _GRAMMARs = {
8 | "go": ("https://github.com/tree-sitter/tree-sitter-go.git", "tree-sitter-go", "v0.13.3"),
9 | "java": ("https://github.com/tree-sitter/tree-sitter-java.git", "tree-sitter-java", "v0.13.0"),
10 | "javascript": ("https://github.com/tree-sitter/tree-sitter-javascript.git", "tree-sitter-javascript", "v0.13.0"),
11 | "python": ("https://github.com/tree-sitter/tree-sitter-python.git", "tree-sitter-python", "v0.14.0"),
12 | "php": ("https://github.com/tree-sitter/tree-sitter-php.git", "tree-sitter-php", "v0.13.0"),
13 | "ruby": ("https://github.com/tree-sitter/tree-sitter-ruby", "tree-sitter-ruby", "v0.13.0")
14 | }
15 |
16 | def main():
17 | languages = []
18 | for lang, (url, dir, tag) in _GRAMMARs.items():
19 | repo_dir = Path(function_parser.__path__[0])/dir
20 | if not repo_dir.exists():
21 | repo = Repo.clone_from(url, repo_dir)
22 | g = Git(str(repo_dir))
23 | g.checkout(tag)
24 | languages.append(str(repo_dir))
25 |
26 | Language.build_library(
27 | # Store the library in the directory
28 | str(Path(function_parser.__path__[0])/"tree-sitter-languages.so"),
29 | # Include one or more languages
30 | languages
31 | )
32 |
33 | if __name__ == '__main__':
34 | main()
35 |
36 |
--------------------------------------------------------------------------------
/function_parser/fetch_licenses.py:
--------------------------------------------------------------------------------
1 | import glob
2 | from itertools import chain
3 | import os
4 | import pickle
5 | import re
6 |
7 | from dask.distributed import Client
8 | import dask.distributed
9 | from tqdm import tqdm
10 |
11 | from function_parser.language_data import LANGUAGE_METADATA
12 | from function_parser.utils import download
13 |
14 | # Gets notices
15 | LEGAL_FILES_REGEX ='(AUTHORS|NOTICE|LEGAL)(?:\..*)?\Z'
16 |
17 | PREFERRED_EXT_REGEX = '\.[md|markdown|txt|html]\Z'
18 |
19 | # Regex to match any extension except .spdx or .header
20 | OTHER_EXT_REGEX = '\.(?!spdx|header|gemspec)[^./]+\Z'
21 |
22 | # Regex to match, LICENSE, LICENCE, unlicense, etc.
23 | LICENSE_REGEX = '(un)?licen[sc]e'
24 |
25 | # Regex to match COPYING, COPYRIGHT, etc.
26 | COPYING_REGEX = 'copy(ing|right)'
27 |
28 | # Regex to match OFL.
29 | OFL_REGEX = 'ofl'
30 |
31 | # BSD + PATENTS patent file
32 | PATENTS_REGEX = 'patents'
33 |
34 |
35 | def match_license_file(filename):
36 | for regex in [LEGAL_FILES_REGEX,
37 | LICENSE_REGEX + '\Z',
38 | LICENSE_REGEX + PREFERRED_EXT_REGEX,
39 | COPYING_REGEX + '\Z',
40 | COPYING_REGEX + PREFERRED_EXT_REGEX,
41 | LICENSE_REGEX + OTHER_EXT_REGEX,
42 | COPYING_REGEX + OTHER_EXT_REGEX,
43 | LICENSE_REGEX + '[-_]',
44 | COPYING_REGEX + '[-_]',
45 | '[-_]' + LICENSE_REGEX,
46 | '[-_]' + COPYING_REGEX,
47 | OFL_REGEX + PREFERRED_EXT_REGEX,
48 | OFL_REGEX + OTHER_EXT_REGEX,
49 | OFL_REGEX + '\Z',
50 | PATENTS_REGEX + '\Z',
51 | PATENTS_REGEX + OTHER_EXT_REGEX]:
52 | if re.match(regex, filename.lower()):
53 | return filename
54 | return None
55 |
56 | def flattenlist(listoflists):
57 | return list(chain.from_iterable(listoflists))
58 |
59 | def fetch_license(nwo):
60 | licenses = []
61 | tmp_dir = download(nwo)
62 | for f in sorted(glob.glob(tmp_dir.name + '/**/*', recursive=True), key=lambda x: len(x)):
63 | if not os.path.isdir(f):
64 | if match_license_file(f.split('/')[-1]):
65 | licenses.append((nwo, f.replace(tmp_dir.name + '/', ''), open(f, errors='surrogateescape').read()))
66 |
67 | return licenses
68 |
69 |
70 | client = Client()
71 |
72 | for language in LANGUAGE_METADATA.keys():
73 | definitions = pickle.load(open('../data/{}_dedupe_definitions_v2.pkl'.format(language), 'rb'))
74 | nwos = list(set([d['nwo'] for d in definitions]))
75 |
76 | futures = client.map(fetch_license, nwos)
77 | results = []
78 | for r in tqdm(futures):
79 | try:
80 | results.append(r.result(2))
81 | except dask.distributed.TimeoutError:
82 | continue
83 |
84 | flat_results = flattenlist(results)
85 | licenses = dict()
86 | for nwo, path, content in flat_results:
87 | if content:
88 | licenses[nwo] = licenses.get(nwo, []) + [(path, content)]
89 | pickle.dump(licenses, open('../data/{}_licenses.pkl'.format(language), 'wb'))
90 |
--------------------------------------------------------------------------------
/function_parser/language_data.py:
--------------------------------------------------------------------------------
1 | from function_parser.parsers.go_parser import GoParser
2 | from function_parser.parsers.java_parser import JavaParser
3 | from function_parser.parsers.javascript_parser import JavascriptParser
4 | from function_parser.parsers.php_parser import PhpParser
5 | from function_parser.parsers.python_parser import PythonParser
6 | from function_parser.parsers.ruby_parser import RubyParser
7 |
8 |
9 | LANGUAGE_METADATA = {
10 | 'python': {
11 | 'platform': 'pypi',
12 | 'ext': 'py',
13 | 'language_parser': PythonParser
14 | },
15 | 'java': {
16 | 'platform': 'maven',
17 | 'ext': 'java',
18 | 'language_parser': JavaParser
19 | },
20 | 'go': {
21 | 'platform': 'go',
22 | 'ext': 'go',
23 | 'language_parser': GoParser
24 | },
25 | 'javascript': {
26 | 'platform': 'npm',
27 | 'ext': 'js',
28 | 'language_parser': JavascriptParser
29 | },
30 | 'php': {
31 | 'platform': 'packagist',
32 | 'ext': 'php',
33 | 'language_parser': PhpParser
34 | },
35 | 'ruby': {
36 | 'platform': 'rubygems',
37 | 'ext': 'rb',
38 | 'language_parser': RubyParser
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/function_parser/parser_cli.py:
--------------------------------------------------------------------------------
1 | """
2 | Usage:
3 | parser_cli.py [options] INPUT_FILEPATH
4 |
5 | Options:
6 | -h --help
7 | --language LANGUAGE Language
8 | """
9 | import json
10 |
11 | from docopt import docopt
12 | from tree_sitter import Language
13 |
14 | from function_parser.language_data import LANGUAGE_METADATA
15 | from function_parser.process import DataProcessor
16 |
17 | if __name__ == '__main__':
18 | args = docopt(__doc__)
19 |
20 | DataProcessor.PARSER.set_language(Language('/src/build/py-tree-sitter-languages.so', args['--language']))
21 | processor = DataProcessor(language=args['--language'],
22 | language_parser=LANGUAGE_METADATA[args['--language']]['language_parser'])
23 |
24 | functions = processor.process_single_file(args['INPUT_FILEPATH'])
25 | print(json.dumps(functions, indent=2))
26 |
--------------------------------------------------------------------------------
/function_parser/parsers/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/function_parser/parsers/commentutils.py:
--------------------------------------------------------------------------------
1 | def strip_c_style_comment_delimiters(comment: str) -> str:
2 | comment_lines = comment.split('\n')
3 | cleaned_lines = []
4 | for l in comment_lines:
5 | l = l.strip()
6 | if l.endswith('*/'):
7 | l = l[:-2]
8 | if l.startswith('*'):
9 | l = l[1:]
10 | elif l.startswith('/**'):
11 | l = l[3:]
12 | elif l.startswith('//'):
13 | l = l[2:]
14 | cleaned_lines.append(l.strip())
15 | return '\n'.join(cleaned_lines)
16 |
17 |
18 | def get_docstring_summary(docstring: str) -> str:
19 | """Get the first lines of the documentation comment up to the empty lines."""
20 | if '\n\n' in docstring:
21 | return docstring.split('\n\n')[0]
22 | elif '@' in docstring:
23 | return docstring[:docstring.find('@')] # This usually is the start of a JavaDoc-style @param comment.
24 | return docstring
--------------------------------------------------------------------------------
/function_parser/parsers/go_parser.py:
--------------------------------------------------------------------------------
1 | from typing import List, Dict, Any
2 |
3 | from function_parser.parsers.language_parser import LanguageParser, match_from_span, tokenize_code
4 | from function_parser.parsers.commentutils import get_docstring_summary, strip_c_style_comment_delimiters
5 |
6 |
7 | class GoParser(LanguageParser):
8 |
9 | FILTER_PATHS = ('test', 'vendor')
10 |
11 | @staticmethod
12 | def get_definition(tree, blob: str) -> List[Dict[str, Any]]:
13 | definitions = []
14 | comment_buffer = []
15 | for child in tree.root_node.children:
16 | if child.type == 'comment':
17 | comment_buffer.append(child)
18 | elif child.type in ('method_declaration', 'function_declaration'):
19 | docstring = '\n'.join([match_from_span(comment, blob) for comment in comment_buffer])
20 | docstring_summary = strip_c_style_comment_delimiters((get_docstring_summary(docstring)))
21 |
22 | metadata = GoParser.get_function_metadata(child, blob)
23 | definitions.append({
24 | 'type': child.type,
25 | 'identifier': metadata['identifier'],
26 | 'parameters': metadata['parameters'],
27 | 'function': match_from_span(child, blob),
28 | 'function_tokens': tokenize_code(child, blob),
29 | 'docstring': docstring,
30 | 'docstring_summary': docstring_summary,
31 | 'start_point': child.start_point,
32 | 'end_point': child.end_point
33 | })
34 | comment_buffer = []
35 | else:
36 | comment_buffer = []
37 | return definitions
38 |
39 |
40 | @staticmethod
41 | def get_function_metadata(function_node, blob: str) -> Dict[str, str]:
42 | metadata = {
43 | 'identifier': '',
44 | 'parameters': '',
45 | }
46 | if function_node.type == 'function_declaration':
47 | metadata['identifier'] = match_from_span(function_node.children[1], blob)
48 | metadata['parameters'] = match_from_span(function_node.children[2], blob)
49 | elif function_node.type == 'method_declaration':
50 | metadata['identifier'] = match_from_span(function_node.children[2], blob)
51 | metadata['parameters'] = ' '.join([match_from_span(function_node.children[1], blob),
52 | match_from_span(function_node.children[3], blob)])
53 | return metadata
54 |
--------------------------------------------------------------------------------
/function_parser/parsers/java_parser.py:
--------------------------------------------------------------------------------
1 | from typing import List, Dict, Any
2 |
3 | from function_parser.parsers.language_parser import LanguageParser, match_from_span, tokenize_code, traverse_type
4 | from function_parser.parsers.commentutils import strip_c_style_comment_delimiters, get_docstring_summary
5 |
6 |
7 | class JavaParser(LanguageParser):
8 |
9 | FILTER_PATHS = ('test', 'tests')
10 |
11 | BLACKLISTED_FUNCTION_NAMES = {'toString', 'hashCode', 'equals', 'finalize', 'notify', 'notifyAll', 'clone'}
12 |
13 | @staticmethod
14 | def get_definition(tree, blob: str) -> List[Dict[str, Any]]:
15 | classes = (node for node in tree.root_node.children if node.type == 'class_declaration')
16 |
17 | definitions = []
18 | for _class in classes:
19 | class_identifier = match_from_span([child for child in _class.children if child.type == 'identifier'][0], blob).strip()
20 | for child in (child for child in _class.children if child.type == 'class_body'):
21 | for idx, node in enumerate(child.children):
22 | if node.type == 'method_declaration':
23 | if JavaParser.is_method_body_empty(node):
24 | continue
25 | docstring = ''
26 | if idx - 1 >= 0 and child.children[idx-1].type == 'comment':
27 | docstring = match_from_span(child.children[idx - 1], blob)
28 | docstring = strip_c_style_comment_delimiters(docstring)
29 | docstring_summary = get_docstring_summary(docstring)
30 |
31 | metadata = JavaParser.get_function_metadata(node, blob)
32 | if metadata['identifier'] in JavaParser.BLACKLISTED_FUNCTION_NAMES:
33 | continue
34 | definitions.append({
35 | 'type': node.type,
36 | 'identifier': '{}.{}'.format(class_identifier, metadata['identifier']),
37 | 'parameters': metadata['parameters'],
38 | 'function': match_from_span(node, blob),
39 | 'function_tokens': tokenize_code(node, blob),
40 | 'docstring': docstring,
41 | 'docstring_summary': docstring_summary,
42 | 'start_point': node.start_point,
43 | 'end_point': node.end_point
44 | })
45 | return definitions
46 |
47 | @staticmethod
48 | def get_class_metadata(class_node, blob: str) -> Dict[str, str]:
49 | metadata = {
50 | 'identifier': '',
51 | 'argument_list': '',
52 | }
53 | is_header = False
54 | for n in class_node.children:
55 | if is_header:
56 | if n.type == 'identifier':
57 | metadata['identifier'] = match_from_span(n, blob).strip('(:')
58 | elif n.type == 'argument_list':
59 | metadata['argument_list'] = match_from_span(n, blob)
60 | if n.type == 'class':
61 | is_header = True
62 | elif n.type == ':':
63 | break
64 | return metadata
65 |
66 | @staticmethod
67 | def is_method_body_empty(node):
68 | for c in node.children:
69 | if c.type in {'method_body', 'constructor_body'}:
70 | if c.start_point[0] == c.end_point[0]:
71 | return True
72 |
73 | @staticmethod
74 | def get_function_metadata(function_node, blob: str) -> Dict[str, str]:
75 | metadata = {
76 | 'identifier': '',
77 | 'parameters': '',
78 | }
79 |
80 | declarators = []
81 | traverse_type(function_node, declarators, '{}_declaration'.format(function_node.type.split('_')[0]))
82 | parameters = []
83 | for n in declarators[0].children:
84 | if n.type == 'identifier':
85 | metadata['identifier'] = match_from_span(n, blob).strip('(')
86 | elif n.type == 'formal_parameter':
87 | parameters.append(match_from_span(n, blob))
88 | metadata['parameters'] = ' '.join(parameters)
89 | return metadata
90 |
--------------------------------------------------------------------------------
/function_parser/parsers/javascript_parser.py:
--------------------------------------------------------------------------------
1 | from typing import List, Dict, Any
2 |
3 | from function_parser.parsers.language_parser import LanguageParser, match_from_span, tokenize_code, traverse_type, previous_sibling, \
4 | node_parent
5 | from function_parser.parsers.commentutils import get_docstring_summary, strip_c_style_comment_delimiters
6 |
7 |
8 | class JavascriptParser(LanguageParser):
9 |
10 | FILTER_PATHS = ('test', 'node_modules')
11 |
12 | BLACKLISTED_FUNCTION_NAMES = {'toString', 'toLocaleString', 'valueOf'}
13 |
14 | @staticmethod
15 | def get_docstring(tree, node, blob: str) -> str:
16 | docstring = ''
17 | parent_node = node_parent(tree, node)
18 |
19 | if parent_node.type == 'variable_declarator':
20 | base_node = node_parent(tree, parent_node) # Get the variable declaration
21 | elif parent_node.type == 'pair':
22 | base_node = parent_node # This is a common pattern where a function is assigned as a value to a dictionary.
23 | else:
24 | base_node = node
25 |
26 | prev_sibling = previous_sibling(tree, base_node)
27 | if prev_sibling is not None and prev_sibling.type == 'comment':
28 | all_prev_comment_nodes = [prev_sibling]
29 | prev_sibling = previous_sibling(tree, prev_sibling)
30 | while prev_sibling is not None and prev_sibling.type == 'comment':
31 | all_prev_comment_nodes.append(prev_sibling)
32 | last_comment_start_line = prev_sibling.start_point[0]
33 | prev_sibling = previous_sibling(tree, prev_sibling)
34 | if prev_sibling.end_point[0] + 1 < last_comment_start_line:
35 | break # if there is an empty line, stop expanding.
36 |
37 | docstring = ' '.join((strip_c_style_comment_delimiters(match_from_span(s, blob)) for s in all_prev_comment_nodes[::-1]))
38 | return docstring
39 |
40 | @staticmethod
41 | def get_definition(tree, blob: str) -> List[Dict[str, Any]]:
42 | function_nodes = []
43 | functions = []
44 | traverse_type(tree.root_node, function_nodes, 'function')
45 | for function in function_nodes:
46 | if function.children is None or len(function.children) == 0:
47 | continue
48 | parent_node = node_parent(tree, function)
49 | functions.append((parent_node.type, function, JavascriptParser.get_docstring(tree, function, blob)))
50 |
51 | definitions = []
52 | for node_type, function_node, docstring in functions:
53 | metadata = JavascriptParser.get_function_metadata(function_node, blob)
54 | docstring_summary = get_docstring_summary(docstring)
55 |
56 | if metadata['identifier'] in JavascriptParser.BLACKLISTED_FUNCTION_NAMES:
57 | continue
58 | definitions.append({
59 | 'type': node_type,
60 | 'identifier': metadata['identifier'],
61 | 'parameters': metadata['parameters'],
62 | 'function': match_from_span(function_node, blob),
63 | 'function_tokens': tokenize_code(function_node, blob),
64 | 'docstring': docstring,
65 | 'docstring_summary': docstring_summary,
66 | 'start_point': function_node.start_point,
67 | 'end_point': function_node.end_point
68 | })
69 | return definitions
70 |
71 |
72 | @staticmethod
73 | def get_function_metadata(function_node, blob: str) -> Dict[str, str]:
74 | metadata = {
75 | 'identifier': '',
76 | 'parameters': '',
77 | }
78 | identifier_nodes = [child for child in function_node.children if child.type == 'identifier']
79 | formal_parameters_nodes = [child for child in function_node.children if child.type == 'formal_parameters']
80 | if identifier_nodes:
81 | metadata['identifier'] = match_from_span(identifier_nodes[0], blob)
82 | if formal_parameters_nodes:
83 | metadata['parameters'] = match_from_span(formal_parameters_nodes[0], blob)
84 | return metadata
85 |
--------------------------------------------------------------------------------
/function_parser/parsers/language_parser.py:
--------------------------------------------------------------------------------
1 | import re
2 | from abc import ABC, abstractmethod
3 | from typing import List, Dict, Any, Set, Optional
4 |
5 | DOCSTRING_REGEX_TOKENIZER = re.compile(r"[^\s,'\"`.():\[\]=*;>{\}+-/\\]+|\\+|\.+|\(\)|{\}|\[\]|\(+|\)+|:+|\[+|\]+|{+|\}+|=+|\*+|;+|>+|\++|-+|/+")
6 |
7 |
8 | def tokenize_docstring(docstring: str) -> List[str]:
9 | return [t for t in DOCSTRING_REGEX_TOKENIZER.findall(docstring) if t is not None and len(t) > 0]
10 |
11 |
12 | def tokenize_code(node, blob: str, nodes_to_exclude: Optional[Set]=None) -> List:
13 | tokens = []
14 | traverse(node, tokens)
15 | return [match_from_span(token, blob) for token in tokens if nodes_to_exclude is None or token not in nodes_to_exclude]
16 |
17 |
18 | def traverse(node, results: List) -> None:
19 | if node.type == 'string':
20 | results.append(node)
21 | return
22 | for n in node.children:
23 | traverse(n, results)
24 | if not node.children:
25 | results.append(node)
26 |
27 | def nodes_are_equal(n1, n2):
28 | return n1.type == n2.type and n1.start_point == n2.start_point and n1.end_point == n2.end_point
29 |
30 | def previous_sibling(tree, node):
31 | """
32 | Search for the previous sibling of the node.
33 |
34 | TODO: C TreeSitter should support this natively, but not its Python bindings yet. Replace later.
35 | """
36 | to_visit = [tree.root_node]
37 | while len(to_visit) > 0:
38 | next_node = to_visit.pop()
39 | for i, node_at_i in enumerate(next_node.children):
40 | if nodes_are_equal(node, node_at_i):
41 | if i > 0:
42 | return next_node.children[i-1]
43 | return None
44 | else:
45 | to_visit.extend(next_node.children)
46 | return ValueError("Could not find node in tree.")
47 |
48 |
49 | def node_parent(tree, node):
50 | to_visit = [tree.root_node]
51 | while len(to_visit) > 0:
52 | next_node = to_visit.pop()
53 | for child in next_node.children:
54 | if nodes_are_equal(child, node):
55 | return next_node
56 | else:
57 | to_visit.extend(next_node.children)
58 | raise ValueError("Could not find node in tree.")
59 |
60 |
61 | def match_from_span(node, blob: str) -> str:
62 | lines = blob.split('\n')
63 | line_start = node.start_point[0]
64 | line_end = node.end_point[0]
65 | char_start = node.start_point[1]
66 | char_end = node.end_point[1]
67 | if line_start != line_end:
68 | return '\n'.join([lines[line_start][char_start:]] + lines[line_start+1:line_end] + [lines[line_end][:char_end]])
69 | else:
70 | return lines[line_start][char_start:char_end]
71 |
72 |
73 | def traverse_type(node, results: List, kind: str) -> None:
74 | if node.type == kind:
75 | results.append(node)
76 | if not node.children:
77 | return
78 | for n in node.children:
79 | traverse_type(n, results, kind)
80 |
81 |
82 | class LanguageParser(ABC):
83 | @staticmethod
84 | @abstractmethod
85 | def get_definition(tree, blob: str) -> List[Dict[str, Any]]:
86 | pass
87 |
88 | @staticmethod
89 | @abstractmethod
90 | def get_class_metadata(class_node, blob):
91 | pass
92 |
93 | @staticmethod
94 | @abstractmethod
95 | def get_function_metadata(function_node, blob) -> Dict[str, str]:
96 | pass
97 |
98 | @staticmethod
99 | @abstractmethod
100 | def get_context(tree, blob):
101 | raise NotImplementedError
102 |
103 | @staticmethod
104 | @abstractmethod
105 | def get_calls(tree, blob):
106 | raise NotImplementedError
107 |
--------------------------------------------------------------------------------
/function_parser/parsers/php_parser.py:
--------------------------------------------------------------------------------
1 | from typing import List, Dict, Any
2 |
3 | from function_parser.parsers.language_parser import LanguageParser, match_from_span, tokenize_code, traverse_type
4 | from function_parser.parsers.commentutils import strip_c_style_comment_delimiters, get_docstring_summary
5 |
6 |
7 | class PhpParser(LanguageParser):
8 |
9 | FILTER_PATHS = ('test', 'tests')
10 |
11 | BLACKLISTED_FUNCTION_NAMES = {'__construct', '__destruct', '__call', '__callStatic',
12 | '__get', '__set', '__isset', '__unset',
13 | '__sleep', '__wakeup', '__toString', '__invoke',
14 | '__set_state', '__clone', '__debugInfo', '__serialize',
15 | '__unserialize'}
16 |
17 | @staticmethod
18 | def get_docstring(trait_node, blob: str, idx: int) -> str:
19 | docstring = ''
20 | if idx - 1 >= 0 and trait_node.children[idx-1].type == 'comment':
21 | docstring = match_from_span(trait_node.children[idx-1], blob)
22 | docstring = strip_c_style_comment_delimiters(docstring)
23 | return docstring
24 |
25 |
26 | @staticmethod
27 | def get_declarations(declaration_node, blob: str, node_type: str) -> List[Dict[str, Any]]:
28 | declarations = []
29 | for idx, child in enumerate(declaration_node.children):
30 | if child.type == 'name':
31 | declaration_name = match_from_span(child, blob)
32 | elif child.type == 'method_declaration':
33 | docstring = PhpParser.get_docstring(declaration_node, blob, idx)
34 | docstring_summary = get_docstring_summary(docstring)
35 | function_nodes = []
36 | traverse_type(child, function_nodes, 'function_definition')
37 | if function_nodes:
38 | function_node = function_nodes[0]
39 | metadata = PhpParser.get_function_metadata(function_node, blob)
40 |
41 | if metadata['identifier'] in PhpParser.BLACKLISTED_FUNCTION_NAMES:
42 | continue
43 |
44 | declarations.append({
45 | 'type': node_type,
46 | 'identifier': '{}.{}'.format(declaration_name, metadata['identifier']),
47 | 'parameters': metadata['parameters'],
48 | 'function': match_from_span(child, blob),
49 | 'function_tokens': tokenize_code(child, blob),
50 | 'docstring': docstring,
51 | 'docstring_summary': docstring_summary,
52 | 'start_point': function_node.start_point,
53 | 'end_point': function_node.end_point
54 | })
55 | return declarations
56 |
57 |
58 | @staticmethod
59 | def get_definition(tree, blob: str) -> List[Dict[str, Any]]:
60 | trait_declarations = [child for child in tree.root_node.children if child.type == 'trait_declaration']
61 | class_declarations = [child for child in tree.root_node.children if child.type == 'class_declaration']
62 | definitions = []
63 | for trait_declaration in trait_declarations:
64 | definitions.extend(PhpParser.get_declarations(trait_declaration, blob, trait_declaration.type))
65 | for class_declaration in class_declarations:
66 | definitions.extend(PhpParser.get_declarations(class_declaration, blob, class_declaration.type))
67 | return definitions
68 |
69 |
70 | @staticmethod
71 | def get_function_metadata(function_node, blob: str) -> Dict[str, str]:
72 | metadata = {
73 | 'identifier': '',
74 | 'parameters': '',
75 | }
76 | metadata['identifier'] = match_from_span(function_node.children[1], blob)
77 | metadata['parameters'] = match_from_span(function_node.children[2], blob)
78 | return metadata
79 |
--------------------------------------------------------------------------------
/function_parser/parsers/python_parser.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, Iterable, Optional, Iterator, Any, List
2 |
3 | from function_parser.parsers.language_parser import LanguageParser, match_from_span, tokenize_code, traverse_type
4 | from function_parser.parsers.commentutils import get_docstring_summary
5 |
6 |
7 | class PythonParser(LanguageParser):
8 |
9 | FILTER_PATHS = ('test',)
10 | STOPWORDS = ()
11 |
12 | # Get function calls
13 | @staticmethod
14 | def get_context(tree, blob):
15 | def _get_import_from(import_from_statement, blob):
16 | context = {}
17 | mode = 'from'
18 | library = ''
19 | for n in import_from_statement.children:
20 | if n.type == 'from':
21 | mode = 'from'
22 | elif n.type == 'import':
23 | mode = 'import'
24 | elif n.type == 'dotted_name':
25 | if mode == 'from':
26 | library = match_from_span(n, blob).strip()
27 | elif mode == 'import':
28 | if library:
29 | context[match_from_span(n, blob).strip().strip(',')] = library
30 | return context
31 |
32 | def _get_import(import_statement, blob):
33 | context = []
34 | for n in import_statement.children:
35 | if n.type == 'dotted_name':
36 | context.append(match_from_span(n, blob).strip())
37 | if n.type == 'aliased_import':
38 | for a in n.children:
39 | if a.type == 'dotted_name':
40 | context.append(match_from_span(a, blob).strip())
41 | return context
42 |
43 | import_from_statements = []
44 | traverse_type(tree.root_node, import_from_statements, 'import_from_statement')
45 |
46 | import_statements = []
47 | traverse_type(tree.root_node, import_statements, 'import_statement')
48 |
49 | context = []
50 | context.extend((_get_import_from(i, blob) for i in import_from_statements))
51 | context.extend((_get_import(i, blob) for i in import_statements))
52 | return context
53 |
54 | @staticmethod
55 | def get_calls(tree, blob):
56 | calls = []
57 | traverse_type(tree.root_node, calls, 'call')
58 |
59 | def _traverse_calls(node, identifiers):
60 | if node.type == 'identifier':
61 | identifiers.append(node)
62 | if not node.children or node.type == 'argument_list':
63 | return
64 | for n in node.children:
65 | _traverse_calls(n, identifiers)
66 |
67 | results = []
68 | for call in calls:
69 | identifiers = []
70 | _traverse_calls(call, identifiers)
71 |
72 | if identifiers:
73 | identifier = identifiers[-1]
74 | argument_lists = [n for n in call.children if n.type == 'argument_list']
75 | argument_list = ''
76 | if argument_lists:
77 | argument_list = match_from_span(argument_lists[-1], blob)
78 | results.append({
79 | 'identifier': match_from_span(identifier, blob),
80 | 'argument_list': argument_list,
81 | 'start_point': identifier.start_point,
82 | 'end_point': identifier.end_point,
83 | })
84 | return results
85 |
86 | @staticmethod
87 | def __get_docstring_node(function_node):
88 | docstring_node = [node for node in function_node.children if
89 | node.type == 'expression_statement' and node.children[0].type == 'string']
90 | if len(docstring_node) > 0:
91 | return docstring_node[0].children[0]
92 | return None
93 |
94 | @staticmethod
95 | def get_docstring(docstring_node, blob: str) -> str:
96 | docstring = ''
97 | if docstring_node is not None:
98 | docstring = match_from_span(docstring_node, blob)
99 | docstring = docstring.strip().strip('"').strip("'")
100 | return docstring
101 |
102 | @staticmethod
103 | def get_function_metadata(function_node, blob: str) -> Dict[str, str]:
104 | metadata = {
105 | 'identifier': '',
106 | 'parameters': '',
107 | 'return_statement': ''
108 | }
109 | is_header = False
110 | for child in function_node.children:
111 | if is_header:
112 | if child.type == 'identifier':
113 | metadata['identifier'] = match_from_span(child, blob)
114 | elif child.type == 'parameters':
115 | metadata['parameters'] = match_from_span(child, blob)
116 | if child.type == 'def':
117 | is_header = True
118 | elif child.type == ':':
119 | is_header = False
120 | elif child.type == 'return_statement':
121 | metadata['return_statement'] = match_from_span(child, blob)
122 | return metadata
123 |
124 | @staticmethod
125 | def get_class_metadata(class_node, blob: str) -> Dict[str, str]:
126 | metadata = {
127 | 'identifier': '',
128 | 'argument_list': '',
129 | }
130 | is_header = False
131 | for child in class_node.children:
132 | if is_header:
133 | if child.type == 'identifier':
134 | metadata['identifier'] = match_from_span(child, blob)
135 | elif child.type == 'argument_list':
136 | metadata['argument_list'] = match_from_span(child, blob)
137 | if child.type == 'class':
138 | is_header = True
139 | elif child.type == ':':
140 | break
141 | return metadata
142 |
143 | @staticmethod
144 | def is_function_empty(function_node) -> bool:
145 | seen_header_end = False
146 | for child in function_node.children:
147 | if seen_header_end and (child.type=='pass_statement' or child.type=='raise_statement'):
148 | return True
149 | elif seen_header_end:
150 | return False
151 |
152 | if child.type == ':':
153 | seen_header_end = True
154 | return False
155 |
156 | @staticmethod
157 | def __process_functions(functions: Iterable, blob: str, func_identifier_scope: Optional[str]=None) -> Iterator[Dict[str, Any]]:
158 | for function_node in functions:
159 | if PythonParser.is_function_empty(function_node):
160 | continue
161 | function_metadata = PythonParser.get_function_metadata(function_node, blob)
162 | if func_identifier_scope is not None:
163 | function_metadata['identifier'] = '{}.{}'.format(func_identifier_scope,
164 | function_metadata['identifier'])
165 | if function_metadata['identifier'].startswith('__') and function_metadata['identifier'].endswith('__'):
166 | continue # Blacklist built-in functions
167 | docstring_node = PythonParser.__get_docstring_node(function_node)
168 | function_metadata['docstring'] = PythonParser.get_docstring(docstring_node, blob)
169 | function_metadata['docstring_summary'] = get_docstring_summary(function_metadata['docstring'])
170 | function_metadata['function'] = match_from_span(function_node, blob)
171 | function_metadata['function_tokens'] = tokenize_code(function_node, blob, {docstring_node})
172 | function_metadata['start_point'] = function_node.start_point
173 | function_metadata['end_point'] = function_node.end_point
174 |
175 | yield function_metadata
176 |
177 | @staticmethod
178 | def get_function_definitions(node):
179 | for child in node.children:
180 | if child.type == 'function_definition':
181 | yield child
182 | elif child.type == 'decorated_definition':
183 | for c in child.children:
184 | if c.type == 'function_definition':
185 | yield c
186 |
187 | @staticmethod
188 | def get_definition(tree, blob: str) -> List[Dict[str, Any]]:
189 | functions = PythonParser.get_function_definitions(tree.root_node)
190 | classes = (node for node in tree.root_node.children if node.type == 'class_definition')
191 |
192 | definitions = list(PythonParser.__process_functions(functions, blob))
193 |
194 | for _class in classes:
195 | class_metadata = PythonParser.get_class_metadata(_class, blob)
196 | docstring_node = PythonParser.__get_docstring_node(_class)
197 | class_metadata['docstring'] = PythonParser.get_docstring(docstring_node, blob)
198 | class_metadata['docstring_summary'] = get_docstring_summary(class_metadata['docstring'])
199 | class_metadata['function'] = ''
200 | class_metadata['function_tokens'] = []
201 | class_metadata['start_point'] = _class.start_point
202 | class_metadata['end_point'] = _class.end_point
203 | definitions.append(class_metadata)
204 |
205 | functions = PythonParser.get_function_definitions(_class)
206 | definitions.extend(PythonParser.__process_functions(functions, blob, class_metadata['identifier']))
207 |
208 | return definitions
209 |
--------------------------------------------------------------------------------
/function_parser/parsers/ruby_parser.py:
--------------------------------------------------------------------------------
1 | from typing import List, Dict, Any
2 |
3 | from function_parser.parsers.language_parser import LanguageParser, match_from_span, tokenize_code
4 | from function_parser.parsers.commentutils import get_docstring_summary
5 |
6 |
7 | class RubyParser(LanguageParser):
8 |
9 | FILTER_PATHS = ('test', 'vendor')
10 |
11 | BLACKLISTED_FUNCTION_NAMES = {'initialize', 'to_text', 'display', 'dup', 'clone', 'equal?', '==', '<=>',
12 | '===', '<=', '<', '>', '>=', 'between?', 'eql?', 'hash'}
13 |
14 | @staticmethod
15 | def get_docstring(trait_node, blob: str, idx: int) -> str:
16 | raise NotImplementedError("Not used for Ruby.")
17 |
18 |
19 | @staticmethod
20 | def get_methods(module_or_class_node, blob: str, module_name: str, node_type: str) -> List[Dict[str, Any]]:
21 | definitions = []
22 | comment_buffer = []
23 | module_or_class_name = match_from_span(module_or_class_node.children[1], blob)
24 | for child in module_or_class_node.children:
25 | if child.type == 'comment':
26 | comment_buffer.append(child)
27 | elif child.type == 'method':
28 | docstring = '\n'.join([match_from_span(comment, blob).strip().strip('#') for comment in comment_buffer])
29 | docstring_summary = get_docstring_summary(docstring)
30 |
31 | metadata = RubyParser.get_function_metadata(child, blob)
32 | if metadata['identifier'] in RubyParser.BLACKLISTED_FUNCTION_NAMES:
33 | continue
34 | definitions.append({
35 | 'type': 'class',
36 | 'identifier': '{}.{}.{}'.format(module_name, module_or_class_name, metadata['identifier']),
37 | 'parameters': metadata['parameters'],
38 | 'function': match_from_span(child, blob),
39 | 'function_tokens': tokenize_code(child, blob),
40 | 'docstring': docstring,
41 | 'docstring_summary': docstring_summary,
42 | 'start_point': child.start_point,
43 | 'end_point': child.end_point
44 | })
45 | comment_buffer = []
46 | else:
47 | comment_buffer = []
48 | return definitions
49 |
50 |
51 | @staticmethod
52 | def get_definition(tree, blob: str) -> List[Dict[str, Any]]:
53 | definitions = []
54 | if 'ERROR' not in set([child.type for child in tree.root_node.children]):
55 | modules = [child for child in tree.root_node.children if child.type == 'module']
56 | for module in modules:
57 | if module.children:
58 | module_name = match_from_span(module.children[1], blob)
59 | sub_modules = [child for child in module.children if child.type == 'module' and child.children]
60 | classes = [child for child in module.children if child.type == 'class']
61 | for sub_module_node in sub_modules:
62 | definitions.extend(RubyParser.get_methods(sub_module_node, blob, module_name, sub_module_node.type))
63 | for class_node in classes:
64 | definitions.extend(RubyParser.get_methods(class_node, blob, module_name, class_node.type))
65 | return definitions
66 |
67 |
68 | @staticmethod
69 | def get_function_metadata(function_node, blob: str) -> Dict[str, str]:
70 | metadata = {
71 | 'identifier': '',
72 | 'parameters': '',
73 | }
74 | metadata['identifier'] = match_from_span(function_node.children[1], blob)
75 | if function_node.children[2].type == 'method_parameters':
76 | metadata['parameters'] = match_from_span(function_node.children[2], blob)
77 | return metadata
78 |
--------------------------------------------------------------------------------
/function_parser/process.py:
--------------------------------------------------------------------------------
1 | """
2 | Usage:
3 | process.py [options] INPUT_DIR OUTPUT_DIR
4 |
5 | Options:
6 | -h --help
7 | --language LANGUAGE Language
8 | --processes PROCESSES # of processes to use [default: 16]
9 | --license-filter FILE License metadata to filter, every row contains [nwo, license, language, score] (e.g. ['pandas-dev/pandas', 'bsd-3-clause', 'Python', 0.9997])
10 | --tree-sitter-build FILE [default: /src/build/py-tree-sitter-languages.so]
11 | """
12 | import functools
13 | from multiprocessing import Pool
14 | import pickle
15 | from os import PathLike
16 | from typing import Optional, Tuple, Type, List, Dict, Any
17 |
18 | from docopt import docopt
19 | from dpu_utils.codeutils.deduplication import DuplicateDetector
20 | import pandas as pd
21 | from tree_sitter import Language, Parser
22 |
23 | from function_parser.language_data import LANGUAGE_METADATA
24 | from function_parser.parsers.language_parser import LanguageParser, tokenize_docstring
25 | from function_parser.utils import download, get_sha, flatten, remap_nwo, walk
26 |
27 | class DataProcessor:
28 |
29 | PARSER = Parser()
30 |
31 | def __init__(self, language: str, language_parser: Type[LanguageParser]):
32 | self.language = language
33 | self.language_parser = language_parser
34 |
35 | def process_dee(self, nwo, ext) -> List[Dict[str, Any]]:
36 | # Process dependees (libraries) to get function implementations
37 | indexes = []
38 | _, nwo = remap_nwo(nwo)
39 | if nwo is None:
40 | return indexes
41 |
42 | tmp_dir = download(nwo)
43 | files = walk(tmp_dir, ext)
44 | # files = glob.iglob(tmp_dir.name + '/**/*.{}'.format(ext), recursive=True)
45 | sha = None
46 |
47 | for f in files:
48 | definitions = self.get_function_definitions(f)
49 | if definitions is None:
50 | continue
51 | if sha is None:
52 | sha = get_sha(tmp_dir, nwo)
53 |
54 | nwo, path, functions = definitions
55 | indexes.extend((self.extract_function_data(func, nwo, path, sha) for func in functions if len(func['function_tokens']) > 1))
56 | return indexes
57 |
58 | def process_dent(self, nwo, ext, library_candidates) -> Tuple[List[Dict[str, Any]], List[Tuple[str, str]]]:
59 | # Process dependents (applications) to get function calls
60 | dents = []
61 | edges = []
62 | _, nwo = remap_nwo(nwo)
63 | if nwo is None:
64 | return dents, edges
65 |
66 | tmp_dir = download(nwo)
67 | files = walk(tmp_dir, ext)
68 | sha = None
69 |
70 | for f in files:
71 | context_and_calls = self.get_context_and_function_calls(f)
72 | if context_and_calls is None:
73 | continue
74 | if sha is None:
75 | sha = get_sha(tmp_dir, nwo)
76 |
77 | nwo, path, context, calls = context_and_calls
78 | libraries = []
79 | for cxt in context:
80 | if type(cxt) == dict:
81 | libraries.extend([v.split('.')[0] for v in cxt.values()])
82 | elif type(cxt) == list:
83 | libraries.extend(cxt)
84 |
85 | match_scopes = {}
86 | for cxt in set(libraries):
87 | if cxt in library_candidates:
88 | match_scopes[cxt] = library_candidates[cxt]
89 |
90 | for call in calls:
91 | for depended_library_name, dependend_library_functions in match_scopes.items():
92 | for depended_library_function in dependend_library_functions:
93 | # Other potential filters: len(call['identifier']) > 6 or len(call['identifier'].split('_')) > 1
94 | if (call['identifier'] not in self.language_parser.STOPWORDS and
95 | ((depended_library_function['identifier'].split('.')[-1] == '__init__' and
96 | call['identifier'] == depended_library_function['identifier'].split('.')[0]) or
97 | ((len(call['identifier']) > 9 or
98 | (not call['identifier'].startswith('_') and len(call['identifier'].split('_')) > 1)) and
99 | call['identifier'] == depended_library_function['identifier'])
100 | )):
101 | dent = {
102 | 'nwo': nwo,
103 | 'sha': sha,
104 | 'path': path,
105 | 'language': self.language,
106 | 'identifier': call['identifier'],
107 | 'argument_list': call['argument_list'],
108 | 'url': 'https://github.com/{}/blob/{}/{}#L{}-L{}'.format(nwo, sha, path,
109 | call['start_point'][0] + 1,
110 | call['end_point'][0] + 1)
111 | }
112 | dents.append(dent)
113 | edges.append((dent['url'], depended_library_function['url']))
114 | return dents, edges
115 |
116 | def process_single_file(self, filepath: PathLike) -> List[Dict[str, Any]]:
117 | definitions = self.get_function_definitions(filepath)
118 | if definitions is None:
119 | return []
120 | _, _, functions = definitions
121 |
122 | return [self.extract_function_data(func, '', '', '') for func in functions if len(func['function_tokens']) > 1]
123 |
124 | def extract_function_data(self, function: Dict[str, Any], nwo, path: str, sha: str):
125 | return {
126 | 'nwo': nwo,
127 | 'sha': sha,
128 | 'path': path,
129 | 'language': self.language,
130 | 'identifier': function['identifier'],
131 | 'parameters': function.get('parameters', ''),
132 | 'argument_list': function.get('argument_list', ''),
133 | 'return_statement': function.get('return_statement', ''),
134 | 'docstring': function['docstring'].strip(),
135 | 'docstring_summary': function['docstring_summary'].strip(),
136 | 'docstring_tokens': tokenize_docstring(function['docstring_summary']),
137 | 'function': function['function'].strip(),
138 | 'function_tokens': function['function_tokens'],
139 | 'url': 'https://github.com/{}/blob/{}/{}#L{}-L{}'.format(nwo, sha, path, function['start_point'][0] + 1,
140 | function['end_point'][0] + 1)
141 | }
142 |
143 | def get_context_and_function_calls(self, filepath: str) -> Optional[Tuple[str, str, List, List]]:
144 | nwo = '/'.join(filepath.split('/')[3:5])
145 | path = '/'.join(filepath.split('/')[5:])
146 | if any(fp in path.lower() for fp in self.language_parser.FILTER_PATHS):
147 | return None
148 | try:
149 | with open(filepath) as source_code:
150 | blob = source_code.read()
151 | tree = DataProcessor.PARSER.parse(blob.encode())
152 | return (nwo, path, self.language_parser.get_context(tree, blob), self.language_parser.get_calls(tree, blob))
153 | except (UnicodeDecodeError, FileNotFoundError, IsADirectoryError, ValueError, OSError):
154 | return None
155 |
156 | def get_function_definitions(self, filepath: str) -> Optional[Tuple[str, str, List]]:
157 | nwo = '/'.join(filepath.split('/')[3:5])
158 | path = '/'.join(filepath.split('/')[5:])
159 | if any(fp in path.lower() for fp in self.language_parser.FILTER_PATHS):
160 | return None
161 | try:
162 | with open(filepath) as source_code:
163 | blob = source_code.read()
164 | tree = DataProcessor.PARSER.parse(blob.encode())
165 | return (nwo, path, self.language_parser.get_definition(tree, blob))
166 | except (UnicodeDecodeError, FileNotFoundError, IsADirectoryError, ValueError, OSError):
167 | return None
168 |
169 |
170 | if __name__ == '__main__':
171 | args = docopt(__doc__)
172 |
173 | repository_dependencies = pd.read_csv(args['INPUT_DIR'] + 'repository_dependencies-1.4.0-2018-12-22.csv', index_col=False)
174 | projects = pd.read_csv(args['INPUT_DIR'] + 'projects_with_repository_fields-1.4.0-2018-12-22.csv', index_col=False)
175 |
176 | repository_dependencies['Manifest Platform'] = repository_dependencies['Manifest Platform'].apply(lambda x: x.lower())
177 | id_to_nwo = {project['ID']: project['Repository Name with Owner'] for project in projects[['ID', 'Repository Name with Owner']].dropna().to_dict(orient='records')}
178 | nwo_to_name = {project['Repository Name with Owner']: project['Name'] for project in projects[['Repository Name with Owner', 'Name']].dropna().to_dict(orient='records')}
179 |
180 | filtered = repository_dependencies[(repository_dependencies['Host Type'] == 'GitHub') & (repository_dependencies['Manifest Platform'] == LANGUAGE_METADATA[args['--language']]['platform'])][['Repository Name with Owner', 'Dependency Project ID']].dropna().to_dict(orient='records')
181 |
182 | dependency_pairs = [(rd['Repository Name with Owner'], id_to_nwo[int(rd['Dependency Project ID'])])
183 | for rd in filtered if int(rd['Dependency Project ID']) in id_to_nwo]
184 |
185 | dependency_pairs = list(set(dependency_pairs))
186 |
187 | dents, dees = zip(*dependency_pairs)
188 | # dents = list(set(dents))
189 | dees = list(set(dees))
190 |
191 | DataProcessor.PARSER.set_language(Language(args['--tree-sitter-build'], args['--language']))
192 |
193 | processor = DataProcessor(language=args['--language'],
194 | language_parser=LANGUAGE_METADATA[args['--language']]['language_parser'])
195 |
196 | with Pool(processes=int(args['--processes'])) as pool:
197 | output = pool.imap_unordered(functools.partial(processor.process_dee,
198 | ext=LANGUAGE_METADATA[args['--language']]['ext']),
199 | dees)
200 |
201 | definitions = list(flatten(output))
202 | with open(args['OUTPUT_DIR'] + '{}_definitions.pkl'.format(args['--language']), 'wb') as f:
203 | pickle.dump(definitions, f)
204 |
205 | license_filter_file = args.get('--license-filter')
206 | if license_filter_file is not None:
207 | with open(license_filter_file, 'rb') as f:
208 | license_filter = pickle.load(f)
209 | valid_nwos = dict([(l[0], l[3]) for l in license_filter])
210 |
211 | # Sort function definitions with repository popularity
212 | definitions = [dict(list(d.items()) + [('score', valid_nwos[d['nwo']])]) for d in definitions if d['nwo'] in valid_nwos]
213 | definitions = sorted(definitions, key=lambda x: -x['score'])
214 |
215 | # dedupe
216 | seen = set()
217 | filtered = []
218 | for d in definitions:
219 | if ' '.join(d['function_tokens']) not in seen:
220 | filtered.append(d)
221 | seen.add(' '.join(d['function_tokens']))
222 |
223 | dd = DuplicateDetector(min_num_tokens_per_document=10)
224 | filter_mask = [dd.add_file(id=idx,
225 | tokens=d['function_tokens'],
226 | language=d['language']) for idx, d in enumerate(filtered)]
227 | exclusion_set = dd.compute_ids_to_exclude()
228 | exclusion_mask = [idx not in exclusion_set for idx, _ in enumerate(filtered)]
229 | filtered = [d for idx, d in enumerate(filtered) if filter_mask[idx] & exclusion_mask[idx]]
230 |
231 | with open(args['OUTPUT_DIR'] + '{}_dedupe_definitions.pkl'.format(args['--language']), 'wb') as f:
232 | pickle.dump(filtered, f)
233 |
--------------------------------------------------------------------------------
/function_parser/process_calls.py:
--------------------------------------------------------------------------------
1 | """
2 | Usage:
3 | process_calls.py [options] INPUT_DIR DEFINITION_FILE OUTPUT_DIR
4 |
5 | Options:
6 | -h --help
7 | --language LANGUAGE Language
8 | --processes PROCESSES # of processes to use [default: 16]
9 | --tree-sitter-build FILE [default: /src/build/py-tree-sitter-languages.so]
10 | """
11 | from collections import Counter, defaultdict
12 | import functools
13 | import gzip
14 | from multiprocessing import Pool
15 | import pandas as pd
16 | import pickle
17 |
18 | from docopt import docopt
19 | from tree_sitter import Language
20 |
21 | from function_parser.language_data import LANGUAGE_METADATA
22 | from function_parser.process import DataProcessor
23 |
24 |
25 | if __name__ == '__main__':
26 | args = docopt(__doc__)
27 |
28 | repository_dependencies = pd.read_csv(args['INPUT_DIR'] + 'repository_dependencies-1.4.0-2018-12-22.csv', index_col=False)
29 | projects = pd.read_csv(args['INPUT_DIR'] + 'projects_with_repository_fields-1.4.0-2018-12-22.csv', index_col=False)
30 |
31 | repository_dependencies['Manifest Platform'] = repository_dependencies['Manifest Platform'].apply(lambda x: x.lower())
32 | id_to_nwo = {project['ID']: project['Repository Name with Owner'] for project in projects[['ID', 'Repository Name with Owner']].dropna().to_dict(orient='records')}
33 | nwo_to_name = {project['Repository Name with Owner']: project['Name'] for project in projects[['Repository Name with Owner', 'Name']].dropna().to_dict(orient='records')}
34 |
35 | filtered = repository_dependencies[(repository_dependencies['Host Type'] == 'GitHub') & (repository_dependencies['Manifest Platform'] == LANGUAGE_METADATA[args['--language']]['platform'])][['Repository Name with Owner', 'Dependency Project ID']].dropna().to_dict(orient='records')
36 |
37 | dependency_pairs = [(rd['Repository Name with Owner'], id_to_nwo[int(rd['Dependency Project ID'])])
38 | for rd in filtered if int(rd['Dependency Project ID']) in id_to_nwo]
39 |
40 | dependency_pairs = list(set(dependency_pairs))
41 |
42 | dents, dees = zip(*dependency_pairs)
43 | dents = list(set(dents))
44 |
45 | definitions = defaultdict(list)
46 | with open(args['DEFINITION_FILE'], 'rb') as f:
47 | for d in pickle.load(f)
48 | definitions[d['nwo']].append(d)
49 | definitions = dict(definitions)
50 |
51 | # Fill candidates from most depended libraries
52 | c = Counter(dees)
53 | library_candidates = {}
54 | for nwo, _ in c.most_common(len(c)):
55 | if nwo.split('/')[-1] not in library_candidates and nwo in definitions:
56 | # Approximate library name with the repository name from nwo
57 | library_candidates[nwo.split('/')[-1]] = definitions[nwo]
58 |
59 | DataProcessor.PARSER.set_language(Language(args['--tree-sitter-build'], args['--language']))
60 | processor = DataProcessor(language=args['--language'],
61 | language_parser=LANGUAGE_METADATA[args['--language']]['language_parser'])
62 |
63 | with Pool(processes=int(args['--processes'])) as pool:
64 | output = pool.imap_unordered(functools.partial(processor.process_dent,
65 | ext=LANGUAGE_METADATA[args['--language']]['ext']),
66 | dents)
67 |
68 | dent_definitions, edges = map(list, map(flatten, zip(*output)))
69 |
70 | with gzip.GzipFile(args['OUTPUT_DIR'] + '{}_dent_definitions.pkl.gz'.format(args['--language']), 'wb') as outfile:
71 | pickle.dump(dent_definitions, outfile)
72 | with gzip.GzipFile(args['OUTPUT_DIR'] + '{}_edges.pkl.gz'.format(args['--language']), 'wb') as outfile:
73 | pickle.dump(edges, outfile)
74 |
--------------------------------------------------------------------------------
/function_parser/utils.py:
--------------------------------------------------------------------------------
1 | import itertools
2 | import os
3 | import re
4 | import subprocess
5 | import tempfile
6 | from typing import List, Tuple
7 |
8 | import requests
9 |
10 |
11 | def flatten(l):
12 | """Flatten list of lists.
13 | Args:
14 | l: A list of lists
15 | Returns: A flattened iterable
16 | """
17 | return itertools.chain.from_iterable(l)
18 |
19 |
20 | def chunks(l: List, n: int):
21 | """Yield successive n-sized chunks from l."""
22 | for i in range(0, len(l), n):
23 | yield l[i:i + n]
24 |
25 |
26 | def remap_nwo(nwo: str) -> Tuple[str, str]:
27 | r = requests.get('https://github.com/{}'.format(nwo))
28 | if r.status_code not in (404, 451, 502): # DMCA
29 | if 'migrated' not in r.text:
30 | if r.history:
31 | return (nwo, '/'.join(re.findall(r'"https://github.com/.+"', r.history[0].text)[0].strip('"').split('/')[-2:]))
32 | return (nwo, nwo)
33 | return (nwo, None)
34 |
35 |
36 | def get_sha(tmp_dir: tempfile.TemporaryDirectory, nwo: str):
37 | os.chdir(os.path.join(tmp_dir.name, nwo))
38 | # git rev-parse HEAD
39 | cmd = ['git', 'rev-parse', 'HEAD']
40 | sha = subprocess.check_output(cmd).strip().decode('utf-8')
41 | os.chdir('/tmp')
42 | return sha
43 |
44 |
45 | def download(nwo: str):
46 | os.environ['GIT_TERMINAL_PROMPT'] = '0'
47 | tmp_dir = tempfile.TemporaryDirectory()
48 | cmd = ['git', 'clone', '--depth=1', 'https://github.com/{}.git'.format(nwo), '{}/{}'.format(tmp_dir.name, nwo)]
49 | subprocess.run(cmd, stdin=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
50 | return tmp_dir
51 |
52 |
53 | def walk(tmp_dir: tempfile.TemporaryDirectory, ext: str):
54 | results = []
55 | for root, _, files in os.walk(tmp_dir.name):
56 | for f in files:
57 | if f.endswith('.' + ext):
58 | results.append(os.path.join(root, f))
59 | return results
60 |
--------------------------------------------------------------------------------
/nbs/00_core.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "\n"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {},
15 | "source": [
16 | "# module name here\n",
17 | "\n",
18 | "> API details."
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": null,
24 | "metadata": {},
25 | "outputs": [],
26 | "source": [
27 | "#hide\n",
28 | "from nbdev.showdoc import *"
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": null,
34 | "metadata": {},
35 | "outputs": [],
36 | "source": []
37 | }
38 | ],
39 | "metadata": {
40 | "kernelspec": {
41 | "display_name": "Python 3",
42 | "language": "python",
43 | "name": "python3"
44 | }
45 | },
46 | "nbformat": 4,
47 | "nbformat_minor": 2
48 | }
49 |
--------------------------------------------------------------------------------
/nbs/build_grammars.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Download Grammars:\n",
8 | "```bash\n",
9 | "git clone https://github.com/tree-sitter/tree-sitter-python.git\n",
10 | "cd tree-sitter-python && git checkout tags/v0.14.0 && cd ..\n",
11 | "\n",
12 | "git clone https://github.com/tree-sitter/tree-sitter-go.git\n",
13 | "cd tree-sitter-go && git checkout tags/v0.13.3 && cd ..\n",
14 | "\n",
15 | "git clone https://github.com/tree-sitter/tree-sitter-java.git\n",
16 | "cd tree-sitter-java && git checkout tags/v0.13.0 && cd ..\n",
17 | "```"
18 | ]
19 | },
20 | {
21 | "cell_type": "markdown",
22 | "metadata": {},
23 | "source": [
24 | "```python\n",
25 | "from tree_sitter import Language\n",
26 | "\n",
27 | "Language.build_library(\n",
28 | " # Store the library in the directory\n",
29 | " '/tree-sitter-languages.so',\n",
30 | " # Include one or more languages\n",
31 | " [\n",
32 | " '/tree-sitter-python',\n",
33 | " '/tree-sitter-go',\n",
34 | " '/tree-sitter-java'\n",
35 | " ]\n",
36 | ")\n",
37 | "```"
38 | ]
39 | }
40 | ],
41 | "metadata": {
42 | "kernelspec": {
43 | "display_name": "Python 3",
44 | "language": "python",
45 | "name": "python3"
46 | }
47 | },
48 | "nbformat": 4,
49 | "nbformat_minor": 2
50 | }
51 |
--------------------------------------------------------------------------------
/nbs/index.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# function_parser\n",
8 | "\n",
9 | "> This library contains various utils to parse GitHub repositories into function definition and docstring pairs. It is based on tree-sitter to parse code into ASTs and apply heuristics to parse metadata in more details. Currently, it supports 6 languages: Python, Java, Go, Php, Ruby, and Javascript. It also parses function calls and links them with their definitions for Python.\n",
10 | "\n",
11 | "Fork of the awesome function_parser library from Github's CodeSearchNet Challenge repo: https://github.com/github/CodeSearchNet/tree/master/function_parser"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {},
17 | "source": [
18 | "## Install"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "`pip install function-parser`"
26 | ]
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "metadata": {},
31 | "source": [
32 | "## How to use"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "In order to use the library you must download and build the language grammars for `tree-sitter` to parser source code with. Included in the library is a handy CLI tool for setting this up.\n",
40 | "\n",
41 | "To download and build grammars: `build_grammars`\n",
42 | "\n",
43 | "This command will download and build the grammars in the same location this python library was installed on your computer after pip installing."
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {},
50 | "outputs": [
51 | {
52 | "data": {
53 | "text/html": [
54 | "\n",
55 | "\n",
68 | "
\n",
69 | " \n",
70 | " \n",
71 | " \n",
72 | " nwo \n",
73 | " sha \n",
74 | " path \n",
75 | " language \n",
76 | " identifier \n",
77 | " parameters \n",
78 | " argument_list \n",
79 | " return_statement \n",
80 | " docstring \n",
81 | " docstring_summary \n",
82 | " docstring_tokens \n",
83 | " function \n",
84 | " function_tokens \n",
85 | " url \n",
86 | " \n",
87 | " \n",
88 | " \n",
89 | " \n",
90 | " 0 \n",
91 | " keras-team/keras \n",
92 | " e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
93 | " keras/backend.py \n",
94 | " python \n",
95 | " backend \n",
96 | " () \n",
97 | " \n",
98 | " return 'tensorflow' \n",
99 | " Publicly accessible method for determining the... \n",
100 | " Publicly accessible method for determining the... \n",
101 | " [Publicly, accessible, method, for, determinin... \n",
102 | " def backend():\\n \"\"\"Publicly accessible metho... \n",
103 | " [def, backend, (, ), :, return, 'tensorflow'] \n",
104 | " https://github.com/keras-team/keras/blob/e43af... \n",
105 | " \n",
106 | " \n",
107 | " 1 \n",
108 | " keras-team/keras \n",
109 | " e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
110 | " keras/backend.py \n",
111 | " python \n",
112 | " cast_to_floatx \n",
113 | " (x) \n",
114 | " \n",
115 | " return np.asarray(x, dtype=floatx()) \n",
116 | " Cast a Numpy array to the default Keras float ... \n",
117 | " Cast a Numpy array to the default Keras float ... \n",
118 | " [Cast, a, Numpy, array, to, the, default, Kera... \n",
119 | " def cast_to_floatx(x):\\n \"\"\"Cast a Numpy arra... \n",
120 | " [def, cast_to_floatx, (, x, ), :, if, isinstan... \n",
121 | " https://github.com/keras-team/keras/blob/e43af... \n",
122 | " \n",
123 | " \n",
124 | " 2 \n",
125 | " keras-team/keras \n",
126 | " e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
127 | " keras/backend.py \n",
128 | " python \n",
129 | " get_uid \n",
130 | " (prefix='') \n",
131 | " \n",
132 | " return layer_name_uids[prefix] \n",
133 | " Associates a string prefix with an integer cou... \n",
134 | " Associates a string prefix with an integer cou... \n",
135 | " [Associates, a, string, prefix, with, an, inte... \n",
136 | " def get_uid(prefix=''):\\n \"\"\"Associates a str... \n",
137 | " [def, get_uid, (, prefix, =, '', ), :, graph, ... \n",
138 | " https://github.com/keras-team/keras/blob/e43af... \n",
139 | " \n",
140 | " \n",
141 | " 3 \n",
142 | " keras-team/keras \n",
143 | " e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
144 | " keras/backend.py \n",
145 | " python \n",
146 | " reset_uids \n",
147 | " () \n",
148 | " \n",
149 | " \n",
150 | " Resets graph identifiers. \n",
151 | " Resets graph identifiers. \n",
152 | " [Resets, graph, identifiers, .] \n",
153 | " def reset_uids():\\n \"\"\"Resets graph identifie... \n",
154 | " [def, reset_uids, (, ), :, PER_GRAPH_OBJECT_NA... \n",
155 | " https://github.com/keras-team/keras/blob/e43af... \n",
156 | " \n",
157 | " \n",
158 | " 4 \n",
159 | " keras-team/keras \n",
160 | " e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
161 | " keras/backend.py \n",
162 | " python \n",
163 | " clear_session \n",
164 | " () \n",
165 | " \n",
166 | " \n",
167 | " Resets all state generated by Keras.\\n\\n Kera... \n",
168 | " Resets all state generated by Keras. \n",
169 | " [Resets, all, state, generated, by, Keras, .] \n",
170 | " def clear_session():\\n \"\"\"Resets all state ge... \n",
171 | " [def, clear_session, (, ), :, global, _SESSION... \n",
172 | " https://github.com/keras-team/keras/blob/e43af... \n",
173 | " \n",
174 | " \n",
175 | "
\n",
176 | "
"
177 | ],
178 | "text/plain": [
179 | " nwo sha \\\n",
180 | "0 keras-team/keras e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
181 | "1 keras-team/keras e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
182 | "2 keras-team/keras e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
183 | "3 keras-team/keras e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
184 | "4 keras-team/keras e43af6c89cd6c4adecc21ad5fc05b21e7fa9477b \n",
185 | "\n",
186 | " path language identifier parameters argument_list \\\n",
187 | "0 keras/backend.py python backend () \n",
188 | "1 keras/backend.py python cast_to_floatx (x) \n",
189 | "2 keras/backend.py python get_uid (prefix='') \n",
190 | "3 keras/backend.py python reset_uids () \n",
191 | "4 keras/backend.py python clear_session () \n",
192 | "\n",
193 | " return_statement \\\n",
194 | "0 return 'tensorflow' \n",
195 | "1 return np.asarray(x, dtype=floatx()) \n",
196 | "2 return layer_name_uids[prefix] \n",
197 | "3 \n",
198 | "4 \n",
199 | "\n",
200 | " docstring \\\n",
201 | "0 Publicly accessible method for determining the... \n",
202 | "1 Cast a Numpy array to the default Keras float ... \n",
203 | "2 Associates a string prefix with an integer cou... \n",
204 | "3 Resets graph identifiers. \n",
205 | "4 Resets all state generated by Keras.\\n\\n Kera... \n",
206 | "\n",
207 | " docstring_summary \\\n",
208 | "0 Publicly accessible method for determining the... \n",
209 | "1 Cast a Numpy array to the default Keras float ... \n",
210 | "2 Associates a string prefix with an integer cou... \n",
211 | "3 Resets graph identifiers. \n",
212 | "4 Resets all state generated by Keras. \n",
213 | "\n",
214 | " docstring_tokens \\\n",
215 | "0 [Publicly, accessible, method, for, determinin... \n",
216 | "1 [Cast, a, Numpy, array, to, the, default, Kera... \n",
217 | "2 [Associates, a, string, prefix, with, an, inte... \n",
218 | "3 [Resets, graph, identifiers, .] \n",
219 | "4 [Resets, all, state, generated, by, Keras, .] \n",
220 | "\n",
221 | " function \\\n",
222 | "0 def backend():\\n \"\"\"Publicly accessible metho... \n",
223 | "1 def cast_to_floatx(x):\\n \"\"\"Cast a Numpy arra... \n",
224 | "2 def get_uid(prefix=''):\\n \"\"\"Associates a str... \n",
225 | "3 def reset_uids():\\n \"\"\"Resets graph identifie... \n",
226 | "4 def clear_session():\\n \"\"\"Resets all state ge... \n",
227 | "\n",
228 | " function_tokens \\\n",
229 | "0 [def, backend, (, ), :, return, 'tensorflow'] \n",
230 | "1 [def, cast_to_floatx, (, x, ), :, if, isinstan... \n",
231 | "2 [def, get_uid, (, prefix, =, '', ), :, graph, ... \n",
232 | "3 [def, reset_uids, (, ), :, PER_GRAPH_OBJECT_NA... \n",
233 | "4 [def, clear_session, (, ), :, global, _SESSION... \n",
234 | "\n",
235 | " url \n",
236 | "0 https://github.com/keras-team/keras/blob/e43af... \n",
237 | "1 https://github.com/keras-team/keras/blob/e43af... \n",
238 | "2 https://github.com/keras-team/keras/blob/e43af... \n",
239 | "3 https://github.com/keras-team/keras/blob/e43af... \n",
240 | "4 https://github.com/keras-team/keras/blob/e43af... "
241 | ]
242 | },
243 | "execution_count": null,
244 | "metadata": {},
245 | "output_type": "execute_result"
246 | }
247 | ],
248 | "source": [
249 | "import function_parser\n",
250 | "import os\n",
251 | "\n",
252 | "import pandas as pd\n",
253 | "\n",
254 | "from function_parser.language_data import LANGUAGE_METADATA\n",
255 | "from function_parser.process import DataProcessor\n",
256 | "from tree_sitter import Language\n",
257 | "\n",
258 | "language = \"python\"\n",
259 | "DataProcessor.PARSER.set_language(\n",
260 | " Language(os.path.join(function_parser.__path__[0], \"tree-sitter-languages.so\"), language)\n",
261 | ")\n",
262 | "processor = DataProcessor(\n",
263 | " language=language, language_parser=LANGUAGE_METADATA[language][\"language_parser\"]\n",
264 | ")\n",
265 | "\n",
266 | "dependee = \"keras-team/keras\"\n",
267 | "definitions = processor.process_dee(dependee, ext=LANGUAGE_METADATA[language][\"ext\"])\n",
268 | "pd.DataFrame(definitions).head()"
269 | ]
270 | }
271 | ],
272 | "metadata": {
273 | "kernelspec": {
274 | "display_name": "Python 3",
275 | "language": "python",
276 | "name": "python3"
277 | }
278 | },
279 | "nbformat": 4,
280 | "nbformat_minor": 2
281 | }
282 |
--------------------------------------------------------------------------------
/settings.ini:
--------------------------------------------------------------------------------
1 | [DEFAULT]
2 | host = github
3 | lib_name = function_parser
4 | user = ncoop57
5 | description = This library contains various utils to parse GitHub repositories into function definition and docstring pairs. It is based on tree-sitter to parse code into ASTs and apply heuristics to parse metadata in more details. Currently, it supports 6 languages: Python, Java, Go, Php, Ruby, and Javascript. It also parses function calls and links them with their definitions for Python.
6 | keywords = source code parser method function software engineering
7 | author = Nathan Cooper and CodeSearchNet Team
8 | author_email = nathanallencooper@gmail.com
9 | copyright = GitHub and Nathan Cooper
10 | branch = main
11 | version = 0.0.4
12 | min_python = 3.7
13 | audience = Developers
14 | language = English
15 | custom_sidebar = False
16 | license = mit
17 | status = 2
18 | requirements = tree_sitter==0.0.5 gitpython requests pyhive tqdm pandas python-arango docopt elasticsearch dpu_utils
19 | console_scripts = build_grammars=function_parser.build_grammars:main
20 | nbs_path = nbs
21 | doc_path = docs
22 | doc_host = https://ncoop57.github.io
23 | doc_baseurl = /function_parser/
24 | git_url = https://github.com/ncoop57/function_parser/tree/main/
25 | lib_path = function_parser
26 | title = function_parser
27 | recursive = False
28 |
29 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from pkg_resources import parse_version
2 | from configparser import ConfigParser
3 | import setuptools
4 | assert parse_version(setuptools.__version__)>=parse_version('36.2')
5 |
6 | # note: all settings are in settings.ini; edit there, not here
7 | config = ConfigParser(delimiters=['='])
8 | config.read('settings.ini')
9 | cfg = config['DEFAULT']
10 |
11 | cfg_keys = 'version description keywords author author_email'.split()
12 | expected = cfg_keys + "lib_name user branch license status min_python audience language".split()
13 | for o in expected: assert o in cfg, "missing expected setting: {}".format(o)
14 | setup_cfg = {o:cfg[o] for o in cfg_keys}
15 |
16 | licenses = {
17 | 'apache2': ('Apache Software License 2.0','OSI Approved :: Apache Software License'),
18 | 'mit': ('MIT License (MIT)','OSI Approved :: MIT License')
19 | }
20 | statuses = [ '1 - Planning', '2 - Pre-Alpha', '3 - Alpha',
21 | '4 - Beta', '5 - Production/Stable', '6 - Mature', '7 - Inactive' ]
22 | py_versions = '2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8'.split()
23 |
24 | requirements = cfg.get('requirements','').split()
25 | lic = licenses[cfg['license']]
26 | min_python = cfg['min_python']
27 |
28 | setuptools.setup(
29 | name = cfg['lib_name'],
30 | license = lic[0],
31 | classifiers = [
32 | 'Development Status :: ' + statuses[int(cfg['status'])],
33 | 'Intended Audience :: ' + cfg['audience'].title(),
34 | 'License :: ' + lic[1],
35 | 'Natural Language :: ' + cfg['language'].title(),
36 | ] + ['Programming Language :: Python :: '+o for o in py_versions[py_versions.index(min_python):]],
37 | url = cfg['git_url'],
38 | packages = setuptools.find_packages(),
39 | include_package_data = True,
40 | install_requires = requirements,
41 | dependency_links = cfg.get('dep_links','').split(),
42 | python_requires = '>=' + cfg['min_python'],
43 | long_description = open('README.md').read(),
44 | long_description_content_type = 'text/markdown',
45 | zip_safe = False,
46 | entry_points = { 'console_scripts': cfg.get('console_scripts','').split() },
47 | **setup_cfg)
48 |
49 |
--------------------------------------------------------------------------------