Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add peeks for idents #367

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions elixir/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ def on_get(self, req, resp, project, ident):
if version == 'latest':
version = query.query('latest')

symbol_definitions, symbol_references, symbol_doccomments = query.query('ident', version, ident, family)
symbol_definitions, symbol_references, symbol_doccomments, peaks = query.query('ident', version, ident, family)

resp.status = falcon.HTTP_200
resp.content_type = falcon.MEDIA_JSON
resp.media = {
'definitions': [sym.__dict__ for sym in symbol_definitions],
'references': [sym.__dict__ for sym in symbol_references],
'documentations': [sym.__dict__ for sym in symbol_doccomments]
'documentations': [sym.__dict__ for sym in symbol_doccomments],
'peeks': peaks
}

query.close()
Expand Down
41 changes: 38 additions & 3 deletions elixir/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,12 @@ def query(self, cmd, *args):

# DT bindings compatible strings are handled differently
if family == 'B':
return self.get_idents_comps(version, ident)
defs, refs, docs = self.get_idents_comps(version, ident)
else:
return self.get_idents_defs(version, ident, family)
defs, refs, docs = self.get_idents_defs(version, ident, family)

peeks = self.get_peeks_of_syms(version, defs, refs)
return defs, refs, docs, peeks

else:
return 'Unknown subcommand: ' + cmd + '\n'
Expand Down Expand Up @@ -402,10 +405,37 @@ def get_idents_defs(self, version, ident, family):
symbol_doccomments.append(SymbolInstance(path, docline))

return symbol_definitions, symbol_references, symbol_doccomments

def get_peeks_of_syms(self, version, symbol_definitions, symbol_references):

peeks = {}

def request_peeks(syms):
if len(syms) > 100:
return
for sym in syms:
if sym.path not in peeks:
peeks[sym.path] = {}

content = self.scriptLines('get-file', version, "/" + sym.path)

if type(sym.line) is int:
lines = (sym.line,)
else:
lines = map(int, sym.line.split(','))

for num in lines:
index = num - 1
if index >= 0 and index < len(content):
peeks[sym.path][num] = decode(content[index]).strip()

request_peeks(symbol_definitions)
request_peeks(symbol_references)
return peeks


def cmd_ident(q, version, ident, family, **kwargs):
symbol_definitions, symbol_references, symbol_doccomments = q.query("ident", version, ident, family)
symbol_definitions, symbol_references, symbol_doccomments, peeks = q.query("ident", version, ident, family)
print("Symbol Definitions:")
for symbol_definition in symbol_definitions:
print(symbol_definition)
Expand All @@ -418,6 +448,11 @@ def cmd_ident(q, version, ident, family, **kwargs):
for symbol_doccomment in symbol_doccomments:
print(symbol_doccomment)

print("\nSymbol peeks:")
for file, content in peeks.items():
for num, line in content.items():
print(f"{file}:{num}: {line}")

def cmd_file(q, version, path, **kwargs):
code = q.query("file", version, path)
print(code)
Expand Down
22 changes: 13 additions & 9 deletions elixir/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,23 +635,26 @@ def generate_source_page(ctx, q, project, version, path):
# type: type of the symbol
# path: path of the file that contains the symbol
# line: list of LineWithURL
SymbolEntry = namedtuple('SymbolEntry', 'type, path, lines')
# peeks: map of code line previews for this path
SymbolEntry = namedtuple('SymbolEntry', 'type, path, lines, peeks')

# Converts SymbolInstance into SymbolEntry
# path of SymbolInstance will be appended to base_url
def symbol_instance_to_entry(base_url, symbol):
def symbol_instance_to_entry(base_url, symbol, peeks):
# TODO this should be a responsibility of Query
if type(symbol.line) is str:
line_numbers = symbol.line.split(',')
else:
line_numbers = [symbol.line]

lines = [
LineWithURL(l, f'{ base_url }/{ symbol.path }#L{ l }')
LineWithURL(int(l), f'{ base_url }/{ symbol.path }#L{ l }')
for l in line_numbers
]

