Skip to content
Merged
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
28 changes: 11 additions & 17 deletions src/analysis/typepal/Collector.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module analysis::typepal::Collector
Implementation of the ICollector interface; this is the API of TypePal's fact and constraint collector
*/

import DateTime;
import Node;
import Map;
import ParseTree;
Expand Down Expand Up @@ -289,11 +290,14 @@ TModel convertTModel2LogicalLocs(TModel tm, map[str,TModel] tmodels){
return tm;
}

Collector newCollector(str modelName, map[str,Tree] namedTrees, TypePalConfig config){
Collector newCollector(str modelName, map[str,Tree] namedTrees, TypePalConfig config, datetime timestamp = $0000-01-01T00:00:00.000+00:00$){

str normalizeName(str input) {
return config.normalizeName(input);
}
if(!timestamp?){
timestamp = now();
}
loc globalScope = |global-scope:///|;
Defines defines = {};

Expand All @@ -320,7 +324,6 @@ Collector newCollector(str modelName, map[str,Tree] namedTrees, TypePalConfig co
loc currentScope = globalScope;
loc rootScope = globalScope;

for(nm <- namedTrees) scopes[getLoc(namedTrees[nm])] = globalScope;
lrel[loc scope, bool lubScope, map[ScopeRole, value] scopeInfo] scopeStack = [<globalScope, false, (anonymousScope(): false)>];
list[loc] lubScopeStack = [];
loc currentLubScope = globalScope;
Expand All @@ -335,6 +338,7 @@ Collector newCollector(str modelName, map[str,Tree] namedTrees, TypePalConfig co
else if(loc ldef := def) l = ldef;
else throw TypePalUsage("Argument `def` of `define` should be `Tree` or `loc`, found <typeOf(def)>");

info.timestamp = timestamp;
def_tup = <orgId, idRole>;
nname = normalizeName(orgId);

Expand Down Expand Up @@ -414,7 +418,7 @@ Collector newCollector(str modelName, map[str,Tree] namedTrees, TypePalConfig co
if(Tree tdef := def) l = getLoc(tdef);
else if(loc ldef := def) l = ldef;
else throw TypePalUsage("Argument `def` of `defineInScope` should be `Tree` or `loc`, found <typeOf(def)>");

info.timestamp = timestamp;
nname = normalizeName(orgId);
if(info is defTypeLub){
throw TypePalUsage("`defLub` cannot be used in combination with `defineInScope`");
Expand Down Expand Up @@ -1005,10 +1009,10 @@ Collector newCollector(str modelName, map[str,Tree] namedTrees, TypePalConfig co
logical2physical += tm.logical2physical;
messages += tm.messages;

scopes += tm.scopes;
scopes = tm.scopes + scopes;
Comment thread
PaulKlint marked this conversation as resolved.
defines += tm.defines;
facts += tm.facts;
paths += tm.paths;
facts = tm.facts + facts;
paths = tm.paths + paths;
}

map[loc,loc] buildLogical2physical(Defines defines){
Expand All @@ -1023,17 +1027,7 @@ Collector newCollector(str modelName, map[str,Tree] namedTrees, TypePalConfig co
}
for(Define def <- defines){
logicalLoc = my_physical2logical[def.defined] ? config.createLogicalLoc(def, modelName, config.typepalPathConfig);
if(logicalLoc != def.defined){
if(logicalLoc in my_logical2physical){
if(my_logical2physical[logicalLoc] != def.defined){
causes = [ info("Clone of `<def.id>`", my_logical2physical[logicalLoc]),
info("Clone of `<def.id>`", def.defined)
];
messages += error("Remove code clone for <prettyRole(def.idRole)> `<def.id>`", def.defined, causes=causes);
}
}
my_logical2physical[logicalLoc] = def.defined;
}
my_logical2physical[logicalLoc] = def.defined;
}
return my_logical2physical;
}
Expand Down
34 changes: 29 additions & 5 deletions src/analysis/typepal/Solver.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ Solver newSolver(map[str,Tree] namedTrees, TModel tm){

bool(loc def, TModel tm) reportUnused = defaultReportUnused;

map[loc,loc] logical2physical = tm.logical2physical;

void configTypePal(TypePalConfig tc){

normalizeName = tc.normalizeName;
Expand Down Expand Up @@ -803,8 +801,35 @@ Solver newSolver(map[str,Tree] namedTrees, TModel tm){
definedBy[u.occ] = foundDefs;
newPaths += {<u.scope, rp.pathRole, def>};
} else {
causes = [ info("Definition of `<u.id>`", d) | d <- foundDefs ];
messages += error("Name `<u.id>` is ambiguous", u.occ, causes=causes);
set[Define] defs = { definitions[d] | d <- foundDefs };
set[str] md5s = { d.defInfo.md5 | d <- defs };
if(size(md5s) == 1){
latestDef = getOneFrom(defs);
for(Define d <- defs){
if(d.defInfo.timestamp?){
if(latestDef.defInfo.timestamp?){
if(d.defInfo.timestamp == latestDef.defInfo.timestamp){
causes = [ info("Definition of `<u.id>`", fd) | loc fd <- foundDefs ];
messages += error("Name `<u.id>` is ambiguous", u.occ, causes=causes);
} else
if(d.defInfo.timestamp > latestDef.defInfo.timestamp){
latestDef = d;
}
} else {
latestDef = d;
}
}
}
definedBy[u.occ] = {latestDef.defined};
newPaths += {<u.scope, rp.pathRole, latestDef.defined>};
} else {
println("Ambiguous <u.id>"); iprintln(foundDefs);
for(d <- foundDefs){
println("<definitions[d]>, <definitions[d].defInfo.md5>");
}
causes = [ info("Definition of `<u.id>`", d) | d <- foundDefs ];
messages += error("Name `<u.id>` is ambiguous", u.occ, causes=causes);
}
}
referPaths -= {rp};
} else {
Expand Down Expand Up @@ -1279,7 +1304,6 @@ Solver newSolver(map[str,Tree] namedTrees, TModel tm){
orgId = udef.orgId;
idRole = udef.idRole;
defined = udef.defined;
if(defined in logical2physical) continue;

u = use(id, orgId, defined, scope, {idRole}); // turn each unused definition into a use and check for double declarations;
try {
Expand Down
3 changes: 1 addition & 2 deletions src/analysis/typepal/TModel.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ alias ReferPaths = set[ReferPath];

// Language-specific auxiliary associated with a name definition
// Extended in a language-specific module

data DefInfo
data DefInfo(str md5 = "", datetime timestamp = $0000-01-01T00:00:00.000+00:00$)
= noDefInfo()
;

Expand Down