Skip to content
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
2 changes: 1 addition & 1 deletion src/org/rascalmpl/library/IO.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Copyright (c) 2009-2022 CWI
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
which accompanies this distribution, and is available a
http://www.eclipse.org/legal/epl-v10.html
}
@contributor{Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI}
Expand Down
13 changes: 7 additions & 6 deletions src/org/rascalmpl/library/lang/html/IO.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,9 @@ private IValue toTextConstructor(TextNode elem, ISourceLocation file) {
* Why go through all the trouble of building a DOM? The only reason is compliance.
* Escapes, encodings, etc. all are maintained by these classes from org.jdom.
*/
public IString writeHTMLString(IConstructor cons, IString charset, IConstructor escapeMode, IBool outline, IBool prettyPrint, IInteger indentAmount, IInteger maxPaddingWidth, IConstructor syntax, IBool dropOrigins) {
public IString writeHTMLString(IConstructor cons, IString charset, IConstructor escapeMode, IBool outline, IBool prettyPrint, IInteger indentAmount, IInteger maxPaddingWidth, IConstructor syntax, IBool dropOrigins, IBool normalise) {
try {
Document doc = createHTMLDocument(cons, dropOrigins.getValue());
Document doc = createHTMLDocument(cons, dropOrigins.getValue(), normalise.getValue());
doc = doc.outputSettings(createOutputSettings(charset.getValue(), escapeMode.getName(), outline.getValue(), prettyPrint.getValue(), indentAmount.intValue(), maxPaddingWidth.intValue(), syntax.getName()));

return factory.string(doc.outerHtml());
Expand All @@ -230,10 +230,10 @@ public IString writeHTMLString(IConstructor cons, IString charset, IConstructor
* Why go through all the trouble of building a DOM? The only reason is compliance.
* Escapes, encodings, etc. all are maintained by these classes from org.w3c.dom.
*/
public void writeHTMLFile(ISourceLocation file, IConstructor cons, IString charset, IConstructor escapeMode, IBool outline, IBool prettyPrint, IInteger indentAmount, IInteger maxPaddingWidth, IConstructor syntax, IBool dropOrigins ) {
public void writeHTMLFile(ISourceLocation file, IConstructor cons, IString charset, IConstructor escapeMode, IBool outline, IBool prettyPrint, IInteger indentAmount, IInteger maxPaddingWidth, IConstructor syntax, IBool dropOrigins, IBool normalise) {

try (Writer out = URIResolverRegistry.getInstance().getCharacterWriter(file, charset.getValue(), false)) {
Document doc = createHTMLDocument(cons, dropOrigins.getValue());
Document doc = createHTMLDocument(cons, dropOrigins.getValue(), normalise.getValue());
doc = doc.outputSettings(createOutputSettings(charset.getValue(), escapeMode.getName(), outline.getValue(), prettyPrint.getValue(), indentAmount.intValue(), maxPaddingWidth.intValue(), syntax.getName()));
out.write(doc.outerHtml());
}
Expand All @@ -257,10 +257,11 @@ private OutputSettings createOutputSettings(String charset, String escapeMode, b
/**
* Translates a constructor tree to a jdom DOM tree, adding nodes where necessary to complete a html element.
*/
private Document createHTMLDocument(IConstructor cons, boolean dropOrigins) throws IOException {
private Document createHTMLDocument(IConstructor cons, boolean dropOrigins, boolean normalize) throws IOException {
Document doc = new Document("http://localhost");

Node node = normalise(cons, createElement(cons, dropOrigins));
Node element = createElement(cons, dropOrigins);
Node node = normalize ? normalise(cons, element) : element;

doc.appendChild(node);
return doc;
Expand Down
8 changes: 6 additions & 2 deletions src/org/rascalmpl/library/lang/html/IO.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,20 @@ java HTMLElement readHTMLString(str content, loc base=|http://localhost|, bool t
@description{
This function uses [JSoup's](http://www.jsoup.org) DOM functionality to
yield a syntactically correct (X)HTML string.

* `normalise`: when true arbitrary HTML elements will be nested in a <body> and a <html> wrapper
* `dropOrigins`: any additional `src` origin attributes will not be serialized into the HTML document
* the other options are JSoup options.
}
java str writeHTMLString(HTMLElement dom, str charset="UTF-8", HTMLEscapeMode escapeMode = baseMode(), bool outline=false, bool prettyPrint=true, int indentAmount=4, int maxPaddingWidth=30, HTMLSyntax \syntax=htmlSyntax(), bool dropOrigins=true);
java str writeHTMLString(HTMLElement dom, str charset="UTF-8", HTMLEscapeMode escapeMode = baseMode(), bool outline=false, bool prettyPrint=true, int indentAmount=4, int maxPaddingWidth=30, HTMLSyntax \syntax=htmlSyntax(), bool dropOrigins=true, bool normalise=true);

@synopsis{Pretty-print the HTMLElement AST to a string}
@description{
This function uses [JSoup's](http://www.jsoup.org) DOM functionality to
yield a syntactically correct (X)HTML file.
}
@javaClass{org.rascalmpl.library.lang.html.IO}
java void writeHTMLFile(loc file, HTMLElement dom, str charset="UTF-8", HTMLEscapeMode escapeMode = baseMode(), bool outline=false, bool prettyPrint=true, int indentAmount=4, int maxPaddingWidth=30, HTMLSyntax \syntax=htmlSyntax(), bool dropOrigins=true);
java void writeHTMLFile(loc file, HTMLElement dom, str charset="UTF-8", HTMLEscapeMode escapeMode = baseMode(), bool outline=false, bool prettyPrint=true, int indentAmount=4, int maxPaddingWidth=30, HTMLSyntax \syntax=htmlSyntax(), bool dropOrigins=true, bool normalise=true);

@synopsis{Convenience function to visualize an HTMLElement tree in the browser}
Content serve(HTMLElement elem) = html(writeHTMLString(elem));
86 changes: 65 additions & 21 deletions src/org/rascalmpl/library/lang/rascal/vis/ImportGraph.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ is clearly visible.
@bootstrapParser
module lang::rascal::vis::ImportGraph

import util::Reflective;
import vis::Graphs;
import lang::rascal::grammar::definition::Modules;
import lang::rascal::\syntax::Rascal;
import Exception;
import util::FileSystem;
import util::IDEServices;
import IO;
import analysis::graphs::Graph;
import Set;
import String;
import analysis::graphs::Graph;
import lang::rascal::\syntax::Rascal;
import lang::rascal::grammar::definition::Modules;
import util::FileSystem;
import util::IDEServices;
import util::Reflective;
import vis::Graphs;

@synopsis{If `projectName` is an open project in the current IDE, the visualize its import/extend graph.}
void importGraph(str projectName, bool hideExternals=true) {
Expand All @@ -41,23 +42,36 @@ void importGraph(loc projectRoot, bool hideExternals=true) {
}

@synopsis{Visualizes an import/extend graph for all the modules in the srcs roots of the current PathConfig}
void importGraph(PathConfig pcfg, bool hideExternals=true) {
void importGraph(PathConfig pcfg, bool hideExternals=true, bool hideTestModules=true) {
m = getProjectModel(pcfg.srcs);

// let's start with a simple graph and elaborate on details in later versions
g = { <from, to> | <from, to> <- sort(m.imports), hideExternals ==> to notin m.external}
+ { <from, to> | <from, to> <- sort(m.extends), hideExternals ==> to notin m.external}
+ { <"_" , to> | to <- top(m.imports + m.extends) } // pull up the top modules
g = { <from, to> | <from, to> <- sort(m.imports), hideExternals ==> to notin m.external, hideTestModules ==> {from, to} & m.tests == {}}
+ { <from, to> | <from, to> <- sort(m.extends), hideExternals ==> to notin m.external, hideTestModules ==> {from, to} & m.tests == {}}
;

list[str] nodeClass(str n) = [
*["external" | n in m.external],
*["project" | n notin m.external]
];

int edgeWeight(str from, str to) {
if (<from, to> in g o gClosed, <from, from> notin gClosed, <to, to> notin gClosed) {
return 1; // transitive edges should not influence things.
}
else if (<from, to> in m.extends) {
// extend structure is very important
return 1;
}
else {
return 1;
}
}

gClosed = g+;

list[str] edgeClass(str from, str to) = [
*["nottop" | from != "_"],
*["extend" | <from, to> in m.extends],
*["import" | <from, to> in m.imports],
*["transitive" | <from, to> in g o gClosed, <from, from> notin gClosed, <to,to> notin gClosed],
Expand All @@ -66,8 +80,23 @@ void importGraph(PathConfig pcfg, bool hideExternals=true) {

styles = [
cytoStyleOf(
selector=\edge(equal("source", "_")),
style=defaultEdgeStyle()[visibility="hidden"]
selector=\node(\className("hover")),
style=defaultNodeStyle()[\background-color="yellow"][color="black"]
),

cytoStyleOf(
selector=\node(className("hover-in")),
style=defaultNodeStyle()[\background-color="red"][color="black"]
),

cytoStyleOf(
selector=\node(className("hover-out")),
style=defaultNodeStyle()[\background-color="orange"][color="black"]
),

cytoStyleOf(
selector=\edge(className("hover-out")),
style=defaultEdgeStyle()[\line-color="orange"]
),

cytoStyleOf(
Expand All @@ -82,10 +111,9 @@ void importGraph(PathConfig pcfg, bool hideExternals=true) {

cytoStyleOf(
selector=\edge(className("transitive")),
style=defaultEdgeStyle()[opacity=".25"][\line-opacity="0.25"]
style=defaultEdgeStyle()[opacity=".25"][\line-opacity="0.50"]
)
,

,
cytoStyleOf(
selector=\edge(className("cyclic")),
style=defaultEdgeStyle()[opacity="1"][\line-opacity="1"][\width=10]
Expand All @@ -101,14 +129,27 @@ void importGraph(PathConfig pcfg, bool hideExternals=true) {

default loc modLinker(value _) = |nothing:///|;

str modTip(str name) {
return "module <name>
'<if (m.imports[name] != {}) {>
'<for (str i <- sort(m.imports[name])) {>import <i>;
'<}><}>
'<if (m.extends[name] != {}) {><for (str i <- sort(m.extends[name])) {>extend <i>;
'<}><}>";
}

str modLabel(str name) = split("::", name)[-1];

cfg = cytoGraphConfig(
\layout=defaultDagreLayout()[ranker=\network-simplex()],
\layout=defaultDagreLayout()[ranker=\network-simplex()][rankSep=100][debugDagreEdgeControlPoints=false],
styles=styles,
title="Rascal Import/Extend Graph",
nodeTipper=modTip,
nodeClassifier=nodeClass,
edgeClassifier=edgeClass,
nodeLinker=modLinker,
edgeStyle=defaultEdgeStyle()[\curve-style=taxi()]
nodeLabeler=modLabel,
edgeWeigher=edgeWeight,
nodeLinker=modLinker
);

showInteractiveContent(graph(g, cfg=cfg), title=cfg.title);
Expand All @@ -117,6 +158,7 @@ void importGraph(PathConfig pcfg, bool hideExternals=true) {
@synopsis{Container for everything we need to know about the modules in a project to visualize it.}
data ProjectModel = projectModel(
set[str] modules = {},
set[str] tests = {},
set[str] external = {},
rel[str, str] imports = {},
rel[str, str] extends = {},
Expand All @@ -133,7 +175,8 @@ ProjectModel getProjectModel(list[loc] srcs) {
modules = {*m.modules | m <- models},
imports = {*m.imports | m <- models},
extends = {*m.extends | m <- models},
files = {*m.files | m <- models}
files = {*m.files | m <- models},
tests = {*m.tests | m <- models}
);

wholeWorld.external = wholeWorld.imports<1> + wholeWorld.extends<1> - wholeWorld.modules;
Expand All @@ -152,7 +195,8 @@ ProjectModel getProjectModel(loc file) {
modules = {name},
imports = {name} * imps,
extends = {name} * exts,
files = {<name, file>}
files = {<name, file>},
tests = {name | /test/ := file.path}
);
}
catch ParseError(_) :
Expand Down
Loading
Loading