From 67cf77cbb1f3b04abeea752dc3966ca59fa42d3c Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 19 Mar 2024 10:42:41 +0100 Subject: [PATCH] Improved handling of || expressions This solves false "Unused variable" warnings of variables introduced in right-hand side --- .settings/org.eclipse.core.resources.prefs | 2 -- .../rascalcore/check/BasicRascalConfig.rsc | 9 +++--- .../rascalcore/check/CollectOperators.rsc | 29 ++++++++++--------- .../lang/rascalcore/check/CollectPattern.rsc | 9 ++++++ .../lang/rascalcore/compile/Examples/Tst5.rsc | 13 +++++---- 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index 4e8aa177..7ec1b20e 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,7 +1,5 @@ eclipse.preferences.version=1 encoding//src/org/rascalmpl/core/library=UTF-8 -encoding//target/generated-test-resources=UTF-8 -encoding//target/generated-test-sources=UTF-8 encoding/=UTF-8 encoding/src=UTF-8 encoding/test=UTF-8 diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/BasicRascalConfig.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/BasicRascalConfig.rsc index f2cb667f..171759be 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/BasicRascalConfig.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/BasicRascalConfig.rsc @@ -51,13 +51,14 @@ data PathRole ; data ScopeRole - = moduleScope() - | functionScope() - | conditionalScope() + = //moduleScope() + functionScope() + //| conditionalScope() | replacementScope() | visitOrSwitchScope() - | boolScope() + //| boolScope() | loopScope() + | orScope() ; data Vis diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectOperators.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectOperators.rsc index 130c1d2f..ed067e36 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectOperators.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectOperators.rsc @@ -756,7 +756,8 @@ void collect(current: (Expression) ` && `, Colle } private set[str] introducedVars(Expression exp, Collector c){ - return exp is match ? introducedVars(exp.pattern, c) : {}; + return exp is \bracket ? introducedVars(exp.expression, c) + : (exp is match ? introducedVars(exp.pattern, c) : {}); } private set[str] introducedVars(Pattern e, Collector c){ @@ -793,6 +794,8 @@ private set[str] introducedVars(Pattern e, Collector c){ // ---- or +data OrInfo = orInfo(set[str] vars); + void collect(current: (Expression) ` || `, Collector c){ c.fact(current, abool()); @@ -802,24 +805,22 @@ void collect(current: (Expression) ` || `, Colle s.requireUnify(abool(), rhs, error(rhs, "Argument of || should be `bool`, found %t", rhs)); }); - // Check that the names introduced in lhs and rhs are the same + collect(lhs, c); introLhs = introducedVars(lhs, c); - introRhs = introducedVars(rhs, c); + introRhs = introducedVars(rhs, c); - collect(lhs, c); + // make common variables available when collecting rhs; + // variables in rhs will use definition from lhs (see CollectPattern: typed variable pattern, qualifiedName pattern) + c.setScopeInfo(c.getScope(), orScope(), orInfo(introLhs)); + collect(rhs, c); - // Trick 1: wrap rhs in a separate scope to avoid double declarations with names introduced in lhs - // Trick 2: use "current" as scope (to avoid clash with scope created by rhs) - c.enterScope(lhs); - collect(rhs, c); - c.leaveScope(lhs); + // Check that the names introduced in lhs and rhs are the same + common = introLhs & introRhs; + missing = (introLhs - common) + (introRhs - common); - for(nm <- introLhs){ - if(nm notin introRhs) c.report(error(rhs, "Arguments of `||` should introduce same variables, right argument does not introduce `%v`", nm)); - } - for(nm <- introRhs){ - if(nm notin introLhs) c.report(error(lhs, "Arguments of `||` should introduce same variables, left argument does not introduce `%v`", nm)); + if(!isEmpty(missing)){ + c.report(error(current, "Variable(s) %v should be introduced on both sides of `||` operator", missing)); } } diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectPattern.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectPattern.rsc index ef54c6d0..fecd0cd1 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectPattern.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectPattern.rsc @@ -78,6 +78,15 @@ void collect(current: (Pattern) ` `, Collector c){ && c.isAlreadyDefined("", name)){ c.use(name, {variableId(), moduleVariableId(), formalId(), nestedFormalId(), patternVariableId()}); } else { + orScopes = c.getScopeInfo(orScope()); + for(<_, orInfo(vars)> <- orScopes){ + for(str id <- vars, id == uname){ + if(c.isAlreadyDefined("", name)){ + c.use(name, {variableId(), formalId(), nestedFormalId(), patternVariableId()}); + return; + } + } + } c.define(uname, formalOrPatternFormal(c), name, defType(tpResolved)); } } else { diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc index 93f1da63..7ce7d1a0 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc @@ -1,11 +1,5 @@ module lang::rascalcore::compile::Examples::Tst5 -void main(){ - previous = "non empty"; - msg = " - '<}>"; -} - //MH //public void showUsageCounts(Corpus corpus, lrel[str p, str v, QueryResult qr] res) { // mr = ( p : size([ e | <- res ]) | p <- corpus ); @@ -19,6 +13,13 @@ void main(){ // return -1; //} +value main(){ + if ((j := 1) || (j := 2)) { + return j; + } + return -1; +} + //data Wrapper[&SAME] = something(&SAME wrapped); //