From 2197c104d527461a05a384e99d2fbaa581dbed61 Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Wed, 19 Jul 2017 16:32:11 -0300 Subject: [PATCH 01/16] Adding interfaces and enums --- spec/InspectorSpec.hs | 14 ++++++++++++++ src/Language/Mulang/Ast.hs | 7 ++++++- src/Language/Mulang/Explorer.hs | 2 ++ src/Language/Mulang/Inspector/ObjectOriented.hs | 12 ++++++++++++ src/Language/Mulang/Unfold.hs | 2 ++ 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/spec/InspectorSpec.hs b/spec/InspectorSpec.hs index dc40c2b69..b07aa506f 100644 --- a/spec/InspectorSpec.hs +++ b/spec/InspectorSpec.hs @@ -199,6 +199,20 @@ spec = do it "is True when anyone present, scoped" $ do declaresObject anyone (js "var g = {}") `shouldBe` True + describe "declaresEnumeration" $ do + it "is True when present" $ do + declaresEnumeration (named "Direction") (Enumeration "Direction" ["SOUTH", "EAST", "WEST", "NORTH"]) `shouldBe` True + + it "is False when not present" $ do + declaresEnumeration (named "Bird") (Class "Bird" (Just "Animal") MuNull) `shouldBe` False + + describe "declaresInterface" $ do + it "is True when present" $ do + declaresInterface (named "Optional") (Interface "Optional" [] (TypeSignature "get" ["A"])) `shouldBe` True + + it "is False when not present" $ do + declaresInterface (named "Bird") (Class "Bird" (Just "Animal") MuNull) `shouldBe` False + describe "usesInheritance" $ do it "is True when present" $ do usesInheritance (Class "Bird" (Just "Animal") MuNull) `shouldBe` True diff --git a/src/Language/Mulang/Ast.hs b/src/Language/Mulang/Ast.hs index e93a2648b..bd15e297a 100644 --- a/src/Language/Mulang/Ast.hs +++ b/src/Language/Mulang/Ast.hs @@ -81,7 +81,12 @@ data Expression -- composed by a name and a body | Class Identifier (Maybe Identifier) Expression -- ^ Object oriented programming global, class declaration, - -- composed by a name, superclass and a body + -- composed by a name, an optional superclass, implemented interfaces and a body + | Enumeration Identifier [Identifier] + -- ^ Imperative named enumeration of values + | Interface Identifier [Identifier] Expression + -- ^ Object oriented programming global interface or contract declaration, + -- composed by a name, subinterfaces and a body | Rule Identifier [Pattern] [Expression] -- ^ Logic programming declaration of a fact, composed by the rue name, rule arguments, and rule body | Fact Identifier [Pattern] diff --git a/src/Language/Mulang/Explorer.hs b/src/Language/Mulang/Explorer.hs index 9305e0aae..8a9ee30ab 100644 --- a/src/Language/Mulang/Explorer.hs +++ b/src/Language/Mulang/Explorer.hs @@ -86,6 +86,8 @@ extractDeclaration e@(Record n) = Just (n, e) extractDeclaration e@(Clause n _ _) = Just (n, e) extractDeclaration e@(Object n _) = Just (n, e) extractDeclaration e@(Class n _ _) = Just (n, e) +extractDeclaration e@(Interface n _ _) = Just (n, e) +extractDeclaration e@(Enumeration n _) = Just (n, e) extractDeclaration e@(Attribute n _) = Just (n, e) extractDeclaration e@(EntryPoint n _) = Just (n, e) extractDeclaration _ = Nothing diff --git a/src/Language/Mulang/Inspector/ObjectOriented.hs b/src/Language/Mulang/Inspector/ObjectOriented.hs index 9203e0a4d..b772941bb 100644 --- a/src/Language/Mulang/Inspector/ObjectOriented.hs +++ b/src/Language/Mulang/Inspector/ObjectOriented.hs @@ -3,6 +3,8 @@ module Language.Mulang.Inspector.ObjectOriented ( declaresObject, declaresSuperclass, declaresClass, + declaresInterface, + declaresEnumeration, declaresAttribute, declaresMethod) where @@ -28,6 +30,16 @@ declaresClass = containsDeclaration f where f (Class _ _ _) = True f _ = False +declaresEnumeration :: BindingPredicate -> Inspection +declaresEnumeration = containsDeclaration f + where f (Enumeration _ _) = True + f _ = False + +declaresInterface :: BindingPredicate -> Inspection +declaresInterface = containsDeclaration f + where f (Interface _ _ _) = True + f _ = False + declaresAttribute :: BindingPredicate -> Inspection declaresAttribute = containsDeclaration f where f (Attribute _ _) = True diff --git a/src/Language/Mulang/Unfold.hs b/src/Language/Mulang/Unfold.hs index fedd94b34..74c5c1dc7 100644 --- a/src/Language/Mulang/Unfold.hs +++ b/src/Language/Mulang/Unfold.hs @@ -19,6 +19,7 @@ allExpressions expr = expr : concatMap allExpressions (subExpressions expr) subExpressions (Attribute _ v) = [v] subExpressions (Object _ v) = [v] subExpressions (Class _ _ v) = [v] + subExpressions (Interface _ _ v) = [v] subExpressions (EntryPoint _ e) = [e] subExpressions (Call op args) = op:args subExpressions (Lambda _ a) = [a] @@ -44,6 +45,7 @@ allExpressions expr = expr : concatMap allExpressions (subExpressions expr) mainExpressions :: Unfold mainExpressions o@(Object _ b) = o : mainExpressions b mainExpressions c@(Class _ _ b) = c : mainExpressions b +mainExpressions c@(Interface _ _ b) = c : mainExpressions b mainExpressions e@(EntryPoint _ b) = e : mainExpressions b mainExpressions t@(TypeSignature _ _) = [t] mainExpressions t@(TypeAlias _ ) = [t] From 75d5827ff05ef5263d35c7eb18f787b38dc5214a Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sat, 22 Jul 2017 00:41:59 -0300 Subject: [PATCH 02/16] Adding return type to type signature --- spec/InspectorSpec.hs | 2 +- spec/SignatureSpec.hs | 6 ++-- spec/SignaturesAnalyzerSpec.hs | 1 + src/Language/Mulang/Ast.hs | 6 ++-- src/Language/Mulang/Explorer.hs | 2 +- src/Language/Mulang/Inspector/Generic.hs | 8 ++--- src/Language/Mulang/Parsers/Haskell.hs | 9 +++-- src/Language/Mulang/Signature.hs | 44 ++++++++++++------------ src/Language/Mulang/Unfold.hs | 2 +- 9 files changed, 42 insertions(+), 38 deletions(-) diff --git a/spec/InspectorSpec.hs b/spec/InspectorSpec.hs index b07aa506f..4eb98253f 100644 --- a/spec/InspectorSpec.hs +++ b/spec/InspectorSpec.hs @@ -208,7 +208,7 @@ spec = do describe "declaresInterface" $ do it "is True when present" $ do - declaresInterface (named "Optional") (Interface "Optional" [] (TypeSignature "get" ["A"])) `shouldBe` True + declaresInterface (named "Optional") (Interface "Optional" [] (TypeSignature "get" [] "A")) `shouldBe` True it "is False when not present" $ do declaresInterface (named "Bird") (Class "Bird" (Just "Animal") MuNull) `shouldBe` False diff --git a/spec/SignatureSpec.hs b/spec/SignatureSpec.hs index d8c8468b9..c063360de 100644 --- a/spec/SignatureSpec.hs +++ b/spec/SignatureSpec.hs @@ -45,13 +45,13 @@ spec = do describe "TypedSignature" $ do it "simple variable type declaration" $ do - signaturesOf (hs "foo :: Int") `shouldBe` [TypedSignature "foo" ["Int"]] + signaturesOf (hs "foo :: Int") `shouldBe` [TypedSignature "foo" [] "Int"] it "simple function type declaration" $ do - signaturesOf (hs "foo :: Int -> Int") `shouldBe` [TypedSignature "foo" ["Int", "Int"]] + signaturesOf (hs "foo :: Int -> Int") `shouldBe` [TypedSignature "foo" ["Int"] "Int"] it "simple function tuple declaration" $ do - signaturesOf (hs "foo :: b -> (Int, [a])") `shouldBe` [TypedSignature "foo" ["b", "(Int, [a])"]] + signaturesOf (hs "foo :: b -> (Int, [a])") `shouldBe` [TypedSignature "foo" ["b"] "(Int, [a])"] describe "NamedSignature" $ do it "empty expression" $ do diff --git a/spec/SignaturesAnalyzerSpec.hs b/spec/SignaturesAnalyzerSpec.hs index fc40f43b8..05ae33e94 100644 --- a/spec/SignaturesAnalyzerSpec.hs +++ b/spec/SignaturesAnalyzerSpec.hs @@ -10,6 +10,7 @@ run language content style = analyse (signaturesAnalysis (CodeSample language co spec = describe "SignturesAnalyzer" $ do it "handles MulangStyle" $ do (run Haskell "f x = x + 1" MulangStyle ) `shouldReturn` (result ["-- f(x)"]) + (run Haskell "f :: Int -> String" MulangStyle ) `shouldReturn` (result ["-- f(Int): String"]) it "handles HaskellStyle" $ do (run Haskell "f x = x + 1" HaskellStyle ) `shouldReturn` (result ["-- f x"]) diff --git a/src/Language/Mulang/Ast.hs b/src/Language/Mulang/Ast.hs index bd15e297a..e5f1e333f 100644 --- a/src/Language/Mulang/Ast.hs +++ b/src/Language/Mulang/Ast.hs @@ -61,9 +61,9 @@ data Expression | Record Identifier -- ^ Imperative / Functional programming struct declaration. -- Only the record name is parsed - | TypeSignature Identifier [Identifier] - -- ^ Generic type signature for a computation. - -- Only the target name of the computation is parsed + | TypeSignature Identifier [Identifier] Identifier + -- ^ Generic type signature for a computation, + -- composed by a name, parameter types and return type | EntryPoint Identifier Expression -- ^ Entry point with its body | Function Identifier [Equation] diff --git a/src/Language/Mulang/Explorer.hs b/src/Language/Mulang/Explorer.hs index 8a9ee30ab..77d8bab0c 100644 --- a/src/Language/Mulang/Explorer.hs +++ b/src/Language/Mulang/Explorer.hs @@ -78,7 +78,7 @@ extractReference _ = Nothing extractDeclaration :: Expression -> Maybe (Binding, Expression) -extractDeclaration e@(TypeSignature n _) = Just (n, e) +extractDeclaration e@(TypeSignature n _ _)= Just (n, e) extractDeclaration e@(TypeAlias n ) = Just (n, e) extractDeclaration e@(Variable n _) = Just (n, e) extractDeclaration e@(Subroutine n _) = Just (n, e) diff --git a/src/Language/Mulang/Inspector/Generic.hs b/src/Language/Mulang/Inspector/Generic.hs index 9d1b0e38b..70fa9076d 100644 --- a/src/Language/Mulang/Inspector/Generic.hs +++ b/src/Language/Mulang/Inspector/Generic.hs @@ -55,8 +55,8 @@ usesIf = containsExpression f -- | Inspection that tells whether a top level binding exists declares :: BindedInspection declares = containsDeclaration f - where f (TypeSignature _ _) = False - f _ = True + where f (TypeSignature _ _ _) = False + f _ = True -- | Inspection that tells whether an expression is direct recursive declaresRecursively :: BindedInspection @@ -104,8 +104,8 @@ declaresTypeAlias = containsDeclaration f declaresTypeSignature :: BindedInspection declaresTypeSignature = containsDeclaration f - where f (TypeSignature _ _) = True - f _ = False + where f (TypeSignature _ _ _) = True + f _ = False usesAnonymousVariable :: Inspection diff --git a/src/Language/Mulang/Parsers/Haskell.hs b/src/Language/Mulang/Parsers/Haskell.hs index 8e4da45ca..b5a750dfa 100644 --- a/src/Language/Mulang/Parsers/Haskell.hs +++ b/src/Language/Mulang/Parsers/Haskell.hs @@ -31,7 +31,7 @@ mu (HsModule _ _ _ _ decls) = compact (concatMap muDecls decls) muDecls (HsTypeDecl _ name _ _) = [TypeAlias (muName name)] muDecls (HsDataDecl _ _ name _ _ _ ) = [Record (muName name)] - muDecls (HsTypeSig _ names (HsQualType _ t)) = map (\name -> TypeSignature (muName name) (muTopType t)) names + muDecls (HsTypeSig _ names (HsQualType _ t)) = map (muTypeSignature t) names muDecls (HsFunBind equations) | (HsMatch _ name _ _ _) <- head equations = [Function (muName name) (map muEquation equations)] muDecls (HsPatBind _ (HsPVar name) (HsUnGuardedRhs exp) _) = [Variable (muName name) (muExp exp)] @@ -118,9 +118,11 @@ mu (HsModule _ _ _ _ decls) = compact (concatMap muDecls decls) muStmt (HsGenerator _ pat exp) = MuGenerator (muPat pat) (muExp exp) muStmt (HsQualifier exp) = MuQualifier (muExp exp) + muTypeSignature t name = TypeSignature (muName name) (init topTypes) (last topTypes) + where topTypes = muTopTypes t - muTopType (HsTyFun i o) = muType i : muTopType o - muTopType t = [muType t] + muTopTypes (HsTyFun i o) = muType i : muTopTypes o + muTopTypes t = [muType t] muType (HsTyFun i o) = muType i ++ " -> " ++ muType o muType (HsTyCon name) = muQName name @@ -128,3 +130,4 @@ mu (HsModule _ _ _ _ decls) = compact (concatMap muDecls decls) muType (HsTyTuple ts) = "(" ++ (intercalate ", " . map muType $ ts) ++ ")" muType (HsTyApp (HsTyCon (Special HsListCon)) t2) = "[" ++ muType t2 ++ "]" muType (HsTyApp t1 t2) = muType t1 ++ " " ++ muType t2 + diff --git a/src/Language/Mulang/Signature.hs b/src/Language/Mulang/Signature.hs index ca1ed9678..c5ce37fc3 100644 --- a/src/Language/Mulang/Signature.hs +++ b/src/Language/Mulang/Signature.hs @@ -27,37 +27,37 @@ import Data.Function (on) type SignatureStyle = [Signature] -> [String] data Signature = AritySignature Binding Int - | TypedSignature Binding [Binding] + | TypedSignature Binding [Binding] Binding | NamedSignature Binding [Maybe Binding] deriving (Show, Eq) arity :: Signature -> Int -arity (AritySignature _ a) = a -arity (TypedSignature _ ps) = length ps -arity (NamedSignature _ ps) = length ps +arity (AritySignature _ a) = a +arity (TypedSignature _ ps _) = length ps +arity (NamedSignature _ ps) = length ps name :: Signature -> Binding -name (AritySignature n _) = n -name (TypedSignature n _) = n -name (NamedSignature n _) = n +name (AritySignature n _) = n +name (TypedSignature n _ _) = n +name (NamedSignature n _) = n nameAndArity :: Signature -> (Binding, Int) nameAndArity signature = (name signature, arity signature) parameterNames :: Signature -> [Maybe Binding] -parameterNames (AritySignature _ arity) = replicate arity Nothing -parameterNames (TypedSignature _ types) = map (const Nothing) types -parameterNames (NamedSignature _ names) = names +parameterNames (AritySignature _ arity) = replicate arity Nothing +parameterNames (TypedSignature _ types _) = map (const Nothing) types +parameterNames (NamedSignature _ names) = names signaturesOf :: Expression -> [Signature] signaturesOf = nub . mapMaybe (signatureOf.snd) . declarationsOf mainExpressions signatureOf :: Expression -> Maybe Signature -signatureOf (Subroutine name es) = Just $ NamedSignature name (parameterNamesOf es) -signatureOf (Clause name args _) = Just $ AritySignature name (length args) -signatureOf (TypeSignature name args) = Just $ TypedSignature name args -signatureOf (Variable name _) = Just $ AritySignature name 0 -signatureOf _ = Nothing +signatureOf (Subroutine name es) = Just $ NamedSignature name (parameterNamesOf es) +signatureOf (Clause name args _) = Just $ AritySignature name (length args) +signatureOf (TypeSignature name args ret) = Just $ TypedSignature name args ret +signatureOf (Variable name _) = Just $ AritySignature name 0 +signatureOf _ = Nothing parameterNamesOf :: [Equation] -> [Maybe Binding] parameterNamesOf = map msum . transpose . map (map parameterNameOf . equationParams) @@ -77,9 +77,9 @@ styledCodeSignaturesOf style = style . signaturesOf mulangStyle :: SignatureStyle mulangStyle = makeLines "--" (return.s) where s :: Signature -> String - s (AritySignature name arity) = name ++ "/" ++ show arity - s (NamedSignature name names) = name ++ "(" ++ (intercalate ", " . makeParamNames $ names) ++ ")" - s (TypedSignature name types) = name ++ " :: " ++ (intercalate " -> " types) + s (AritySignature name arity) = name ++ "/" ++ show arity + s (NamedSignature name names) = name ++ "(" ++ (intercalate ", " . makeParamNames $ names) ++ ")" + s (TypedSignature name types ret) = name ++ "(" ++ (intercalate ", " types) ++ "): " ++ ret untypedCStyle :: SignatureStyle untypedCStyle = makeLines "//" s @@ -89,10 +89,10 @@ untypedCStyle = makeLines "//" s haskellStyle :: SignatureStyle haskellStyle = groupAndMakeLinesOn "--" name s - where s (NamedSignature name names) = Just $ name ++ " " ++ (intercalate " " . makeParamNames $ names) - s (TypedSignature name types) = Just $ name ++ " :: " ++ (intercalate " -> " types) - s (AritySignature name 0) = Just name - s _ = Nothing + where s (NamedSignature name names) = Just $ name ++ " " ++ (intercalate " " . makeParamNames $ names) + s (TypedSignature name types ret) = Just $ name ++ " :: " ++ (intercalate " -> " (types ++ [ret])) + s (AritySignature name 0) = Just name + s _ = Nothing prologStyle :: SignatureStyle prologStyle = groupAndMakeLinesOn "%%" nameAndArity s diff --git a/src/Language/Mulang/Unfold.hs b/src/Language/Mulang/Unfold.hs index 74c5c1dc7..ec53ac238 100644 --- a/src/Language/Mulang/Unfold.hs +++ b/src/Language/Mulang/Unfold.hs @@ -47,7 +47,7 @@ mainExpressions o@(Object _ b) = o : mainExpressions b mainExpressions c@(Class _ _ b) = c : mainExpressions b mainExpressions c@(Interface _ _ b) = c : mainExpressions b mainExpressions e@(EntryPoint _ b) = e : mainExpressions b -mainExpressions t@(TypeSignature _ _) = [t] +mainExpressions t@(TypeSignature _ _ _)= [t] mainExpressions t@(TypeAlias _ ) = [t] mainExpressions r@(Record _) = [r] mainExpressions v@(Variable _ _) = [v] From 4863243c679f8bc0f90aa8ac62f2e6fbe6246dc4 Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sat, 22 Jul 2017 01:55:06 -0300 Subject: [PATCH 03/16] Implementing very basic parsing --- mulang.cabal | 3 ++ spec/JavaSpec.hs | 76 ++++++++++++++++++++++++++++++++++ src/Language/Mulang/Builder.hs | 2 - 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 spec/JavaSpec.hs diff --git a/mulang.cabal b/mulang.cabal index f0908c87c..850dd2fc0 100644 --- a/mulang.cabal +++ b/mulang.cabal @@ -73,6 +73,7 @@ library vector , haskell-src , language-javascript , + language-java , aeson , inflections , parsec , @@ -136,6 +137,8 @@ test-suite spec aeson , hspec , neat-interpolation , + language-java , + mulang build-tools: happy, diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs new file mode 100644 index 000000000..307c45190 --- /dev/null +++ b/spec/JavaSpec.hs @@ -0,0 +1,76 @@ +{-# LANGUAGE QuasiQuotes, OverloadedStrings #-} + +module JavaSpec (spec) where + +import Test.Hspec +import Language.Mulang +--import Language.Mulang.Parsers.Java + +import Data.Text (Text, unpack) +import NeatInterpolation (text) + +import Language.Mulang.Parsers +import Language.Mulang.Builder (compact) +import Control.Fallible +import Language.Java.Parser +import Language.Java.Syntax + + +java :: Parser +java = orFail . parseJava' + +parseJava :: MaybeParser +parseJava = orNothing . parseJava' + +--parseJava' :: a -> Either String Expression +parseJava' = fmap m . j + +m (CompilationUnit _ _ typeDecls) = compact . map muTypeDecl $ typeDecls + +muTypeDecl (ClassTypeDecl decl) = muClassTypeDecl decl +muTypeDecl (InterfaceTypeDecl decl) = muInterfaceTypeDecl decl + +muClassTypeDecl (ClassDecl _ name _ superclass interfaces (ClassBody body)) = Class (i name) (fmap r superclass) (compact.map muDecl $ body ) +muClassTypeDecl (EnumDecl _ name _ body) = Other + +muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = Interface (i name) (map r interfaces) (compact.map muMemberDecl $ body ) + +muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl +muDecl (InitDecl _ _) = Other + +muMemberDecl (FieldDecl _ _type varDecls) = Other +muMemberDecl (MethodDecl _ _ _ name params _ methodBody) = SimpleMethod (i name) [] MuNull +muMemberDecl (ConstructorDecl _ _ _ params _ constructorBody) = Other +muMemberDecl (MemberClassDecl decl) = muClassTypeDecl decl +muMemberDecl (MemberInterfaceDecl decl) = muInterfaceTypeDecl decl + +i (Ident name) = name +r (ClassRefType (ClassType [(name, _)])) = i name + +run :: Text -> Expression +run = java . unpack + +j = parser compilationUnit + +spec :: Spec +spec = do + describe "parse" $ do + it "parses Simple Class" $ do + run "public class Foo {}" `shouldBe` Class "Foo" Nothing MuNull + + it "parsers Class With Superclass" $ do + run "public class Foo extends Bar {}" `shouldBe` Class "Foo" (Just "Bar") MuNull + + it "parses Simple Interface" $ do + run "public interface Foo {}" `shouldBe` Interface "Foo" [] MuNull + + it "parses Interface with superinterfaces" $ do + run "public interface Foo extends Bar, Baz {}" `shouldBe` Interface "Foo" ["Bar", "Baz"] MuNull + + it "parses Class With Methods" $ do + run [text| + class Foo { + public void hello() {} + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] MuNull) + + diff --git a/src/Language/Mulang/Builder.hs b/src/Language/Mulang/Builder.hs index 2a5d78293..8411f6308 100644 --- a/src/Language/Mulang/Builder.hs +++ b/src/Language/Mulang/Builder.hs @@ -35,8 +35,6 @@ normalize (MuTuple es) = MuTuple (map normalize es) normalize (MuList es) = MuList (map normalize es) normalize e = e - - normalizeInObject (Function n eqs) = Method n (map normalizeEquation eqs) normalizeInObject (Variable n (Lambda vars e)) = SimpleMethod n vars (normalize e) normalizeInObject (Variable n e) = Attribute n (normalize e) From 2cc2478540b23ff675798460ee4b6ce8ecaed3e6 Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sat, 22 Jul 2017 11:08:50 -0300 Subject: [PATCH 04/16] Extracting Java module --- mulang.cabal | 3 +- spec/JavaSpec.hs | 46 ++++------------------------- src/Language/Mulang/Parsers/Java.hs | 43 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 42 deletions(-) create mode 100644 src/Language/Mulang/Parsers/Java.hs diff --git a/mulang.cabal b/mulang.cabal index 850dd2fc0..34d44eaa8 100644 --- a/mulang.cabal +++ b/mulang.cabal @@ -52,6 +52,7 @@ library Language.Mulang.Parsers Language.Mulang.Parsers.Haskell Language.Mulang.Parsers.Prolog + Language.Mulang.Parsers.Java Language.Mulang.Parsers.JavaScript Language.Mulang.Analyzer Language.Mulang.Analyzer.Analysis @@ -72,8 +73,8 @@ library scientific , vector , haskell-src , - language-javascript , language-java , + language-javascript , aeson , inflections , parsec , diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs index 307c45190..063a8fc21 100644 --- a/spec/JavaSpec.hs +++ b/spec/JavaSpec.hs @@ -4,53 +4,14 @@ module JavaSpec (spec) where import Test.Hspec import Language.Mulang ---import Language.Mulang.Parsers.Java +import Language.Mulang.Parsers.Java import Data.Text (Text, unpack) import NeatInterpolation (text) -import Language.Mulang.Parsers -import Language.Mulang.Builder (compact) -import Control.Fallible -import Language.Java.Parser -import Language.Java.Syntax - - -java :: Parser -java = orFail . parseJava' - -parseJava :: MaybeParser -parseJava = orNothing . parseJava' - ---parseJava' :: a -> Either String Expression -parseJava' = fmap m . j - -m (CompilationUnit _ _ typeDecls) = compact . map muTypeDecl $ typeDecls - -muTypeDecl (ClassTypeDecl decl) = muClassTypeDecl decl -muTypeDecl (InterfaceTypeDecl decl) = muInterfaceTypeDecl decl - -muClassTypeDecl (ClassDecl _ name _ superclass interfaces (ClassBody body)) = Class (i name) (fmap r superclass) (compact.map muDecl $ body ) -muClassTypeDecl (EnumDecl _ name _ body) = Other - -muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = Interface (i name) (map r interfaces) (compact.map muMemberDecl $ body ) - -muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl -muDecl (InitDecl _ _) = Other - -muMemberDecl (FieldDecl _ _type varDecls) = Other -muMemberDecl (MethodDecl _ _ _ name params _ methodBody) = SimpleMethod (i name) [] MuNull -muMemberDecl (ConstructorDecl _ _ _ params _ constructorBody) = Other -muMemberDecl (MemberClassDecl decl) = muClassTypeDecl decl -muMemberDecl (MemberInterfaceDecl decl) = muInterfaceTypeDecl decl - -i (Ident name) = name -r (ClassRefType (ClassType [(name, _)])) = i name - run :: Text -> Expression run = java . unpack -j = parser compilationUnit spec :: Spec spec = do @@ -73,4 +34,7 @@ spec = do public void hello() {} }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] MuNull) - + it "parses Empty Returns" $ do + run [text|class Foo { + public void hello() { return; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return MuNull)) diff --git a/src/Language/Mulang/Parsers/Java.hs b/src/Language/Mulang/Parsers/Java.hs new file mode 100644 index 000000000..34d3098bb --- /dev/null +++ b/src/Language/Mulang/Parsers/Java.hs @@ -0,0 +1,43 @@ +module Language.Mulang.Parsers.Java (java, parseJava) where + +import Language.Mulang.Ast +import Language.Mulang.Parsers +import Language.Mulang.Builder (compact) + +import Language.Java.Parser +import Language.Java.Syntax + +import Control.Fallible + +java :: Parser +java = orFail . parseJava' + +parseJava :: MaybeParser +parseJava = orNothing . parseJava' + +--parseJava' :: a -> Either String Expression +parseJava' = fmap m . j + +m (CompilationUnit _ _ typeDecls) = compact . map muTypeDecl $ typeDecls + +muTypeDecl (ClassTypeDecl decl) = muClassTypeDecl decl +muTypeDecl (InterfaceTypeDecl decl) = muInterfaceTypeDecl decl + +muClassTypeDecl (ClassDecl _ name _ superclass interfaces (ClassBody body)) = Class (i name) (fmap r superclass) (compact.map muDecl $ body ) +muClassTypeDecl (EnumDecl _ name _ body) = Other + +muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = Interface (i name) (map r interfaces) (compact.map muMemberDecl $ body ) + +muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl +muDecl (InitDecl _ _) = Other + +muMemberDecl (FieldDecl _ _type varDecls) = Other +muMemberDecl (MethodDecl _ _ _ name params _ methodBody) = SimpleMethod (i name) [] MuNull +muMemberDecl (ConstructorDecl _ _ _ params _ constructorBody) = Other +muMemberDecl (MemberClassDecl decl) = muClassTypeDecl decl +muMemberDecl (MemberInterfaceDecl decl) = muInterfaceTypeDecl decl + +i (Ident name) = name +r (ClassRefType (ClassType [(name, _)])) = i name + +j = parser compilationUnit From 3c164c2bba84bcf72d98de62a59e93cdb3e38550 Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sat, 22 Jul 2017 11:47:19 -0300 Subject: [PATCH 05/16] Partially parsing methods --- spec/JavaSpec.hs | 15 +++++++++++++ src/Language/Mulang/Parsers/Java.hs | 34 +++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs index 063a8fc21..62e47a2c9 100644 --- a/spec/JavaSpec.hs +++ b/spec/JavaSpec.hs @@ -25,6 +25,9 @@ spec = do it "parses Simple Interface" $ do run "public interface Foo {}" `shouldBe` Interface "Foo" [] MuNull + it "parses Simple Interface With Messages" $ do + run "public interface Foo { void foo(); }" `shouldBe` Interface "Foo" [] (TypeSignature "foo" [] "void") + it "parses Interface with superinterfaces" $ do run "public interface Foo extends Bar, Baz {}" `shouldBe` Interface "Foo" ["Bar", "Baz"] MuNull @@ -38,3 +41,15 @@ spec = do run [text|class Foo { public void hello() { return; } }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return MuNull)) + + it "parses Returns In Strings" $ do + run [text|class Foo { + public String hello() { return "hello"; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return (MuString "hello"))) + + it "parses Parameters" $ do + run "public class Foo extends Bar { int succ(int y) {} }" `shouldBe` Class "Foo" (Just "Bar") (SimpleMethod "succ" [VariablePattern "y"] MuNull) + + it "parses Enums" $ do + run "public enum Foo { A, B }" `shouldBe` Enumeration "Foo" ["A", "B"] + diff --git a/src/Language/Mulang/Parsers/Java.hs b/src/Language/Mulang/Parsers/Java.hs index 34d3098bb..713fa4909 100644 --- a/src/Language/Mulang/Parsers/Java.hs +++ b/src/Language/Mulang/Parsers/Java.hs @@ -1,6 +1,7 @@ module Language.Mulang.Parsers.Java (java, parseJava) where -import Language.Mulang.Ast +import Language.Mulang.Ast hiding (While, Return) +import qualified Language.Mulang.Ast as M (Expression(Return)) import Language.Mulang.Parsers import Language.Mulang.Builder (compact) @@ -9,6 +10,8 @@ import Language.Java.Syntax import Control.Fallible +import Data.Maybe (fromMaybe) + java :: Parser java = orFail . parseJava' @@ -24,7 +27,7 @@ muTypeDecl (ClassTypeDecl decl) = muClassTypeDecl decl muTypeDecl (InterfaceTypeDecl decl) = muInterfaceTypeDecl decl muClassTypeDecl (ClassDecl _ name _ superclass interfaces (ClassBody body)) = Class (i name) (fmap r superclass) (compact.map muDecl $ body ) -muClassTypeDecl (EnumDecl _ name _ body) = Other +muClassTypeDecl (EnumDecl _ name _ (EnumBody constants _)) = Enumeration (i name) (map muEnumConstant constants) muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = Interface (i name) (map r interfaces) (compact.map muMemberDecl $ body ) @@ -32,11 +35,34 @@ muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl muDecl (InitDecl _ _) = Other muMemberDecl (FieldDecl _ _type varDecls) = Other -muMemberDecl (MethodDecl _ _ _ name params _ methodBody) = SimpleMethod (i name) [] MuNull -muMemberDecl (ConstructorDecl _ _ _ params _ constructorBody) = Other +muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody (Just block))) = SimpleMethod (i name) (map (VariablePattern . muFormalParam) params) (muBlock block) +muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody Nothing)) = TypeSignature (i name) (map muFormalParam params) "void" +muMemberDecl (ConstructorDecl _ _ _ params _ constructorBody) = Other muMemberDecl (MemberClassDecl decl) = muClassTypeDecl decl muMemberDecl (MemberInterfaceDecl decl) = muInterfaceTypeDecl decl +muEnumConstant (EnumConstant name _ _) = i name + +muFormalParam (FormalParam _ types _ id) = (v id) + +muBlock (Block statements) = compact . map muBlockStmt $ statements + +muBlockStmt (BlockStmt stmt) = muStmt stmt +muBlockStmt (LocalClass decl) = muClassTypeDecl decl +muBlockStmt (LocalVars _ _type _vars) = Other + +muStmt (StmtBlock block) = muBlock block +muStmt (IfThen _Exp _Stmt) = Other +muStmt (IfThenElse _Exp _Stmt1 _Stmt2) = Other +muStmt (While _Exp _Stmt) = Other +muStmt (BasicFor _MaybeForInit _MaybeExp _MaybeExps _Stmt) = Other +muStmt (Return exp) = M.Return $ fromMaybe MuNull (fmap muExp exp) + +muExp _ = MuString "hello" + +v (VarId name) = i name +v (VarDeclArray id) = (v id) ++ "[]" + i (Ident name) = name r (ClassRefType (ClassType [(name, _)])) = i name From 46195041dd33e147c0c9e965a7f378c367d18692 Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sat, 22 Jul 2017 18:27:58 -0300 Subject: [PATCH 06/16] Supporting entry points --- spec/JavaSpec.hs | 5 +++++ src/Language/Mulang/Parsers/Java.hs | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs index 62e47a2c9..1f8c923a7 100644 --- a/spec/JavaSpec.hs +++ b/spec/JavaSpec.hs @@ -53,3 +53,8 @@ spec = do it "parses Enums" $ do run "public enum Foo { A, B }" `shouldBe` Enumeration "Foo" ["A", "B"] + it "parsesMain" $ do + run [text|public class MyMain { + public static void main(String[] args) { } + }|] `shouldBe` Class "MyMain" Nothing (EntryPoint "main" MuNull) + diff --git a/src/Language/Mulang/Parsers/Java.hs b/src/Language/Mulang/Parsers/Java.hs index 713fa4909..f818c03e8 100644 --- a/src/Language/Mulang/Parsers/Java.hs +++ b/src/Language/Mulang/Parsers/Java.hs @@ -35,8 +35,12 @@ muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl muDecl (InitDecl _ _) = Other muMemberDecl (FieldDecl _ _type varDecls) = Other -muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody (Just block))) = SimpleMethod (i name) (map (VariablePattern . muFormalParam) params) (muBlock block) -muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody Nothing)) = TypeSignature (i name) (map muFormalParam params) "void" +muMemberDecl (MethodDecl modifiers _ _ (Ident "main") [_args] _ (MethodBody (Just block))) | elem Static modifiers = + EntryPoint "main" (muBlock block) +muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody (Just block))) = + SimpleMethod (i name) (map (VariablePattern . muFormalParam) params) (muBlock block) +muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody Nothing)) = + TypeSignature (i name) (map muFormalParam params) "void" muMemberDecl (ConstructorDecl _ _ _ params _ constructorBody) = Other muMemberDecl (MemberClassDecl decl) = muClassTypeDecl decl muMemberDecl (MemberInterfaceDecl decl) = muInterfaceTypeDecl decl From 4cdd421d8baafd1c4ad48bcbb417de212ab6969d Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sat, 22 Jul 2017 19:16:35 -0300 Subject: [PATCH 07/16] Parsing literals --- spec/JavaSpec.hs | 36 ++++++++++++++++- src/Language/Mulang/Builder.hs | 8 +++- src/Language/Mulang/Parsers/Java.hs | 61 ++++++++++++++++++----------- 3 files changed, 79 insertions(+), 26 deletions(-) diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs index 1f8c923a7..36d656e78 100644 --- a/spec/JavaSpec.hs +++ b/spec/JavaSpec.hs @@ -42,11 +42,31 @@ spec = do public void hello() { return; } }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return MuNull)) - it "parses Returns In Strings" $ do + it "parses Strings In Returns" $ do run [text|class Foo { public String hello() { return "hello"; } }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return (MuString "hello"))) + it "parses Int In Returns" $ do + run [text|class Foo { + public int hello() { return 1; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return (MuNumber 1))) + + it "parses Double In Returns" $ do + run [text|class Foo { + public double hello() { return 453.2; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return (MuNumber 453.2))) + + it "parses Bools In Returns" $ do + run [text|class Foo { + public boolean hello() { return true; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return MuTrue)) + + it "parses Chars In Returns" $ do + run [text|class Foo { + public char hello() { return 'f'; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return (MuString "f"))) + it "parses Parameters" $ do run "public class Foo extends Bar { int succ(int y) {} }" `shouldBe` Class "Foo" (Just "Bar") (SimpleMethod "succ" [VariablePattern "y"] MuNull) @@ -54,7 +74,19 @@ spec = do run "public enum Foo { A, B }" `shouldBe` Enumeration "Foo" ["A", "B"] it "parsesMain" $ do - run [text|public class MyMain { + run [text| + public class MyMain { public static void main(String[] args) { } }|] `shouldBe` Class "MyMain" Nothing (EntryPoint "main" MuNull) + it "parses Variables And Ints" $ do + run [text| + class Foo { + public void hello() { int x = 1; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Variable "x" (MuNumber 1))) + + it "parses Variables without initialization" $ do + run [text| + class Foo { + public void hello() { int x; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Variable "x" MuNull)) diff --git a/src/Language/Mulang/Builder.hs b/src/Language/Mulang/Builder.hs index 8411f6308..cb637eb23 100644 --- a/src/Language/Mulang/Builder.hs +++ b/src/Language/Mulang/Builder.hs @@ -1,7 +1,13 @@ -module Language.Mulang.Builder (compact, normalize) where +module Language.Mulang.Builder (compact, compactMap, compactConcatMap, normalize) where import Language.Mulang.Ast +compactConcatMap :: (a -> [Expression]) -> [a] -> Expression +compactConcatMap f = compact . concat . map f + +compactMap :: (a -> Expression) -> [a] -> Expression +compactMap f = compact . map f + compact :: [Expression] -> Expression compact [] = MuNull compact [e] = e diff --git a/src/Language/Mulang/Parsers/Java.hs b/src/Language/Mulang/Parsers/Java.hs index f818c03e8..60b2e37c1 100644 --- a/src/Language/Mulang/Parsers/Java.hs +++ b/src/Language/Mulang/Parsers/Java.hs @@ -1,9 +1,12 @@ +{-# LANGUAGE ViewPatterns #-} + + module Language.Mulang.Parsers.Java (java, parseJava) where import Language.Mulang.Ast hiding (While, Return) import qualified Language.Mulang.Ast as M (Expression(Return)) import Language.Mulang.Parsers -import Language.Mulang.Builder (compact) +import Language.Mulang.Builder (compactMap, compactConcatMap) import Language.Java.Parser import Language.Java.Syntax @@ -18,51 +21,63 @@ java = orFail . parseJava' parseJava :: MaybeParser parseJava = orNothing . parseJava' ---parseJava' :: a -> Either String Expression parseJava' = fmap m . j -m (CompilationUnit _ _ typeDecls) = compact . map muTypeDecl $ typeDecls +m (CompilationUnit _ _ typeDecls) = compactMap muTypeDecl $ typeDecls muTypeDecl (ClassTypeDecl decl) = muClassTypeDecl decl muTypeDecl (InterfaceTypeDecl decl) = muInterfaceTypeDecl decl -muClassTypeDecl (ClassDecl _ name _ superclass interfaces (ClassBody body)) = Class (i name) (fmap r superclass) (compact.map muDecl $ body ) -muClassTypeDecl (EnumDecl _ name _ (EnumBody constants _)) = Enumeration (i name) (map muEnumConstant constants) +muClassTypeDecl (ClassDecl _ name _ superclass _interfaces (ClassBody body)) = Class (i name) (fmap r superclass) (compactMap muDecl body ) +muClassTypeDecl (EnumDecl _ name _ (EnumBody constants _)) = Enumeration (i name) (map muEnumConstant constants) -muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = Interface (i name) (map r interfaces) (compact.map muMemberDecl $ body ) +muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = Interface (i name) (map r interfaces) (compactMap muMemberDecl body ) muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl muDecl (InitDecl _ _) = Other -muMemberDecl (FieldDecl _ _type varDecls) = Other -muMemberDecl (MethodDecl modifiers _ _ (Ident "main") [_args] _ (MethodBody (Just block))) | elem Static modifiers = - EntryPoint "main" (muBlock block) -muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody (Just block))) = - SimpleMethod (i name) (map (VariablePattern . muFormalParam) params) (muBlock block) -muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody Nothing)) = - TypeSignature (i name) (map muFormalParam params) "void" -muMemberDecl (ConstructorDecl _ _ _ params _ constructorBody) = Other -muMemberDecl (MemberClassDecl decl) = muClassTypeDecl decl -muMemberDecl (MemberInterfaceDecl decl) = muInterfaceTypeDecl decl +muMemberDecl (FieldDecl _ _type varDecls) = Other +muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody Nothing)) = TypeSignature (i name) (map muFormalParam params) "void" +muMemberDecl (MethodDecl (elem Static -> True) _ _ (Ident "main") [_] _ body) = EntryPoint "main" (muMethodBody body) +muMemberDecl (MethodDecl _ _ _ name params _ body) = SimpleMethod (i name) (map (VariablePattern . muFormalParam) params) (muMethodBody body) +muMemberDecl (ConstructorDecl _ _ _ _params _ _constructorBody) = Other +muMemberDecl (MemberClassDecl decl) = muClassTypeDecl decl +muMemberDecl (MemberInterfaceDecl decl) = muInterfaceTypeDecl decl muEnumConstant (EnumConstant name _ _) = i name -muFormalParam (FormalParam _ types _ id) = (v id) +muFormalParam (FormalParam _ _types _ id) = (v id) -muBlock (Block statements) = compact . map muBlockStmt $ statements +muBlock (Block statements) = compactConcatMap muBlockStmt statements -muBlockStmt (BlockStmt stmt) = muStmt stmt -muBlockStmt (LocalClass decl) = muClassTypeDecl decl -muBlockStmt (LocalVars _ _type _vars) = Other +muBlockStmt (BlockStmt stmt) = [muStmt stmt] +muBlockStmt (LocalClass decl) = [muClassTypeDecl decl] +muBlockStmt (LocalVars _ _type vars) = map muVarDecl vars muStmt (StmtBlock block) = muBlock block muStmt (IfThen _Exp _Stmt) = Other muStmt (IfThenElse _Exp _Stmt1 _Stmt2) = Other muStmt (While _Exp _Stmt) = Other muStmt (BasicFor _MaybeForInit _MaybeExp _MaybeExps _Stmt) = Other -muStmt (Return exp) = M.Return $ fromMaybe MuNull (fmap muExp exp) +muStmt (Return exp) = M.Return $ fmapOrNull muExp exp + +muExp (Lit (String s)) = MuString s +muExp (Lit (Char c)) = MuString [c] +muExp (Lit (Int i)) = MuNumber (fromIntegral i) +muExp (Lit (Float d)) = MuNumber d +muExp (Lit (Double d)) = MuNumber d +muExp (Lit (Boolean b)) = MuBool b +muExp (Lit Null) = MuNull +muExp _ = Other + +muVarDecl (VarDecl id init) = Variable (v id) (fmapOrNull muVarInit init) + +muMethodBody (MethodBody (Just block)) = muBlock block + +muVarInit (InitExp exp) = muExp exp +muVarInit (InitArray _ArrayInit) = Other -muExp _ = MuString "hello" +fmapOrNull f = fromMaybe MuNull . fmap f v (VarId name) = i name v (VarDeclArray id) = (v id) ++ "[]" From fb97bf53e5a101843d6bd9c91cc48e54cab9b88a Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sat, 22 Jul 2017 20:28:39 -0300 Subject: [PATCH 08/16] Implementing ifs and send --- spec/JavaSpec.hs | 75 ++++++++++++++++++++++++++ src/Language/Mulang/Ast.hs | 3 ++ src/Language/Mulang/Parsers/Java.hs | 83 +++++++++++++++++++++++------ 3 files changed, 144 insertions(+), 17 deletions(-) diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs index 36d656e78..c58227fcf 100644 --- a/spec/JavaSpec.hs +++ b/spec/JavaSpec.hs @@ -85,8 +85,83 @@ spec = do public void hello() { int x = 1; } }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Variable "x" (MuNumber 1))) + it "parses Variables And Ints" $ do + run [text| + class Foo { + public void hello() { Foo x = this; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Variable "x" Self)) + + it "parses Variables And ternaries" $ do + run [text| + class Foo { + public void hello() { Foo x = true ? this : this; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Variable "x" (If MuTrue Self Self))) + it "parses Variables without initialization" $ do run [text| class Foo { public void hello() { int x; } }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Variable "x" MuNull)) + + it "parses self-send" $ do + run [text| + class Foo { + public void hello() { f(); } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (SimpleSend Self "f" [])) + + it "parses self-send" $ do + run [text| + class Foo { + public void hello() { f(2); } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (SimpleSend Self "f" [MuNumber 2])) + + it "parses explict self-send" $ do + run [text| + class Foo { + public void hello() { this.f(); } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (SimpleSend Self "f" [])) + + it "parses argument-send" $ do + run [text| + class Foo { + public void hello(String g) { g.toString(); } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [VariablePattern "g"] (SimpleSend (Reference "g") "toString" [])) + + it "parses expression-send" $ do + run [text| + class Foo { + public void hello(String g) { g.size().toString(); } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [VariablePattern "g"] (SimpleSend (SimpleSend (Reference "g") "size" []) "toString" [])) + + + it "parses Ifs with empty braces" $ do + run [text| + class Foo { + public void hello() { if (true) { } } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (If MuTrue MuNull MuNull)) + + it "parses Ifs with return in braces" $ do + run [text| + class Foo { + public void hello() { if (true) { return true; } else { return false; } } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (If MuTrue (Return MuTrue) (Return MuFalse))) + + it "parses Ifs with equal comparisons on conditions" $ do + run [text| + class Foo { + public void hello(String x) { if (x == "foo") { } } + }|] `shouldBe` Class "Foo" Nothing ( + SimpleMethod "hello" [VariablePattern "x"] ( + If (Send (Reference "x") Equal [MuString "foo"]) + MuNull + MuNull)) + + it "parses Ifs with not-equal comparisons on conditions" $ do + run [text| + class Foo { + public void hello(String x) { if (x != "foo") { } } + }|] `shouldBe` Class "Foo" Nothing ( + SimpleMethod "hello" [VariablePattern "x"] ( + If (Send (Reference "x") NotEqual [MuString "foo"]) + MuNull + MuNull)) diff --git a/src/Language/Mulang/Ast.hs b/src/Language/Mulang/Ast.hs index e5f1e333f..1c8187d7f 100644 --- a/src/Language/Mulang/Ast.hs +++ b/src/Language/Mulang/Ast.hs @@ -24,6 +24,7 @@ module Language.Mulang.Ast ( pattern SimpleFunction, pattern SimpleProcedure, pattern SimpleMethod, + pattern SimpleSend, pattern MuTrue, pattern MuFalse, pattern Subroutine, @@ -172,6 +173,8 @@ data ComprehensionStatement pattern SimpleEquation params body = Equation params (UnguardedBody body) +pattern SimpleSend receptor selector args = Send receptor (Reference selector) args + pattern SimpleFunction name params body = Function name [SimpleEquation params body] pattern SimpleProcedure name params body = Procedure name [SimpleEquation params body] pattern SimpleMethod name params body = Method name [SimpleEquation params body] diff --git a/src/Language/Mulang/Parsers/Java.hs b/src/Language/Mulang/Parsers/Java.hs index 60b2e37c1..c1d8fd47d 100644 --- a/src/Language/Mulang/Parsers/Java.hs +++ b/src/Language/Mulang/Parsers/Java.hs @@ -3,8 +3,8 @@ module Language.Mulang.Parsers.Java (java, parseJava) where -import Language.Mulang.Ast hiding (While, Return) -import qualified Language.Mulang.Ast as M (Expression(Return)) +import Language.Mulang.Ast hiding (While, Return, Equal) +import qualified Language.Mulang.Ast as M (Expression(Return, Equal)) import Language.Mulang.Parsers import Language.Mulang.Builder (compactMap, compactConcatMap) @@ -14,6 +14,7 @@ import Language.Java.Syntax import Control.Fallible import Data.Maybe (fromMaybe) +import Data.List (intercalate) java :: Parser java = orFail . parseJava' @@ -36,7 +37,7 @@ muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = I muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl muDecl (InitDecl _ _) = Other -muMemberDecl (FieldDecl _ _type varDecls) = Other +muMemberDecl (FieldDecl _ _type _varDecls) = Other muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody Nothing)) = TypeSignature (i name) (map muFormalParam params) "void" muMemberDecl (MethodDecl (elem Static -> True) _ _ (Ident "main") [_] _ body) = EntryPoint "main" (muMethodBody body) muMemberDecl (MethodDecl _ _ _ name params _ body) = SimpleMethod (i name) (map (VariablePattern . muFormalParam) params) (muMethodBody body) @@ -54,21 +55,48 @@ muBlockStmt (BlockStmt stmt) = [muStmt stmt] muBlockStmt (LocalClass decl) = [muClassTypeDecl decl] muBlockStmt (LocalVars _ _type vars) = map muVarDecl vars -muStmt (StmtBlock block) = muBlock block -muStmt (IfThen _Exp _Stmt) = Other -muStmt (IfThenElse _Exp _Stmt1 _Stmt2) = Other -muStmt (While _Exp _Stmt) = Other +muStmt (StmtBlock block) = muBlock block +muStmt (IfThen exp ifTrue) = If (muExp exp) (muStmt ifTrue) MuNull +muStmt (IfThenElse exp ifTrue ifFalse) = If (muExp exp) (muStmt ifTrue) (muStmt ifFalse) +muStmt (While _Exp _Stmt) = Other muStmt (BasicFor _MaybeForInit _MaybeExp _MaybeExps _Stmt) = Other -muStmt (Return exp) = M.Return $ fmapOrNull muExp exp - -muExp (Lit (String s)) = MuString s -muExp (Lit (Char c)) = MuString [c] -muExp (Lit (Int i)) = MuNumber (fromIntegral i) -muExp (Lit (Float d)) = MuNumber d -muExp (Lit (Double d)) = MuNumber d -muExp (Lit (Boolean b)) = MuBool b -muExp (Lit Null) = MuNull -muExp _ = Other +muStmt (Return exp) = M.Return $ fmapOrNull muExp exp +muStmt (ExpStmt exp) = muExp exp +muStmt _ = Other + +muExp (Lit lit) = muLit lit +muExp (MethodInv invoke) = muMethodInvocation invoke +muExp This = Self +muExp (BinOp arg1 op arg2) = Send (muExp arg1) (muOp op) [muExp arg2] +muExp (Cond cond ifTrue ifFalse) = If (muExp cond) (muExp ifTrue) (muExp ifFalse) +muExp (ExpName name) = muName name +muExp _ = Other + +muName (Name names) = Reference . ns $ names + +muLit (String s) = MuString s +muLit (Char c) = MuString [c] +muLit (Int i) = MuNumber (fromIntegral i) +muLit (Float d) = MuNumber d +muLit (Double d) = MuNumber d +muLit (Boolean b) = MuBool b +muLit Null = MuNull +muLit _ = Other + +muOp Mult = Reference "*" +muOp Div = Reference "/" +muOp Rem = Reference "rem" +muOp Add = Reference "+" +muOp Sub = Reference "-" +muOp LThan = Reference "<" +muOp LThanE = Reference "<=" +muOp GThan = Reference ">" +muOp GThanE = Reference ">=" +muOp And = Reference "&&" +muOp Or = Reference "||" +muOp Equal = M.Equal +muOp NotEq = NotEqual +muOp _ = Other muVarDecl (VarDecl id init) = Variable (v id) (fmapOrNull muVarInit init) @@ -77,8 +105,27 @@ muMethodBody (MethodBody (Just block)) = muBlock block muVarInit (InitExp exp) = muExp exp muVarInit (InitArray _ArrayInit) = Other +muMethodInvocation (MethodCall (Name [message]) args) = SimpleSend Self (i message) (map muExp args) +muMethodInvocation (MethodCall (Name (receptor:message)) args) = SimpleSend (Reference (i receptor)) (ns message) (map muExp args) +muMethodInvocation (PrimaryMethodCall receptor _ selector args) = SimpleSend (muExp receptor) (i selector) (map muExp args) +muMethodInvocation _ = Other + +{- +Invoking a method of a class computed from a primary expression, giving arguments for any generic type parameters. +SuperMethodCall [RefType] Ident [Argument] +Invoking a method of the super class, giving arguments for any generic type parameters. +ClassMethodCall Name [RefType] Ident [Argument] +Invoking a method of the superclass of a named class, giving arguments for any generic type parameters. +TypeMethodCall Name [RefType] Ident [Argument] +Invoking a method of a named type, giving arguments for any generic type parameters. +-} + +-- Combinators + fmapOrNull f = fromMaybe MuNull . fmap f +-- Helpers + v (VarId name) = i name v (VarDeclArray id) = (v id) ++ "[]" @@ -86,3 +133,5 @@ i (Ident name) = name r (ClassRefType (ClassType [(name, _)])) = i name j = parser compilationUnit + +ns = intercalate "." . map i From e943a4eea0d94c89f817bc0dfaeab08002d025f8 Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sat, 22 Jul 2017 20:35:34 -0300 Subject: [PATCH 09/16] Added DeclaresEnumeration and DeclaresInterface --- README.md | 4 +++- src/Language/Mulang/Analyzer/ExpectationsCompiler.hs | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index aa89fb42b..17e4a7027 100644 --- a/README.md +++ b/README.md @@ -97,8 +97,10 @@ Nice, we know. But not very awesome, it only can tell you if you are using a _bi 1. `declaresComputation`: **any paradigm** that is, does the given computation - method, predicate, function, etc - exist? 1. `declaresComputationWithArity`: **any paradigm** that is, does the given computation have the exact given arity? 1. `declaresEntryPoint`: **any paradigm** is there a program entry point, like a `main` procedure? +1. `declaresEnumeration`: **imperative paradigm** is a given enumeration declared? 1. `declaresFact`: **logic paradigm** is a given logic fact declared? 1. `declaresFunction`: **functional/imperative paradigm** is a given function declared? +1. `declaresInterface`: **objects paradigm** is a given interface declared? 1. `declaresMethod`: **objects paradigm** is a given method declared? 1. `declaresObject`: **objects paradigm** is a given named object declared? 1. `declaresPredicate`: **logic paradigm** is a given rule o fact declared? @@ -143,7 +145,7 @@ Nice, we know. But not very awesome, it only can tell you if you are using a _bi 1. `usesRepeat` 1. `usesSwitch` 1. `usesUnificationOperator`: **logic paradigm** is the logic unification operator `=` used? -1. `usesWhile` +1. `usesWhile`: **imperative paradigm** is a `while` control structure used? For example, let's go trickier: diff --git a/src/Language/Mulang/Analyzer/ExpectationsCompiler.hs b/src/Language/Mulang/Analyzer/ExpectationsCompiler.hs index b9e6d8894..3300b70cf 100644 --- a/src/Language/Mulang/Analyzer/ExpectationsCompiler.hs +++ b/src/Language/Mulang/Analyzer/ExpectationsCompiler.hs @@ -64,8 +64,10 @@ compileInspectionPrimitive = f f "DeclaresComputationWithArity4" = binded (declaresComputationWithArity 4) f "DeclaresComputationWithArity5" = binded (declaresComputationWithArity 5) f "DeclaresEntryPoint" = binded declaresEntryPoint + f "DeclaresEnumeration" = binded declaresEnumeration f "DeclaresFact" = binded declaresFact f "DeclaresFunction" = binded declaresFunction + f "DeclaresInterface" = binded declaresInterface f "DeclaresMethod" = binded declaresMethod f "DeclaresObject" = binded declaresObject f "DeclaresPredicate" = binded declaresPredicate From 7f176aa6acdfcdee0fb97dc6d8c73c190f67b9e6 Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sun, 23 Jul 2017 03:47:06 -0300 Subject: [PATCH 10/16] Handling negation, news and lambdas --- spec/JavaSpec.hs | 25 ++++++++++++++ src/Language/Mulang/Ast.hs | 10 ++++-- src/Language/Mulang/Parsers/Java.hs | 51 +++++++++++++++++++++-------- 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs index c58227fcf..e514c522a 100644 --- a/spec/JavaSpec.hs +++ b/spec/JavaSpec.hs @@ -62,6 +62,11 @@ spec = do public boolean hello() { return true; } }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return MuTrue)) + it "parses Negation In Returns" $ do + run [text|class Foo { + public boolean hello() { return !true; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] (Return (SimpleSend MuTrue "!" []))) + it "parses Chars In Returns" $ do run [text|class Foo { public char hello() { return 'f'; } @@ -165,3 +170,23 @@ spec = do If (Send (Reference "x") NotEqual [MuString "foo"]) MuNull MuNull)) + + it "parsesAssignmentsAndDoubles" $ do + run [text|class Foo { + public void hello() { double m = 1.0; m = 3.4; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] ( + Sequence [ + Variable "m" (MuNumber 1.0), + Assignment "m" (MuNumber 3.4)])) + + it "parses Lambdas" $ do + run [text|class Foo { + public Object hello() { return (int x) -> x + 1; } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] ( + Return (Lambda [VariablePattern "x"] (SimpleSend (Reference "x") "+" [MuNumber 1])))) + + it "parses News" $ do + run [text|class Foo { + public Foo hello() { return new Bar(3); } + }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] ( + Return (SimpleNew "Bar" [MuNumber 3]))) diff --git a/src/Language/Mulang/Ast.hs b/src/Language/Mulang/Ast.hs index 1c8187d7f..916027f4b 100644 --- a/src/Language/Mulang/Ast.hs +++ b/src/Language/Mulang/Ast.hs @@ -25,6 +25,7 @@ module Language.Mulang.Ast ( pattern SimpleProcedure, pattern SimpleMethod, pattern SimpleSend, + pattern SimpleNew, pattern MuTrue, pattern MuFalse, pattern Subroutine, @@ -40,6 +41,8 @@ type Code = String -- | Mulang does not assume any special naming convention or format type Identifier = String +type Type = String + -- | An equation. See @Function@ and @Procedure@ above data Equation = Equation [Pattern] EquationBody deriving (Eq, Show, Read, Generic) @@ -62,7 +65,7 @@ data Expression | Record Identifier -- ^ Imperative / Functional programming struct declaration. -- Only the record name is parsed - | TypeSignature Identifier [Identifier] Identifier + | TypeSignature Identifier [Type] Type -- ^ Generic type signature for a computation, -- composed by a name, parameter types and return type | EntryPoint Identifier Expression @@ -87,7 +90,7 @@ data Expression -- ^ Imperative named enumeration of values | Interface Identifier [Identifier] Expression -- ^ Object oriented programming global interface or contract declaration, - -- composed by a name, subinterfaces and a body + -- composed by a name, superinterfaces and a body | Rule Identifier [Pattern] [Expression] -- ^ Logic programming declaration of a fact, composed by the rue name, rule arguments, and rule body | Fact Identifier [Pattern] @@ -106,6 +109,8 @@ data Expression -- ^ Generic, non-curried application of a function or procedure, composed by the applied element itself, and the application arguments | Send Expression Expression [Expression] -- ^ Object oriented programming message send, composed by the reciever, selector and arguments + | New Expression [Expression] + -- ^ Object oriented instantiation, composed by the class expression and instantiation arguments | Lambda [Pattern] Expression | If Expression Expression Expression | Return Expression @@ -174,6 +179,7 @@ data ComprehensionStatement pattern SimpleEquation params body = Equation params (UnguardedBody body) pattern SimpleSend receptor selector args = Send receptor (Reference selector) args +pattern SimpleNew clazz args = New (Reference clazz) args pattern SimpleFunction name params body = Function name [SimpleEquation params body] pattern SimpleProcedure name params body = Procedure name [SimpleEquation params body] diff --git a/src/Language/Mulang/Parsers/Java.hs b/src/Language/Mulang/Parsers/Java.hs index c1d8fd47d..e1b71e4b8 100644 --- a/src/Language/Mulang/Parsers/Java.hs +++ b/src/Language/Mulang/Parsers/Java.hs @@ -3,8 +3,8 @@ module Language.Mulang.Parsers.Java (java, parseJava) where -import Language.Mulang.Ast hiding (While, Return, Equal) -import qualified Language.Mulang.Ast as M (Expression(Return, Equal)) +import Language.Mulang.Ast hiding (While, Return, Equal, Lambda) +import qualified Language.Mulang.Ast as M (Expression(While, Return, Equal, Lambda)) import Language.Mulang.Parsers import Language.Mulang.Builder (compactMap, compactConcatMap) @@ -29,10 +29,10 @@ m (CompilationUnit _ _ typeDecls) = compactMap muTypeDecl $ typeDecls muTypeDecl (ClassTypeDecl decl) = muClassTypeDecl decl muTypeDecl (InterfaceTypeDecl decl) = muInterfaceTypeDecl decl -muClassTypeDecl (ClassDecl _ name _ superclass _interfaces (ClassBody body)) = Class (i name) (fmap r superclass) (compactMap muDecl body ) +muClassTypeDecl (ClassDecl _ name _ superclass _interfaces (ClassBody body)) = Class (i name) (fmap muClassRefType superclass) (compactMap muDecl body ) muClassTypeDecl (EnumDecl _ name _ (EnumBody constants _)) = Enumeration (i name) (map muEnumConstant constants) -muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = Interface (i name) (map r interfaces) (compactMap muMemberDecl body ) +muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = Interface (i name) (map muClassRefType interfaces) (compactMap muMemberDecl body ) muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl muDecl (InitDecl _ _) = Other @@ -58,19 +58,40 @@ muBlockStmt (LocalVars _ _type vars) = map muVarDecl vars muStmt (StmtBlock block) = muBlock block muStmt (IfThen exp ifTrue) = If (muExp exp) (muStmt ifTrue) MuNull muStmt (IfThenElse exp ifTrue ifFalse) = If (muExp exp) (muStmt ifTrue) (muStmt ifFalse) -muStmt (While _Exp _Stmt) = Other -muStmt (BasicFor _MaybeForInit _MaybeExp _MaybeExps _Stmt) = Other +muStmt (While cond body) = M.While (muExp cond) (muStmt body) muStmt (Return exp) = M.Return $ fmapOrNull muExp exp muStmt (ExpStmt exp) = muExp exp +muStmt Empty = MuNull +muStmt (Assert exp _) = SimpleSend Self "assert" [muExp exp] +muStmt (Synchronized _ block) = muBlock block +muStmt (Labeled _ stmt) = muStmt stmt +--muStmt (EnhancedFor _ _ name gen body) = Other +--Throw Exp +--Try Block [Catch] (Maybe Block) +--Switch Exp [SwitchBlock] muStmt _ = Other -muExp (Lit lit) = muLit lit -muExp (MethodInv invoke) = muMethodInvocation invoke -muExp This = Self -muExp (BinOp arg1 op arg2) = Send (muExp arg1) (muOp op) [muExp arg2] -muExp (Cond cond ifTrue ifFalse) = If (muExp cond) (muExp ifTrue) (muExp ifFalse) -muExp (ExpName name) = muName name -muExp _ = Other +muExp (Lit lit) = muLit lit +muExp (MethodInv invoke) = muMethodInvocation invoke +muExp This = Self +muExp (BinOp arg1 op arg2) = Send (muExp arg1) (muOp op) [muExp arg2] +muExp (Cond cond ifTrue ifFalse) = If (muExp cond) (muExp ifTrue) (muExp ifFalse) +muExp (ExpName name) = muName name +muExp (Assign lhs EqualA exp) = Assignment (muLhs lhs) (muExp exp) +muExp (InstanceCreation _ clazz args _) = SimpleNew (r clazz) (map muExp args) +muExp (PreNot exp) = SimpleSend (muExp exp) "!" [] +muExp (Lambda params exp) = M.Lambda (muLambdaParams params) (muLambdaExp exp) +muExp (MethodRef _ message) = M.Lambda [VariablePattern "it"] (SimpleSend (Reference "it") (i message) []) +muExp _ = Other + +muLambdaExp (LambdaExpression exp) = muExp exp +muLambdaExp (LambdaBlock block) = muBlock block + +muLambdaParams (LambdaSingleParam name) = [VariablePattern (i name)] +muLambdaParams (LambdaInferredParams names) = map (VariablePattern . i) names +muLambdaParams (LambdaFormalParams params) = map (VariablePattern . muFormalParam) params + +muLhs (NameLhs (Name names)) = ns names muName (Name names) = Reference . ns $ names @@ -110,6 +131,8 @@ muMethodInvocation (MethodCall (Name (receptor:message)) args) = SimpleSend (R muMethodInvocation (PrimaryMethodCall receptor _ selector args) = SimpleSend (muExp receptor) (i selector) (map muExp args) muMethodInvocation _ = Other +muClassRefType (ClassRefType clazz) = r clazz + {- Invoking a method of a class computed from a primary expression, giving arguments for any generic type parameters. SuperMethodCall [RefType] Ident [Argument] @@ -130,7 +153,7 @@ v (VarId name) = i name v (VarDeclArray id) = (v id) ++ "[]" i (Ident name) = name -r (ClassRefType (ClassType [(name, _)])) = i name +r (ClassType [(name, _)]) = i name j = parser compilationUnit From c5a362a7c8c9d9dc623f67d02a57fb0686e64aee Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sun, 23 Jul 2017 03:58:26 -0300 Subject: [PATCH 11/16] Generalizing Interface type --- spec/JavaSpec.hs | 2 +- src/Language/Mulang/Ast.hs | 2 +- src/Language/Mulang/Parsers/Java.hs | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs index e514c522a..7de1c1a5a 100644 --- a/spec/JavaSpec.hs +++ b/spec/JavaSpec.hs @@ -29,7 +29,7 @@ spec = do run "public interface Foo { void foo(); }" `shouldBe` Interface "Foo" [] (TypeSignature "foo" [] "void") it "parses Interface with superinterfaces" $ do - run "public interface Foo extends Bar, Baz {}" `shouldBe` Interface "Foo" ["Bar", "Baz"] MuNull + run "public interface Foo extends Bar, Baz {}" `shouldBe` Interface "Foo" [Reference "Bar", Reference "Baz"] MuNull it "parses Class With Methods" $ do run [text| diff --git a/src/Language/Mulang/Ast.hs b/src/Language/Mulang/Ast.hs index 916027f4b..e6832efb1 100644 --- a/src/Language/Mulang/Ast.hs +++ b/src/Language/Mulang/Ast.hs @@ -88,7 +88,7 @@ data Expression -- composed by a name, an optional superclass, implemented interfaces and a body | Enumeration Identifier [Identifier] -- ^ Imperative named enumeration of values - | Interface Identifier [Identifier] Expression + | Interface Identifier [Expression] Expression -- ^ Object oriented programming global interface or contract declaration, -- composed by a name, superinterfaces and a body | Rule Identifier [Pattern] [Expression] diff --git a/src/Language/Mulang/Parsers/Java.hs b/src/Language/Mulang/Parsers/Java.hs index e1b71e4b8..4663ad464 100644 --- a/src/Language/Mulang/Parsers/Java.hs +++ b/src/Language/Mulang/Parsers/Java.hs @@ -29,10 +29,13 @@ m (CompilationUnit _ _ typeDecls) = compactMap muTypeDecl $ typeDecls muTypeDecl (ClassTypeDecl decl) = muClassTypeDecl decl muTypeDecl (InterfaceTypeDecl decl) = muInterfaceTypeDecl decl -muClassTypeDecl (ClassDecl _ name _ superclass _interfaces (ClassBody body)) = Class (i name) (fmap muClassRefType superclass) (compactMap muDecl body ) -muClassTypeDecl (EnumDecl _ name _ (EnumBody constants _)) = Enumeration (i name) (map muEnumConstant constants) +muClassTypeDecl (ClassDecl _ name _ superclass _interfaces (ClassBody body)) = + Class (i name) (fmap muClassRefType superclass) (compactMap muDecl body ) +muClassTypeDecl (EnumDecl _ name _ (EnumBody constants _)) = + Enumeration (i name) (map muEnumConstant constants) -muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = Interface (i name) (map muClassRefType interfaces) (compactMap muMemberDecl body ) +muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = + Interface (i name) (map (Reference . muClassRefType) interfaces) (compactMap muMemberDecl body ) muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl muDecl (InitDecl _ _) = Other From eb75a38e1b72621d0722d629a309f1113adbe86a Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sun, 23 Jul 2017 04:27:36 -0300 Subject: [PATCH 12/16] Fixing type signature parameters --- spec/JavaSpec.hs | 3 +++ src/Language/Mulang/Parsers/Java.hs | 34 +++++++++++++++-------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs index 7de1c1a5a..ced34382b 100644 --- a/spec/JavaSpec.hs +++ b/spec/JavaSpec.hs @@ -28,6 +28,9 @@ spec = do it "parses Simple Interface With Messages" $ do run "public interface Foo { void foo(); }" `shouldBe` Interface "Foo" [] (TypeSignature "foo" [] "void") + it "parses Simple Interface With Messages With Params" $ do + run "public interface Foo { void foo(String x, int y); }" `shouldBe` Interface "Foo" [] (TypeSignature "foo" ["String", "int"] "void") + it "parses Interface with superinterfaces" $ do run "public interface Foo extends Bar, Baz {}" `shouldBe` Interface "Foo" [Reference "Bar", Reference "Baz"] MuNull diff --git a/src/Language/Mulang/Parsers/Java.hs b/src/Language/Mulang/Parsers/Java.hs index 4663ad464..54d3cf5c3 100644 --- a/src/Language/Mulang/Parsers/Java.hs +++ b/src/Language/Mulang/Parsers/Java.hs @@ -15,6 +15,7 @@ import Control.Fallible import Data.Maybe (fromMaybe) import Data.List (intercalate) +import Data.Char (toLower) java :: Parser java = orFail . parseJava' @@ -30,27 +31,28 @@ muTypeDecl (ClassTypeDecl decl) = muClassTypeDecl decl muTypeDecl (InterfaceTypeDecl decl) = muInterfaceTypeDecl decl muClassTypeDecl (ClassDecl _ name _ superclass _interfaces (ClassBody body)) = - Class (i name) (fmap muClassRefType superclass) (compactMap muDecl body ) + Class (i name) (fmap muRefType superclass) (compactMap muDecl body ) muClassTypeDecl (EnumDecl _ name _ (EnumBody constants _)) = Enumeration (i name) (map muEnumConstant constants) muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = - Interface (i name) (map (Reference . muClassRefType) interfaces) (compactMap muMemberDecl body ) + Interface (i name) (map (Reference . muRefType) interfaces) (compactMap muMemberDecl body ) muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl muDecl (InitDecl _ _) = Other muMemberDecl (FieldDecl _ _type _varDecls) = Other -muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody Nothing)) = TypeSignature (i name) (map muFormalParam params) "void" +muMemberDecl (MethodDecl _ _ _ name params _ (MethodBody Nothing)) = TypeSignature (i name) (map muFormalParamType params) "void" muMemberDecl (MethodDecl (elem Static -> True) _ _ (Ident "main") [_] _ body) = EntryPoint "main" (muMethodBody body) -muMemberDecl (MethodDecl _ _ _ name params _ body) = SimpleMethod (i name) (map (VariablePattern . muFormalParam) params) (muMethodBody body) +muMemberDecl (MethodDecl _ _ _ name params _ body) = SimpleMethod (i name) (map muFormalParam params) (muMethodBody body) muMemberDecl (ConstructorDecl _ _ _ _params _ _constructorBody) = Other muMemberDecl (MemberClassDecl decl) = muClassTypeDecl decl muMemberDecl (MemberInterfaceDecl decl) = muInterfaceTypeDecl decl muEnumConstant (EnumConstant name _ _) = i name -muFormalParam (FormalParam _ _types _ id) = (v id) +muFormalParam (FormalParam _ _ _ id) = VariablePattern (v id) +muFormalParamType (FormalParam _ typ _ _) = (muType typ) muBlock (Block statements) = compactConcatMap muBlockStmt statements @@ -58,6 +60,9 @@ muBlockStmt (BlockStmt stmt) = [muStmt stmt] muBlockStmt (LocalClass decl) = [muClassTypeDecl decl] muBlockStmt (LocalVars _ _type vars) = map muVarDecl vars +muType (PrimType t) = muPrimType t +muType (RefType t) = muRefType t + muStmt (StmtBlock block) = muBlock block muStmt (IfThen exp ifTrue) = If (muExp exp) (muStmt ifTrue) MuNull muStmt (IfThenElse exp ifTrue ifFalse) = If (muExp exp) (muStmt ifTrue) (muStmt ifFalse) @@ -92,7 +97,7 @@ muLambdaExp (LambdaBlock block) = muBlock block muLambdaParams (LambdaSingleParam name) = [VariablePattern (i name)] muLambdaParams (LambdaInferredParams names) = map (VariablePattern . i) names -muLambdaParams (LambdaFormalParams params) = map (VariablePattern . muFormalParam) params +muLambdaParams (LambdaFormalParams params) = map muFormalParam params muLhs (NameLhs (Name names)) = ns names @@ -134,17 +139,10 @@ muMethodInvocation (MethodCall (Name (receptor:message)) args) = SimpleSend (R muMethodInvocation (PrimaryMethodCall receptor _ selector args) = SimpleSend (muExp receptor) (i selector) (map muExp args) muMethodInvocation _ = Other -muClassRefType (ClassRefType clazz) = r clazz +muRefType (ClassRefType clazz) = r clazz +muRefType (ArrayType t) = (muType t) ++ "[]" -{- -Invoking a method of a class computed from a primary expression, giving arguments for any generic type parameters. -SuperMethodCall [RefType] Ident [Argument] -Invoking a method of the super class, giving arguments for any generic type parameters. -ClassMethodCall Name [RefType] Ident [Argument] -Invoking a method of the superclass of a named class, giving arguments for any generic type parameters. -TypeMethodCall Name [RefType] Ident [Argument] -Invoking a method of a named type, giving arguments for any generic type parameters. --} +muPrimType = map toLower . dropLast 1 . show -- Combinators @@ -161,3 +159,7 @@ r (ClassType [(name, _)]) = i name j = parser compilationUnit ns = intercalate "." . map i + +-- list helpers + +dropLast n xs = take (length xs - n) xs From b18f4410c7cc1f48046aeaaab0dd2b724da4cbd5 Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sun, 23 Jul 2017 11:11:54 -0300 Subject: [PATCH 13/16] Implementing implements and instantiates --- spec/InspectorSpec.hs | 29 +++++++++++++++++-- spec/JavaSpec.hs | 5 ++-- src/Language/Mulang/Ast.hs | 16 +++++----- src/Language/Mulang/Explorer.hs | 6 ++-- .../Mulang/Inspector/ObjectOriented.hs | 27 ++++++++++++----- src/Language/Mulang/Parsers/Java.hs | 12 ++++---- 6 files changed, 67 insertions(+), 28 deletions(-) diff --git a/spec/InspectorSpec.hs b/spec/InspectorSpec.hs index 4eb98253f..f0f97af93 100644 --- a/spec/InspectorSpec.hs +++ b/spec/InspectorSpec.hs @@ -4,6 +4,7 @@ import Test.Hspec import Language.Mulang import Language.Mulang.Parsers.Haskell import Language.Mulang.Parsers.JavaScript +import Language.Mulang.Parsers.Java (java) import Language.Mulang.Inspector.Generic.Smell import Data.Maybe (fromJust) @@ -208,12 +209,28 @@ spec = do describe "declaresInterface" $ do it "is True when present" $ do - declaresInterface (named "Optional") (Interface "Optional" [] (TypeSignature "get" [] "A")) `shouldBe` True + declaresInterface (named "Optional") (java "interface Optional { Object get(); }") `shouldBe` True it "is False when not present" $ do - declaresInterface (named "Bird") (Class "Bird" (Just "Animal") MuNull) `shouldBe` False + declaresInterface (named "Bird") (java "class Bird extends Animal {}") `shouldBe` False + + describe "instantiates" $ do + it "is True when instantiates" $ do + instantiates (named "Bird") (java "class Main { void main(String[] args) { Animal a = new Bird(); } }") `shouldBe` True + + it "is False when not instantiates" $ do + instantiates (named "Bird") (java "class Main { void main(String[] args) { Animal a = new Mammal(); } }") `shouldBe` False + + describe "implements" $ do + it "is True when implements" $ do + implements (named "Bird") (java "class Eagle implements Bird {}") `shouldBe` True + + it "is False when implements declaration not present" $ do + implements (named "Bird") (java "class Cell {}") `shouldBe` False + + it "is False when a superinterface is declares" $ do + implements (named "Iterable") (java "interface Collection extends Iterable {}") `shouldBe` False - describe "usesInheritance" $ do it "is True when present" $ do usesInheritance (Class "Bird" (Just "Animal") MuNull) `shouldBe` True @@ -233,6 +250,12 @@ spec = do it "is True when any present" $ do declaresMethod anyone (js "var f = {x: function(){}}") `shouldBe` True + it "is True when scoped in a class" $ do + scoped (declaresMethod (named "foo")) "A" (java "class A { void foo() {} }") `shouldBe` True + + it "is False when scoped in a class and not present" $ do + scoped (declaresMethod (named "foo")) "A" (java "class A { void foobar() {} }") `shouldBe` False + it "is False when not present" $ do declaresMethod (named "m") (js "var f = {x: function(){}}") `shouldBe` False diff --git a/spec/JavaSpec.hs b/spec/JavaSpec.hs index ced34382b..5699089f1 100644 --- a/spec/JavaSpec.hs +++ b/spec/JavaSpec.hs @@ -31,8 +31,9 @@ spec = do it "parses Simple Interface With Messages With Params" $ do run "public interface Foo { void foo(String x, int y); }" `shouldBe` Interface "Foo" [] (TypeSignature "foo" ["String", "int"] "void") + it "parses Interface with superinterfaces" $ do - run "public interface Foo extends Bar, Baz {}" `shouldBe` Interface "Foo" [Reference "Bar", Reference "Baz"] MuNull + run "public interface Foo extends Bar, Baz {}" `shouldBe` Interface "Foo" ["Bar", "Baz"] MuNull it "parses Class With Methods" $ do run [text| @@ -192,4 +193,4 @@ spec = do run [text|class Foo { public Foo hello() { return new Bar(3); } }|] `shouldBe` Class "Foo" Nothing (SimpleMethod "hello" [] ( - Return (SimpleNew "Bar" [MuNumber 3]))) + Return (New "Bar" [MuNumber 3]))) diff --git a/src/Language/Mulang/Ast.hs b/src/Language/Mulang/Ast.hs index e6832efb1..077193702 100644 --- a/src/Language/Mulang/Ast.hs +++ b/src/Language/Mulang/Ast.hs @@ -25,7 +25,6 @@ module Language.Mulang.Ast ( pattern SimpleProcedure, pattern SimpleMethod, pattern SimpleSend, - pattern SimpleNew, pattern MuTrue, pattern MuFalse, pattern Subroutine, @@ -41,8 +40,6 @@ type Code = String -- | Mulang does not assume any special naming convention or format type Identifier = String -type Type = String - -- | An equation. See @Function@ and @Procedure@ above data Equation = Equation [Pattern] EquationBody deriving (Eq, Show, Read, Generic) @@ -65,7 +62,7 @@ data Expression | Record Identifier -- ^ Imperative / Functional programming struct declaration. -- Only the record name is parsed - | TypeSignature Identifier [Type] Type + | TypeSignature Identifier [Identifier] Identifier -- ^ Generic type signature for a computation, -- composed by a name, parameter types and return type | EntryPoint Identifier Expression @@ -88,7 +85,7 @@ data Expression -- composed by a name, an optional superclass, implemented interfaces and a body | Enumeration Identifier [Identifier] -- ^ Imperative named enumeration of values - | Interface Identifier [Expression] Expression + | Interface Identifier [Identifier] Expression -- ^ Object oriented programming global interface or contract declaration, -- composed by a name, superinterfaces and a body | Rule Identifier [Pattern] [Expression] @@ -109,8 +106,12 @@ data Expression -- ^ Generic, non-curried application of a function or procedure, composed by the applied element itself, and the application arguments | Send Expression Expression [Expression] -- ^ Object oriented programming message send, composed by the reciever, selector and arguments - | New Expression [Expression] - -- ^ Object oriented instantiation, composed by the class expression and instantiation arguments + | New Identifier [Expression] + -- ^ Object oriented instantiation, composed by the class reference and instantiation arguments + | Implement Identifier + -- ^ Object oriented instantiation, interface implementation + | Include Identifier + -- ^ Object oriented instantiation, mixin inclusion | Lambda [Pattern] Expression | If Expression Expression Expression | Return Expression @@ -179,7 +180,6 @@ data ComprehensionStatement pattern SimpleEquation params body = Equation params (UnguardedBody body) pattern SimpleSend receptor selector args = Send receptor (Reference selector) args -pattern SimpleNew clazz args = New (Reference clazz) args pattern SimpleFunction name params body = Function name [SimpleEquation params body] pattern SimpleProcedure name params body = Procedure name [SimpleEquation params body] diff --git a/src/Language/Mulang/Explorer.hs b/src/Language/Mulang/Explorer.hs index 77d8bab0c..e4315f5b6 100644 --- a/src/Language/Mulang/Explorer.hs +++ b/src/Language/Mulang/Explorer.hs @@ -72,9 +72,9 @@ nameOf :: Expression -> Maybe Binding nameOf = fmap fst . extractDeclaration extractReference :: Expression -> Maybe (Binding, Expression) -extractReference e@(Reference n) = Just (n, e) -extractReference e@(Exist n _) = Just (n, e) -extractReference _ = Nothing +extractReference e@(Reference n) = Just (n, e) +extractReference e@(Exist n _) = Just (n, e) +extractReference _ = Nothing extractDeclaration :: Expression -> Maybe (Binding, Expression) diff --git a/src/Language/Mulang/Inspector/ObjectOriented.hs b/src/Language/Mulang/Inspector/ObjectOriented.hs index b772941bb..38ac97905 100644 --- a/src/Language/Mulang/Inspector/ObjectOriented.hs +++ b/src/Language/Mulang/Inspector/ObjectOriented.hs @@ -1,4 +1,6 @@ module Language.Mulang.Inspector.ObjectOriented ( + implements, + instantiates, usesInheritance, declaresObject, declaresSuperclass, @@ -12,40 +14,51 @@ import Language.Mulang.Ast import Language.Mulang.Binding import Language.Mulang.Inspector.Generic +implements :: BindedInspection +implements predicate = containsExpression f + where f (Implement name) = predicate name + f _ = False + +instantiates :: BindedInspection +instantiates predicate = containsExpression f + where f (New name _) = predicate name + f _ = False + + usesInheritance :: Inspection usesInheritance = declaresSuperclass anyone -declaresObject :: BindingPredicate -> Inspection +declaresObject :: BindedInspection declaresObject = containsDeclaration f where f (Object _ _) = True f _ = False -declaresSuperclass :: BindingPredicate -> Inspection +declaresSuperclass :: BindedInspection declaresSuperclass predicate = containsExpression f where f (Class _ (Just name) _) = predicate name f _ = False -declaresClass :: BindingPredicate -> Inspection +declaresClass :: BindedInspection declaresClass = containsDeclaration f where f (Class _ _ _) = True f _ = False -declaresEnumeration :: BindingPredicate -> Inspection +declaresEnumeration :: BindedInspection declaresEnumeration = containsDeclaration f where f (Enumeration _ _) = True f _ = False -declaresInterface :: BindingPredicate -> Inspection +declaresInterface :: BindedInspection declaresInterface = containsDeclaration f where f (Interface _ _ _) = True f _ = False -declaresAttribute :: BindingPredicate -> Inspection +declaresAttribute :: BindedInspection declaresAttribute = containsDeclaration f where f (Attribute _ _) = True f _ = False -declaresMethod :: BindingPredicate -> Inspection +declaresMethod :: BindedInspection declaresMethod = containsDeclaration f where f (Method _ _) = True f _ = False diff --git a/src/Language/Mulang/Parsers/Java.hs b/src/Language/Mulang/Parsers/Java.hs index 54d3cf5c3..ce068d0ef 100644 --- a/src/Language/Mulang/Parsers/Java.hs +++ b/src/Language/Mulang/Parsers/Java.hs @@ -6,7 +6,7 @@ module Language.Mulang.Parsers.Java (java, parseJava) where import Language.Mulang.Ast hiding (While, Return, Equal, Lambda) import qualified Language.Mulang.Ast as M (Expression(While, Return, Equal, Lambda)) import Language.Mulang.Parsers -import Language.Mulang.Builder (compactMap, compactConcatMap) +import Language.Mulang.Builder (compact, compactMap, compactConcatMap) import Language.Java.Parser import Language.Java.Syntax @@ -30,13 +30,15 @@ m (CompilationUnit _ _ typeDecls) = compactMap muTypeDecl $ typeDecls muTypeDecl (ClassTypeDecl decl) = muClassTypeDecl decl muTypeDecl (InterfaceTypeDecl decl) = muInterfaceTypeDecl decl -muClassTypeDecl (ClassDecl _ name _ superclass _interfaces (ClassBody body)) = - Class (i name) (fmap muRefType superclass) (compactMap muDecl body ) +muClassTypeDecl (ClassDecl _ name _ superclass interfaces (ClassBody body)) = + Class (i name) (fmap muRefType superclass) (compact (map muImplements interfaces ++ map muDecl body)) muClassTypeDecl (EnumDecl _ name _ (EnumBody constants _)) = Enumeration (i name) (map muEnumConstant constants) +muImplements interface = Implement $ muRefType interface + muInterfaceTypeDecl (InterfaceDecl _ name _ interfaces (InterfaceBody body)) = - Interface (i name) (map (Reference . muRefType) interfaces) (compactMap muMemberDecl body ) + Interface (i name) (map muRefType interfaces) (compactMap muMemberDecl body ) muDecl (MemberDecl memberDecl) = muMemberDecl memberDecl muDecl (InitDecl _ _) = Other @@ -86,7 +88,7 @@ muExp (BinOp arg1 op arg2) = Send (muExp arg1) (muOp op) [muExp arg muExp (Cond cond ifTrue ifFalse) = If (muExp cond) (muExp ifTrue) (muExp ifFalse) muExp (ExpName name) = muName name muExp (Assign lhs EqualA exp) = Assignment (muLhs lhs) (muExp exp) -muExp (InstanceCreation _ clazz args _) = SimpleNew (r clazz) (map muExp args) +muExp (InstanceCreation _ clazz args _) = New (r clazz) (map muExp args) muExp (PreNot exp) = SimpleSend (muExp exp) "!" [] muExp (Lambda params exp) = M.Lambda (muLambdaParams params) (muLambdaExp exp) muExp (MethodRef _ message) = M.Lambda [VariablePattern "it"] (SimpleSend (Reference "it") (i message) []) From d90250a65a99a249b0ef8118dccac589bdff988e Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sun, 23 Jul 2017 11:13:35 -0300 Subject: [PATCH 14/16] Documenting and adding Implements and Instantiates --- README.md | 16 +++++++++------- .../Mulang/Analyzer/ExpectationsCompiler.hs | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 17e4a7027..e967b6bab 100644 --- a/README.md +++ b/README.md @@ -92,22 +92,22 @@ Nice, we know. But not very awesome, it only can tell you if you are using a _bi 1. `assigns`: **any paradigm** is the given variable or attribute assigned? 1. `declares`: **any paradigm** is the given element declared? -1. `declaresAttribute`: **objects paradigm** is a given attribute declared? -1. `declaresClass`: **objects paradigm** is a given class declared? +1. `declaresAttribute`: **object oriented paradigm** is a given attribute declared? +1. `declaresClass`: **object oriented paradigm** is a given class declared? 1. `declaresComputation`: **any paradigm** that is, does the given computation - method, predicate, function, etc - exist? 1. `declaresComputationWithArity`: **any paradigm** that is, does the given computation have the exact given arity? 1. `declaresEntryPoint`: **any paradigm** is there a program entry point, like a `main` procedure? 1. `declaresEnumeration`: **imperative paradigm** is a given enumeration declared? 1. `declaresFact`: **logic paradigm** is a given logic fact declared? 1. `declaresFunction`: **functional/imperative paradigm** is a given function declared? -1. `declaresInterface`: **objects paradigm** is a given interface declared? -1. `declaresMethod`: **objects paradigm** is a given method declared? -1. `declaresObject`: **objects paradigm** is a given named object declared? +1. `declaresInterface`: **object oriented paradigm** is a given interface declared? +1. `declaresMethod`: **object oriented paradigm** is a given method declared? +1. `declaresObject`: **object oriented paradigm** is a given named object declared? 1. `declaresPredicate`: **logic paradigm** is a given rule o fact declared? 1. `declaresProcedure`: **imperative paradigm** is a given procedure declared? 1. `declaresRecursively`: **any paradigm** is a given computation declared using recusion? 1. `declaresRule`: **logic paradigm** is a given logic rule declared? -1. `declaresSuperclass`: **objects paradigm** is a given class declared as superclass? +1. `declaresSuperclass`: **object oriented paradigm** is a given class declared as superclass? 1. `declaresTypeAlias`: **any paradigm** is a given type synonym declared? 1. `declaresTypeSignature`: **any paradigm** is a given computation type signature declared? 1. `declaresVariable`: **any paradigm** is a given local o global variable declared? @@ -125,6 +125,8 @@ Nice, we know. But not very awesome, it only can tell you if you are using a _bi 1. `hasRedundantReduction`: **logic paradigm** is a is-operator used to unify individuals that don't require a reduction, like `X is 4` 1. `hasTooShortBindings`: **any paradigm** whether a binding is too short and not part of domain language's jargon 1. `hasWrongCaseBindings`: **any paradigm** whether a binding does not match the domain language's case style +1. `implements`: **object oriented paradigm** is the given interface implemented? +1. `instantiates`: **object oriented paradigm** is the given class instantiated? 1. `isLongCode`: **any paradigm** has the code long sequences of statements? 1. `returnsNull` 1. `uses`: **any paradigm** is there any reference to the given element? @@ -138,7 +140,7 @@ Nice, we know. But not very awesome, it only can tell you if you are using a _bi 1. `usesForall`: **logic paradigm** is the logic `forall` consult used? 1. `usesGuards` 1. `usesIf`: **any paradigm** is an `if` control structure used? -1. `usesInheritance`: **objects paradigm** is a superclass explicitly declared? +1. `usesInheritance`: **object oriented paradigm** is a superclass explicitly declared? 1. `usesLambda` 1. `usesNot` 1. `usesPatternMatching` diff --git a/src/Language/Mulang/Analyzer/ExpectationsCompiler.hs b/src/Language/Mulang/Analyzer/ExpectationsCompiler.hs index 3300b70cf..06f31326c 100644 --- a/src/Language/Mulang/Analyzer/ExpectationsCompiler.hs +++ b/src/Language/Mulang/Analyzer/ExpectationsCompiler.hs @@ -78,6 +78,8 @@ compileInspectionPrimitive = f f "DeclaresTypeAlias" = binded declaresTypeAlias f "DeclaresTypeSignature" = binded declaresTypeSignature f "DeclaresVariable" = binded declaresVariable + f "Implements" = binded implements + f "Instantiates" = binded instantiates f "Uses" = binded uses f "UsesAnonymousVariable" = simple usesAnonymousVariable f "UsesComposition" = simple usesComposition From 32f04d585ef4c290469cae5e3942889801b1a40b Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sun, 23 Jul 2017 11:13:59 -0300 Subject: [PATCH 15/16] Supporting Java as native language --- spec/ExpectationsCompilerSpec.hs | 4 ++++ src/Language/Mulang/Analyzer/Analysis.hs | 1 + src/Language/Mulang/Analyzer/SampleParser.hs | 2 ++ 3 files changed, 7 insertions(+) diff --git a/spec/ExpectationsCompilerSpec.hs b/spec/ExpectationsCompilerSpec.hs index 90e13bcb6..4c11e4b02 100644 --- a/spec/ExpectationsCompilerSpec.hs +++ b/spec/ExpectationsCompilerSpec.hs @@ -5,6 +5,7 @@ import Language.Mulang.Analyzer hiding (spec) import Language.Mulang.Analyzer.ExpectationsCompiler (compileExpectation) import Language.Mulang.Parsers.Haskell import Language.Mulang.Parsers.JavaScript +import Language.Mulang.Parsers.Java spec :: Spec spec = do @@ -166,3 +167,6 @@ spec = do it "works with UsesLambda" $ do run (hs "f 3 = 3") "f" "UsesLambda" `shouldBe` False + it "works with Implements" $ do + run (java "class Foo implements Bar {}") "Foo" "Implements:Bar" `shouldBe` True + run (java "class Foo implements Bar {}") "Foo" "Implements:Baz" `shouldBe` False diff --git a/src/Language/Mulang/Analyzer/Analysis.hs b/src/Language/Mulang/Analyzer/Analysis.hs index ace850c02..d710f7b8a 100644 --- a/src/Language/Mulang/Analyzer/Analysis.hs +++ b/src/Language/Mulang/Analyzer/Analysis.hs @@ -100,6 +100,7 @@ data Sample data Language = Json + | Java | JavaScript | Prolog | Haskell deriving (Show, Eq, Generic) diff --git a/src/Language/Mulang/Analyzer/SampleParser.hs b/src/Language/Mulang/Analyzer/SampleParser.hs index c78cd0c87..b4c220635 100644 --- a/src/Language/Mulang/Analyzer/SampleParser.hs +++ b/src/Language/Mulang/Analyzer/SampleParser.hs @@ -6,6 +6,7 @@ import Language.Mulang.Parsers (MaybeParser) import Language.Mulang.Parsers.Haskell import Language.Mulang.Parsers.JavaScript (parseJavaScript) import Language.Mulang.Parsers.Prolog (parseProlog) +import Language.Mulang.Parsers.Java (parseJava) import Language.Mulang.Analyzer.Analysis (Sample(..), Language(..)) parseSample :: Sample -> Maybe Expression @@ -14,5 +15,6 @@ parseSample (MulangSample ast) = Just ast parserFor :: Language -> MaybeParser parserFor Haskell = parseHaskell +parserFor Java = parseJava parserFor JavaScript = parseJavaScript parserFor Prolog = parseProlog From 3ce43732d923d48a06e7509c9bf7cbcf2b0f833c Mon Sep 17 00:00:00 2001 From: Franco Bulgarelli Date: Sun, 23 Jul 2017 11:25:13 -0300 Subject: [PATCH 16/16] Removing duplicated language-java dep --- mulang.cabal | 2 -- 1 file changed, 2 deletions(-) diff --git a/mulang.cabal b/mulang.cabal index 34d44eaa8..2ffce914c 100644 --- a/mulang.cabal +++ b/mulang.cabal @@ -138,8 +138,6 @@ test-suite spec aeson , hspec , neat-interpolation , - language-java , - mulang build-tools: happy,