return SymbolEntry(symbol.type, symbol.path, lines)
current_peeks = peeks.get(symbol.path, {})

return SymbolEntry(symbol.type, symbol.path, lines, current_peeks)

# Generates response (status code and optionally HTML) of the `ident` route
# ctx: RequestContext
Expand All @@ -662,15 +665,16 @@ def generate_ident_page(ctx, q, project, version, family, ident):

source_base_url = get_source_base_url(project, version)

symbol_definitions, symbol_references, symbol_doccomments = q.query('ident', version, ident, family)
symbol_definitions, symbol_references, symbol_doccomments, peeks = q.query('ident', version, ident, family)

symbol_sections = []
empty_peeks = {}

if len(symbol_definitions) or len(symbol_references):
if len(symbol_doccomments):
symbol_sections.append({
'title': 'Documented',
'symbols': {'_unknown': [symbol_instance_to_entry(source_base_url, sym) for sym in symbol_doccomments]},
'symbols': {'_unknown': [symbol_instance_to_entry(source_base_url, sym, empty_peeks) for sym in symbol_doccomments]},
})

if len(symbol_definitions):
Expand All @@ -679,9 +683,9 @@ def generate_ident_page(ctx, q, project, version, family, ident):
# TODO this should be a responsibility of Query
for sym in symbol_definitions:
if sym.type not in defs_by_type:
defs_by_type[sym.type] = [symbol_instance_to_entry(source_base_url, sym)]
defs_by_type[sym.type] = [symbol_instance_to_entry(source_base_url, sym, peeks)]
else:
defs_by_type[sym.type].append(symbol_instance_to_entry(source_base_url, sym))
defs_by_type[sym.type].append(symbol_instance_to_entry(source_base_url, sym, peeks))

