Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ private tuple[set[str], rel[str,Type]] computeBoundsAndDefineTypeParams(Signatur
c.define(tpname, typeVarId(), tp.name,
defType(toList(typeParamBounds[tpname]), makeBoundDef(tp, typeParamBounds, closed=false)));
c.fact(tp, tp.name);
//c.calculate("bounded type var", tp, [tp, returnType], makeTypeGetter(tp));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ void collect(current: (Pattern) `{ <{Pattern ","}* elements0> }`, Collector c){
}
c.push(patternContainer, "set");
collect(elements0, c);
c.calculate("set pattern", current, [e | e <- elements0],
AType (Solver s){ return alist(lubList([s.getType(e) | e <- elements0])); });
c.pop(patternContainer);
}

Expand All @@ -82,31 +84,19 @@ void collect(current: (Pattern) `[ <{Pattern ","}* elements0> ]`, Collector c){
}
c.push(patternContainer, "list");
collect(elements0, c);
c.calculate("list pattern", current, [e | e <- elements0],
AType (Solver s){ return alist(lubList([s.getType(e) | e <- elements0])); });
c.pop(patternContainer);
}

// ---- typed variable pattern

void collect(current: (Pattern) `<Type tp> <Name name>`, Collector c){
uname = unescape("<name>");
if(tp is function) c.enterScope(current);
collect(tp, c);
if(tp is function) c.leaveScope(current);
calcDeps = [tp];
functionScopes = c.getScopeInfo(functionScope());
if(!isEmpty(functionScopes)){
for(<_, scopeInfo> <- functionScopes){
if(signatureInfo(Type returnType) := scopeInfo){
calcDeps += returnType;
break;
} else {
throw rascalCheckerInternalError(getLoc(current), "Inconsistent info from function scope: <scopeInfo>");
}
}
}
c.calculate("typed variable pattern", current, calcDeps, AType(Solver s){ return s.getType(tp)[alabel=uname]; });
calcDeps = addReturnTypeDependency(current, tp, c);
Comment thread
PaulKlint marked this conversation as resolved.
c.calculate("typed variable pattern", current, calcDeps, AType(Solver s){ return s.getType(tp)[alabel=uname]; });


if(!isWildCard(uname)){
c.push(patternNames, <uname, getLoc(name)>);
orScopes = c.getScopeInfo(orScope());
Expand All @@ -120,7 +110,7 @@ void collect(current: (Pattern) `<Type tp> <Name name>`, Collector c){
}
c.define(uname, formalOrPatternFormal(c), name, defType(tp));
} else {
c.fact(name, tp);
c.calculate("variable <name>", name, calcDeps, AType(Solver s) { return s.getType(tp); });
}
}

