From 27b669997477d1af51f0b79d8b4997d317aa265b Mon Sep 17 00:00:00 2001 From: Franco Leonardo Bulgarelli Date: Thu, 16 Feb 2023 13:59:38 -0300 Subject: [PATCH 1/3] Generalize declares computation --- .../Mulang/Analyzer/EdlQueryCompiler.hs | 14 +++++------ src/Language/Mulang/Inspector/Generic.hs | 23 ++++++++++++------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/Language/Mulang/Analyzer/EdlQueryCompiler.hs b/src/Language/Mulang/Analyzer/EdlQueryCompiler.hs index 952a6295..d6aada1c 100644 --- a/src/Language/Mulang/Analyzer/EdlQueryCompiler.hs +++ b/src/Language/Mulang/Analyzer/EdlQueryCompiler.hs @@ -106,13 +106,13 @@ compileInspection = f f "Declares" E.Unmatching = bound declares f "DeclaresAttribute" m = boundMatching declaresAttributeMatching m f "DeclaresClass" m = boundMatching declaresClassMatching m - f "DeclaresComputation" E.Unmatching = bound declaresComputation - f "DeclaresComputationWithArity0" E.Unmatching = bound (declaresComputationWithArity 0) - f "DeclaresComputationWithArity1" E.Unmatching = bound (declaresComputationWithArity 1) - f "DeclaresComputationWithArity2" E.Unmatching = bound (declaresComputationWithArity 2) - f "DeclaresComputationWithArity3" E.Unmatching = bound (declaresComputationWithArity 3) - f "DeclaresComputationWithArity4" E.Unmatching = bound (declaresComputationWithArity 4) - f "DeclaresComputationWithArity5" E.Unmatching = bound (declaresComputationWithArity 5) + f "DeclaresComputation" m = boundMatching declaresComputationMatching m + f "DeclaresComputationWithArity0" m = boundMatching (declaresComputationWithArityMatching 0) m + f "DeclaresComputationWithArity1" m = boundMatching (declaresComputationWithArityMatching 1) m + f "DeclaresComputationWithArity2" m = boundMatching (declaresComputationWithArityMatching 2) m + f "DeclaresComputationWithArity3" m = boundMatching (declaresComputationWithArityMatching 3) m + f "DeclaresComputationWithArity4" m = boundMatching (declaresComputationWithArityMatching 4) m + f "DeclaresComputationWithArity5" m = boundMatching (declaresComputationWithArityMatching 5) m f "DeclaresEntryPoint" m = boundMatching declaresEntryPointMatching m f "DeclaresEnumeration" E.Unmatching = bound declaresEnumeration f "DeclaresFact" E.Unmatching = bound declaresFact diff --git a/src/Language/Mulang/Inspector/Generic.hs b/src/Language/Mulang/Inspector/Generic.hs index 8037f489..b3548879 100644 --- a/src/Language/Mulang/Inspector/Generic.hs +++ b/src/Language/Mulang/Inspector/Generic.hs @@ -17,7 +17,8 @@ module Language.Mulang.Inspector.Generic ( declares, declaresComputation, declaresComputationWithArity, - declaresComputationWithArity', + declaresComputationMatching, + declaresComputationWithArityMatching, declaresEntryPoint, declaresEntryPointMatching, declaresFunction, @@ -187,16 +188,22 @@ declaresEntryPointMatching matcher = containsBoundDeclaration f f _ = False -- | Inspection that tells whether a top level computation declaration exists -declaresComputation :: BoundInspection -declaresComputation = declaresComputationWithArity' (const True) +declaresComputation ::BoundInspection +declaresComputation = unmatching declaresComputationMatching + +declaresComputationMatching :: Matcher -> BoundInspection +declaresComputationMatching = declaresComputationWithArityMatching' (const True) declaresComputationWithArity :: Int -> BoundInspection -declaresComputationWithArity arity = declaresComputationWithArity' (== arity) +declaresComputationWithArity arity = unmatching (declaresComputationWithArityMatching arity) + +declaresComputationWithArityMatching :: Int -> Matcher -> BoundInspection +declaresComputationWithArityMatching arity = declaresComputationWithArityMatching' (== arity) -declaresComputationWithArity' :: (Int -> Bool) -> BoundInspection -declaresComputationWithArity' arityPredicate = containsBoundDeclaration f - where f (Subroutine _ es) = any equationArityIs es - f (Clause _ args _) = argsHaveArity args +declaresComputationWithArityMatching' :: (Int -> Bool) -> Matcher -> BoundInspection +declaresComputationWithArityMatching' arityPredicate matcher = containsBoundDeclaration f + where f (Subroutine _ eqs) = any equationArityIs eqs && matches matcher equationsExpandedExpressions eqs + f (Clause _ args es) = argsHaveArity args && matcher es f _ = False equationArityIs (Equation args _) = argsHaveArity args From c7f14486211fbae657fcb70f94cca4ee43498f80 Mon Sep 17 00:00:00 2001 From: Franco Leonardo Bulgarelli Date: Thu, 16 Feb 2023 14:04:56 -0300 Subject: [PATCH 2/3] Add translations --- gem/lib/locales/en.yml | 8 ++++---- gem/lib/locales/es.yml | 8 ++++---- gem/lib/locales/pt.yml | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gem/lib/locales/en.yml b/gem/lib/locales/en.yml index 475e424e..0ded97d7 100644 --- a/gem/lib/locales/en.yml +++ b/gem/lib/locales/en.yml @@ -39,10 +39,10 @@ en: DeclaresClass_like: '%{binding} %{must} declare a class similar to %{target}' DeclaresClass_named: '%{binding} %{must} declare a class %{target}' DeclaresClass: '%{binding} %{must} declare classes' - DeclaresComputation_except: '%{binding} %{must} declare computations distinct from %{target}' - DeclaresComputation_like: '%{binding} %{must} declare a computation similar to %{target}' - DeclaresComputation_named: '%{binding} %{must} declare a computation %{target}' - DeclaresComputation: '%{binding} %{must} declare computations' + DeclaresComputation_except: '%{binding} %{must} declare computations distinct from %{target}%{matching}' + DeclaresComputation_like: '%{binding} %{must} declare a computation similar to %{target}%{matching}' + DeclaresComputation_named: '%{binding} %{must} declare a computation %{target}%{matching}' + DeclaresComputation: '%{binding} %{must} declare computations%{matching}' DeclaresComputationWithArity0_named: '%{target} %{must} have zero parameters' DeclaresComputationWithArity1_named: '%{target} %{must} have one parameter' DeclaresComputationWithArity2_named: '%{target} %{must} have 2 parameters' diff --git a/gem/lib/locales/es.yml b/gem/lib/locales/es.yml index 137203b8..f2b787ab 100644 --- a/gem/lib/locales/es.yml +++ b/gem/lib/locales/es.yml @@ -39,10 +39,10 @@ es: DeclaresClass_like: '%{binding} %{must} declarar una clase parecida a %{target}' DeclaresClass_named: '%{binding} %{must} declarar una clase %{target}' DeclaresClass: '%{binding} %{must} declarar clases' - DeclaresComputation_except: '%{binding} %{must} declarar computaciones diferentes a %{target}' - DeclaresComputation_like: '%{binding} %{must} declarar una computación parecida a %{target}' - DeclaresComputation_named: '%{binding} %{must} declarar una computación %{target}' - DeclaresComputation: '%{binding} %{must} declarar computaciones' + DeclaresComputation_except: '%{binding} %{must} declarar computaciones diferentes a %{target}%{matching}' + DeclaresComputation_like: '%{binding} %{must} declarar una computación parecida a %{target}%{matching}' + DeclaresComputation_named: '%{binding} %{must} declarar una computación %{target}%{matching}' + DeclaresComputation: '%{binding} %{must} declarar computaciones%{matching}' DeclaresComputationWithArity0_named: '%{target} %{must} declarar cero parametros' DeclaresComputationWithArity1_named: '%{target} %{must} tener un parámetro' DeclaresComputationWithArity2_named: '%{target} %{must} tener dos parámetros' diff --git a/gem/lib/locales/pt.yml b/gem/lib/locales/pt.yml index 50bb00d7..e0ca69b8 100644 --- a/gem/lib/locales/pt.yml +++ b/gem/lib/locales/pt.yml @@ -39,10 +39,10 @@ pt: DeclaresClass_like: '%{binding} %{must} declarar uma classe semelhante a %{target}' DeclaresClass_named: '%{binding} %{must} declarar uma classe %{target}' DeclaresClass: '%{binding} %{must} declarar classes' - DeclaresComputation_except: '%{binding} %{must} declarar cálculos diferentes de %{target}' - DeclaresComputation_like: '%{binding} %{must} declarar uma computação semelhante a %{target}' - DeclaresComputation_named: '%{binding} %{must} declarar uma computação %{target}' - DeclaresComputation: '%{binding} %{must} declarar cálculos' + DeclaresComputation_except: '%{binding} %{must} declarar cálculos diferentes de %{target}%{matching}' + DeclaresComputation_like: '%{binding} %{must} declarar uma computação semelhante a %{target}%{matching}' + DeclaresComputation_named: '%{binding} %{must} declarar uma computação %{target}%{matching}' + DeclaresComputation: '%{binding} %{must} declarar cálculos%{matching}' DeclaresComputationWithArity0_named: '%{target} %{must} declarar parâmetros zero' DeclaresComputationWithArity1_named: '%{target} %{must} ter um parâmetro' DeclaresComputationWithArity2_named: '%{target} %{must} ter dois parâmetros' From 6246354afa167e6f5b69efd950598a15800f423d Mon Sep 17 00:00:00 2001 From: Franco Leonardo Bulgarelli Date: Tue, 21 Mar 2023 16:46:40 -0300 Subject: [PATCH 3/3] Add tests --- spec/GenericSpec.hs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/spec/GenericSpec.hs b/spec/GenericSpec.hs index 206eb95e..1a5d9496 100644 --- a/spec/GenericSpec.hs +++ b/spec/GenericSpec.hs @@ -547,6 +547,32 @@ spec = do it "is True when exists" $ do declaresComputation (named "x") (hs "x _ = True") `shouldBe` True + describe "with matchers" $ do + it "is True when using a matcher that matches" $ do + (declaresComputationMatching (with isSelf) anyone) (js "function f(x) { this; return 0; }") `shouldBe` True + (declaresComputationMatching (with isSelf) anyone) (js "function f(x) { this; }") `shouldBe` True + + it "is False when using a matcher that does not match" $ do + (declaresComputationMatching (with isSelf) anyone) (js "function f(x) { return 0; }") `shouldBe` False + (declaresComputationMatching (with isSelf) anyone) (js "function f(x) { }") `shouldBe` False + + it "is True when using a non literal returns matcher that matches" $ do + (declaresComputationMatching (with (returnsMatching (with (isNumber 2)))) anyone) (js "function f() { return 2; }") `shouldBe` True + + it "is False when using a non literal returns matcher that doesn't match" $ do + (declaresComputationMatching (with (returnsMatching (with (isNumber 2)))) anyone) (js "function f() { return 3; }") `shouldBe` False + + it "is True when using a non literal assigns matcher that matches" $ do + (declaresComputationMatching (with (assignsMatching (with (isNumber 2)) anyone)) anyone) (js "function f() { window.aGlobal = 2; }") `shouldBe` True + + it "is False when using a non literal assigns matcher that doesn't match" $ do + (declaresComputationMatching (with (assignsMatching (with (isNumber 2)) anyone)) anyone) (js "function f() { window.aGlobal = 3; }") `shouldBe` False + + it "is False when using a literal matcher and it does not match literally" $ do + (declaresComputationMatching (with . isNumber $ 2) anyone) (js "function f() { return 2; }") `shouldBe` False + (declaresComputationMatching (with . isNumber $ 2) anyone) (js "function f() { window.aGlobal = 2 }") `shouldBe` False + + describe "declares" $ do describe "with constants" $ do it "is True when exists" $ do