symbol_sections.append({
'title': 'Defined',
Expand All @@ -695,7 +699,7 @@ def generate_ident_page(ctx, q, project, version, family, ident):
if len(symbol_references):
symbol_sections.append({
'title': 'Referenced',
'symbols': {'_unknown': [symbol_instance_to_entry(source_base_url, sym) for sym in symbol_references]},
'symbols': {'_unknown': [symbol_instance_to_entry(source_base_url, sym, peeks) for sym in symbol_references]},
})
else:
symbol_sections.append({
Expand Down
31 changes: 23 additions & 8 deletions static/dynamic-references.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function identUrl(project, ident, version, family) {
]
*/

function generateSymbolDefinitionsHTML(symbolDefinitions, project, version) {
function generateSymbolDefinitionsHTML(symbolDefinitions, peeks, project, version) {
let result = "";
let typesCount = {};
let previous_type = "";
Expand All @@ -55,7 +55,7 @@ function generateSymbolDefinitionsHTML(symbolDefinitions, project, version) {
previous_type = sd.type;
}
let ln = sd.line.toString().split(',');
if (ln.length == 1) {
if (ln.length == 1 && !peeks) {
let n = ln[0];
result += `<li><a href="/${project}/${version}/source/${sd.path}#L${n}"><strong>${sd.path}</strong>, line ${n} <em>(as a ${sd.type})</em></a>`;
} else {
Expand All @@ -66,7 +66,14 @@ function generateSymbolDefinitionsHTML(symbolDefinitions, project, version) {
result += `<li><a href="/${project}/${version}/source/${sd.path}#L${ln[0]}"><strong>${sd.path}</strong> <em>(as a ${sd.type})</em></a>`;
result += '<ul>';
for(let n of ln) {
result += `<li><a href="/${project}/${version}/source/${sd.path}#L${n}">line ${n}</a></li>`;
result += `<li><a href="/${project}/${version}/source/${sd.path}#L${n}"><span>line ${n}</span>`;
let srcLine = peeks?.[sd.path]?.[n];
if(srcLine) {
let tag = document.createElement("pre");
tag.textContent = srcLine;
result += tag.outerHTML;
}
result += '</a></li>'
}
result += '</ul>';
}
Expand All @@ -77,7 +84,7 @@ function generateSymbolDefinitionsHTML(symbolDefinitions, project, version) {
return result;
}

function generateSymbolReferencesHTML(symbolReferences, project, version) {
function generateSymbolReferencesHTML(symbolReferences, peeks, project, version) {
let result = "";

if(symbolReferences.length == 0) {
Expand All @@ -88,7 +95,7 @@ function generateSymbolReferencesHTML(symbolReferences, project, version) {
result += '<ul>';
for (let sr of symbolReferences) {
let ln = sr.line.split(',');
if (ln.length == 1) {
if (ln.length == 1 && !peeks) {
let n = ln[0];
result += `<li><a href="/${project}/${version}/source/${sr.path}#L${n}"><strong>${sr.path}</strong>, line ${n}</a>`;
} else {
Expand All @@ -99,7 +106,14 @@ function generateSymbolReferencesHTML(symbolReferences, project, version) {
result += `<li><a href="/${project}/${version}/source/${sr.path}#L${ln[0]}"><strong>${sr.path}</strong></a>`;
result += '<ul>'
for(let n of ln) {
result += `<li><a href="/${project}/${version}/source/${sr.path}#L${n}">line ${n}</a>`
result += `<li><a href="/${project}/${version}/source/${sr.path}#L${n}"><span>line ${n}</span>`
let srcLine = peeks?.[sr.path]?.[n];
if (srcLine) {
let tag = document.createElement("pre");
tag.textContent = srcLine;
result += tag.outerHTML;
}
result += '</a></li>'
}
result += '</ul>'
}
Expand Down Expand Up @@ -143,10 +157,11 @@ function generateReferencesHTML(data, project, version) {
let symbolDefinitions = data["definitions"];
let symbolReferences = data["references"];
let symbolDocumentations = data["documentations"];
let peeks = data["peeks"];
return '<div class="lxrident">' +
generateDocCommentsHTML(symbolDocumentations, project, version) +
generateSymbolDefinitionsHTML(symbolDefinitions, project, version) +
generateSymbolReferencesHTML(symbolReferences, project, version) +
generateSymbolDefinitionsHTML(symbolDefinitions, peeks, project, version) +
generateSymbolReferencesHTML(symbolReferences, peeks, project, version) +
'</div>';
}

Expand Down
11 changes: 11 additions & 0 deletions static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,12 @@ h2 {
font-weight: 400;
color: #000;
}

.lxrident a span {
width: 8em;
display: inline-block;
}

.lxrident li li::before {
color: #444;
}
Expand All @@ -714,6 +720,11 @@ h2 {
content: '└╴';
}

.lxrident li pre {
display: inline-block;
margin: auto;
}


/* tree */

Expand Down
10 changes: 7 additions & 3 deletions templates/ident.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h2>{{ section['title'] }} in {{ symbols|length }} files
<li>
<a href="{{ symbol.lines[0].url }}">
<strong>{{ symbol.path }}</strong>
{%- if symbol.lines|length == 1 %},
{%- if symbol.lines|length == 1 and symbol.peeks|length == 0 %},
line {{ symbol.lines[0].lineno }}
{%- elif symbols|length > 100 %},
<em>{{ symbol.lines|length }} times</em>
Expand All @@ -42,10 +42,14 @@ <h2>{{ section['title'] }} in {{ symbols|length }} files
<em>(as a {{ symbol.type }})</em>
{% endif %}
</a>
{% if symbol.lines|length > 1 and symbols|length <= 100 %}
{% if (symbol.lines|length > 1 or symbol.peeks|length > 0) and symbols|length <= 100 %}
<ul>
{% for line, url in symbol.lines %}
<li><a href="{{ url }}">line {{ line }}</a>
<li><a href="{{ url }}"><span>line {{ line }}</span>
{% if line in symbol.peeks %}
<pre>{{ symbol.peeks[line] }}</pre>
{% endif %}
</a></li>
{% endfor %}
</ul>
{% endif %}
Expand Down