Expand Down
14 changes: 8 additions & 6 deletions src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ void collect(current:(TypeVar) `& <Name n>`, Collector c){

void collect(current: (TypeVar) `& <Name n> \<: <Type tp>`, Collector c){
pname = prettyPrintName(n);

calcDeps = addReturnTypeDependency(current, tp, c);
if(<true, bool closed> := defineOrReuseTypeParameters(c)){
if(c.isAlreadyDefined(pname, n)){
c.use(n, {typeVarId() });
Expand All @@ -853,23 +853,25 @@ void collect(current: (TypeVar) `& <Name n> \<: <Type tp>`, Collector c){
c.define(pname, typeVarId(), n, defTypeCall([getLoc(tp)], AType(Solver s) {return aparameter(pname,s.getType(tp), closed=closed); }));
//if(debugTP)println("Define <pname> at <current@\loc>");
}
c.fact(current, n);
//c.fact(current, n);
c.calculate("type parameter, 1", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; });
} else if(<true, bool closed> := useTypeParameters(c)){
c.use(n, {typeVarId() });
c.calculate("xxx", current, [n], AType (Solver s) { return s.getType(n)[closed=closed]; });
c.calculate("type parameter, 2", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; });
//if(debugTP)println("Use <pname> at <current@\loc>");
} else if(<true, rel[str, Type] tpbounds> := useBoundedTypeParameters(c)){
if(!isEmpty(tpbounds[pname])){
bnds = toList(tpbounds[pname]);
c.calculate("type parameter with bound", n, bnds,
c.calculate("type parameter with bound, 1", n, bnds + calcDeps,
AType(Solver s){
new_bnd = (avalue() | aglb(it, s.getType(bnd)) | bnd <- bnds);
return aparameter(prettyPrintName(n), s.getType(new_bnd), closed=true);
});
} else {
c.calculate("type parameter with bound", n, [tp], AType(Solver s){ return aparameter(prettyPrintName(n), s.getType(tp), closed=true); });
c.calculate("type parameter with bound, 2", n, [tp, *calcDeps], AType(Solver s){ return aparameter(prettyPrintName(n), s.getType(tp), closed=true); });
}
c.fact(current, n);
//c.fact(current, n);
c.calculate("type parameter with bound, 3", current, [tp, *calcDeps], AType(Solver s){ return s.getType(n)[closed=true]; });
}

collect(tp, c);
Expand Down
208 changes: 208 additions & 0 deletions src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
module lang::rascalcore::check::DependencyViewer

import analysis::typepal::TModel;
import analysis::typepal::Collector;
import vis::Graphs;
import IO;
import util::IDEServices;
import ListRelation;
import Map;
import Relation;
import Set;

// Management of node identities
alias NodeId = str;
int nodeCounter = 0;

map[NodeId, value] id2node = ();
map[value, NodeId] node2id = ();

map[NodeId,loc] node2src = ();
map[NodeId,str] node2label = ();
map[loc,NodeId] src2calc = ();

void initNodes(){
nodeCounter = 0;
id2node = ();
node2id = ();
node2src = ();
node2label = ();
src2calc = ();
}

NodeId getNodeId(value v){
assert Calculator _ := v || Requirement _ := v || loc _ := v: "Illegal <v>";
if(v notin node2id) {
node2id[v] = "<nodeCounter>";
id2node["<nodeCounter>"] = v;
nodeCounter += 1;
}
return node2id[v];
}

NodeId getNodeIdViaCalculator(loc l){
if(l in src2calc){
return src2calc[l];
}
return getNodeId(l);
}

loc getNodeSource(NodeId id) {
if(id in node2src) return node2src[id];
v = id2node[id];
if(loc l := v) return l;
return |unknown:///|;
}

str getNodeLabel(NodeId id) {
if(id in node2label) return node2label[id];
v = id2node[id];
if(loc l := v) return "<id>: <getText(l)>";
return "<id>: ???:<v>";
}

str getText(loc l) {
try return readFile(l);
catch _: return "???<l>";
}

lrel[NodeId,NodeId] srcDependsOn(NodeId src, list[loc] dependsOn)
= [<src, getNodeIdViaCalculator(d)> | d <- dependsOn];

lrel[NodeId,NodeId] srcDependsOn(NodeId l, NodeId r, list[loc] dependsOn)
= srcDependsOn(l, dependsOn) + srcDependsOn(r, dependsOn);

lrel[NodeId,NodeId] calcEdges(c:calcType(loc src, AType atype)) {
id = getNodeId(c);
node2src[id] = src;
node2label[id] = "<id>: <getText(src)>";
src2calc[src] = id;
return [<id, getNodeId(|nothing:///|)>];
}

lrel[NodeId,NodeId] calcEdges(c:calcLoc(loc src, list[loc] dependsOn)){
NodeId id = getNodeId(c);
node2src[id] = src;
node2label[id] = "<id>: <getText(src)>";
src2calc[src] = id;
return srcDependsOn(id, dependsOn);
}

lrel[NodeId,NodeId] calcEdges(c:calc(str cname, loc src, list[loc] dependsOn, AType(Solver s) getAType)){
NodeId id = getNodeId(c);
node2src[id] = src;
node2label[id] = "C <id>, <cname>: <getText(src)>";
src2calc[src] = id;
return srcDependsOn(id, dependsOn);
}

lrel[NodeId,NodeId] calcEdges(c:calcLub(str cname, list[loc] srcs, list[loc] dependsOn, list[AType(Solver s)] getATypes)){
NodeId id = getNodeId(c);
node2label[id] = "C <id>, <cname>: <for(src<-srcs){><getText(src)>/<}>";
for(src <- srcs) src2calc[src] = id;
return srcDependsOn(id, dependsOn);
}

lrel[NodeId,NodeId] reqEdges(rq:req(str rname, loc src, list[loc] dependsOn, void(Solver s) preds)){
NodeId id = getNodeId(rq);
node2src[id] = src;
node2label[id] = "R <rname>: <getText(src)>";
return srcDependsOn(id, dependsOn);
}

lrel[NodeId,NodeId] reqEdges(rq:reqEqual(str rname, value l, value r, list[loc] dependsOn, FailMessage fm)){
NodeId id = getNodeId(rq);
node2label[id] = "R <rname>";
return srcDependsOn(getNodeId(l), getNodeId(r), dependsOn);
}

lrel[NodeId,NodeId] reqEdges(rq:reqComparable(str rname, value l, value r, list[loc] dependsOn, FailMessage fm)){
NodeId id = getNodeId(rq);
node2label[id] = "R <rname>";
return srcDependsOn(getNodeId(l), getNodeId(r), dependsOn);
}

lrel[NodeId,NodeId] reqEdges(rq:reqSubtype(str rname, value l, value r, list[loc] dependsOn, FailMessage fm)){
NodeId id = getNodeId(rq);
node2label[id] = "R <rname>";
return srcDependsOn(getNodeId(l), getNodeId(r), dependsOn);
}

lrel[NodeId,NodeId] reqEdges(rq:reqUnify(str rname, value l, value r, list[loc] dependsOn, FailMessage fm)){
NodeId id = getNodeId(rq);
node2label[id] = "R <rname>";
return srcDependsOn(getNodeId(l), getNodeId(r), dependsOn);
}

lrel[NodeId,NodeId] reqEdges(rq:reqError (loc src, list[loc] dependsOn, FailMessage fm)){
NodeId id = getNodeId(rq);
node2src[id] = src;
node2label[id] = "R error: <getText(src)>";
return srcDependsOn(id, dependsOn);
}

lrel[NodeId,NodeId] reqEdges(rq:reqErrors(loc src, list[loc] dependsOn, list[FailMessage] fms)){
NodeId id = getNodeId(rq);
node2src[id] = src;
node2label[id] = "R errors: <getText(src)>";
return srcDependsOn(id, dependsOn);
}

NodeId replaceByCalc(NodeId id){
if(id in node2src){
src = node2src[id];
if(src in src2calc) return src2calc[src];
}
return id;
}

void viewDependencies(TModel tm){
initNodes();
for(Calculator c <- tm.calculators){
NodeId id = getNodeId(c);
if(c has src){
src2calc[c.src] = id;
} else if(c has srsc){
for(src <- c.srcs){
src2calc[src] = id;
}
}
}

cedges = {*calcEdges(c) | Calculator c <- tm.calculators};
redges = {*reqEdges(r) | Requirement r <- tm.requirements};
edges = toList(cedges + redges);
println("edges: <edges>");
for(NodeId id <- sort(domain(id2node))) { println("<id>"); iprintln(id2node[id]); }

list[str] nodeClassifier(NodeId id){
res = [];
switch(id2node[id]){
case Calculator _: res = ["calc"];
case Requirement _: res = ["req"];
case loc _: res = ["text"];
}
return res;
}

styles = [
cytoStyleOf(
selector=\node(className("text")),
style=defaultNodeStyle()[shape=CytoNodeShape::rectangle()][\background-color="grey"]),
cytoStyleOf(
selector=\node(className("calc")),
style=defaultNodeStyle()[shape=CytoNodeShape::ellipse()][\background-color="green"]),
cytoStyleOf(
selector=\node(className("req")),
style=defaultNodeStyle()[shape=CytoNodeShape::diamond()][\background-color="blue"])
];
cfg = cytoGraphConfig(
title="Graph: <tm.modelName>",
nodeClassifier=nodeClassifier,
nodeLinker=getNodeSource,
nodeLabeler=getNodeLabel,
styles=styles,
\layout=defaultDagreLayout()[ranker=\tight-tree()]);

showInteractiveContent(graph(edges, cfg=cfg));
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ import lang::rascalcore::compile::util::Names;
import analysis::typepal::StringSimilarity;
import analysis::typepal::LocationChecks;

import lang::rascalcore::check::DependencyViewer;

import IO;
import List;
import Map;
Expand Down Expand Up @@ -403,6 +405,7 @@ rel[loc, PathRole,loc] enhancePathRelation(rel[MODID, PathRole, MODID] paths){
// Enhance TModel before running Solver by

TModel rascalPreSolver(map[str,Tree] _namedTrees, TModel m){
// viewDependencies(m);
return m[paths = enhancePathRelation(m.paths)];
}

Expand Down
18 changes: 17 additions & 1 deletion src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module lang::rascalcore::check::ScopeInfo
import lang::rascalcore::check::BasicRascalConfig;
import lang::rascalcore::check::NameUtils;
import lang::rascal::\syntax::Rascal;
import lang::rascalcore::check::ATypeExceptions;

public /*const*/ str patternContainer = "patternContainer";
public /*const*/ str patternNames = "patternNames";
Expand Down Expand Up @@ -158,5 +159,20 @@ void endUseBoundedTypeParameters(Collector c){
if(useBoundedTP(_) !:= handler)
throw "beginUseBoundedTypeParameters/endUseBoundedTypeParameters not properly nested";
}

list[Tree] addReturnTypeDependency(Tree current, Tree tp, Collector c){
if(/TypeVar _ := current){
functionScopes = c.getScopeInfo(functionScope());
if(!isEmpty(functionScopes)){
for(<_, scopeInfo> <- functionScopes){
if(signatureInfo(Type returnType) := scopeInfo){
return [tp, returnType];
} else {
throw rascalCheckerInternalError(getLoc(current), "Inconsistent info from function scope: <scopeInfo>");
}
}
}
}
return [tp];
}

data OrInfo = orInfo(set[str] vars);
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@ import lang::rascalcore::check::RascalConfig;

import lang::rascalcore::check::Checker;
import lang::rascal::\syntax::Rascal;
loc root = |memory://e0711529-477e-4a4c-b44b-44b00157728eXXX|;

// this uuid matters
loc root = |memory://36a14c42-e4e6-41e0-a59a-ac11f637070c|;

PathConfig pcfg = pathConfig(
srcs = [root + "src"],
bin = root + "bin",
libs = []
);

// this name matters
str moduleName = "TestModule612d1";

loc writeModule() {
loc moduleLoc = pcfg.srcs[0] + "<moduleName>.rsc";
// the spaces before &T seems to matter?
writeFile(moduleLoc,
"module TestModule612d1\r\n \r\n &T \<: int f(&T \<: num _) = 1;"
"module TestModule612d1\n \n &T \<: int f(&T \<: num _) = 1;"
);
return moduleLoc;
}
Expand Down Expand Up @@ -74,7 +77,7 @@ void findCollission(loc l) {
}
}


void main() {
remove(root, recursive = true);
l = writeModule();
Expand Down
Loading
Loading