From c96f4a01586c03bdb56d3d17b6b5d75ef65d4d01 Mon Sep 17 00:00:00 2001 From: paulklint Date: Sun, 6 Oct 2024 12:05:41 +0200 Subject: [PATCH] Made isAlreadyDefined more robust - Take scoping structure in comprehensions into account --- src/analysis/typepal/Collector.rsc | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/analysis/typepal/Collector.rsc b/src/analysis/typepal/Collector.rsc index c2dc95d..ca78e08 100644 --- a/src/analysis/typepal/Collector.rsc +++ b/src/analysis/typepal/Collector.rsc @@ -333,21 +333,37 @@ Collector newCollector(str modelName, map[str,Tree] namedTrees, TypePalConfig co return appl(prod(sort("$PREDEFINED-"), [], {}), [])[@\loc=defining[query="predefined="][fragment=""]]; } + + bool isContainedInScopes(loc l, loc r){ + outer = r; + do { + if(isContainedIn(l, outer)){ + return true; + } + if(scopes[outer]?) { + outer = scopes[outer]; + } else { + return false; + } + } while (true); + return false; + } bool collector_isAlreadyDefined(str id, Tree useOrDef){ lubdefs = { def | def <- definesPerLubScope[currentLubScope], def.id == id } + { def | def <- lubDefinesPerLubScope[currentLubScope], def.id == id }; + useOrDefLoc = getLoc(useOrDef); - if(!isEmpty(lubdefs) && any(def <- lubdefs, isContainedIn(getLoc(useOrDef), def.scope))){ + if(!isEmpty(lubdefs) && any(def <- lubdefs, isContainedInScopes(useOrDefLoc, def.scope))){ return true; } - for(def <- defines, def.id == id, config.isInferrable(def.idRole), isContainedIn(getLoc(useOrDef), def.scope)){ + for(def <- defines, def.id == id, config.isInferrable(def.idRole), isContainedInScopes(useOrDefLoc, def.scope)){ return true; } - for(def <- defines, def.id == id, isContainedIn(getLoc(useOrDef), def.scope)){ + for(def <- defines, def.id == id, isContainedInScopes(useOrDefLoc, def.scope)){ return true; } return false;