From 797d2b3102b3d30f0a301fe1dc6e50a4a267e7a0 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:45:05 -0400 Subject: [PATCH 001/133] :fire: toVarDeclOrAssignment. --- src/Language.hs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Language.hs b/src/Language.hs index 95457d4d5..4cb44c72c 100644 --- a/src/Language.hs +++ b/src/Language.hs @@ -38,14 +38,6 @@ languageForType mediaType = case mediaType of ".py" -> Just Python _ -> Nothing -toVarDeclOrAssignment :: HasField fields Category => Term S.Syntax (Record fields) -> Term S.Syntax (Record fields) -toVarDeclOrAssignment child = case unwrap child of - S.Indexed [child', assignment] -> cofree $ setCategory (extract child) VarAssignment :< S.VarAssignment [child'] assignment - S.Indexed [child'] -> cofree $ setCategory (extract child) VarDecl :< S.VarDecl [child'] - S.VarDecl _ -> cofree $ setCategory (extract child) VarDecl :< unwrap child - S.VarAssignment _ _ -> child - _ -> toVarDecl child - toVarDecl :: HasField fields Category => Term S.Syntax (Record fields) -> Term S.Syntax (Record fields) toVarDecl child = cofree $ setCategory (extract child) VarDecl :< S.VarDecl [child] From 198578a45ff7fab616addfb32ed26e2082835004 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:45:10 -0400 Subject: [PATCH 002/133] :fire: toVarDecl. --- src/Language.hs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Language.hs b/src/Language.hs index 4cb44c72c..e23746870 100644 --- a/src/Language.hs +++ b/src/Language.hs @@ -38,9 +38,6 @@ languageForType mediaType = case mediaType of ".py" -> Just Python _ -> Nothing -toVarDecl :: HasField fields Category => Term S.Syntax (Record fields) -> Term S.Syntax (Record fields) -toVarDecl child = cofree $ setCategory (extract child) VarDecl :< S.VarDecl [child] - toTuple :: Term S.Syntax (Record fields) -> [Term S.Syntax (Record fields)] toTuple child | S.Indexed [key,value] <- unwrap child = [cofree (extract child :< S.Pair key value)] toTuple child | S.Fixed [key,value] <- unwrap child = [cofree (extract child :< S.Pair key value)] From efe2fdb4682eb82c4a5f4bc42203dc909c8c6b91 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:47:01 -0400 Subject: [PATCH 003/133] :fire: toPublicFieldDefinition. --- src/Language.hs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Language.hs b/src/Language.hs index e23746870..9365dd71f 100644 --- a/src/Language.hs +++ b/src/Language.hs @@ -44,12 +44,6 @@ toTuple child | S.Fixed [key,value] <- unwrap child = [cofree (extract child :< toTuple child | S.Leaf c <- unwrap child = [cofree (extract child :< S.Comment c)] toTuple child = pure child -toPublicFieldDefinition :: HasField fields Category => [SyntaxTerm fields] -> Maybe (S.Syntax (SyntaxTerm fields)) -toPublicFieldDefinition children = case break (\x -> category (extract x) == Identifier) children of - (prev, [identifier, assignment]) -> Just $ S.VarAssignment (prev ++ [identifier]) assignment - (_, [_]) -> Just $ S.VarDecl children - _ -> Nothing - toInterface :: HasField fields Category => [SyntaxTerm fields] -> Maybe (S.Syntax (SyntaxTerm fields)) toInterface (id : rest) = case break (\x -> category (extract x) == Other "object_type") rest of (clauses, [body]) -> Just $ S.Interface id clauses (toList (unwrap body)) From 99ed0787c7a79d3508311948f7b3c8d9330d7e2d Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:47:23 -0400 Subject: [PATCH 004/133] :fire: toInterface. --- src/Language.hs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Language.hs b/src/Language.hs index 9365dd71f..13bf3042a 100644 --- a/src/Language.hs +++ b/src/Language.hs @@ -43,9 +43,3 @@ toTuple child | S.Indexed [key,value] <- unwrap child = [cofree (extract child : toTuple child | S.Fixed [key,value] <- unwrap child = [cofree (extract child :< S.Pair key value)] toTuple child | S.Leaf c <- unwrap child = [cofree (extract child :< S.Comment c)] toTuple child = pure child - -toInterface :: HasField fields Category => [SyntaxTerm fields] -> Maybe (S.Syntax (SyntaxTerm fields)) -toInterface (id : rest) = case break (\x -> category (extract x) == Other "object_type") rest of - (clauses, [body]) -> Just $ S.Interface id clauses (toList (unwrap body)) - _ -> Nothing -toInterface _ = Nothing From 96db2e443ced633aa5f0c0f972fcbd510a4730d5 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:48:24 -0400 Subject: [PATCH 005/133] :fire: the empty Python module. --- semantic-diff.cabal | 1 - src/Language/Python.hs | 1 - 2 files changed, 2 deletions(-) delete mode 100644 src/Language/Python.hs diff --git a/semantic-diff.cabal b/semantic-diff.cabal index 5e8d794e8..3d5e6c0f8 100644 --- a/semantic-diff.cabal +++ b/semantic-diff.cabal @@ -60,7 +60,6 @@ library , Language.TypeScript , Language.TypeScript.Grammar , Language.TypeScript.Syntax - , Language.Python , Language.Python.Grammar , Language.Python.Syntax , Parser diff --git a/src/Language/Python.hs b/src/Language/Python.hs deleted file mode 100644 index 31890baf5..000000000 --- a/src/Language/Python.hs +++ /dev/null @@ -1 +0,0 @@ -module Language.Python where From fb860e1fa6d5437e92e7f72191b67d515990b1ec Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:48:34 -0400 Subject: [PATCH 006/133] :fire: the empty TypeScript module. --- semantic-diff.cabal | 1 - src/Language/TypeScript.hs | 13 ------------- 2 files changed, 14 deletions(-) delete mode 100644 src/Language/TypeScript.hs diff --git a/semantic-diff.cabal b/semantic-diff.cabal index 3d5e6c0f8..8847943f3 100644 --- a/semantic-diff.cabal +++ b/semantic-diff.cabal @@ -57,7 +57,6 @@ library , Language.Ruby , Language.Ruby.Grammar , Language.Ruby.Syntax - , Language.TypeScript , Language.TypeScript.Grammar , Language.TypeScript.Syntax , Language.Python.Grammar diff --git a/src/Language/TypeScript.hs b/src/Language/TypeScript.hs deleted file mode 100644 index 66bdca023..000000000 --- a/src/Language/TypeScript.hs +++ /dev/null @@ -1,13 +0,0 @@ -{-# LANGUAGE DataKinds #-} -module Language.TypeScript where - -import Control.Comonad (extract) -import Control.Comonad.Cofree (unwrap) -import Data.Foldable (toList) -import Data.Source -import Data.Text (Text) -import Info -import Language -import qualified Syntax as S -import Term - From bb2c66d32ce85e1e40444fba987bf651f4dd67da Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:48:49 -0400 Subject: [PATCH 007/133] :fire: unused imports. --- src/Language.hs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Language.hs b/src/Language.hs index 13bf3042a..3a4ac6156 100644 --- a/src/Language.hs +++ b/src/Language.hs @@ -5,10 +5,8 @@ import Control.Comonad import Control.Comonad.Trans.Cofree hiding (cofree) import Control.DeepSeq import Data.Aeson -import Data.Foldable import Data.Record import GHC.Generics -import Info import qualified Syntax as S import Term From 81eb3f8425bf5e21115b49eac93b221ed679439c Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:50:11 -0400 Subject: [PATCH 008/133] :fire: monolithic Ruby assignment. --- semantic-diff.cabal | 1 - src/Language/Ruby.hs | 178 ------------------------------------------- src/TreeSitter.hs | 4 - 3 files changed, 183 deletions(-) delete mode 100644 src/Language/Ruby.hs diff --git a/semantic-diff.cabal b/semantic-diff.cabal index 8847943f3..5d249deb5 100644 --- a/semantic-diff.cabal +++ b/semantic-diff.cabal @@ -54,7 +54,6 @@ library , Language.Go.Syntax , Language.JSON.Grammar , Language.JSON.Syntax - , Language.Ruby , Language.Ruby.Grammar , Language.Ruby.Syntax , Language.TypeScript.Grammar diff --git a/src/Language/Ruby.hs b/src/Language/Ruby.hs deleted file mode 100644 index d76db7809..000000000 --- a/src/Language/Ruby.hs +++ /dev/null @@ -1,178 +0,0 @@ -{-# LANGUAGE DataKinds #-} -module Language.Ruby where - -import Control.Comonad -import Control.Comonad.Cofree -import Data.Foldable (toList) -import Data.List (partition) -import Data.Semigroup -import Data.Source -import Data.Text (Text) -import Info -import Language -import qualified Syntax as S -import Term hiding ((:<)) - -termAssignment - :: Source -- ^ The source of the term. - -> Category -- ^ The category for the term. - -> [ SyntaxTerm DefaultFields ] -- ^ The child nodes of the term. - -> Maybe (S.Syntax (SyntaxTerm DefaultFields)) -- ^ The resulting term, in Maybe. -termAssignment _ category children - = case (category, children) of - (ArgumentPair, [ k, v ] ) -> Just $ S.Pair k v - (KeywordParameter, [ k, v ] ) -> Just $ S.Pair k v - -- NB: ("keyword_parameter", k) is a required keyword parameter, e.g.: - -- def foo(name:); end - -- Let it fall through to generate an Indexed syntax. - (OptionalParameter, [ k, v ] ) -> Just $ S.Pair k v - (AnonymousFunction, first : rest) - | null rest -> Just $ S.AnonymousFunction [] [first] - | otherwise -> Just $ S.AnonymousFunction (toList (unwrap first)) rest - (ArrayLiteral, _ ) -> Just $ S.Array Nothing children - (Assignment, [ identifier, value ]) -> Just $ S.Assignment identifier value - (Begin, _ ) -> Just $ case partition (\x -> Info.category (extract x) == Rescue) children of - (rescues, rest) -> case partition (\x -> Info.category (extract x) == Ensure || Info.category (extract x) == Else) rest of - (ensureElse, body) -> case ensureElse of - [ elseBlock, ensure ] - | Else <- Info.category (extract elseBlock) - , Ensure <- Info.category (extract ensure) -> S.Try body rescues (Just elseBlock) (Just ensure) - [ ensure, elseBlock ] - | Ensure <- Info.category (extract ensure) - , Else <- Info.category (extract elseBlock) -> S.Try body rescues (Just elseBlock) (Just ensure) - [ elseBlock ] | Else <- Info.category (extract elseBlock) -> S.Try body rescues (Just elseBlock) Nothing - [ ensure ] | Ensure <- Info.category (extract ensure) -> S.Try body rescues Nothing (Just ensure) - _ -> S.Try body rescues Nothing Nothing - (Class, constant : superclass : body) - | Superclass <- Info.category (extract superclass) - -> Just $ S.Class constant [superclass] body - (Class, constant : rest) -> Just $ S.Class constant [] rest - (SingletonClass, identifier : rest) -> Just $ S.Class identifier [] rest - (Case, _) -> Just $ uncurry S.Switch (break ((== When) . Info.category . extract) children) - (When, expr : body) -> Just $ S.Case expr body - (Ternary, condition : cases) -> Just $ S.Ternary condition cases - (MethodCall, fn : args) - | MemberAccess <- Info.category (extract fn) - , [target, method] <- toList (unwrap fn) - -> Just $ S.MethodCall target method [] (toList . unwrap =<< args) - | otherwise - -> Just $ S.FunctionCall fn [] (toList . unwrap =<< args) - (Object, _ ) -> Just . S.Object Nothing $ foldMap toTuple children - (Modifier If, [ lhs, condition ]) -> Just $ S.If condition [lhs] - (Modifier Unless, [lhs, rhs]) -> Just $ S.If (setCategory (extract rhs) Negate :< S.Negate rhs) [lhs] - (Unless, expr : rest) -> Just $ S.If ((setCategory (extract expr) Negate) :< S.Negate expr) rest - (Modifier Until, [ lhs, rhs ]) -> Just $ S.While (setCategory (extract rhs) Negate :< S.Negate rhs) [lhs] - (Until, expr : rest) -> Just $ S.While (setCategory (extract expr) Negate :< S.Negate expr) rest - (Elsif, condition : body ) -> Just $ S.If condition body - (SubscriptAccess, [ base, element ]) -> Just $ S.SubscriptAccess base element - (For, lhs : expr : rest ) -> Just $ S.For [lhs, expr] rest - (OperatorAssignment, [ identifier, value ]) -> Just $ S.OperatorAssignment identifier value - (MemberAccess, [ base, property ]) -> Just $ S.MemberAccess base property - (SingletonMethod, expr : methodName : rest) - | params : body <- rest - , Params <- Info.category (extract params) - -> Just $ S.Method [] methodName (Just expr) [params] body - | Identifier <- Info.category (extract methodName) - -> Just $ S.Method [] methodName (Just expr) [] rest - (Method, identifier : rest) - | params : body <- rest - , Params <- Info.category (extract params) - -> Just $ S.Method [] identifier Nothing [params] body - | otherwise - -> Just $ S.Method [] identifier Nothing [] rest - (Module, constant : body ) -> Just $ S.Module constant body - (Modifier Rescue, [lhs, rhs] ) -> Just $ S.Rescue [lhs] [rhs] - (Rescue, exceptions : exceptionVar : rest) - | RescueArgs <- Info.category (extract exceptions) - , RescuedException <- Info.category (extract exceptionVar) - -> Just $ S.Rescue (toList (unwrap exceptions) <> [exceptionVar]) rest - (Rescue, exceptionVar : rest) - | RescuedException <- Info.category (extract exceptionVar) - -> Just $ S.Rescue [exceptionVar] rest - (Rescue, exceptions : body) - | RescueArgs <- Info.category (extract exceptions) - -> Just $ S.Rescue (toList (unwrap exceptions)) body - (Rescue, body) -> Just $ S.Rescue [] body - (Modifier While, [ lhs, condition ]) -> Just $ S.While condition [lhs] - _ | category `elem` [ BeginBlock, EndBlock ] -> Just $ S.BlockStatement children - _ -> Nothing - -categoryForRubyName :: Text -> Category -categoryForRubyName name = case name of - "argument_list_with_parens" -> Args - "argument_list" -> Args - "argument_pair" -> ArgumentPair - "array" -> ArrayLiteral - "assignment" -> Assignment - "begin_block" -> BeginBlock - "begin" -> Begin - "binary" -> Binary - "block" -> ExpressionStatements - "block_parameter" -> BlockParameter - "block_parameters" -> Params - "boolean" -> Boolean - "call" -> MemberAccess - "case" -> Case - "class" -> Class - "comment" -> Comment - "conditional" -> Ternary - "constant" -> Constant - "element_reference" -> SubscriptAccess - "else" -> Else - "elsif" -> Elsif - "empty_statement" -> Empty - "end_block" -> EndBlock - "ensure" -> Ensure - "exception_variable" -> RescuedException - "exceptions" -> RescueArgs - "false" -> Boolean - "float" -> NumberLiteral - "for" -> For - "hash_splat_parameter" -> HashSplatParameter - "hash" -> Object - "identifier" -> Identifier - "if_modifier" -> Modifier If - "if" -> If - "instance_variable" -> Identifier - "integer" -> IntegerLiteral - "interpolation" -> Interpolation - "keyword_parameter" -> KeywordParameter - "lambda_parameters" -> Params - "lambda" -> AnonymousFunction - "left_assignment_list" -> Args - "method_call" -> MethodCall - "method_parameters" -> Params - "method" -> Method - "module" -> Module - "nil" -> Identifier - "operator_assignment" -> OperatorAssignment - "optional_parameter" -> OptionalParameter - "pair" -> Pair - "pattern" -> Args - "program" -> Program - "range" -> RangeExpression - "regex" -> Regex - "rescue_modifier" -> Modifier Rescue - "rescue" -> Rescue - "rest_assignment" -> SplatParameter - "return" -> Return - "scope_resolution" -> ScopeOperator - "self" -> Identifier - "singleton_class" -> SingletonClass - "singleton_method" -> SingletonMethod - "splat_parameter" -> SplatParameter - "string" -> StringLiteral - "subshell" -> Subshell - "superclass" -> Superclass - "symbol" -> SymbolLiteral - "true" -> Boolean - "unary" -> Unary - "unless_modifier" -> Modifier Unless - "unless" -> Unless - "until_modifier" -> Modifier Until - "until" -> Until - "when" -> When - "while_modifier" -> Modifier While - "while" -> While - "yield" -> Yield - s -> Other s diff --git a/src/TreeSitter.hs b/src/TreeSitter.hs index 9e5e0951a..e4d3d9ad4 100644 --- a/src/TreeSitter.hs +++ b/src/TreeSitter.hs @@ -21,7 +21,6 @@ import qualified Data.Syntax.Assignment as A import Data.Text (Text, pack) import Language import qualified Language.Go as Go -import qualified Language.Ruby as Ruby import Foreign import Foreign.C.String (peekCString) import Foreign.Marshal.Array (allocaArray) @@ -115,7 +114,6 @@ assignTerm language source annotation children allChildren = where assignTermByLanguage :: Source -> Category -> [ SyntaxTerm DefaultFields ] -> Maybe (S.Syntax (SyntaxTerm DefaultFields)) assignTermByLanguage = case languageForTSLanguage language of Just Language.Go -> Go.termAssignment - Just Ruby -> Ruby.termAssignment _ -> \ _ _ _ -> Nothing defaultTermAssignment :: Source -> Record DefaultFields -> [ SyntaxTerm DefaultFields ] -> IO [ SyntaxTerm DefaultFields ] -> IO (SyntaxTerm DefaultFields) @@ -192,7 +190,6 @@ categoryForLanguageProductionName = withDefaults . byLanguage s -> productionMap s byLanguage language = case languageForTSLanguage language of - Just Ruby -> Ruby.categoryForRubyName Just Language.Go -> Go.categoryForGoName _ -> Other @@ -200,6 +197,5 @@ categoryForLanguageProductionName = withDefaults . byLanguage languageForTSLanguage :: Ptr TS.Language -> Maybe Language languageForTSLanguage = flip lookup [ (TS.tree_sitter_go, Language.Go) - , (TS.tree_sitter_ruby, Ruby) , (TS.tree_sitter_typescript, TypeScript) ] From dbd05d33bda5ffa6c86f0ffc8c35c4dca5cf00c4 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:53:30 -0400 Subject: [PATCH 009/133] :fire: monolithic Go assignment. --- semantic-diff.cabal | 1 - src/Language/Go.hs | 144 -------------------------------------------- src/TreeSitter.hs | 3 - 3 files changed, 148 deletions(-) delete mode 100644 src/Language/Go.hs diff --git a/semantic-diff.cabal b/semantic-diff.cabal index 5d249deb5..27181b535 100644 --- a/semantic-diff.cabal +++ b/semantic-diff.cabal @@ -50,7 +50,6 @@ library , Language , Language.Markdown , Language.Markdown.Syntax - , Language.Go , Language.Go.Syntax , Language.JSON.Grammar , Language.JSON.Syntax diff --git a/src/Language/Go.hs b/src/Language/Go.hs deleted file mode 100644 index 636be0922..000000000 --- a/src/Language/Go.hs +++ /dev/null @@ -1,144 +0,0 @@ -{-# LANGUAGE DataKinds #-} -module Language.Go where - -import Control.Comonad -import Control.Comonad.Cofree -import Data.Foldable (toList) -import Data.Maybe -import Data.Source -import Data.Text -import Info -import qualified Syntax as S -import Term - -termAssignment - :: Source -- ^ The source of the term. - -> Category -- ^ The category for the term. - -> [ SyntaxTerm DefaultFields ] -- ^ The child nodes of the term. - -> Maybe (S.Syntax (SyntaxTerm DefaultFields)) -- ^ The resulting term, in Maybe. -termAssignment source category children = case (category, children) of - (Module, [moduleName]) -> Just $ S.Module moduleName [] - (Import, [importName]) -> Just $ S.Import importName [] - (Function, [id, params, block]) -> Just $ S.Function id [params] (toList (unwrap block)) - (Function, [id, params, ty, block]) -> Just $ S.Function id [params, ty] (toList (unwrap block)) - (For, [body]) | Other "block" <- Info.category (extract body) -> Just $ S.For [] (toList (unwrap body)) - (For, [forClause, body]) | Other "for_clause" <- Info.category (extract forClause) -> Just $ S.For (toList (unwrap forClause)) (toList (unwrap body)) - (For, [rangeClause, body]) | Other "range_clause" <- Info.category (extract rangeClause) -> Just $ S.For (toList (unwrap rangeClause)) (toList (unwrap body)) - (TypeDecl, [identifier, ty]) -> Just $ S.TypeDecl identifier ty - (StructTy, _) -> Just (S.Ty children) - (FieldDecl, _) -> Just (S.FieldDecl children) - (ParameterDecl, param : ty) -> Just $ S.ParameterDecl (listToMaybe ty) param - (Assignment, [identifier, expression]) -> Just $ S.VarAssignment [identifier] expression - (Select, _) -> Just $ S.Select (children >>= toList . unwrap) - (Go, [expr]) -> Just $ S.Go expr - (Defer, [expr]) -> Just $ S.Defer expr - (SubscriptAccess, [a, b]) -> Just $ S.SubscriptAccess a b - (IndexExpression, [a, b]) -> Just $ S.SubscriptAccess a b - (Slice, [a, rest]) -> Just $ S.SubscriptAccess a rest - (Literal, children) -> Just . S.Indexed $ unpackElement <$> children - (Other "composite_literal", [ty, values]) - | ArrayTy <- Info.category (extract ty) - -> Just $ S.Array (Just ty) (toList (unwrap values)) - | DictionaryTy <- Info.category (extract ty) - -> Just $ S.Object (Just ty) (toList (unwrap values)) - | SliceTy <- Info.category (extract ty) - -> Just $ S.SubscriptAccess ty values - (Other "composite_literal", []) -> Just $ S.Struct Nothing [] - (Other "composite_literal", [ty]) -> Just $ S.Struct (Just ty) [] - (Other "composite_literal", [ty, values]) -> Just $ S.Struct (Just ty) (toList (unwrap values)) - (TypeAssertion, [a, b]) -> Just $ S.TypeAssertion a b - (TypeConversion, [a, b]) -> Just $ S.TypeConversion a b - -- TODO: Handle multiple var specs - (VarAssignment, [identifier, expression]) -> Just $ S.VarAssignment [identifier] expression - (VarDecl, children) -> Just $ S.VarDecl children - (FunctionCall, id : rest) -> Just $ S.FunctionCall id [] rest - (AnonymousFunction, [params, _, body]) - | [params'] <- toList (unwrap params) - -> Just $ S.AnonymousFunction (toList (unwrap params')) (toList (unwrap body)) - (PointerTy, _) -> Just $ S.Ty children - (ChannelTy, _) -> Just $ S.Ty children - (Send, [channel, expr]) -> Just $ S.Send channel expr - (Operator, _) -> Just $ S.Operator children - (FunctionTy, _) -> Just $ S.Ty children - (IncrementStatement, _) -> Just $ S.Leaf (toText source) - (DecrementStatement, _) -> Just $ S.Leaf (toText source) - (QualifiedType, _) -> Just $ S.Leaf (toText source) - (Method, [receiverParams, name, body]) -> Just (S.Method [] name (Just receiverParams) [] (toList (unwrap body))) - (Method, [receiverParams, name, params, body]) - -> Just (S.Method [] name (Just receiverParams) [params] (toList (unwrap body))) - (Method, [receiverParams, name, params, ty, body]) - -> Just (S.Method [] name (Just receiverParams) [params, ty] (toList (unwrap body))) - _ -> Nothing - where unpackElement element - | Element <- Info.category (extract element) - , S.Indexed [ child ] <- unwrap element = child - | otherwise = element - -categoryForGoName :: Text -> Category -categoryForGoName name = case name of - "identifier" -> Identifier - "package_identifier" -> Identifier - "type_identifier" -> Identifier - "field_identifier" -> Identifier - "label_name" -> Identifier - "int_literal" -> NumberLiteral - "float_literal" -> FloatLiteral - "comment" -> Comment - "return_statement" -> Return - "interpreted_string_literal" -> StringLiteral - "raw_string_literal" -> StringLiteral - "binary_expression" -> RelationalOperator - "function_declaration" -> Function - "func_literal" -> AnonymousFunction - "call_expression" -> FunctionCall - "selector_expression" -> SubscriptAccess - "index_expression" -> IndexExpression - "slice_expression" -> Slice - "parameters" -> Args - "short_var_declaration" -> VarDecl - "var_spec" -> VarAssignment - "const_spec" -> VarAssignment - "assignment_statement" -> Assignment - "source_file" -> Program - "package_clause" -> Module - "if_statement" -> If - "for_statement" -> For - "expression_switch_statement" -> Switch - "type_switch_statement" -> Switch - "expression_case_clause" -> Case - "type_case_clause" -> Case - "select_statement" -> Select - "communication_case" -> Case - "defer_statement" -> Defer - "go_statement" -> Go - "type_assertion_expression" -> TypeAssertion - "type_conversion_expression" -> TypeConversion - "keyed_element" -> Pair - "struct_type" -> StructTy - "map_type" -> DictionaryTy - "array_type" -> ArrayTy - "implicit_length_array_type" -> ArrayTy - "parameter_declaration" -> ParameterDecl - "expression_case" -> Case - "type_spec" -> TypeDecl - "field_declaration" -> FieldDecl - "pointer_type" -> PointerTy - "slice_type" -> SliceTy - "element" -> Element - "literal_value" -> Literal - "channel_type" -> ChannelTy - "send_statement" -> Send - "unary_expression" -> Operator - "function_type" -> FunctionTy - "inc_statement" -> IncrementStatement - "dec_statement" -> DecrementStatement - "qualified_type" -> QualifiedType - "break_statement" -> Break - "continue_statement" -> Continue - "rune_literal" -> RuneLiteral - "method_declaration" -> Method - "import_spec" -> Import - "block" -> ExpressionStatements - "parenthesized_expression" -> ParenthesizedExpression - "parenthesized_type" -> ParenthesizedType - s -> Other s diff --git a/src/TreeSitter.hs b/src/TreeSitter.hs index e4d3d9ad4..ef2f7e7a6 100644 --- a/src/TreeSitter.hs +++ b/src/TreeSitter.hs @@ -20,7 +20,6 @@ import Data.Span import qualified Data.Syntax.Assignment as A import Data.Text (Text, pack) import Language -import qualified Language.Go as Go import Foreign import Foreign.C.String (peekCString) import Foreign.Marshal.Array (allocaArray) @@ -113,7 +112,6 @@ assignTerm language source annotation children allChildren = _ -> defaultTermAssignment source annotation children allChildren where assignTermByLanguage :: Source -> Category -> [ SyntaxTerm DefaultFields ] -> Maybe (S.Syntax (SyntaxTerm DefaultFields)) assignTermByLanguage = case languageForTSLanguage language of - Just Language.Go -> Go.termAssignment _ -> \ _ _ _ -> Nothing defaultTermAssignment :: Source -> Record DefaultFields -> [ SyntaxTerm DefaultFields ] -> IO [ SyntaxTerm DefaultFields ] -> IO (SyntaxTerm DefaultFields) @@ -190,7 +188,6 @@ categoryForLanguageProductionName = withDefaults . byLanguage s -> productionMap s byLanguage language = case languageForTSLanguage language of - Just Language.Go -> Go.categoryForGoName _ -> Other From 7ee1f0db6f4efcd8d983d93570f45fef538b8b12 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:57:09 -0400 Subject: [PATCH 010/133] :fire: TreeSitterParser. --- src/Parser.hs | 13 +------------ src/Semantic/Task.hs | 1 - 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/Parser.hs b/src/Parser.hs index a14b70123..6e9b328f3 100644 --- a/src/Parser.hs +++ b/src/Parser.hs @@ -32,7 +32,6 @@ import qualified Language.TypeScript.Syntax as TypeScript import Syntax hiding (Go) import Term import qualified TreeSitter.Language as TS (Language, Symbol) -import TreeSitter.Go import TreeSitter.Python import TreeSitter.Ruby import TreeSitter.TypeScript @@ -47,8 +46,6 @@ data Parser term where => Parser (Cofree ast (Node grammar)) -- ^ A parser producing AST. -> Assignment ast grammar (Term (Union fs) (Record Location)) -- ^ An assignment from AST onto 'Term's. -> Parser (Term (Union fs) (Record Location)) -- ^ A parser producing 'Term's. - -- | A tree-sitter parser. - TreeSitterParser :: Ptr TS.Language -> Parser (SyntaxTerm DefaultFields) -- | A parser for 'Markdown' using cmark. MarkdownParser :: Parser (Cofree (CofreeF [] CMarkGFM.NodeType) (Node Markdown.Grammar)) -- | A parser which will parse any input 'Source' into a top-level 'Term' whose children are leaves consisting of the 'Source's lines. @@ -56,15 +53,7 @@ data Parser term where -- | Return a 'Language'-specific 'Parser', if one exists, falling back to the 'LineByLineParser'. parserForLanguage :: Maybe Language -> Parser (SyntaxTerm DefaultFields) -parserForLanguage Nothing = LineByLineParser -parserForLanguage (Just language) = case language of - Go -> TreeSitterParser tree_sitter_go - JavaScript -> TreeSitterParser tree_sitter_typescript - JSON -> TreeSitterParser tree_sitter_json - JSX -> TreeSitterParser tree_sitter_typescript - Ruby -> TreeSitterParser tree_sitter_ruby - TypeScript -> TreeSitterParser tree_sitter_typescript - _ -> LineByLineParser +parserForLanguage _ = LineByLineParser rubyParser :: Parser Ruby.Term rubyParser = AssignmentParser (ASTParser tree_sitter_ruby) Ruby.assignment diff --git a/src/Semantic/Task.hs b/src/Semantic/Task.hs index 440456aa0..f1fb54a36 100644 --- a/src/Semantic/Task.hs +++ b/src/Semantic/Task.hs @@ -206,7 +206,6 @@ runParser Options{..} blob@Blob{..} = go for_ (errors term) $ \ err -> writeLog Warning (Error.formatError optionsPrintSource (optionsIsTerminal && optionsEnableColour) blob err) blobFields pure $ Right term - TreeSitterParser tslanguage -> logTiming "ts parse" $ liftIO (Right <$> treeSitterParser tslanguage blob) MarkdownParser -> logTiming "cmark parse" $ pure (Right (cmarkParser blobSource)) LineByLineParser -> logTiming "line-by-line parse" $ pure (Right (lineByLineParser blobSource)) blobFields = [ ("path", blobPath), ("language", maybe "" show blobLanguage) ] From 126036b60c08f0bf53ce3b3e17d667d180854dff Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:57:29 -0400 Subject: [PATCH 011/133] :fire: monolithic parsing & term assignment. --- src/TreeSitter.hs | 148 +--------------------------------------------- 1 file changed, 1 insertion(+), 147 deletions(-) diff --git a/src/TreeSitter.hs b/src/TreeSitter.hs index ef2f7e7a6..cb0fc7caf 100644 --- a/src/TreeSitter.hs +++ b/src/TreeSitter.hs @@ -1,48 +1,23 @@ {-# LANGUAGE DataKinds, ScopedTypeVariables, TypeOperators #-} module TreeSitter -( treeSitterParser -, parseToAST +( parseToAST ) where -import Category -import Control.Comonad (extract) -import Control.Comonad.Cofree (unwrap) import Control.Exception import Control.Monad ((<=<)) import Data.Blob import Data.ByteString.Unsafe (unsafeUseAsCStringLen) -import Data.Foldable (toList) import Data.Functor.Foldable hiding (Nil) import Data.Range -import Data.Record import Data.Source import Data.Span import qualified Data.Syntax.Assignment as A -import Data.Text (Text, pack) -import Language import Foreign -import Foreign.C.String (peekCString) import Foreign.Marshal.Array (allocaArray) -import qualified Syntax as S import Term import qualified TreeSitter.Document as TS import qualified TreeSitter.Node as TS import qualified TreeSitter.Language as TS -import qualified TreeSitter.Go as TS -import qualified TreeSitter.Ruby as TS -import qualified TreeSitter.TypeScript as TS -import Info - --- | Returns a TreeSitter parser for the given language and TreeSitter grammar. -treeSitterParser :: Ptr TS.Language -> Blob -> IO (SyntaxTerm DefaultFields) -treeSitterParser language blob = bracket TS.ts_document_new TS.ts_document_free $ \ document -> do - TS.ts_document_set_language document language - unsafeUseAsCStringLen (sourceBytes (blobSource blob)) $ \ (sourceBytes, len) -> do - TS.ts_document_set_input_string_with_length document sourceBytes len - TS.ts_document_parse_halt_on_error document - term <- documentToTerm language document blob - pure term - -- | Parse 'Source' with the given 'TS.Language' and return its AST. parseToAST :: (Bounded grammar, Enum grammar) => Ptr TS.Language -> Blob -> IO (A.AST [] grammar) @@ -69,130 +44,9 @@ anaM :: (Corecursive t, Monad m, Traversable (Base t)) => (a -> m (Base t a)) -> anaM g = a where a = pure . embed <=< traverse a <=< g --- | Return a parser for a tree sitter language & document. -documentToTerm :: Ptr TS.Language -> Ptr TS.Document -> Blob -> IO (SyntaxTerm DefaultFields) -documentToTerm language document Blob{..} = do - root <- alloca (\ rootPtr -> do - TS.ts_document_root_node_p document rootPtr - peek rootPtr) - toTerm root - where toTerm :: TS.Node -> IO (SyntaxTerm DefaultFields) - toTerm node@TS.Node{..} = do - name <- peekCString nodeType - - children <- getChildren (fromIntegral nodeNamedChildCount) copyNamed - let allChildren = getChildren (fromIntegral nodeChildCount) copyAll - - let source = slice (nodeRange node) blobSource - assignTerm language source (range :. categoryForLanguageProductionName language (pack name) :. nodeSpan node :. Nil) children allChildren - where getChildren count copy = do - nodes <- allocaArray count $ \ childNodesPtr -> do - _ <- with nodeTSNode (\ nodePtr -> copy nodePtr childNodesPtr (fromIntegral count)) - peekArray count childNodesPtr - children <- traverse toTerm nodes - return $! filter isNonEmpty children - range = nodeRange node - copyNamed = TS.ts_node_copy_named_child_nodes document - copyAll = TS.ts_node_copy_child_nodes document - -isNonEmpty :: HasField fields Category => SyntaxTerm fields -> Bool -isNonEmpty = (/= Empty) . category . extract - nodeRange :: TS.Node -> Range nodeRange TS.Node{..} = Range (fromIntegral nodeStartByte) (fromIntegral nodeEndByte) nodeSpan :: TS.Node -> Span nodeSpan TS.Node{..} = nodeStartPoint `seq` nodeEndPoint `seq` Span (pointPos nodeStartPoint) (pointPos nodeEndPoint) where pointPos TS.TSPoint{..} = pointRow `seq` pointColumn `seq` Pos (1 + fromIntegral pointRow) (1 + fromIntegral pointColumn) - -assignTerm :: Ptr TS.Language -> Source -> Record DefaultFields -> [ SyntaxTerm DefaultFields ] -> IO [ SyntaxTerm DefaultFields ] -> IO (SyntaxTerm DefaultFields) -assignTerm language source annotation children allChildren = - case assignTermByLanguage source (category annotation) children of - Just a -> pure (cofree (annotation :< a)) - _ -> defaultTermAssignment source annotation children allChildren - where assignTermByLanguage :: Source -> Category -> [ SyntaxTerm DefaultFields ] -> Maybe (S.Syntax (SyntaxTerm DefaultFields)) - assignTermByLanguage = case languageForTSLanguage language of - _ -> \ _ _ _ -> Nothing - -defaultTermAssignment :: Source -> Record DefaultFields -> [ SyntaxTerm DefaultFields ] -> IO [ SyntaxTerm DefaultFields ] -> IO (SyntaxTerm DefaultFields) -defaultTermAssignment source annotation children allChildren - | category annotation `elem` operatorCategories = cofree . (annotation :<) . S.Operator <$> allChildren - | otherwise = case (category annotation, children) of - (ParseError, children) -> toTerm $ S.ParseError children - - (Comment, _) -> toTerm $ S.Comment (toText source) - - (Pair, [key, value]) -> toTerm $ S.Pair key value - - -- Control flow statements - (If, condition : body) -> toTerm $ S.If condition body - (Switch, _) -> let (subject, body) = break ((== Other "switch_body") . Info.category . extract) children in toTerm $ S.Switch subject (body >>= toList . unwrap) - (Case, expr : body) -> toTerm $ S.Case expr body - (While, expr : rest) -> toTerm $ S.While expr rest - - -- Statements - (Return, _) -> toTerm $ S.Return children - (Yield, _) -> toTerm $ S.Yield children - (Throw, [expr]) -> toTerm $ S.Throw expr - (Break, [label]) -> toTerm $ S.Break (Just label) - (Break, []) -> toTerm $ S.Break Nothing - (Continue, [label]) -> toTerm $ S.Continue (Just label) - (Continue, []) -> toTerm $ S.Continue Nothing - - (ParenthesizedExpression, [child]) -> pure child - - (Other "unary_expression", _) -> do - cs <- allChildren - let c = case category . extract <$> cs of - [Other s, _] - | s `elem` ["-", "+", "++", "--"] -> MathOperator - | s == "~" -> BitwiseOperator - | s == "!" -> BooleanOperator - [_, Other t] - | t `elem` ["--", "++"] -> MathOperator - _ -> Operator - pure (cofree ((setCategory annotation c) :< S.Operator cs)) - - (Other "binary_expression", _) -> do - cs <- allChildren - let c = case category . extract <$> cs of - [_, Other s, _] - | s `elem` ["<=", "<", ">=", ">", "==", "===", "!=", "!=="] -> RelationalOperator - | s `elem` ["*", "+", "-", "/", "%"] -> MathOperator - | s `elem` ["&&", "||"] -> BooleanOperator - | s `elem` [">>", ">>=", ">>>", ">>>=", "<<", "<<=", "&", "^", "|"] -> BitwiseOperator - _ -> Operator - pure (cofree ((setCategory annotation c) :< S.Operator cs)) - - (_, []) -> toTerm $ S.Leaf (toText source) - (_, children) -> toTerm $ S.Indexed children - where operatorCategories = - [ Operator - , Binary - , Unary - , RangeExpression - , ScopeOperator - , BooleanOperator - , MathOperator - , RelationalOperator - , BitwiseOperator - ] - toTerm = pure . cofree . (annotation :<) - - -categoryForLanguageProductionName :: Ptr TS.Language -> Text -> Category -categoryForLanguageProductionName = withDefaults . byLanguage - where - withDefaults productionMap name = case name of - "ERROR" -> ParseError - s -> productionMap s - - byLanguage language = case languageForTSLanguage language of - _ -> Other - - -languageForTSLanguage :: Ptr TS.Language -> Maybe Language -languageForTSLanguage = flip lookup - [ (TS.tree_sitter_go, Language.Go) - , (TS.tree_sitter_typescript, TypeScript) - ] From 2f437928b909a1f6f4372fddfae0a0cfd58cb9c4 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 29 Aug 2017 15:58:13 -0400 Subject: [PATCH 012/133] :fire: toTuple. --- src/Language.hs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Language.hs b/src/Language.hs index 3a4ac6156..43dbf716a 100644 --- a/src/Language.hs +++ b/src/Language.hs @@ -1,14 +1,9 @@ {-# LANGUAGE DataKinds, DeriveGeneric, DeriveAnyClass #-} module Language where -import Control.Comonad -import Control.Comonad.Trans.Cofree hiding (cofree) import Control.DeepSeq import Data.Aeson -import Data.Record import GHC.Generics -import qualified Syntax as S -import Term -- | A programming language. data Language @@ -35,9 +30,3 @@ languageForType mediaType = case mediaType of ".jsx" -> Just JSX ".py" -> Just Python _ -> Nothing - -toTuple :: Term S.Syntax (Record fields) -> [Term S.Syntax (Record fields)] -toTuple child | S.Indexed [key,value] <- unwrap child = [cofree (extract child :< S.Pair key value)] -toTuple child | S.Fixed [key,value] <- unwrap child = [cofree (extract child :< S.Pair key value)] -toTuple child | S.Leaf c <- unwrap child = [cofree (extract child :< S.Comment c)] -toTuple child = pure child From 9e9837ab276af0f33f322ba1354739759397fbd2 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:22:02 -0400 Subject: [PATCH 013/133] Define a SemanticException type. --- src/Semantic.hs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index 5ca913381..e22e906ba 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE DataKinds, GADTs, TypeOperators #-} +{-# LANGUAGE DataKinds, GADTs, StandaloneDeriving, TypeOperators #-} module Semantic ( parseBlobs , parseBlob @@ -9,6 +9,7 @@ module Semantic import Algorithm hiding (diff) import Control.Applicative ((<|>)) +import Control.Exception import Control.Monad ((<=<)) import Data.Align.Generic (GAlign) import Data.Blob @@ -18,8 +19,10 @@ import Data.Functor.Classes (Eq1, Show1) import Data.Output import Data.Record import qualified Data.Syntax.Declaration as Declaration +import Data.Typeable import Data.Union import Decorators +import GHC.Stack import Diff import Info import Interpreter @@ -139,3 +142,12 @@ keepCategory = (:. Nil) . category keepConstructorLabel :: Record (ConstructorLabel ': fields) -> Record '[ConstructorLabel] keepConstructorLabel = (:. Nil) . rhead + + +data SemanticException where + SemanticException :: HasCallStack => String -> SemanticException + deriving (Typeable) + +deriving instance Show SemanticException + +instance Exception SemanticException From 4d2b9a772361a518af203d684e0b4ddb5f871e83 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:22:55 -0400 Subject: [PATCH 014/133] Throw an exception for unsupported configurations. --- src/Semantic.hs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index e22e906ba..519908d18 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -11,6 +11,7 @@ import Algorithm hiding (diff) import Control.Applicative ((<|>)) import Control.Exception import Control.Monad ((<=<)) +import Control.Monad.Error.Class import Data.Align.Generic (GAlign) import Data.Blob import Data.ByteString (ByteString) @@ -53,29 +54,25 @@ parseBlob renderer blob@Blob{..} = case (renderer, blobLanguage) of (ToCTermRenderer, Just Language.Python) -> parse pythonParser blob >>= decorate (declarationAlgebra blob) >>= render (renderToCTerm blob) (ToCTermRenderer, Just Language.Ruby) -> parse rubyParser blob >>= decorate (declarationAlgebra blob) >>= render (renderToCTerm blob) (ToCTermRenderer, Just Language.TypeScript) -> parse typescriptParser blob >>= decorate (declarationAlgebra blob) >>= render (renderToCTerm blob) - (ToCTermRenderer, _) -> parse syntaxParser blob >>= decorate (syntaxDeclarationAlgebra blob) >>= render (renderToCTerm blob) (JSONTermRenderer, Just Language.Go) -> parse goParser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob) (JSONTermRenderer, Just Language.JSON) -> parse jsonParser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob) (JSONTermRenderer, Just Language.Markdown) -> parse markdownParser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob) (JSONTermRenderer, Just Language.Python) -> parse pythonParser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob) (JSONTermRenderer, Just Language.Ruby) -> parse rubyParser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob) (JSONTermRenderer, Just Language.TypeScript) -> parse typescriptParser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob) - (JSONTermRenderer, _) -> parse syntaxParser blob >>= decorate identifierAlgebra >>= render (renderJSONTerm blob) (SExpressionTermRenderer, Just Language.Go) -> parse goParser blob >>= decorate constructorLabel >>= render renderSExpressionTerm . fmap keepConstructorLabel (SExpressionTermRenderer, Just Language.JSON) -> parse jsonParser blob >>= decorate constructorLabel >>= render renderSExpressionTerm . fmap keepConstructorLabel (SExpressionTermRenderer, Just Language.Markdown) -> parse markdownParser blob >>= decorate constructorLabel >>= render renderSExpressionTerm . fmap keepConstructorLabel (SExpressionTermRenderer, Just Language.Python) -> parse pythonParser blob >>= decorate constructorLabel >>= render renderSExpressionTerm . fmap keepConstructorLabel (SExpressionTermRenderer, Just Language.Ruby) -> parse rubyParser blob >>= decorate constructorLabel >>= render renderSExpressionTerm . fmap keepConstructorLabel (SExpressionTermRenderer, Just Language.TypeScript) -> parse typescriptParser blob >>= decorate constructorLabel >>= render renderSExpressionTerm . fmap keepConstructorLabel - (SExpressionTermRenderer, _) -> parse syntaxParser blob >>= render renderSExpressionTerm . fmap keepCategory (IdentityTermRenderer, Just Language.Go) -> pure Nothing (IdentityTermRenderer, Just Language.JSON) -> pure Nothing (IdentityTermRenderer, Just Language.Markdown) -> pure Nothing (IdentityTermRenderer, Just Language.Python) -> pure Nothing (IdentityTermRenderer, Just Language.Ruby) -> pure Nothing (IdentityTermRenderer, Just Language.TypeScript) -> pure Nothing - (IdentityTermRenderer, _) -> Just <$> parse syntaxParser blob - where syntaxParser = parserForLanguage blobLanguage + _ -> throwError (toException (SemanticException ("don’t know how to produce " ++ show renderer ++ " for " ++ show blobLanguage))) diffBlobPairs :: Output output => DiffRenderer output -> [Both Blob] -> Task ByteString From 16635c29c097c203a4c6d921296a10de453a1d0c Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:24:05 -0400 Subject: [PATCH 015/133] Throw an exception for unsupported diffing configurations. --- src/Semantic.hs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index 519908d18..37db34ab7 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -86,31 +86,26 @@ diffBlobPair renderer blobs = case (renderer, effectiveLanguage) of (ToCDiffRenderer, Just Language.Python) -> run (\ blob -> parse pythonParser blob >>= decorate (declarationAlgebra blob)) diffRecursively (renderToCDiff blobs) (ToCDiffRenderer, Just Language.Ruby) -> run (\ blob -> parse rubyParser blob >>= decorate (declarationAlgebra blob)) diffRecursively (renderToCDiff blobs) (ToCDiffRenderer, Just Language.TypeScript) -> run (\ blob -> parse typescriptParser blob >>= decorate (declarationAlgebra blob)) diffRecursively (renderToCDiff blobs) - (ToCDiffRenderer, _) -> run (\ blob -> parse syntaxParser blob >>= decorate (syntaxDeclarationAlgebra blob)) diffTerms (renderToCDiff blobs) (JSONDiffRenderer, Just Language.Go) -> run (parse goParser) diffRecursively (renderJSONDiff blobs) (JSONDiffRenderer, Just Language.JSON) -> run (parse jsonParser) diffRecursively (renderJSONDiff blobs) (JSONDiffRenderer, Just Language.Markdown) -> run (parse markdownParser) diffRecursively (renderJSONDiff blobs) (JSONDiffRenderer, Just Language.Python) -> run (parse pythonParser) diffRecursively (renderJSONDiff blobs) (JSONDiffRenderer, Just Language.Ruby) -> run (parse rubyParser) diffRecursively (renderJSONDiff blobs) (JSONDiffRenderer, Just Language.TypeScript) -> run (parse typescriptParser) diffRecursively (renderJSONDiff blobs) - (JSONDiffRenderer, _) -> run (decorate identifierAlgebra <=< parse syntaxParser) diffTerms (renderJSONDiff blobs) (PatchDiffRenderer, Just Language.Go) -> run (parse goParser) diffRecursively (renderPatch blobs) (PatchDiffRenderer, Just Language.JSON) -> run (parse jsonParser) diffRecursively (renderPatch blobs) (PatchDiffRenderer, Just Language.Markdown) -> run (parse markdownParser) diffRecursively (renderPatch blobs) (PatchDiffRenderer, Just Language.Python) -> run (parse pythonParser) diffRecursively (renderPatch blobs) (PatchDiffRenderer, Just Language.Ruby) -> run (parse rubyParser) diffRecursively (renderPatch blobs) (PatchDiffRenderer, Just Language.TypeScript) -> run (parse typescriptParser) diffRecursively (renderPatch blobs) - (PatchDiffRenderer, _) -> run (parse syntaxParser) diffTerms (renderPatch blobs) (SExpressionDiffRenderer, Just Language.Go) -> run (decorate constructorLabel <=< parse goParser) diffRecursively (renderSExpressionDiff . mapAnnotations keepConstructorLabel) (SExpressionDiffRenderer, Just Language.JSON) -> run (decorate constructorLabel <=< parse jsonParser) diffRecursively (renderSExpressionDiff . mapAnnotations keepConstructorLabel) (SExpressionDiffRenderer, Just Language.Markdown) -> run (decorate constructorLabel <=< parse markdownParser) diffRecursively (renderSExpressionDiff . mapAnnotations keepConstructorLabel) (SExpressionDiffRenderer, Just Language.Python) -> run (decorate constructorLabel <=< parse pythonParser) diffRecursively (renderSExpressionDiff . mapAnnotations keepConstructorLabel) (SExpressionDiffRenderer, Just Language.Ruby) -> run (decorate constructorLabel <=< parse rubyParser) diffRecursively (renderSExpressionDiff . mapAnnotations keepConstructorLabel) (SExpressionDiffRenderer, Just Language.TypeScript) -> run (decorate constructorLabel <=< parse typescriptParser) diffRecursively (renderSExpressionDiff . mapAnnotations keepConstructorLabel) - (SExpressionDiffRenderer, _) -> run (parse syntaxParser) diffTerms (renderSExpressionDiff . mapAnnotations keepCategory) - (IdentityDiffRenderer, _) -> run (\ blob -> parse syntaxParser blob >>= decorate (syntaxDeclarationAlgebra blob)) diffTerms Just + _ -> throwError (toException (SemanticException ("don’t know how to produce " ++ show renderer ++ " for " ++ show (fmap blobLanguage blobs)))) where effectiveLanguage = runBothWith (<|>) (blobLanguage <$> blobs) - syntaxParser = parserForLanguage effectiveLanguage run :: Functor f => (Blob -> Task (Term f a)) -> (Both (Term f a) -> Diff f a) -> (Diff f a -> output) -> Task output run parse diff renderer = distributeFor blobs parse >>= diffTermPair blobs diff >>= render renderer From b161ff8ef292b68954f5c562dbdf9da4664f9606 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:24:39 -0400 Subject: [PATCH 016/133] :fire: keepCategory. --- src/Semantic.hs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index 37db34ab7..6fa475375 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -25,7 +25,6 @@ import Data.Union import Decorators import GHC.Stack import Diff -import Info import Interpreter import qualified Language import Patch @@ -129,9 +128,6 @@ diffTermPair blobs differ terms = case runJoin (blobExists <$> blobs) of , ("after_language", maybe "" show (blobLanguage b)) ] -keepCategory :: HasField fields Category => Record fields -> Record '[Category] -keepCategory = (:. Nil) . category - keepConstructorLabel :: Record (ConstructorLabel ': fields) -> Record '[ConstructorLabel] keepConstructorLabel = (:. Nil) . rhead From 792446850f08eeceba71d93ecc59194bde2b0d46 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:26:02 -0400 Subject: [PATCH 017/133] :fire: support for diffing SyntaxTerms. --- src/Interpreter.hs | 68 +--------------------------------------------- 1 file changed, 1 insertion(+), 67 deletions(-) diff --git a/src/Interpreter.hs b/src/Interpreter.hs index c87ca4832..02d58adb6 100644 --- a/src/Interpreter.hs +++ b/src/Interpreter.hs @@ -1,7 +1,6 @@ {-# LANGUAGE DataKinds, GADTs, RankNTypes, ScopedTypeVariables, TypeOperators #-} module Interpreter -( diffTerms -, decoratingWith +( decoratingWith , diffTermsWith , comparableByConstructor , equivalentTerms @@ -18,24 +17,14 @@ import Data.Functor.Classes (Eq1(..)) import Data.Hashable (Hashable) import Data.Maybe (isJust) import Data.Record -import Data.Text (Text) import Data.These import Data.Union import qualified Data.Syntax.Declaration as Declaration import Diff -import Info hiding (Return) import Patch (inserting, deleting, replacing, patchSum) import RWS -import Syntax as S hiding (Return) import Term - --- | Diff two terms recursively, given functions characterizing the diffing. -diffTerms :: HasField fields Category - => Both (SyntaxTerm fields) -- ^ A pair of terms representing the old and new state, respectively. - -> SyntaxDiff fields -diffTerms = decoratingWith getLabel (diffTermsWith algorithmWithTerms comparableByCategory (equalTerms comparableByCategory)) - -- | Diff two terms by decorating with feature vectors computed using the supplied labelling algebra, and stripping the feature vectors from the resulting diff. decoratingWith :: (Hashable label, Traversable f) => (forall a. TermF f (Record fields) a -> label) @@ -63,61 +52,6 @@ diffTermsWith refine comparable eqTerms (Join (a, b)) = runFreer decompose (diff Insert b -> pure (inserting b) Replace a b -> pure (replacing a b) --- | Compute the label for a given term, suitable for inclusion in a _p_,_q_-gram. -getLabel :: HasField fields Category => TermF Syntax (Record fields) a -> (Category, Maybe Text) -getLabel (h :< t) = (Info.category h, case t of - Leaf s -> Just s - _ -> Nothing) - - --- | Construct an algorithm to diff a pair of terms. -algorithmWithTerms :: SyntaxTerm fields - -> SyntaxTerm fields - -> Algorithm (SyntaxTerm fields) (SyntaxDiff fields) (SyntaxDiff fields) -algorithmWithTerms t1 t2 = case (unwrap t1, unwrap t2) of - (Indexed a, Indexed b) -> - annotate . Indexed <$> byRWS a b - (S.Module idA a, S.Module idB b) -> - (annotate .) . S.Module <$> linearly idA idB <*> byRWS a b - (S.FunctionCall identifierA typeParamsA argsA, S.FunctionCall identifierB typeParamsB argsB) -> fmap annotate $ - S.FunctionCall <$> linearly identifierA identifierB - <*> byRWS typeParamsA typeParamsB - <*> byRWS argsA argsB - (S.Switch exprA casesA, S.Switch exprB casesB) -> fmap annotate $ - S.Switch <$> byRWS exprA exprB - <*> byRWS casesA casesB - (S.Object tyA a, S.Object tyB b) -> fmap annotate $ - S.Object <$> diffMaybe tyA tyB - <*> byRWS a b - (Commented commentsA a, Commented commentsB b) -> fmap annotate $ - Commented <$> byRWS commentsA commentsB - <*> diffMaybe a b - (Array tyA a, Array tyB b) -> fmap annotate $ - Array <$> diffMaybe tyA tyB - <*> byRWS a b - (S.Class identifierA clausesA expressionsA, S.Class identifierB clausesB expressionsB) -> fmap annotate $ - S.Class <$> linearly identifierA identifierB - <*> byRWS clausesA clausesB - <*> byRWS expressionsA expressionsB - (S.Method clausesA identifierA receiverA paramsA expressionsA, S.Method clausesB identifierB receiverB paramsB expressionsB) -> fmap annotate $ - S.Method <$> byRWS clausesA clausesB - <*> linearly identifierA identifierB - <*> diffMaybe receiverA receiverB - <*> byRWS paramsA paramsB - <*> byRWS expressionsA expressionsB - (S.Function idA paramsA bodyA, S.Function idB paramsB bodyB) -> fmap annotate $ - S.Function <$> linearly idA idB - <*> byRWS paramsA paramsB - <*> byRWS bodyA bodyB - _ -> linearly t1 t2 - where - annotate = wrap . (both (extract t1) (extract t2) :<) - - --- | Test whether two terms are comparable by their Category. -comparableByCategory :: HasField fields Category => ComparabilityRelation f fields -comparableByCategory (a :< _) (b :< _) = category a == category b - -- | Test whether two terms are comparable by their constructor. comparableByConstructor :: (GAlign f) => ComparabilityRelation f fields comparableByConstructor (_ :< a) (_ :< b) = isJust (galign a b) From 07a0acd44be08e988a565e755e2839393173f6eb Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:27:44 -0400 Subject: [PATCH 018/133] :fire: IdentityDiffRenderer. --- src/Renderer.hs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Renderer.hs b/src/Renderer.hs index 74b820625..8da4ff020 100644 --- a/src/Renderer.hs +++ b/src/Renderer.hs @@ -28,7 +28,6 @@ import qualified Data.Map as Map import Data.Output import Data.Syntax.Algebra (RAlgebra) import Data.Text (Text) -import Diff (SyntaxDiff) import Info (DefaultFields) import Renderer.JSON as R import Renderer.Patch as R @@ -47,8 +46,6 @@ data DiffRenderer output where JSONDiffRenderer :: DiffRenderer (Map.Map Text Value) -- | Render to a 'ByteString' formatted as nested s-expressions with patches indicated. SExpressionDiffRenderer :: DiffRenderer ByteString - -- | “Render” by returning the computed 'SyntaxDiff'. This renderer is not surfaced in the command-line interface, and is intended strictly for tests. Further, as it cannot render à la carte terms, it should be regarded as a (very) short-term hack until such time as we have a better idea for TOCSpec.hs. - IdentityDiffRenderer :: DiffRenderer (Maybe (SyntaxDiff (Maybe Declaration ': DefaultFields))) deriving instance Eq (DiffRenderer output) deriving instance Show (DiffRenderer output) From a1bbc9ce6ec8e390606bb750f6c0e3b6cfc1ecc6 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:27:54 -0400 Subject: [PATCH 019/133] :fire: IdentityTermRenderer. --- src/Renderer.hs | 4 ---- src/Semantic.hs | 6 ------ 2 files changed, 10 deletions(-) diff --git a/src/Renderer.hs b/src/Renderer.hs index 8da4ff020..eeead74fe 100644 --- a/src/Renderer.hs +++ b/src/Renderer.hs @@ -28,13 +28,11 @@ import qualified Data.Map as Map import Data.Output import Data.Syntax.Algebra (RAlgebra) import Data.Text (Text) -import Info (DefaultFields) import Renderer.JSON as R import Renderer.Patch as R import Renderer.SExpression as R import Renderer.TOC as R import Syntax as S -import Term (SyntaxTerm) -- | Specification of renderers for diffs, producing output in the parameter type. data DiffRenderer output where @@ -58,8 +56,6 @@ data TermRenderer output where JSONTermRenderer :: TermRenderer [Value] -- | Render to a 'ByteString' formatted as nested s-expressions. SExpressionTermRenderer :: TermRenderer ByteString - -- | “Render” by returning the computed 'SyntaxTerm'. This renderer is not surfaced in the command-line interface, and is intended strictly for tests. Further, as it cannot render à la carte terms, it should be regarded as a (very) short-term hack until such time as we have a better idea for SemanticSpec.hs. - IdentityTermRenderer :: TermRenderer (Maybe (SyntaxTerm DefaultFields)) deriving instance Eq (TermRenderer output) deriving instance Show (TermRenderer output) diff --git a/src/Semantic.hs b/src/Semantic.hs index 6fa475375..55151a3dd 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -65,12 +65,6 @@ parseBlob renderer blob@Blob{..} = case (renderer, blobLanguage) of (SExpressionTermRenderer, Just Language.Python) -> parse pythonParser blob >>= decorate constructorLabel >>= render renderSExpressionTerm . fmap keepConstructorLabel (SExpressionTermRenderer, Just Language.Ruby) -> parse rubyParser blob >>= decorate constructorLabel >>= render renderSExpressionTerm . fmap keepConstructorLabel (SExpressionTermRenderer, Just Language.TypeScript) -> parse typescriptParser blob >>= decorate constructorLabel >>= render renderSExpressionTerm . fmap keepConstructorLabel - (IdentityTermRenderer, Just Language.Go) -> pure Nothing - (IdentityTermRenderer, Just Language.JSON) -> pure Nothing - (IdentityTermRenderer, Just Language.Markdown) -> pure Nothing - (IdentityTermRenderer, Just Language.Python) -> pure Nothing - (IdentityTermRenderer, Just Language.Ruby) -> pure Nothing - (IdentityTermRenderer, Just Language.TypeScript) -> pure Nothing _ -> throwError (toException (SemanticException ("don’t know how to produce " ++ show renderer ++ " for " ++ show blobLanguage))) From a698014f57f6e6d8d916f636abddf7372d72a26d Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:28:59 -0400 Subject: [PATCH 020/133] :fire: syntaxDeclarationAlgebra. --- src/Renderer.hs | 1 - src/Renderer/TOC.hs | 15 --------------- 2 files changed, 16 deletions(-) diff --git a/src/Renderer.hs b/src/Renderer.hs index eeead74fe..3ee2227ed 100644 --- a/src/Renderer.hs +++ b/src/Renderer.hs @@ -12,7 +12,6 @@ module Renderer , renderToCTerm , declarationAlgebra , markupSectionAlgebra -, syntaxDeclarationAlgebra , identifierAlgebra , Summaries(..) , File(..) diff --git a/src/Renderer/TOC.hs b/src/Renderer/TOC.hs index 1ce69ed42..2b15e3bcd 100644 --- a/src/Renderer/TOC.hs +++ b/src/Renderer/TOC.hs @@ -10,7 +10,6 @@ module Renderer.TOC , declaration , declarationAlgebra , markupSectionAlgebra -, syntaxDeclarationAlgebra , Entry(..) , tableOfContentsBy , dedupe @@ -51,7 +50,6 @@ import Language import Patch import qualified Data.List as List import qualified Data.Map as Map hiding (null) -import Syntax as S import Data.Syntax.Algebra (RAlgebra) import qualified Data.Syntax as Syntax import qualified Data.Syntax.Declaration as Declaration @@ -105,19 +103,6 @@ declaration :: HasField fields (Maybe Declaration) => TermF f (Record fields) a declaration (annotation :< _) = annotation <$ (getField annotation :: Maybe Declaration) --- | Compute 'Declaration's for methods and functions in 'Syntax'. -syntaxDeclarationAlgebra :: HasField fields Range => Blob -> RAlgebra (SyntaxTermF fields) (SyntaxTerm fields) (Maybe Declaration) -syntaxDeclarationAlgebra Blob{..} (a :< r) = case r of - S.Function (identifier, _) _ _ -> Just $ FunctionDeclaration (getSource identifier) - S.Method _ (identifier, _) Nothing _ _ -> Just $ MethodDeclaration (getSource identifier) - S.Method _ (identifier, _) (Just (receiver, _)) _ _ - | S.Indexed [receiverParams] <- unwrap receiver - , S.ParameterDecl (Just ty) _ <- unwrap receiverParams -> Just $ MethodDeclaration ("(" <> getSource ty <> ") " <> getSource identifier) - | otherwise -> Just $ MethodDeclaration (getSource receiver <> "." <> getSource identifier) - S.ParseError{} -> Just $ ErrorDeclaration (toText (Source.slice (byteRange a) blobSource)) blobLanguage - _ -> Nothing - where getSource = toText . flip Source.slice blobSource . byteRange . extract - -- | Compute 'Declaration's for methods and functions. declarationAlgebra :: (Declaration.Function :< fs, Declaration.Method :< fs, Syntax.Error :< fs, Syntax.Empty :< fs, Apply1 Functor fs, HasField fields Range, HasField fields Span) => Blob From a6790a24b4e173795b48fe0b890929e345fc1db8 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:30:23 -0400 Subject: [PATCH 021/133] :fire: the line-by-line parser. --- src/Parser.hs | 20 -------------------- src/Semantic/Task.hs | 1 - 2 files changed, 21 deletions(-) diff --git a/src/Parser.hs b/src/Parser.hs index 1f1b345b1..fbc5fcb91 100644 --- a/src/Parser.hs +++ b/src/Parser.hs @@ -1,10 +1,6 @@ {-# LANGUAGE DataKinds, GADTs, RankNTypes, ScopedTypeVariables, TypeOperators #-} module Parser ( Parser(..) --- Syntax parsers -, parserForLanguage -, lineByLineParser --- À la carte parsers , goParser , jsonParser , markdownParser @@ -18,20 +14,16 @@ import Control.Comonad.Trans.Cofree (CofreeF) import qualified CMarkGFM import Data.Ix import Data.Record -import Data.Source as Source import qualified Data.Syntax as Syntax import Data.Syntax.Assignment import Data.Union import Foreign.Ptr -import Info hiding (Empty, Go) -import Language import qualified Language.Go.Syntax as Go import qualified Language.JSON.Syntax as JSON import qualified Language.Markdown.Syntax as Markdown import qualified Language.Python.Syntax as Python import qualified Language.Ruby.Syntax as Ruby import qualified Language.TypeScript.Syntax as TypeScript -import Syntax hiding (Go) import Term import qualified TreeSitter.Language as TS (Language, Symbol) import TreeSitter.Go @@ -51,12 +43,6 @@ data Parser term where -> Parser (Term (Union fs) (Record Location)) -- ^ A parser producing 'Term's. -- | A parser for 'Markdown' using cmark. MarkdownParser :: Parser (Cofree (CofreeF [] CMarkGFM.NodeType) (Node Markdown.Grammar)) - -- | A parser which will parse any input 'Source' into a top-level 'Term' whose children are leaves consisting of the 'Source's lines. - LineByLineParser :: Parser (SyntaxTerm DefaultFields) - --- | Return a 'Language'-specific 'Parser', if one exists, falling back to the 'LineByLineParser'. -parserForLanguage :: Maybe Language -> Parser (SyntaxTerm DefaultFields) -parserForLanguage _ = LineByLineParser goParser :: Parser Go.Term goParser = AssignmentParser (ASTParser tree_sitter_go) Go.assignment @@ -75,9 +61,3 @@ typescriptParser = AssignmentParser (ASTParser tree_sitter_typescript) TypeScrip markdownParser :: Parser Markdown.Term markdownParser = AssignmentParser MarkdownParser Markdown.assignment - - --- | A fallback parser that treats a file simply as rows of strings. -lineByLineParser :: Source -> SyntaxTerm DefaultFields -lineByLineParser source = cofree $ (totalRange source :. Program :. totalSpan source :. Nil) :< Indexed (zipWith toLine [1..] (sourceLineRanges source)) - where toLine line range = cofree $ (range :. Program :. Span (Pos line 1) (Pos line (end range)) :. Nil) :< Leaf (toText (slice range source)) diff --git a/src/Semantic/Task.hs b/src/Semantic/Task.hs index af28fd289..3004350af 100644 --- a/src/Semantic/Task.hs +++ b/src/Semantic/Task.hs @@ -216,7 +216,6 @@ runParser Options{..} blob@Blob{..} = go writeLog Warning (Error.formatError optionsPrintSource (optionsIsTerminal && optionsEnableColour) blob err) blobFields pure term MarkdownParser -> logTiming "cmark parse" $ pure (cmarkParser blobSource) - LineByLineParser -> logTiming "line-by-line parse" $ pure (lineByLineParser blobSource) blobFields = [ ("path", blobPath), ("language", maybe "" show blobLanguage) ] errors :: (Syntax.Error :< fs, Apply1 Foldable fs, Apply1 Functor fs) => Term (Union fs) (Record Assignment.Location) -> [Error.Error String] errors = cata $ \ (a :< syntax) -> case syntax of From 07450fbdbcf0f6b3dae387fb533d1609af86afe5 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:30:59 -0400 Subject: [PATCH 022/133] :fire: SyntaxTerm & SyntaxTermF. --- src/Term.hs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Term.hs b/src/Term.hs index 918d3d304..6360d0f38 100644 --- a/src/Term.hs +++ b/src/Term.hs @@ -3,8 +3,6 @@ module Term ( Term , TermF -, SyntaxTerm -, SyntaxTermF , zipTerms , termSize , alignCofreeWith @@ -23,19 +21,13 @@ import Data.Functor.Classes.Pretty.Generic import Data.Functor.Foldable import Data.Maybe import Data.Proxy -import Data.Record import Data.These import Data.Union -import Syntax -- | A Term with an abstract syntax tree and an annotation. type Term f = Cofree.Cofree f type TermF = CofreeF.CofreeF --- | A Term with a Syntax leaf and a record of fields. -type SyntaxTerm fields = Term Syntax (Record fields) -type SyntaxTermF fields = TermF Syntax (Record fields) - instance (NFData (f (Cofree.Cofree f a)), NFData a, Functor f) => NFData (Cofree.Cofree f a) where rnf = rnf . runCofree From 95bd2514494106bddada1b083be9ca42286522b3 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:31:59 -0400 Subject: [PATCH 023/133] :fire: SyntaxDiff. --- src/Diff.hs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Diff.hs b/src/Diff.hs index 444c7979e..7d1b9a7ec 100644 --- a/src/Diff.hs +++ b/src/Diff.hs @@ -10,17 +10,13 @@ import Data.Bifunctor import Data.Functor.Both as Both import Data.Functor.Classes.Pretty.Generic import Data.Mergeable -import Data.Record import Patch -import Syntax import Term -- | An annotated series of patches of terms. type DiffF f annotation = FreeF.FreeF (TermF f (Both annotation)) (Patch (Term f annotation)) type Diff f annotation = Free.Free (TermF f (Both annotation)) (Patch (Term f annotation)) -type SyntaxDiff fields = Diff Syntax (Record fields) - diffSum :: (Foldable f, Functor f) => (Patch (Term f annotation) -> Int) -> Diff f annotation -> Int diffSum patchCost diff = sum $ fmap patchCost diff From 8c1925332d26a6848aea0f74ffde0f20211a55cf Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:33:18 -0400 Subject: [PATCH 024/133] :fire: identifierAlgebra. --- src/Renderer.hs | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/Renderer.hs b/src/Renderer.hs index 3ee2227ed..f516dc7ca 100644 --- a/src/Renderer.hs +++ b/src/Renderer.hs @@ -12,26 +12,20 @@ module Renderer , renderToCTerm , declarationAlgebra , markupSectionAlgebra -, identifierAlgebra , Summaries(..) , File(..) ) where -import Control.Comonad.Cofree (Cofree, unwrap) -import Control.Comonad.Trans.Cofree (CofreeF(..)) import Control.DeepSeq import Data.Aeson (Value, (.=)) import Data.ByteString (ByteString) -import Data.Foldable (asum) import qualified Data.Map as Map import Data.Output -import Data.Syntax.Algebra (RAlgebra) import Data.Text (Text) import Renderer.JSON as R import Renderer.Patch as R import Renderer.SExpression as R import Renderer.TOC as R -import Syntax as S -- | Specification of renderers for diffs, producing output in the parameter type. data DiffRenderer output where @@ -68,23 +62,6 @@ data SomeRenderer f where deriving instance Show (SomeRenderer f) -identifierAlgebra :: RAlgebra (CofreeF Syntax a) (Cofree Syntax a) (Maybe Identifier) -identifierAlgebra (_ :< syntax) = case syntax of - S.Assignment f _ -> identifier f - S.Class f _ _ -> identifier f - S.Export f _ -> f >>= identifier - S.Function f _ _ -> identifier f - S.FunctionCall f _ _ -> identifier f - S.Import f _ -> identifier f - S.Method _ f _ _ _ -> identifier f - S.MethodCall _ f _ _ -> identifier f - S.Module f _ -> identifier f - S.OperatorAssignment f _ -> identifier f - S.SubscriptAccess f _ -> identifier f - S.TypeDecl f _ -> identifier f - S.VarAssignment f _ -> asum $ identifier <$> f - _ -> Nothing - where identifier = fmap Identifier . extractLeafValue . unwrap . fst newtype Identifier = Identifier Text deriving (Eq, NFData, Show) From 6dc827a09ef332d2cd10378835088d459097ed1e Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:33:45 -0400 Subject: [PATCH 025/133] :fire: the ToJSONFields instance for Syntax. --- src/Renderer/JSON.hs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Renderer/JSON.hs b/src/Renderer/JSON.hs index 6c9dbd5e3..0bd27bedf 100644 --- a/src/Renderer/JSON.hs +++ b/src/Renderer/JSON.hs @@ -29,7 +29,6 @@ import GHC.Generics import Info import Language import Patch -import Syntax as S -- -- Diffs @@ -108,9 +107,6 @@ instance ToJSON a => ToJSONFields (Patch a) where instance ToJSON a => ToJSONFields [a] where toJSONFields list = [ "children" .= list ] -instance ToJSON recur => ToJSONFields (Syntax recur) where - toJSONFields syntax = [ "children" .= toList syntax ] - instance (Apply1 Foldable fs, ToJSON a) => ToJSONFields (Union fs a) where toJSONFields = apply1 (Proxy :: Proxy Foldable) (\ r -> [ "children" .= toList r ]) From 9697caccc94b4cefb7b003d645f42ef1ce68d0b7 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:35:58 -0400 Subject: [PATCH 026/133] :fire: DefaultFields. --- src/Info.hs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Info.hs b/src/Info.hs index 50e441de2..27f580efb 100644 --- a/src/Info.hs +++ b/src/Info.hs @@ -1,7 +1,6 @@ {-# LANGUAGE ConstraintKinds, DataKinds #-} module Info -( DefaultFields -, HasDefaultFields +( HasDefaultFields , Range(..) , byteRange , setByteRange @@ -19,9 +18,6 @@ import Data.Range import Data.Record import Data.Span --- | The default set of fields produced by our parsers. -type DefaultFields = '[ Range, Category, Span ] - -- | A type alias for HasField constraints commonly used throughout semantic-diff. type HasDefaultFields fields = (HasField fields Category, HasField fields Range, HasField fields Span) From 5d479d25607a85641fd5e4e7742a730d73ac5e92 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:36:28 -0400 Subject: [PATCH 027/133] :fire: HasDefaultFields. --- src/Info.hs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Info.hs b/src/Info.hs index 27f580efb..62bf23216 100644 --- a/src/Info.hs +++ b/src/Info.hs @@ -1,7 +1,6 @@ {-# LANGUAGE ConstraintKinds, DataKinds #-} module Info -( HasDefaultFields -, Range(..) +( Range(..) , byteRange , setByteRange , Category(..) @@ -18,9 +17,6 @@ import Data.Range import Data.Record import Data.Span --- | A type alias for HasField constraints commonly used throughout semantic-diff. -type HasDefaultFields fields = (HasField fields Category, HasField fields Range, HasField fields Span) - byteRange :: HasField fields Range => Record fields -> Range byteRange = getField From 4e507e797628ba1506bf203e0e2517e287d405e2 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:37:26 -0400 Subject: [PATCH 028/133] :fire: the ToJSONFields instance for Category. --- src/Renderer/JSON.hs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Renderer/JSON.hs b/src/Renderer/JSON.hs index 0bd27bedf..783a3839e 100644 --- a/src/Renderer/JSON.hs +++ b/src/Renderer/JSON.hs @@ -22,7 +22,7 @@ import Data.Output import Data.Proxy import Data.Record import Data.Semigroup ((<>)) -import Data.Text (pack, Text) +import Data.Text (Text) import Data.Text.Encoding (decodeUtf8) import Data.Union import GHC.Generics @@ -76,9 +76,6 @@ instance ToJSONFields (Record fs) => ToJSON (Record fs) where instance ToJSONFields Range where toJSONFields Range{..} = ["sourceRange" .= [ start, end ]] -instance ToJSONFields Category where - toJSONFields c = ["category" .= case c of { Other s -> s ; _ -> pack (show c) }] - instance ToJSONFields Span where toJSONFields sourceSpan = [ "sourceSpan" .= sourceSpan ] From 7f44d01f4591a8d54e766370fd0c1d7b79e63d88 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:37:35 -0400 Subject: [PATCH 029/133] :fire: category/setCategory. --- src/Info.hs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Info.hs b/src/Info.hs index 62bf23216..228a6353e 100644 --- a/src/Info.hs +++ b/src/Info.hs @@ -3,16 +3,12 @@ module Info ( Range(..) , byteRange , setByteRange -, Category(..) -, category -, setCategory , Span(..) , Pos(..) , sourceSpan , setSpan ) where -import Category import Data.Range import Data.Record import Data.Span @@ -23,12 +19,6 @@ byteRange = getField setByteRange :: HasField fields Range => Record fields -> Range -> Record fields setByteRange = setField -category :: HasField fields Category => Record fields -> Category -category = getField - -setCategory :: HasField fields Category => Record fields -> Category -> Record fields -setCategory = setField - sourceSpan :: HasField fields Span => Record fields -> Span sourceSpan = getField From d8ee640ee05188eaa960db3e5be6580201ff45e5 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:38:05 -0400 Subject: [PATCH 030/133] Simplify the import of Info. --- src/Semantic/Task.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Semantic/Task.hs b/src/Semantic/Task.hs index 3004350af..0bfbe7e18 100644 --- a/src/Semantic/Task.hs +++ b/src/Semantic/Task.hs @@ -47,7 +47,7 @@ import qualified Data.Time.Clock.POSIX as Time (getCurrentTime) import qualified Data.Time.LocalTime as LocalTime import Data.Union import Diff -import Info hiding (Category(..)) +import Info import qualified Files import GHC.Conc (atomically) import Language From 91b9cbcf76a5b54048fdfc6006dcf7a95b10c705 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:38:57 -0400 Subject: [PATCH 031/133] Drop an import of Info. --- src/Semantic/Task.hs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Semantic/Task.hs b/src/Semantic/Task.hs index 0bfbe7e18..78c32daf8 100644 --- a/src/Semantic/Task.hs +++ b/src/Semantic/Task.hs @@ -47,7 +47,6 @@ import qualified Data.Time.Clock.POSIX as Time (getCurrentTime) import qualified Data.Time.LocalTime as LocalTime import Data.Union import Diff -import Info import qualified Files import GHC.Conc (atomically) import Language @@ -219,7 +218,7 @@ runParser Options{..} blob@Blob{..} = go blobFields = [ ("path", blobPath), ("language", maybe "" show blobLanguage) ] errors :: (Syntax.Error :< fs, Apply1 Foldable fs, Apply1 Functor fs) => Term (Union fs) (Record Assignment.Location) -> [Error.Error String] errors = cata $ \ (a :< syntax) -> case syntax of - _ | Just err@Syntax.Error{} <- prj syntax -> [Syntax.unError (sourceSpan a) err] + _ | Just err@Syntax.Error{} <- prj syntax -> [Syntax.unError (getField a) err] _ -> fold syntax logTiming :: String -> Task a -> Task a logTiming msg = time msg blobFields From 30ab5f5ae3286792f5a7be648891987c06fa087c Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:42:40 -0400 Subject: [PATCH 032/133] Use getField directly in SplitDiff. --- src/SplitDiff.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SplitDiff.hs b/src/SplitDiff.hs index e71f2260b..4ec472e06 100644 --- a/src/SplitDiff.hs +++ b/src/SplitDiff.hs @@ -3,8 +3,8 @@ module SplitDiff where import Control.Comonad import Control.Comonad.Trans.Cofree import Control.Monad.Free +import Data.Range import Data.Record -import Info import Term (Term, TermF) -- | A patch to only one side of a diff. @@ -15,8 +15,8 @@ data SplitPatch a deriving (Show, Eq, Functor) -- | Get the range of a SplitDiff. -getRange :: Functor f => HasField fields Range => SplitDiff f (Record fields) -> Range -getRange diff = byteRange $ case diff of +getRange :: (Functor f, HasField fields Range) => SplitDiff f (Record fields) -> Range +getRange diff = getField $ case diff of Free annotated -> headF annotated Pure patch -> extract (splitTerm patch) From c5cac7d2f8a4bfcc6177fa049893479cff78f518 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:42:47 -0400 Subject: [PATCH 033/133] Use Record accessors directly in Alignment. --- src/Alignment.hs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Alignment.hs b/src/Alignment.hs index 98d5bf94b..500e3fb05 100644 --- a/src/Alignment.hs +++ b/src/Alignment.hs @@ -28,7 +28,6 @@ import Data.Source import Data.Record import Data.These import Diff -import Info import Patch import Prelude hiding (fst, snd) import SplitDiff @@ -58,7 +57,7 @@ alignPatch sources patch = case patch of Replace term1 term2 -> fmap (pure . SplitReplace) <$> alignWith (fmap (these id id const . runJoin) . Join) (alignSyntax' this (fst sources) term1) (alignSyntax' that (snd sources) term2) - where getRange = byteRange . extract + where getRange = getField . extract alignSyntax' :: (forall a. Identity a -> Join These a) -> Source -> Term f (Record fields) -> [Join These (Term [] (Record fields))] alignSyntax' side source term = hylo (alignSyntax side cofree getRange (Identity source)) runCofree (Identity <$> term) this = Join . This . runIdentity @@ -69,9 +68,9 @@ alignSyntax :: (Applicative f, HasField fields Range, Foldable g) => (forall a. alignSyntax toJoinThese toNode getRange sources (infos :< syntax) = catMaybes $ wrapInBranch <$> alignBranch getRange (join (toList syntax)) bothRanges where bothRanges = modifyJoin (fromThese [] []) lineRanges - lineRanges = toJoinThese $ sourceLineRangesWithin . byteRange <$> infos <*> sources + lineRanges = toJoinThese $ sourceLineRangesWithin . getField <$> infos <*> sources wrapInBranch = applyThese $ toJoinThese (makeNode <$> infos) - makeNode info (range, children) = toNode (setByteRange info range :< children) + makeNode info (range, children) = toNode (setField info range :< children) -- | Given a function to get the range, a list of already-aligned children, and the lists of ranges spanned by a branch, return the aligned lines. alignBranch :: (term -> Range) -> [Join These term] -> Both [Range] -> [Join These (Range, [term])] From 3b618a2e2bf8cea674ab1858e2d4de1104c2bfa5 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:42:57 -0400 Subject: [PATCH 034/133] Use Record accessors directly in TOC. --- src/Renderer/TOC.hs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Renderer/TOC.hs b/src/Renderer/TOC.hs index 2b15e3bcd..c3f928fd8 100644 --- a/src/Renderer/TOC.hs +++ b/src/Renderer/TOC.hs @@ -35,9 +35,11 @@ import Data.Function (on) import Data.List.NonEmpty (nonEmpty) import Data.Maybe (fromMaybe, mapMaybe) import Data.Output +import Data.Range import Data.Record import Data.Semigroup ((<>), sconcat) import Data.Source as Source +import Data.Span import Data.Text (toLower) import qualified Data.Text as T import Data.Text.Listable @@ -45,7 +47,6 @@ import Data.These import Data.Union import Diff import GHC.Generics -import Info import Language import Patch import qualified Data.List as List @@ -127,19 +128,19 @@ declarationAlgebra Blob{..} (a :< r) = Just $ MethodDeclaration (getSource (extract receiver) <> "." <> getSource (extract identifier)) | Just err@Syntax.Error{} <- prj r - = Just $ ErrorDeclaration (T.pack (formatTOCError (Syntax.unError (sourceSpan a) err))) blobLanguage + = Just $ ErrorDeclaration (T.pack (formatTOCError (Syntax.unError (getField a) err))) blobLanguage | otherwise = Nothing - where getSource = toText . flip Source.slice blobSource . byteRange + where getSource = toText . flip Source.slice blobSource . getField -- | Compute 'Declaration's with the headings of 'Markup.Section's. markupSectionAlgebra :: (Markup.Section :< fs, Syntax.Error :< fs, HasField fields Range, HasField fields Span, Apply1 Functor fs, Apply1 Foldable fs) => Blob -> RAlgebra (TermF (Union fs) (Record fields)) (Term (Union fs) (Record fields)) (Maybe Declaration) markupSectionAlgebra Blob{..} (a :< r) - | Just (Markup.Section level (heading, _) _) <- prj r = Just $ SectionDeclaration (maybe (getSource (extract heading)) (firstLine . toText . flip Source.slice blobSource . sconcat) (nonEmpty (byteRange . extract <$> toList (unwrap heading)))) level - | Just err@Syntax.Error{} <- prj r = Just $ ErrorDeclaration (T.pack (formatTOCError (Syntax.unError (sourceSpan a) err))) blobLanguage + | Just (Markup.Section level (heading, _) _) <- prj r = Just $ SectionDeclaration (maybe (getSource (extract heading)) (firstLine . toText . flip Source.slice blobSource . sconcat) (nonEmpty (getField . extract <$> toList (unwrap heading)))) level + | Just err@Syntax.Error{} <- prj r = Just $ ErrorDeclaration (T.pack (formatTOCError (Syntax.unError (getField a) err))) blobLanguage | otherwise = Nothing - where getSource = firstLine . toText . flip Source.slice blobSource . byteRange + where getSource = firstLine . toText . flip Source.slice blobSource . getField firstLine = T.takeWhile (/= '\n') formatTOCError :: Error.Error String -> String @@ -200,8 +201,8 @@ entrySummary entry = case entry of -- | Construct a 'JSONSummary' from a node annotation and a change type label. recordSummary :: (HasField fields (Maybe Declaration), HasField fields Span) => Record fields -> T.Text -> Maybe JSONSummary recordSummary record = case getDeclaration record of - Just (ErrorDeclaration text language) -> Just . const (ErrorSummary text (sourceSpan record) language) - Just declaration -> Just . JSONSummary (toCategoryName declaration) (declarationIdentifier declaration) (sourceSpan record) + Just (ErrorDeclaration text language) -> Just . const (ErrorSummary text (getField record) language) + Just declaration -> Just . JSONSummary (toCategoryName declaration) (declarationIdentifier declaration) (getField record) Nothing -> const Nothing renderToCDiff :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Both Blob -> Diff f (Record fields) -> Summaries From 655e239b41229fd9f84f0b4cb0f5c1f827d2d61d Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:44:07 -0400 Subject: [PATCH 035/133] Import Range/Span instead of Info. --- src/Language/Markdown.hs | 3 ++- src/Renderer/JSON.hs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Language/Markdown.hs b/src/Language/Markdown.hs index dfd770402..345638722 100644 --- a/src/Language/Markdown.hs +++ b/src/Language/Markdown.hs @@ -9,9 +9,10 @@ import Control.Comonad.Cofree as Cofree import Control.Comonad.Trans.Cofree as CofreeF (CofreeF(..)) import CMarkGFM import Data.Ix +import Data.Range +import Data.Span import Data.Source import qualified Data.Syntax.Assignment as A (AST, Node(..)) -import Info import TreeSitter.Language (Symbol(..), SymbolType(..)) data Grammar diff --git a/src/Renderer/JSON.hs b/src/Renderer/JSON.hs index 783a3839e..57979d221 100644 --- a/src/Renderer/JSON.hs +++ b/src/Renderer/JSON.hs @@ -20,13 +20,14 @@ import Data.Functor.Both (Both) import qualified Data.Map as Map import Data.Output import Data.Proxy +import Data.Range import Data.Record import Data.Semigroup ((<>)) +import Data.Span import Data.Text (Text) import Data.Text.Encoding (decodeUtf8) import Data.Union import GHC.Generics -import Info import Language import Patch From 2efc3c665c6a6ac4e18c74b0a921a9dc354a6541 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:46:30 -0400 Subject: [PATCH 036/133] Import Range/Span directly in Assignment. --- src/Data/Syntax/Assignment.hs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Data/Syntax/Assignment.hs b/src/Data/Syntax/Assignment.hs index feb247802..93f68abe9 100644 --- a/src/Data/Syntax/Assignment.hs +++ b/src/Data/Syntax/Assignment.hs @@ -111,11 +111,12 @@ import Data.Ix (Ix(..)) import Data.List (union) import Data.List.NonEmpty (NonEmpty(..)) import Data.Maybe +import Data.Range import Data.Record import Data.Semigroup import qualified Data.Source as Source (Source, slice, sourceBytes) +import Data.Span import GHC.Stack -import qualified Info import Prelude hiding (until) import Term (runCofree) import Text.Parser.Combinators as Parsers @@ -205,15 +206,15 @@ toIndex = index (minBound, maxBound) -- | A location specified as possibly-empty intervals of bytes and line/column positions. -type Location = '[Info.Range, Info.Span] +type Location = '[Range, Span] -- | An AST node labelled with symbols and source location. type AST f grammar = Cofree f (Node grammar) data Node grammar = Node { nodeSymbol :: !grammar - , nodeByteRange :: {-# UNPACK #-} !Info.Range - , nodeSpan :: {-# UNPACK #-} !Info.Span + , nodeByteRange :: {-# UNPACK #-} !Range + , nodeSpan :: {-# UNPACK #-} !Span } deriving (Eq, Show) @@ -272,7 +273,7 @@ runAssignment source = \ assignment state -> go assignment state >>= requireExha anywhere node = case runTracing t of End -> requireExhaustive (tracingCallSite t) ((), state) >>= uncurry yield - Location -> yield (Info.Range stateOffset stateOffset :. Info.Span statePos statePos :. Nil) state + Location -> yield (Range stateOffset stateOffset :. Span statePos statePos :. Nil) state Many rule -> fix (\ recur state -> (go rule state >>= \ (a, state') -> first (a:) <$> if state == state' then pure ([], state') else recur state') `catchError` const (pure ([], state))) state >>= uncurry yield Alt (a:as) -> sconcat (flip yield state <$> a:|as) Throw e -> Left e @@ -283,7 +284,7 @@ runAssignment source = \ assignment state -> go assignment state >>= requireExha state@State{..} = if not (null expectedSymbols) && all ((== Regular) . symbolType) expectedSymbols then skipTokens initialState else initialState expectedSymbols = firstSet (t `Then` return) - makeError = withStateCallStack (tracingCallSite t) state $ maybe (Error (Info.Span statePos statePos) (fmap Right expectedSymbols) Nothing) (nodeError (fmap Right expectedSymbols)) + makeError = withStateCallStack (tracingCallSite t) state $ maybe (Error (Span statePos statePos) (fmap Right expectedSymbols) Nothing) (nodeError (fmap Right expectedSymbols)) requireExhaustive :: Symbol grammar => Maybe (String, SrcLoc) -> (result, State ast grammar) -> Either (Error (Either String grammar)) (result, State ast grammar) requireExhaustive callSite (a, state) = let state' = skipTokens state in case stateNodes state' of @@ -299,13 +300,13 @@ skipTokens state = state { stateNodes = dropWhile ((/= Regular) . symbolType . n -- | Advances the state past the current (head) node (if any), dropping it off stateNodes, and updating stateOffset & statePos to its end; or else returns the state unchanged. advanceState :: State ast grammar -> State ast grammar advanceState state@State{..} - | (Node{..} Cofree.:< _) : rest <- stateNodes = State (Info.end nodeByteRange) (Info.spanEnd nodeSpan) stateCallSites rest + | (Node{..} Cofree.:< _) : rest <- stateNodes = State (end nodeByteRange) (spanEnd nodeSpan) stateCallSites rest | otherwise = state -- | State kept while running 'Assignment's. data State ast grammar = State { stateOffset :: {-# UNPACK #-} !Int -- ^ The offset into the Source thus far reached, measured in bytes. - , statePos :: {-# UNPACK #-} !Info.Pos -- ^ The (1-indexed) line/column position in the Source thus far reached. + , statePos :: {-# UNPACK #-} !Pos -- ^ The (1-indexed) line/column position in the Source thus far reached. , stateCallSites :: ![(String, SrcLoc)] -- ^ The symbols & source locations of the calls thus far. , stateNodes :: ![AST ast grammar] -- ^ The remaining nodes to assign. Note that 'children' rules recur into subterms, and thus this does not necessarily reflect all of the terms remaining to be assigned in the overall algorithm, only those “in scope.” } @@ -314,7 +315,7 @@ deriving instance (Eq grammar, Eq (ast (AST ast grammar))) => Eq (State ast gram deriving instance (Show grammar, Show (ast (AST ast grammar))) => Show (State ast grammar) makeState :: [AST ast grammar] -> State ast grammar -makeState = State 0 (Info.Pos 1 1) [] +makeState = State 0 (Pos 1 1) [] -- Instances @@ -379,7 +380,7 @@ instance (Eq grammar, Eq (ast (AST ast grammar)), Show grammar, Show (ast (AST a a s = tracing (Label a s) `Then` return unexpected :: HasCallStack => String -> Assignment ast grammar a - unexpected s = location >>= \ loc -> throwError (Error (Info.sourceSpan loc) [] (Just (Left s))) + unexpected s = location >>= \ loc -> throwError (Error (getField loc) [] (Just (Left s))) eof :: HasCallStack => Assignment ast grammar () eof = tracing End `Then` return @@ -401,7 +402,7 @@ instance (Show grammar, Show (ast (AST ast grammar))) => Show1 (AssignmentF ast liftShowsPrec sp sl d a = case a of End -> showString "End" . showChar ' ' . sp d () Advance -> showString "Advance" . showChar ' ' . sp d () - Location -> showString "Location" . sp d (Info.Range 0 0 :. Info.Span (Info.Pos 1 1) (Info.Pos 1 1) :. Nil) + Location -> showString "Location" . sp d (Range 0 0 :. Span (Pos 1 1) (Pos 1 1) :. Nil) CurrentNode -> showString "CurrentNode" Source -> showString "Source" . showChar ' ' . sp d "" Children a -> showsUnaryWith (liftShowsPrec sp sl) "Children" d a From 0fa8c3255ae5ee1840bdd688326b937cb928e0b2 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:46:36 -0400 Subject: [PATCH 037/133] :fire: Info.hs. --- semantic-diff.cabal | 1 - src/Info.hs | 26 -------------------------- 2 files changed, 27 deletions(-) delete mode 100644 src/Info.hs diff --git a/semantic-diff.cabal b/semantic-diff.cabal index 863d7c432..cf706dd5e 100644 --- a/semantic-diff.cabal +++ b/semantic-diff.cabal @@ -45,7 +45,6 @@ library , Decorators , Diff , Files - , Info , Interpreter , Language , Language.Markdown diff --git a/src/Info.hs b/src/Info.hs deleted file mode 100644 index 228a6353e..000000000 --- a/src/Info.hs +++ /dev/null @@ -1,26 +0,0 @@ -{-# LANGUAGE ConstraintKinds, DataKinds #-} -module Info -( Range(..) -, byteRange -, setByteRange -, Span(..) -, Pos(..) -, sourceSpan -, setSpan -) where - -import Data.Range -import Data.Record -import Data.Span - -byteRange :: HasField fields Range => Record fields -> Range -byteRange = getField - -setByteRange :: HasField fields Range => Record fields -> Range -> Record fields -setByteRange = setField - -sourceSpan :: HasField fields Span => Record fields -> Span -sourceSpan = getField - -setSpan :: HasField fields Span => Record fields -> Span -> Record fields -setSpan = setField From ff2d371afdb77187cab8b1a94a237c30a7dedf20 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:47:43 -0400 Subject: [PATCH 038/133] :fire: Category. --- semantic-diff.cabal | 1 - src/Category.hs | 369 -------------------------------------------- 2 files changed, 370 deletions(-) delete mode 100644 src/Category.hs diff --git a/semantic-diff.cabal b/semantic-diff.cabal index cf706dd5e..f4055ba8b 100644 --- a/semantic-diff.cabal +++ b/semantic-diff.cabal @@ -15,7 +15,6 @@ library hs-source-dirs: src exposed-modules: Algorithm , Alignment - , Category , Data.Align.Generic , Data.Blob , Data.Error diff --git a/src/Category.hs b/src/Category.hs deleted file mode 100644 index a8c14b8ba..000000000 --- a/src/Category.hs +++ /dev/null @@ -1,369 +0,0 @@ -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE DeriveAnyClass #-} -{-# OPTIONS_GHC -funbox-strict-fields #-} -module Category where - -import Control.DeepSeq -import Data.Functor.Listable -import Data.Hashable -import Data.Text (Text) -import Data.Text.Prettyprint.Doc -import GHC.Generics - --- | A standardized category of AST node. Used to determine the semantics for --- | semantic diffing and define comparability of nodes. -data Category - -- | The top-level branch node. - = Program - -- | A node indicating syntax errors. - | ParseError - -- | A boolean expression. - | Boolean - -- | A bitwise operator. - | BitwiseOperator - -- | A boolean operator (e.g. ||, &&). - | BooleanOperator - -- | A literal key-value data structure. - | DictionaryLiteral - -- | A pair, e.g. of a key & value - | Pair - -- | A call to a function. - | FunctionCall - -- | A function declaration. - | Function - -- | An identifier. - | Identifier - -- | A function's parameters. - | Params - -- | A function's expression statements. - | ExpressionStatements - -- | A method call on an object. - | MethodCall - -- | A method's arguments. - | Args - -- | A string literal. - | StringLiteral - -- | An integer literal. - | IntegerLiteral - -- | A regex literal. - | Regex - -- | A return statement. - | Return - -- | A symbol literal. - | SymbolLiteral - -- | A template string literal. - | TemplateString - -- | An array literal. - | ArrayLiteral - -- | An assignment expression. - | Assignment - -- | A math assignment expression. - | MathAssignment - -- | A member access expression. - | MemberAccess - -- | A subscript access expression. - | SubscriptAccess - -- | A variable assignment within a variable declaration. - | VarAssignment - -- | A variable declaration. - | VarDecl - -- | A switch expression. - | Switch - -- | A if/else expression. - | If - -- | A for expression. - | For - -- | A while expression. - | While - -- | A do/while expression. - | DoWhile - -- | A ternary expression. - | Ternary - -- | A case expression. - | Case - -- | An expression with an operator. - | Operator - -- | An comma operator expression - | CommaOperator - -- | An object/dictionary/hash literal. - | Object - -- | A throw statement. - | Throw - -- | A constructor statement, e.g. new Foo; - | Constructor - -- | A try statement. - | Try - -- | A catch statement. - | Catch - -- | A finally statement. - | Finally - -- | A class declaration. - | Class - -- | A class method declaration. - | Method - -- | A comment. - | Comment - -- | A non-standard category, which can be used for comparability. - | Other Text - -- | A relational operator (e.g. < or >=) - | RelationalOperator - -- | An empty statement. (e.g. ; in JavaScript) - | Empty - -- | A number literal. - | NumberLiteral - -- | A mathematical operator (e.g. +, -, *, /). - | MathOperator - -- | A module - | Module - -- | A namespace in TypeScript. - | Namespace - -- | An interface - | Interface - -- | An import - | Import - -- | An export - | Export - -- | An anonymous function. - | AnonymousFunction - -- | An interpolation (e.g. "#{bar}" in Ruby) - | Interpolation - -- | A subshell command (e.g. `ls -la` in Ruby) - | Subshell - -- | Operator assignment, e.g. a ||= b, a += 1 in Ruby. - | OperatorAssignment - -- | A yield statement. - | Yield - -- | An until expression. - | Until - -- | A unless/else expression. - | Unless - | Begin - | Else - | Elsif - | Ensure - | Rescue - -- | Formerly used for Ruby’s @x rescue y@ modifier syntax. Deprecated. Use @Modifier Rescue@ instead. Left in place to preserve hashing & RWS results. - | RescueModifier - | RescuedException - | RescueArgs - | When - | Negate - -- | A select expression in Go. - | Select - | Defer - | Go - | Slice - | TypeAssertion - | TypeConversion - -- | An argument pair, e.g. foo(run: true) or foo(:run => true) in Ruby. - | ArgumentPair - -- | A keyword parameter, e.g. def foo(name:) or def foo(name:false) in Ruby. - | KeywordParameter - -- | An optional/default parameter, e.g. def foo(name = nil) in Ruby. - | OptionalParameter - -- | A splat parameter, e.g. def foo(*array) in Ruby. - | SplatParameter - -- | A hash splat parameter, e.g. def foo(**option) in Ruby. - | HashSplatParameter - -- | A block parameter, e.g. def foo(&block) in Ruby. - | BlockParameter - -- | A float literal. - | FloatLiteral - -- | An array type declaration, e.g. [2]string in Go. - | ArrayTy - -- | A dictionary type declaration, e.g. map[string] in Go. - | DictionaryTy - -- | A Struct type declaration, struct Foo {..} in Go. - | StructTy - -- | A Struct constructor, e.g. foo = Foo {..} in Go. - | Struct - -- | A break statement, e.g. break; in JavaScript. - | Break - -- | A continue statement, e.g. continue; in JavaScript. - | Continue - -- | A binary statement, e.g. a | b in Ruby. - | Binary - -- | A unary statement, e.g. !a in Ruby. - | Unary - -- | A constant, e.g `Foo::Bar` in Ruby. - | Constant - -- | A superclass, e.g `< Foo` in Ruby. - | Superclass - -- | A singleton class declaration, e.g. `class << self;end` in Ruby - | SingletonClass - -- | A range expression, e.g. `1..10` in Ruby. - | RangeExpression - -- | A scope resolution operator, e.g. `Foo::bar` in Ruby. - | ScopeOperator - -- | A BEGIN {} block of statements. - | BeginBlock - -- | An END {} block of statements. - | EndBlock - | ParameterDecl - -- | A default case in a switch statement. - | DefaultCase - -- | A type declaration. - | TypeDecl - | PointerTy - -- | A field declaration. - | FieldDecl - -- | A slice type, e.g. []string{"hello"} in Go. - | SliceTy - -- | An element of a slice literal. - | Element - -- | A literal value. - | Literal - -- | A channel type in Go. - | ChannelTy - -- | A send statement in Go. - | Send - -- | An Index expression, e.g. x[1] in Go. - | IndexExpression - -- | A function type. - | FunctionTy - -- | An increment statement, e.g. i++ in Go. - | IncrementStatement - -- | A decrement statement, e.g. i-- in Go. - | DecrementStatement - -- | A qualified identifier, e.g. Module.function in Go. - | QualifiedType - | FieldDeclarations - -- | A Go rune literal. - | RuneLiteral - -- | A modifier version of another Category, e.g. Ruby’s trailing @if@, @while@, etc. terms, whose subterms are swapped relative to regular @if@, @while@, etc. terms. - | Modifier Category - -- | A singleton method declaration, e.g. `def self.foo;end` in Ruby - | SingletonMethod - -- | An arbitrary type annotation. - | Ty - | ParenthesizedExpression - | ParenthesizedType - deriving (Eq, Generic, Ord, Show, NFData) - -{-# DEPRECATED RescueModifier "Deprecated; use Modifier Rescue instead." #-} - - --- Instances - -instance Hashable Category - -instance Listable Category where - tiers = cons0 Program - \/ cons0 ParseError - \/ cons0 Boolean - \/ cons0 BooleanOperator - -- \/ cons0 MathOperator - -- \/ cons0 DictionaryLiteral - -- \/ cons0 Pair - \/ cons0 FunctionCall - \/ cons0 Function - \/ cons0 Identifier - -- \/ cons0 Params - -- \/ cons0 ExpressionStatements - \/ cons0 MethodCall - -- \/ cons0 Args - \/ cons0 StringLiteral - \/ cons0 IntegerLiteral - \/ cons0 NumberLiteral - -- \/ cons0 Regex - \/ cons0 Return - -- \/ cons0 SymbolLiteral - -- \/ cons0 TemplateString - -- \/ cons0 ArrayLiteral - -- \/ cons0 Assignment - -- \/ cons0 MathAssignment - -- \/ cons0 MemberAccess - -- \/ cons0 SubscriptAccess - -- \/ cons0 VarAssignment - -- \/ cons0 VarDecl - -- \/ cons0 For - -- \/ cons0 DoWhile - -- \/ cons0 While - -- \/ cons0 Switch - \/ cons0 If - -- \/ cons0 Ternary - -- \/ cons0 Case - -- \/ cons0 Operator - -- \/ cons0 CommaOperator - -- \/ cons0 Object - -- \/ cons0 Throw - -- \/ cons0 Constructor - -- \/ cons0 Try - -- \/ cons0 Catch - -- \/ cons0 Finally - \/ cons0 Class - \/ cons0 Method - -- \/ cons0 Comment - -- \/ cons0 RelationalOperator - -- \/ cons0 Empty - -- \/ cons0 Module - -- \/ cons0 Import - -- \/ cons0 Export - -- \/ cons0 AnonymousFunction - -- \/ cons0 Interpolation - -- \/ cons0 Subshell - -- \/ cons0 OperatorAssignment - -- \/ cons0 Yield - -- \/ cons0 Until - -- \/ cons0 Unless - -- \/ cons0 Begin - -- \/ cons0 Else - -- \/ cons0 Elsif - -- \/ cons0 Ensure - -- \/ cons0 Rescue - -- \/ cons0 RescueModifier - -- \/ cons0 RescuedException - -- \/ cons0 RescueArgs - -- \/ cons0 When - -- \/ cons0 Negate - -- \/ cons0 Select - -- \/ cons0 Defer - -- \/ cons0 Go - -- \/ cons0 Slice - -- \/ cons0 TypeAssertion - -- \/ cons0 TypeConversion - -- \/ cons0 ArgumentPair - -- \/ cons0 KeywordParameter - -- \/ cons0 OptionalParameter - -- \/ cons0 SplatParameter - -- \/ cons0 HashSplatParameter - -- \/ cons0 BlockParameter - -- \/ cons0 FloatLiteral - -- \/ cons0 ArrayTy - -- \/ cons0 DictionaryTy - -- \/ cons0 StructTy - -- \/ cons0 Struct - -- \/ cons0 Break - -- \/ cons0 Continue - \/ cons0 Binary - \/ cons0 Unary - -- \/ cons0 Constant - -- \/ cons0 Superclass - -- \/ cons0 SingletonClass - -- \/ cons0 RangeExpression - -- \/ cons0 ScopeOperator - -- \/ cons0 BeginBlock - -- \/ cons0 EndBlock - -- \/ cons0 ParameterDecl - -- \/ cons0 DefaultCase - -- \/ cons0 TypeDecl - -- \/ cons0 PointerTy - -- \/ cons0 FieldDecl - -- \/ cons0 SliceTy - -- \/ cons0 Element - -- \/ cons0 Literal - -- \/ cons0 ChannelTy - -- \/ cons0 Send - -- \/ cons0 IndexExpression - -- \/ cons0 FunctionTy - -- \/ cons0 IncrementStatement - -- \/ cons0 DecrementStatement - -- \/ cons0 QualifiedType - -- \/ cons0 FieldDeclarations - -- \/ cons0 RuneLiteral - -- \/ cons0 (Modifier If) - \/ cons0 SingletonMethod - -- \/ cons0 (Other "other") - -instance Pretty Category where - pretty = pretty . show From f22f0b053f993cc74cf1537fd16d4db7ea51dcce Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 30 Aug 2017 14:48:24 -0400 Subject: [PATCH 039/133] :fire: Syntax. --- semantic-diff.cabal | 1 - src/Syntax.hs | 187 -------------------------------------------- 2 files changed, 188 deletions(-) delete mode 100644 src/Syntax.hs diff --git a/semantic-diff.cabal b/semantic-diff.cabal index f4055ba8b..b882161e7 100644 --- a/semantic-diff.cabal +++ b/semantic-diff.cabal @@ -75,7 +75,6 @@ library , SES , SES.Myers , SplitDiff - , Syntax , Term , TreeSitter build-depends: base >= 4.8 && < 5 diff --git a/src/Syntax.hs b/src/Syntax.hs deleted file mode 100644 index b04d80f69..000000000 --- a/src/Syntax.hs +++ /dev/null @@ -1,187 +0,0 @@ -{-# LANGUAGE DeriveAnyClass #-} -module Syntax where - -import Control.DeepSeq -import Data.Aeson -import Data.Align.Generic -import Data.Functor.Classes -import Data.Functor.Classes.Eq.Generic -import Data.Functor.Classes.Pretty.Generic -import Data.Functor.Listable -import Data.Mergeable -import Data.Text (pack, Text) -import GHC.Generics - --- | A node in an abstract syntax tree. --- --- 'f' is the type representing another level of the tree, e.g. the children of branches. Often 'Cofree', 'Free' or similar. -data Syntax f - -- | A terminal syntax node, e.g. an identifier, or atomic literal. - = Leaf Text - -- | An ordered branch of child nodes, expected to be variadic in the grammar, e.g. a list of statements or uncurried function parameters. - | Indexed [f] - -- | An ordered branch of child nodes, expected to be of fixed length in the grammar, e.g. a binary operator & its operands. - | Fixed [f] - -- | A function call has an identifier where f is a (Leaf a) and a list of arguments. - | FunctionCall f [f] [f] - -- | A ternary has a condition, a true case and a false case - | Ternary f [f] - -- | An anonymous function has a list of expressions and params. - | AnonymousFunction [f] [f] - -- | A function has an identifier, possible type arguments, params, a possible type, and list of expressions. - | Function f [f] [f] - -- | An assignment has an identifier where f can be a member access, and the value is another syntax element (function call, leaf, etc.) - | Assignment f f - -- | An operator assignment represents expressions with operators like math (e.g x += 1) or conditional (e.g. x ||= 1) assignment. - | OperatorAssignment f f - -- | A member access contains a syntax, and another syntax that identifies a property or value in the first syntax. - -- | e.g. in Javascript x.y represents a member access syntax. - | MemberAccess f f - -- | A method call consisting of its target, the method name, and the parameters passed to the method. - -- | e.g. in Javascript console.log('hello') represents a method call. - | MethodCall f f [f] [f] - -- | An operator can be applied to a list of syntaxes. - | Operator [f] - -- | A variable declaration. e.g. var foo; - | VarDecl [f] - -- | A variable assignment in a variable declaration. var foo = bar; - | VarAssignment [f] f - -- | A subscript access contains a syntax, and another syntax that indefies a property or value in the first syntax. - -- | e.g. in Javascript x["y"] represents a subscript access syntax. - | SubscriptAccess f f - | Switch [f] [f] - | Case f [f] - -- | A default case in a switch statement. - | DefaultCase [f] - | Select [f] - | Object (Maybe f) [f] - -- | A pair in an Object. e.g. foo: bar or foo => bar - | Pair f f - -- | A comment. - | Comment Text - -- | A term preceded or followed by any number of comments. - | Commented [f] (Maybe f) - | ParseError [f] - -- | A for statement has a list of expressions to setup the iteration and then a list of expressions in the body. - | For [f] [f] - | DoWhile f f - | While f [f] - | Return [f] - | Throw f - | Constructor f - -- | TODO: Is it a problem that in Ruby, this pattern can work for method def too? - | Try [f] [f] (Maybe f) (Maybe f) - -- | An array literal with list of children. - | Array (Maybe f) [f] - -- | A class with an identifier, superclass, and a list of definitions. - | Class f [f] [f] - -- | A method definition with an identifier, optional receiver, optional type arguments, params, optional return type, and a list of expressions. - | Method [f] f (Maybe f) [f] [f] - -- | An if statement with an expression and maybe more expression clauses. - | If f [f] - -- | A module with an identifier, and a list of syntaxes. - | Module f [f] - -- | An interface with an identifier, a list of clauses, and a list of declarations.. - | Interface f [f] [f] - | Namespace f [f] - | Import f [f] - | Export (Maybe f) [f] - | Yield [f] - -- | A negation of a single expression. - | Negate f - -- | A rescue block has a list of arguments to rescue and a list of expressions. - | Rescue [f] [f] - | Go f - | Defer f - | TypeAssertion f f - | TypeConversion f f - -- | A struct with an optional type. - | Struct (Maybe f) [f] - | Break (Maybe f) - | Continue (Maybe f) - -- | A block statement has an ordered branch of child nodes, e.g. BEGIN {...} or END {...} in Ruby/Perl. - | BlockStatement [f] - -- | A parameter declaration with an optional type. - | ParameterDecl (Maybe f) f - -- | A type declaration has an identifier and a type. - | TypeDecl f f - -- | A field declaration with an optional type, and an optional tag. - | FieldDecl [f] - -- | A type. - | Ty [f] - -- | A send statement has a channel and an expression in Go. - | Send f f - deriving (Eq, Foldable, Functor, GAlign, Generic, Generic1, Mergeable, Ord, Show, Traversable, ToJSON, NFData) - - -extractLeafValue :: Syntax a -> Maybe Text -extractLeafValue syntax = case syntax of - Leaf a -> Just a - _ -> Nothing - --- Instances - -instance Listable1 Syntax where - liftTiers recur - = liftCons1 (pack `mapT` tiers) Leaf - \/ liftCons1 (liftTiers recur) Indexed - \/ liftCons1 (liftTiers recur) Fixed - \/ liftCons3 recur (liftTiers recur) (liftTiers recur) FunctionCall - \/ liftCons2 recur (liftTiers recur) Ternary - \/ liftCons2 (liftTiers recur) (liftTiers recur) AnonymousFunction - \/ liftCons3 recur (liftTiers recur) (liftTiers recur) Function - \/ liftCons2 recur recur Assignment - \/ liftCons2 recur recur OperatorAssignment - \/ liftCons2 recur recur MemberAccess - \/ liftCons4 recur recur (liftTiers recur) (liftTiers recur) MethodCall - \/ liftCons1 (liftTiers recur) Operator - \/ liftCons1 (liftTiers recur) VarDecl - \/ liftCons2 (liftTiers recur) recur VarAssignment - \/ liftCons2 recur recur SubscriptAccess - \/ liftCons2 (liftTiers recur) (liftTiers recur) Switch - \/ liftCons2 recur (liftTiers recur) Case - \/ liftCons1 (liftTiers recur) Select - \/ liftCons2 (liftTiers recur) (liftTiers recur) Syntax.Object - \/ liftCons2 recur recur Pair - \/ liftCons1 (pack `mapT` tiers) Comment - \/ liftCons2 (liftTiers recur) (liftTiers recur) Commented - \/ liftCons1 (liftTiers recur) Syntax.ParseError - \/ liftCons2 (liftTiers recur) (liftTiers recur) For - \/ liftCons2 recur recur DoWhile - \/ liftCons2 recur (liftTiers recur) While - \/ liftCons1 (liftTiers recur) Return - \/ liftCons1 recur Throw - \/ liftCons1 recur Constructor - \/ liftCons4 (liftTiers recur) (liftTiers recur) (liftTiers recur) (liftTiers recur) Try - \/ liftCons2 (liftTiers recur) (liftTiers recur) Syntax.Array - \/ liftCons3 recur (liftTiers recur) (liftTiers recur) Class - \/ liftCons5 (liftTiers recur) recur (liftTiers recur) (liftTiers recur) (liftTiers recur) Method - \/ liftCons2 recur (liftTiers recur) If - \/ liftCons2 recur (liftTiers recur) Module - \/ liftCons2 recur (liftTiers recur) Namespace - \/ liftCons2 recur (liftTiers recur) Import - \/ liftCons2 (liftTiers recur) (liftTiers recur) Export - \/ liftCons1 (liftTiers recur) Yield - \/ liftCons1 recur Negate - \/ liftCons2 (liftTiers recur) (liftTiers recur) Rescue - \/ liftCons1 recur Go - \/ liftCons1 recur Defer - \/ liftCons2 recur recur TypeAssertion - \/ liftCons2 recur recur TypeConversion - \/ liftCons1 (liftTiers recur) Break - \/ liftCons1 (liftTiers recur) Continue - \/ liftCons1 (liftTiers recur) BlockStatement - \/ liftCons2 (liftTiers recur) recur ParameterDecl - \/ liftCons2 recur recur TypeDecl - \/ liftCons1 (liftTiers recur) FieldDecl - \/ liftCons1 (liftTiers recur) Ty - \/ liftCons2 recur recur Send - \/ liftCons1 (liftTiers recur) DefaultCase - -instance Listable recur => Listable (Syntax recur) where - tiers = tiers1 - -instance Eq1 Syntax where - liftEq = genericLiftEq - -instance Pretty1 Syntax where liftPretty = genericLiftPretty From 7e09cada8145fcd1315bb8a655476637e24a6235 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 12:29:57 -0400 Subject: [PATCH 040/133] Make `someParser` total. --- src/Parser.hs | 22 +++++++++++----------- src/Semantic.hs | 14 +++++++------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Parser.hs b/src/Parser.hs index 05c263e8c..cae2f1f0a 100644 --- a/src/Parser.hs +++ b/src/Parser.hs @@ -70,17 +70,17 @@ someParser :: ( ApplyAll typeclasses Go.Syntax , ApplyAll typeclasses Ruby.Syntax , ApplyAll typeclasses TypeScript.Syntax ) - => proxy typeclasses -- ^ A proxy for the list of typeclasses required, e.g. @(Proxy :: Proxy '[Show1])@. - -> Language -- ^ The 'Language' to select. - -> Maybe (SomeParser typeclasses) -- ^ 'Maybe' a 'SomeParser' abstracting the syntax type to be produced. -someParser _ Go = Just (SomeParser goParser) -someParser _ JavaScript = Just (SomeParser typescriptParser) -someParser _ JSON = Just (SomeParser jsonParser) -someParser _ JSX = Just (SomeParser typescriptParser) -someParser _ Markdown = Just (SomeParser markdownParser) -someParser _ Python = Just (SomeParser pythonParser) -someParser _ Ruby = Just (SomeParser rubyParser) -someParser _ TypeScript = Just (SomeParser typescriptParser) + => proxy typeclasses -- ^ A proxy for the list of typeclasses required, e.g. @(Proxy :: Proxy '[Show1])@. + -> Language -- ^ The 'Language' to select. + -> SomeParser typeclasses -- ^ 'Maybe' a 'SomeParser' abstracting the syntax type to be produced. +someParser _ Go = SomeParser goParser +someParser _ JavaScript = SomeParser typescriptParser +someParser _ JSON = SomeParser jsonParser +someParser _ JSX = SomeParser typescriptParser +someParser _ Markdown = SomeParser markdownParser +someParser _ Python = SomeParser pythonParser +someParser _ Ruby = SomeParser rubyParser +someParser _ TypeScript = SomeParser typescriptParser goParser :: Parser Go.Term diff --git a/src/Semantic.hs b/src/Semantic.hs index 75fd74aa3..b8ee51c59 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -46,15 +46,15 @@ parseBlobs renderer = fmap toOutput . distributeFoldMap (parseBlob renderer) . f parseBlob :: TermRenderer output -> Blob -> Task output parseBlob renderer blob@Blob{..} = case (renderer, blobLanguage) of (ToCTermRenderer, lang) - | Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) -> + | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) <$> lang -> parse parser blob >>= decorate (declarationAlgebra blob) >>= render (renderToCTerm blob) (JSONTermRenderer, lang) - | Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) -> + | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) <$> lang -> parse parser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob) (SExpressionTermRenderer, lang) - | Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) -> + | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) <$> lang -> parse parser blob >>= decorate constructorLabel . (Nil <$) >>= render renderSExpressionTerm _ -> throwError (SomeException (NoParserForLanguage blobPath blobLanguage)) @@ -70,19 +70,19 @@ diffBlobPairs renderer = fmap toOutput . distributeFoldMap (diffBlobPair rendere diffBlobPair :: DiffRenderer output -> Both Blob -> Task output diffBlobPair renderer blobs = case (renderer, effectiveLanguage) of (ToCDiffRenderer, lang) - | Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, HasDeclaration, Show1, Traversable]) -> + | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, HasDeclaration, Show1, Traversable]) <$> lang -> run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) diffTerms (renderToCDiff blobs) (JSONDiffRenderer, lang) - | Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) -> + | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) <$> lang -> run (parse parser) diffTerms (renderJSONDiff blobs) (PatchDiffRenderer, lang) - | Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) -> + | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) <$> lang -> run (parse parser) diffTerms (renderPatch blobs) (SExpressionDiffRenderer, lang) - | Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[ConstructorName, Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) -> + | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[ConstructorName, Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) <$> lang -> run (decorate constructorLabel . (Nil <$) <=< parse parser) diffTerms renderSExpressionDiff _ -> throwError (SomeException (NoParserForLanguage effectivePath effectiveLanguage)) From ac5e0b3e9f32a95c272a0ebdb29cc76e3e31c221 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 13:00:26 -0400 Subject: [PATCH 041/133] :fire: the Listable instances for Category & Syntax. --- test/Data/Functor/Listable.hs | 84 ----------------------------------- 1 file changed, 84 deletions(-) diff --git a/test/Data/Functor/Listable.hs b/test/Data/Functor/Listable.hs index e7a088814..5fd0dbc72 100644 --- a/test/Data/Functor/Listable.hs +++ b/test/Data/Functor/Listable.hs @@ -27,7 +27,6 @@ module Data.Functor.Listable , ListableSyntax ) where -import qualified Category import Control.Monad.Free as Free import Control.Monad.Trans.Free as FreeF import Data.ByteString (ByteString) @@ -52,7 +51,6 @@ import Data.These import Data.Union import Renderer.TOC import RWS -import Syntax as S import Test.LeanCheck type Tier a = [a] @@ -204,27 +202,6 @@ instance Listable (Record '[]) where tiers = cons0 Nil -instance Listable Category.Category where - tiers = cons0 Category.Program - \/ cons0 Category.ParseError - \/ cons0 Category.Boolean - \/ cons0 Category.BooleanOperator - \/ cons0 Category.FunctionCall - \/ cons0 Category.Function - \/ cons0 Category.Identifier - \/ cons0 Category.MethodCall - \/ cons0 Category.StringLiteral - \/ cons0 Category.IntegerLiteral - \/ cons0 Category.NumberLiteral - \/ cons0 Category.Return - \/ cons0 Category.If - \/ cons0 Category.Class - \/ cons0 Category.Method - \/ cons0 Category.Binary - \/ cons0 Category.Unary - \/ cons0 Category.SingletonMethod - - instance Listable2 Patch where liftTiers2 t1 t2 = liftCons1 t2 Insert \/ liftCons1 t1 Delete \/ liftCons2 t1 t2 Replace @@ -232,67 +209,6 @@ instance (Listable a, Listable b) => Listable (Patch a b) where tiers = tiers2 -instance Listable1 Syntax where - liftTiers recur - = liftCons1 (pack `mapT` tiers) Leaf - \/ liftCons1 (liftTiers recur) Indexed - \/ liftCons1 (liftTiers recur) Fixed - \/ liftCons3 recur (liftTiers recur) (liftTiers recur) FunctionCall - \/ liftCons2 recur (liftTiers recur) Ternary - \/ liftCons2 (liftTiers recur) (liftTiers recur) AnonymousFunction - \/ liftCons3 recur (liftTiers recur) (liftTiers recur) Function - \/ liftCons2 recur recur Assignment - \/ liftCons2 recur recur OperatorAssignment - \/ liftCons2 recur recur MemberAccess - \/ liftCons4 recur recur (liftTiers recur) (liftTiers recur) MethodCall - \/ liftCons1 (liftTiers recur) Operator - \/ liftCons1 (liftTiers recur) VarDecl - \/ liftCons2 (liftTiers recur) recur VarAssignment - \/ liftCons2 recur recur SubscriptAccess - \/ liftCons2 (liftTiers recur) (liftTiers recur) Switch - \/ liftCons2 recur (liftTiers recur) Case - \/ liftCons1 (liftTiers recur) Select - \/ liftCons2 (liftTiers recur) (liftTiers recur) S.Object - \/ liftCons2 recur recur S.Pair - \/ liftCons1 (pack `mapT` tiers) Comment - \/ liftCons2 (liftTiers recur) (liftTiers recur) Commented - \/ liftCons1 (liftTiers recur) S.ParseError - \/ liftCons2 (liftTiers recur) (liftTiers recur) For - \/ liftCons2 recur recur DoWhile - \/ liftCons2 recur (liftTiers recur) While - \/ liftCons1 (liftTiers recur) Return - \/ liftCons1 recur Throw - \/ liftCons1 recur Constructor - \/ liftCons4 (liftTiers recur) (liftTiers recur) (liftTiers recur) (liftTiers recur) Try - \/ liftCons2 (liftTiers recur) (liftTiers recur) S.Array - \/ liftCons3 recur (liftTiers recur) (liftTiers recur) Class - \/ liftCons5 (liftTiers recur) recur (liftTiers recur) (liftTiers recur) (liftTiers recur) Method - \/ liftCons2 recur (liftTiers recur) If - \/ liftCons2 recur (liftTiers recur) Module - \/ liftCons2 recur (liftTiers recur) Namespace - \/ liftCons2 recur (liftTiers recur) Import - \/ liftCons2 (liftTiers recur) (liftTiers recur) Export - \/ liftCons1 (liftTiers recur) Yield - \/ liftCons1 recur Negate - \/ liftCons2 (liftTiers recur) (liftTiers recur) Rescue - \/ liftCons1 recur Go - \/ liftCons1 recur Defer - \/ liftCons2 recur recur TypeAssertion - \/ liftCons2 recur recur TypeConversion - \/ liftCons1 (liftTiers recur) Break - \/ liftCons1 (liftTiers recur) Continue - \/ liftCons1 (liftTiers recur) BlockStatement - \/ liftCons2 (liftTiers recur) recur ParameterDecl - \/ liftCons2 recur recur TypeDecl - \/ liftCons1 (liftTiers recur) FieldDecl - \/ liftCons1 (liftTiers recur) Ty - \/ liftCons2 recur recur Send - \/ liftCons1 (liftTiers recur) DefaultCase - -instance Listable recur => Listable (Syntax recur) where - tiers = tiers1 - - instance (Listable1 f, Listable1 (Union (g ': fs))) => Listable1 (Union (f ': g ': fs)) where liftTiers tiers = (inj `mapT` ((liftTiers :: [Tier a] -> [Tier (f a)]) tiers)) \/ (weaken `mapT` ((liftTiers :: [Tier a] -> [Tier (Union (g ': fs) a)]) tiers)) From 44fafdbd9a5f733da19225c22f65005c03d9d215 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 13:10:57 -0400 Subject: [PATCH 042/133] Define a Listable instance for Unions. --- test/Data/Functor/Listable.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/Data/Functor/Listable.hs b/test/Data/Functor/Listable.hs index 5fd0dbc72..6da1f340e 100644 --- a/test/Data/Functor/Listable.hs +++ b/test/Data/Functor/Listable.hs @@ -215,6 +215,9 @@ instance (Listable1 f, Listable1 (Union (g ': fs))) => Listable1 (Union (f ': g instance Listable1 f => Listable1 (Union '[f]) where liftTiers tiers = inj `mapT` ((liftTiers :: [Tier a] -> [Tier (f a)]) tiers) +instance (Listable1 (Union fs), Listable a) => Listable (Union fs a) where + tiers = tiers1 + instance Listable1 Comment.Comment where liftTiers _ = cons1 Comment.Comment From 750bca5bfcd328f762b39765e3323584e997d02d Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 13:14:05 -0400 Subject: [PATCH 043/133] Migrate the Go ToC test to diffWithParser. --- test/TOCSpec.hs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index c20110233..e7ed546e6 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -88,8 +88,7 @@ spec = parallel $ do it "summarizes Go methods with receivers with special formatting" $ do sourceBlobs <- blobsForPaths (both "go/method-with-receiver.A.go" "go/method-with-receiver.B.go") - let Just goParser = syntaxParserForLanguage Go - diff <- runTask $ distributeFor sourceBlobs (\ blob -> parse goParser blob >>= decorate (syntaxDeclarationAlgebra blob)) >>= runBothWith (diffTermPair sourceBlobs diffSyntaxTerms) + diff <- runTask $ diffWithParser goParser sourceBlobs diffTOC diff `shouldBe` [ JSONSummary "Method" "(*apiClient) CheckAuth" (sourceSpanBetween (3,1) (3,101)) "added" ] From ed8e08ef26f1c5b81f1dda8d7015cee605d91fd1 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 13:18:11 -0400 Subject: [PATCH 044/133] Migrate a bunch of the tests away from Syntax. --- test/AlignmentSpec.hs | 33 ++++++++++++++++----------------- test/Data/Mergeable/Spec.hs | 7 +++---- test/PatchOutputSpec.hs | 3 +-- test/SemanticCmdLineSpec.hs | 2 +- test/SemanticSpec.hs | 1 - test/TOCSpec.hs | 24 ++++++++++++------------ test/TermSpec.hs | 5 +---- 7 files changed, 34 insertions(+), 41 deletions(-) diff --git a/test/AlignmentSpec.hs b/test/AlignmentSpec.hs index 8343c3af3..af2e42fd4 100644 --- a/test/AlignmentSpec.hs +++ b/test/AlignmentSpec.hs @@ -22,7 +22,6 @@ import Data.SplitDiff import Data.Term import qualified Data.Text as Text import Data.These -import Syntax import Test.Hspec (Spec, describe, it, parallel) import Test.Hspec.Expectations.Pretty import Test.Hspec.LeanCheck @@ -33,7 +32,7 @@ spec :: Spec spec = parallel $ do describe "alignBranch" $ do it "produces symmetrical context" $ - alignBranch getRange ([] :: [Join These (SplitDiff Syntax (Record '[Range]))]) (both [Range 0 2, Range 2 4] [Range 0 2, Range 2 4]) `shouldBe` + alignBranch getRange ([] :: [Join These (SplitDiff [] (Record '[Range]))]) (both [Range 0 2, Range 2 4] [Range 0 2, Range 2 4]) `shouldBe` [ Join (These (Range 0 2, []) (Range 0 2, [])) , Join (These (Range 2 4, []) @@ -41,7 +40,7 @@ spec = parallel $ do ] it "produces asymmetrical context" $ - alignBranch getRange ([] :: [Join These (SplitDiff Syntax (Record '[Range]))]) (both [Range 0 2, Range 2 4] [Range 0 1]) `shouldBe` + alignBranch getRange ([] :: [Join These (SplitDiff [] (Record '[Range]))]) (both [Range 0 2, Range 2 4] [Range 0 1]) `shouldBe` [ Join (These (Range 0 2, []) (Range 0 1, [])) , Join (This (Range 2 4, [])) @@ -64,13 +63,13 @@ spec = parallel $ do describe "alignDiff" $ do it "aligns identical branches on a single line" $ let sources = both (Source.fromText "[ foo ]") (Source.fromText "[ foo ]") in - align sources ((info 0 7, info 0 7) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources + align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ]) (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ])) ] it "aligns identical branches spanning multiple lines" $ let sources = both (Source.fromText "[\nfoo\n]") (Source.fromText "[\nfoo\n]") in - align sources ((info 0 7, info 0 7) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources + align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 2 `In` []) (wrap $ info 0 2 `In` [])) , Join (These (wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ]) @@ -81,7 +80,7 @@ spec = parallel $ do it "aligns reformatted branches" $ let sources = both (Source.fromText "[ foo ]") (Source.fromText "[\nfoo\n]") in - align sources ((info 0 7, info 0 7) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources + align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources [ Join (That (wrap $ info 0 2 `In` [])) , Join (These (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ]) (wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ])) @@ -90,7 +89,7 @@ spec = parallel $ do it "aligns nodes following reformatted branches" $ let sources = both (Source.fromText "[ foo ]\nbar\n") (Source.fromText "[\nfoo\n]\nbar\n") in - align sources ((info 0 12, info 0 12) `merge` Indexed [ (info 0 7, info 0 7) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo" ], (info 8 11, info 8 11) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources + align sources ((info 0 12, info 0 12) `merge` [ (info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ], (info 8 11, info 8 11) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources [ Join (That (wrap $ info 0 2 `In` [ wrap $ info 0 2 `In` [] ])) , Join (These (wrap $ info 0 8 `In` [ wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ] ]) (wrap $ info 2 6 `In` [ wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ] ])) @@ -103,12 +102,12 @@ spec = parallel $ do it "aligns identical branches with multiple children on the same line" $ let sources = pure (Source.fromText "[ foo, bar ]") in - align sources ((info 0 12, info 0 12) `merge` Indexed [ (info 2 5, info 2 5) `merge` Leaf "foo", (info 7 10, info 7 10) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources + align sources ((info 0 12, info 0 12) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo", (info 7 10, info 7 10) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources [ Join (runBothWith These (pure (wrap $ info 0 12 `In` [ wrap $ info 2 5 `In` [], wrap $ info 7 10 `In` [] ])) ) ] it "aligns insertions" $ let sources = both (Source.fromText "a") (Source.fromText "a\nb") in - align sources ((info 0 1, info 0 3) `merge` Indexed [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources + align sources ((info 0 1, info 0 3) `merge` [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 1 `In` [ wrap $ info 0 1 `In` [] ]) (wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ])) , Join (That (wrap $ info 2 3 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ])) @@ -121,14 +120,14 @@ spec = parallel $ do it "aligns insertions into empty branches" $ let sources = both (Source.fromText "[ ]") (Source.fromText "[a]") in - align sources ((info 0 3, info 0 3) `merge` Indexed [ inserting (Term (info 1 2 `In` Leaf "a")) ]) `shouldBe` prettyDiff sources + align sources ((info 0 3, info 0 3) `merge` [ inserting (Term (info 1 2 `In` Leaf "a")) ]) `shouldBe` prettyDiff sources [ Join (That (wrap $ info 0 3 `In` [ pure (SplitInsert (Term (info 1 2 `In` []))) ])) , Join (This (wrap $ info 0 3 `In` [])) ] it "aligns symmetrically following insertions" $ let sources = both (Source.fromText "a\nc") (Source.fromText "a\nb\nc") in - align sources ((info 0 3, info 0 5) `merge` Indexed [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")), (info 2 3, info 4 5) `merge` Leaf "c" ]) + align sources ((info 0 3, info 0 5) `merge` [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")), (info 2 3, info 4 5) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ]) (wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ])) @@ -139,13 +138,13 @@ spec = parallel $ do it "symmetrical nodes force the alignment of asymmetrical nodes on both sides" $ let sources = both (Source.fromText "[ a, b ]") (Source.fromText "[ b, c ]") in - align sources ((info 0 8, info 0 8) `merge` Indexed [ deleting (Term (info 2 3 `In` Leaf "a")), (info 5 6, info 2 3) `merge` Leaf "b", inserting (Term (info 5 6 `In` Leaf "c")) ]) `shouldBe` prettyDiff sources + align sources ((info 0 8, info 0 8) `merge` [ deleting (Term (info 2 3 `In` Leaf "a")), (info 5 6, info 2 3) `merge` Leaf "b", inserting (Term (info 5 6 `In` Leaf "c")) ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))), wrap $ info 5 6 `In` [] ]) (wrap $ info 0 8 `In` [ wrap $ info 2 3 `In` [], pure (SplitInsert (Term (info 5 6 `In` []))) ])) ] it "when one of two symmetrical nodes must be split, splits the latter" $ let sources = both (Source.fromText "[ a, b ]") (Source.fromText "[ a\n, b\n]") in - align sources ((info 0 8, info 0 9) `merge` Indexed [ (info 2 3, info 2 3) `merge` Leaf "a", (info 5 6, info 6 7) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources + align sources ((info 0 8, info 0 9) `merge` [ (info 2 3, info 2 3) `merge` Leaf "a", (info 5 6, info 6 7) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 8 `In` [ wrap $ info 2 3 `In` [], wrap $ info 5 6 `In` [] ]) (wrap $ info 0 4 `In` [ wrap $ info 2 3 `In` [] ])) , Join (That (wrap $ info 4 8 `In` [ wrap $ info 6 7 `In` [] ])) @@ -154,14 +153,14 @@ spec = parallel $ do it "aligns deletions before insertions" $ let sources = both (Source.fromText "[ a ]") (Source.fromText "[ b ]") in - align sources ((info 0 5, info 0 5) `merge` Indexed [ deleting (Term (info 2 3 `In` Leaf "a")), inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources + align sources ((info 0 5, info 0 5) `merge` [ deleting (Term (info 2 3 `In` Leaf "a")), inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources [ Join (This (wrap $ info 0 5 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))) ])) , Join (That (wrap $ info 0 5 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ])) ] it "aligns context-only lines symmetrically" $ let sources = both (Source.fromText "[\n a\n,\n b\n]") (Source.fromText "[\n a, b\n\n\n]") in - align sources ((info 0 13, info 0 12) `merge` Indexed [ (info 4 5, info 4 5) `merge` Leaf "a", (info 10 11, info 7 8) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources + align sources ((info 0 13, info 0 12) `merge` [ (info 4 5, info 4 5) `merge` Leaf "a", (info 10 11, info 7 8) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 2 `In` []) (wrap $ info 0 2 `In` [])) , Join (These (wrap $ info 2 6 `In` [ wrap $ info 4 5 `In` [] ]) @@ -176,7 +175,7 @@ spec = parallel $ do it "aligns asymmetrical nodes preceding their symmetrical siblings conservatively" $ let sources = both (Source.fromText "[ b, c ]") (Source.fromText "[ a\n, c\n]") in - align sources ((info 0 8, info 0 9) `merge` Indexed [ inserting (Term (info 2 3 `In` Leaf "a")), deleting (Term (info 2 3 `In` Leaf "b")), (info 5 6, info 6 7) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources + align sources ((info 0 8, info 0 9) `merge` [ inserting (Term (info 2 3 `In` Leaf "a")), deleting (Term (info 2 3 `In` Leaf "b")), (info 5 6, info 6 7) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources [ Join (That (wrap $ info 0 4 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ])) , Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))), wrap $ info 5 6 `In` [] ]) (wrap $ info 4 8 `In` [ wrap $ info 6 7 `In` [] ])) @@ -185,7 +184,7 @@ spec = parallel $ do it "aligns symmetrical reformatted nodes" $ let sources = both (Source.fromText "a [ b ]\nc") (Source.fromText "a [\nb\n]\nc") in - align sources ((info 0 9, info 0 9) `merge` Indexed [ (info 0 1, info 0 1) `merge` Leaf "a", (info 2 7, info 2 7) `merge` Indexed [ (info 4 5, info 4 5) `merge` Leaf "b" ], (info 8 9, info 8 9) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources + align sources ((info 0 9, info 0 9) `merge` [ (info 0 1, info 0 1) `merge` Leaf "a", (info 2 7, info 2 7) `merge` [ (info 4 5, info 4 5) `merge` Leaf "b" ], (info 8 9, info 8 9) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 8 `In` [ wrap $ info 0 1 `In` [], wrap $ info 2 7 `In` [ wrap $ info 4 5 `In` [] ] ]) (wrap $ info 0 4 `In` [ wrap $ info 0 1 `In` [], wrap $ info 2 4 `In` [] ])) , Join (That (wrap $ info 4 6 `In` [ wrap $ info 4 6 `In` [ wrap $ info 4 5 `In` [] ] ])) diff --git a/test/Data/Mergeable/Spec.hs b/test/Data/Mergeable/Spec.hs index 3179df746..9f3bd3cfe 100644 --- a/test/Data/Mergeable/Spec.hs +++ b/test/Data/Mergeable/Spec.hs @@ -6,7 +6,6 @@ import Data.Functor.Identity import Data.Functor.Listable import Data.Maybe (catMaybes) import Data.Mergeable -import Syntax import Test.Hspec import Test.Hspec.LeanCheck import Test.LeanCheck @@ -22,9 +21,9 @@ spec = parallel $ do describe "Identity" $ do withAlternativeInstances sequenceAltLaws (Identity `mapT` tiers :: [Tier (Identity Char)]) withAlternativeInstances mergeLaws (Identity `mapT` tiers :: [Tier (Identity Char)]) - describe "Syntax" $ do - withAlternativeInstances sequenceAltLaws (tiers :: [Tier (Syntax Char)]) - withAlternativeInstances mergeLaws (tiers :: [Tier (Syntax Char)]) + describe "ListableSyntax" $ do + withAlternativeInstances sequenceAltLaws (tiers :: [Tier (ListableSyntax Char)]) + withAlternativeInstances mergeLaws (tiers :: [Tier (ListableSyntax Char)]) prop "subsumes catMaybes/Just" $ \ a -> sequenceAlt a `shouldBe` pure (catMaybes (a :: [Maybe Char])) diff --git a/test/PatchOutputSpec.hs b/test/PatchOutputSpec.hs index d3fd74464..9ff9f6880 100644 --- a/test/PatchOutputSpec.hs +++ b/test/PatchOutputSpec.hs @@ -6,7 +6,6 @@ import Data.Functor.Both import Data.Range import Data.Record import Renderer.Patch -import Syntax import Test.Hspec (Spec, describe, it, parallel) import Test.Hspec.Expectations.Pretty @@ -14,4 +13,4 @@ spec :: Spec spec = parallel $ do describe "hunks" $ do it "empty diffs have empty hunks" $ - hunks (merge (Range 0 0 :. Nil, Range 0 0 :. Nil) (Leaf "")) (both (Blob mempty "abcde" "path2.txt" (Just defaultPlainBlob) Nothing) (Blob mempty "xyz" "path2.txt" (Just defaultPlainBlob) Nothing)) `shouldBe` [Hunk {offset = pure 0, changes = [], trailingContext = []}] + hunks (merge (Range 0 0 :. Nil, Range 0 0 :. Nil) []) (both (Blob mempty "abcde" "path2.txt" (Just defaultPlainBlob) Nothing) (Blob mempty "xyz" "path2.txt" (Just defaultPlainBlob) Nothing)) `shouldBe` [Hunk {offset = pure 0, changes = [], trailingContext = []}] diff --git a/test/SemanticCmdLineSpec.hs b/test/SemanticCmdLineSpec.hs index d7ffc813a..87852b7fa 100644 --- a/test/SemanticCmdLineSpec.hs +++ b/test/SemanticCmdLineSpec.hs @@ -56,7 +56,7 @@ diffFixtures = [ (SomeRenderer PatchDiffRenderer, pathMode, patchOutput) , (SomeRenderer JSONDiffRenderer, pathMode, jsonOutput) , (SomeRenderer SExpressionDiffRenderer, pathMode, sExpressionOutput) - , (SomeRenderer OldToCDiffRenderer, pathMode, tocOutput) + , (SomeRenderer ToCDiffRenderer, pathMode, tocOutput) ] where pathMode = Right [both ("test/fixtures/ruby/method-declaration.A.rb", Just Ruby) ("test/fixtures/ruby/method-declaration.B.rb", Just Ruby)] diff --git a/test/SemanticSpec.hs b/test/SemanticSpec.hs index 461fc0241..671d5b54a 100644 --- a/test/SemanticSpec.hs +++ b/test/SemanticSpec.hs @@ -10,7 +10,6 @@ import Language import Renderer import Semantic import Semantic.Task -import Syntax import System.Exit import Test.Hspec hiding (shouldBe, shouldNotBe, shouldThrow, errorCall) import Test.Hspec.Expectations.Pretty diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index e7ed546e6..a2cf6f2cb 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -2,7 +2,6 @@ {-# LANGUAGE DataKinds, TypeOperators #-} module TOCSpec where -import Category as C hiding (Go) import Data.Aeson import Data.Bifunctor import Data.Blob @@ -14,13 +13,15 @@ import Data.Maybe (fromMaybe) import Data.Monoid (Last(..)) import Data.Output import Data.Patch +import Data.Range import Data.Record import Data.Semigroup ((<>)) import Data.Source +import Data.Span +import Data.Syntax.Algebra (constructorNameAndConstantFields) import Data.Term import Data.Text (Text) import Data.These -import Info hiding (Go) import Interpreter import Language import Prelude hiding (readFile) @@ -31,7 +32,6 @@ import Semantic import Semantic.Task import Semantic.Util import SpecHelpers -import Syntax as S hiding (Go) import Test.Hspec (Spec, describe, it, parallel) import Test.Hspec.Expectations.Pretty import Test.Hspec.LeanCheck @@ -42,23 +42,23 @@ spec :: Spec spec = parallel $ do describe "tableOfContentsBy" $ do prop "drops all nodes with the constant Nothing function" $ - \ diff -> tableOfContentsBy (const Nothing :: a -> Maybe ()) (diff :: Diff Syntax () ()) `shouldBe` [] + \ diff -> tableOfContentsBy (const Nothing :: a -> Maybe ()) (diff :: Diff ListableSyntax () ()) `shouldBe` [] let diffSize = max 1 . length . diffPatches let lastValue a = fromMaybe (extract a) (getLast (foldMap (Last . Just) a)) prop "includes all nodes with a constant Just function" $ - \ diff -> let diff' = (diff :: Diff Syntax () ()) in entryPayload <$> tableOfContentsBy (const (Just ())) diff' `shouldBe` replicate (diffSize diff') () + \ diff -> let diff' = (diff :: Diff ListableSyntax () ()) in entryPayload <$> tableOfContentsBy (const (Just ())) diff' `shouldBe` replicate (diffSize diff') () prop "produces an unchanged entry for identity diffs" $ - \ term -> tableOfContentsBy (Just . termAnnotation) (diffSyntaxTerms term term) `shouldBe` [Unchanged (lastValue (term :: Term Syntax (Record '[Category])))] + \ term -> tableOfContentsBy (Just . termAnnotation) (diffTerms term term) `shouldBe` [Unchanged (lastValue (term :: Term ListableSyntax (Record '[String])))] prop "produces inserted/deleted/replaced entries for relevant nodes within patches" $ \ p -> tableOfContentsBy (Just . termAnnotation) (patch deleting inserting replacing p) `shouldBe` - patch (fmap Deleted) (fmap Inserted) (const (fmap Replaced)) (bimap (foldMap pure) (foldMap pure) (p :: Patch (Term Syntax Int) (Term Syntax Int))) + patch (fmap Deleted) (fmap Inserted) (const (fmap Replaced)) (bimap (foldMap pure) (foldMap pure) (p :: Patch (Term ListableSyntax Int) (Term ListableSyntax Int))) prop "produces changed entries for relevant nodes containing irrelevant patches" $ - \ diff -> let diff' = merge (0, 0) (Indexed [bimap (const 1) (const 1) (diff :: Diff Syntax Int Int)]) in + \ diff -> let diff' = merge (0, 0) (Indexed [bimap (const 1) (const 1) (diff :: Diff ListableSyntax Int Int)]) in tableOfContentsBy (\ (n `In` _) -> if n == (0 :: Int) then Just n else Nothing) diff' `shouldBe` if null (diffPatches diff') then [Unchanged 0] else replicate (length (diffPatches diff')) (Changed 0) @@ -135,8 +135,8 @@ spec = parallel $ do in numTocSummaries diff `shouldBe` 0 prop "equal terms produce identity diffs" $ - \a -> let term = defaultFeatureVectorDecorator (Info.category . termAnnotation) (a :: Term') in - diffTOC (diffSyntaxTerms term term) `shouldBe` [] + \a -> let term = defaultFeatureVectorDecorator constructorNameAndConstantFields (a :: Term') in + diffTOC (diffTerms term term) `shouldBe` [] describe "JSONSummary" $ do it "encodes modified summaries to JSON" $ do @@ -169,8 +169,8 @@ spec = parallel $ do toOutput output `shouldBe` ("{\"changes\":{\"test/fixtures/toc/markdown/headings.A.md -> test/fixtures/toc/markdown/headings.B.md\":[{\"span\":{\"start\":[5,1],\"end\":[7,10]},\"category\":\"Heading 2\",\"term\":\"Two\",\"changeType\":\"added\"},{\"span\":{\"start\":[9,1],\"end\":[10,4]},\"category\":\"Heading 1\",\"term\":\"Final\",\"changeType\":\"added\"}]},\"errors\":{}}\n" :: ByteString) -type Diff' = Diff Syntax (Record (Maybe Declaration ': DefaultFields)) (Record (Maybe Declaration ': DefaultFields)) -type Term' = Term Syntax (Record (Maybe Declaration ': DefaultFields)) +type Diff' = Diff ListableSyntax (Record '[Maybe Declaration, Range, Span]) (Record '[Maybe Declaration, Range, Span]) +type Term' = Term ListableSyntax (Record '[Maybe Declaration, Range, Span]) numTocSummaries :: Diff' -> Int numTocSummaries diff = length $ filter isValidSummary (diffTOC diff) diff --git a/test/TermSpec.hs b/test/TermSpec.hs index 6487a656d..ec829677f 100644 --- a/test/TermSpec.hs +++ b/test/TermSpec.hs @@ -1,11 +1,8 @@ {-# LANGUAGE DataKinds #-} module TermSpec where -import Category import Data.Functor.Listable -import Data.Record import Data.Term -import Syntax import Test.Hspec (Spec, describe, parallel) import Test.Hspec.Expectations.Pretty import Test.Hspec.LeanCheck @@ -14,4 +11,4 @@ spec :: Spec spec = parallel $ do describe "Term" $ do prop "equality is reflexive" $ - \ a -> unListableF a `shouldBe` (unListableF a :: Term Syntax (Record '[Category])) + \ a -> a `shouldBe` (a :: Term ListableSyntax ()) From 7eeba8f7e97d520a3e4b6eddde4e41cc4e2c165f Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 13:19:18 -0400 Subject: [PATCH 045/133] :fire: decoratingWith. --- src/Interpreter.hs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/Interpreter.hs b/src/Interpreter.hs index 2d2f241ec..ac507efe7 100644 --- a/src/Interpreter.hs +++ b/src/Interpreter.hs @@ -9,7 +9,6 @@ import Control.Monad.Free.Freer import Data.Align.Generic import Data.Diff import Data.Functor.Classes -import Data.Hashable (Hashable) import Data.Maybe (fromMaybe) import Data.Record import Data.Syntax.Algebra @@ -21,18 +20,7 @@ diffTerms :: (Diffable syntax, Eq1 syntax, Foldable syntax, Functor syntax, GAli => Term syntax (Record fields1) -> Term syntax (Record fields2) -> Diff syntax (Record fields1) (Record fields2) -diffTerms = decoratingWith comparableTerms equivalentTerms constructorNameAndConstantFields constructorNameAndConstantFields - --- | Diff two terms by decorating with feature vectors computed using the supplied labelling algebra, and stripping the feature vectors from the resulting diff. -decoratingWith :: (Hashable label, Diffable syntax, GAlign syntax, Traversable syntax) - => ComparabilityRelation syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2)) -- ^ A relation on terms used to determine comparability and equality. - -> (Term syntax (Record (FeatureVector ': fields1)) -> Term syntax (Record (FeatureVector ': fields2)) -> Bool) -- ^ A relation used to determine term equivalence. - -> (forall a. TermF syntax (Record fields1) a -> label) - -> (forall a. TermF syntax (Record fields2) a -> label) - -> Term syntax (Record fields1) - -> Term syntax (Record fields2) - -> Diff syntax (Record fields1) (Record fields2) -decoratingWith comparability equivalence getLabel1 getLabel2 t1 t2 = stripDiff (diffTermsWith comparability equivalence (defaultFeatureVectorDecorator getLabel1 t1) (defaultFeatureVectorDecorator getLabel2 t2)) +diffTerms t1 t2 = stripDiff (diffTermsWith comparableTerms equivalentTerms (defaultFeatureVectorDecorator constructorNameAndConstantFields t1) (defaultFeatureVectorDecorator constructorNameAndConstantFields t2)) -- | Diff a pair of terms recurisvely, using the supplied continuation and 'ComparabilityRelation'. diffTermsWith :: forall syntax fields1 fields2 From fdfe11d9ca5ab3b9742272e478f7c16840ff73ca Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 13:21:19 -0400 Subject: [PATCH 046/133] :fire: diffTermsWith. --- src/Interpreter.hs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/Interpreter.hs b/src/Interpreter.hs index ac507efe7..21c9105e1 100644 --- a/src/Interpreter.hs +++ b/src/Interpreter.hs @@ -20,17 +20,9 @@ diffTerms :: (Diffable syntax, Eq1 syntax, Foldable syntax, Functor syntax, GAli => Term syntax (Record fields1) -> Term syntax (Record fields2) -> Diff syntax (Record fields1) (Record fields2) -diffTerms t1 t2 = stripDiff (diffTermsWith comparableTerms equivalentTerms (defaultFeatureVectorDecorator constructorNameAndConstantFields t1) (defaultFeatureVectorDecorator constructorNameAndConstantFields t2)) - --- | Diff a pair of terms recurisvely, using the supplied continuation and 'ComparabilityRelation'. -diffTermsWith :: forall syntax fields1 fields2 - . (Diffable syntax, GAlign syntax, Traversable syntax) - => ComparabilityRelation syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2)) -- ^ A relation on terms used to determine comparability and equality. - -> (Term syntax (Record (FeatureVector ': fields1)) -> Term syntax (Record (FeatureVector ': fields2)) -> Bool) -- ^ A relation used to determine term equivalence. - -> Term syntax (Record (FeatureVector ': fields1)) -- ^ A term representing the old state. - -> Term syntax (Record (FeatureVector ': fields2)) -- ^ A term representing the new state. - -> Diff syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2)) -- ^ The resulting diff. -diffTermsWith comparable eqTerms t1 t2 = fromMaybe (replacing t1 t2) (runAlgorithm comparable eqTerms (diff t1 t2)) +diffTerms t1 t2 = stripDiff (fromMaybe (replacing t1' t2') (runAlgorithm comparableTerms equivalentTerms (diff t1' t2'))) + where (t1', t2') = ( defaultFeatureVectorDecorator constructorNameAndConstantFields t1 + , defaultFeatureVectorDecorator constructorNameAndConstantFields t2) -- | Run an 'Algorithm' to completion in an 'Alternative' context using the supplied comparability & equivalence relations. runAlgorithm :: forall syntax fields1 fields2 m result From fc0d0c440723d0c96e93158ecf337667c338db25 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 13:23:33 -0400 Subject: [PATCH 047/133] =?UTF-8?q?Don=E2=80=99t=20pass=20the=20comparabil?= =?UTF-8?q?ity=20&=20equivalence=20relations=20to=20runAlgorithm.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Interpreter.hs | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/Interpreter.hs b/src/Interpreter.hs index 21c9105e1..efabda55d 100644 --- a/src/Interpreter.hs +++ b/src/Interpreter.hs @@ -20,35 +20,25 @@ diffTerms :: (Diffable syntax, Eq1 syntax, Foldable syntax, Functor syntax, GAli => Term syntax (Record fields1) -> Term syntax (Record fields2) -> Diff syntax (Record fields1) (Record fields2) -diffTerms t1 t2 = stripDiff (fromMaybe (replacing t1' t2') (runAlgorithm comparableTerms equivalentTerms (diff t1' t2'))) +diffTerms t1 t2 = stripDiff (fromMaybe (replacing t1' t2') (runAlgorithm (diff t1' t2'))) where (t1', t2') = ( defaultFeatureVectorDecorator constructorNameAndConstantFields t1 , defaultFeatureVectorDecorator constructorNameAndConstantFields t2) -- | Run an 'Algorithm' to completion in an 'Alternative' context using the supplied comparability & equivalence relations. runAlgorithm :: forall syntax fields1 fields2 m result - . (Diffable syntax, GAlign syntax, Traversable syntax, Alternative m, Monad m) - => ComparabilityRelation syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2)) -- ^ A relation on terms used to determine comparability and equality. - -> (Term syntax (Record (FeatureVector ': fields1)) -> Term syntax (Record (FeatureVector ': fields2)) -> Bool) -- ^ A relation used to determine term equivalence. - -> Algorithm + . (Diffable syntax, Eq1 syntax, GAlign syntax, Traversable syntax, Alternative m, Monad m) + => Algorithm (Term syntax (Record (FeatureVector ': fields1))) (Term syntax (Record (FeatureVector ': fields2))) (Diff syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2))) result -> m result -runAlgorithm comparable eqTerms = go - where go :: forall result - . Algorithm - (Term syntax (Record (FeatureVector ': fields1))) - (Term syntax (Record (FeatureVector ': fields2))) - (Diff syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2))) - result - -> m result - go = iterFreerA (\ step yield -> case step of - Algorithm.Diff t1 t2 -> go (algorithmForTerms t1 t2) <|> pure (replacing t1 t2) >>= yield - Linear (Term (In ann1 f1)) (Term (In ann2 f2)) -> merge (ann1, ann2) <$> galignWith (go . diffThese) f1 f2 >>= yield - RWS as bs -> traverse (go . diffThese) (rws comparable eqTerms as bs) >>= yield - Delete a -> yield (deleting a) - Insert b -> yield (inserting b) - Replace a b -> yield (replacing a b) - Empty -> empty - Alt a b -> yield a <|> yield b) +runAlgorithm = iterFreerA (\ step yield -> case step of + Algorithm.Diff t1 t2 -> runAlgorithm (algorithmForTerms t1 t2) <|> pure (replacing t1 t2) >>= yield + Linear (Term (In ann1 f1)) (Term (In ann2 f2)) -> merge (ann1, ann2) <$> galignWith (runAlgorithm . diffThese) f1 f2 >>= yield + RWS as bs -> traverse (runAlgorithm . diffThese) (rws comparableTerms equivalentTerms as bs) >>= yield + Delete a -> yield (deleting a) + Insert b -> yield (inserting b) + Replace a b -> yield (replacing a b) + Empty -> empty + Alt a b -> yield a <|> yield b) From 914958aa39275862bef980f0dc79f9b7c1a8116f Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 13:29:40 -0400 Subject: [PATCH 048/133] Correct the docs for someParser. --- src/Parser.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Parser.hs b/src/Parser.hs index cae2f1f0a..56ff6bda1 100644 --- a/src/Parser.hs +++ b/src/Parser.hs @@ -62,7 +62,7 @@ data SomeParser typeclasses where -- -- This can be used to perform operations uniformly over terms produced by blobs with different 'Language's, and which therefore have different types in general. For example, given some 'Blob', we can parse and 'show' the parsed & assigned 'Term' like so: -- --- > case someParser (Proxy :: Proxy '[Show1]) (blobLanguage language) of { Just (SomeParser parser) -> runTask (parse parser blob) >>= putStrLn . show ; _ -> return () } +-- > case someParser (Proxy :: Proxy '[Show1]) <$> blobLanguage language of { Just (SomeParser parser) -> runTask (parse parser blob) >>= putStrLn . show ; _ -> return () } someParser :: ( ApplyAll typeclasses Go.Syntax , ApplyAll typeclasses JSON.Syntax , ApplyAll typeclasses Markdown.Syntax @@ -72,7 +72,7 @@ someParser :: ( ApplyAll typeclasses Go.Syntax ) => proxy typeclasses -- ^ A proxy for the list of typeclasses required, e.g. @(Proxy :: Proxy '[Show1])@. -> Language -- ^ The 'Language' to select. - -> SomeParser typeclasses -- ^ 'Maybe' a 'SomeParser' abstracting the syntax type to be produced. + -> SomeParser typeclasses -- ^ A 'SomeParser' abstracting the syntax type to be produced. someParser _ Go = SomeParser goParser someParser _ JavaScript = SomeParser typescriptParser someParser _ JSON = SomeParser jsonParser From cd30584dba91ac73fe9035f1667a07713b171123 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 10 Oct 2017 13:34:50 -0400 Subject: [PATCH 049/133] :fire: a bunch of references to categories. --- test/TOCSpec.hs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index a2cf6f2cb..db8f1126a 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -180,14 +180,14 @@ programWithChange :: Term' -> Diff' programWithChange body = merge (programInfo, programInfo) (Indexed [ function' ]) where function' = merge ((Just (FunctionDeclaration "foo") :. functionInfo, Just (FunctionDeclaration "foo") :. functionInfo)) (S.Function name' [] [ inserting body ]) - name' = let info = Nothing :. Range 0 0 :. C.Identifier :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (Leaf "foo") + name' = let info = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (Leaf "foo") -- Return a diff where term is inserted in the program, below a function found on both sides of the diff. programWithChangeOutsideFunction :: Term' -> Diff' programWithChangeOutsideFunction term = merge (programInfo, programInfo) (Indexed [ function', term' ]) where function' = merge (Just (FunctionDeclaration "foo") :. functionInfo, Just (FunctionDeclaration "foo") :. functionInfo) (S.Function name' [] []) - name' = let info = Nothing :. Range 0 0 :. C.Identifier :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (Leaf "foo") + name' = let info = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (Leaf "foo") term' = inserting term programWithInsert :: Text -> Term' -> Diff' @@ -205,22 +205,20 @@ programOf diff = merge (programInfo, programInfo) (Indexed [ diff ]) functionOf :: Text -> Term' -> Term' functionOf name body = Term $ (Just (FunctionDeclaration name) :. functionInfo) `In` S.Function name' [] [body] where - name' = Term $ (Nothing :. Range 0 0 :. C.Identifier :. sourceSpanBetween (0,0) (0,0) :. Nil) `In` Leaf name + name' = Term $ (Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil) `In` Leaf name -programInfo :: Record (Maybe Declaration ': DefaultFields) -programInfo = Nothing :. Range 0 0 :. C.Program :. sourceSpanBetween (0,0) (0,0) :. Nil +programInfo :: Record '[Maybe Declaration, Range, Span] +programInfo = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil -functionInfo :: Record DefaultFields -functionInfo = Range 0 0 :. C.Function :. sourceSpanBetween (0,0) (0,0) :. Nil +functionInfo :: Record '[Range, Span] +functionInfo = Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil -- Filter tiers for terms that we consider "meaniningful" in TOC summaries. isMeaningfulTerm :: Term Syntax a -> Bool -isMeaningfulTerm a = case unTerm a of - (_ `In` S.Indexed _) -> False - (_ `In` S.Fixed _) -> False - (_ `In` S.Commented _ _) -> False - (_ `In` S.ParseError _) -> False - _ -> True +isMeaningfulTerm a + | (_:_) <- prj (termOut (unTerm a)) = False + | [] <- prj (termOut (unTerm a)) = False + | otherwise = True -- Filter tiers for terms if the Syntax is a Method or a Function. isMethodOrFunction :: HasField fields Category => Term Syntax (Record fields) -> Bool @@ -241,8 +239,8 @@ sourceSpanBetween (s1, e1) (s2, e2) = Span (Pos s1 e1) (Pos s2 e2) blankDiff :: Diff' blankDiff = merge (arrayInfo, arrayInfo) (Indexed [ inserting (Term $ literalInfo `In` Leaf "\"a\"") ]) where - arrayInfo = Nothing :. Range 0 3 :. ArrayLiteral :. sourceSpanBetween (1, 1) (1, 5) :. Nil - literalInfo = Nothing :. Range 1 2 :. StringLiteral :. sourceSpanBetween (1, 2) (1, 4) :. Nil + arrayInfo = Nothing :. Range 0 3 :. sourceSpanBetween (1, 1) (1, 5) :. Nil + literalInfo = Nothing :. Range 1 2 :. sourceSpanBetween (1, 2) (1, 4) :. Nil blankDiffBlobs :: Both Blob blankDiffBlobs = both (Blob (fromText "[]") nullOid "a.js" (Just defaultPlainBlob) (Just TypeScript)) (Blob (fromText "[a]") nullOid "b.js" (Just defaultPlainBlob) (Just TypeScript)) From 76050700f90bc48d793dc4af5995c3fb8525a5ab Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 15 Nov 2017 10:54:20 -0500 Subject: [PATCH 050/133] Fix an import. --- src/Parser.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Parser.hs b/src/Parser.hs index 14066d012..459e03acd 100644 --- a/src/Parser.hs +++ b/src/Parser.hs @@ -22,7 +22,7 @@ import Data.Term import Data.Union import Foreign.Ptr import Language -import qualified Language.Go.Assignment as Go +import qualified Language.Go.Syntax as Go import qualified Language.JSON.Assignment as JSON import qualified Language.Markdown.Assignment as Markdown import qualified Language.Python.Assignment as Python From 1b7f7555cd3520818682f5d3535c9dac66405562 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 15 Nov 2017 10:54:37 -0500 Subject: [PATCH 051/133] Use getField instead of byteRange. --- src/Renderer/TOC.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Renderer/TOC.hs b/src/Renderer/TOC.hs index 018a5a848..cadd10cfa 100644 --- a/src/Renderer/TOC.hs +++ b/src/Renderer/TOC.hs @@ -166,7 +166,7 @@ instance CustomHasDeclaration Declaration.Class where customToDeclaration Blob{..} _ (Declaration.Class _ (Term (In identifierAnn _), _) _ _) -- Classes = Just $ ClassDeclaration (getSource identifierAnn) - where getSource = toText . flip Source.slice blobSource . byteRange + where getSource = toText . flip Source.slice blobSource . getField -- | Produce a 'Declaration' for 'Union's using the 'HasDeclaration' instance & therefore using a 'CustomHasDeclaration' instance when one exists & the type is listed in 'DeclarationStrategy'. instance Apply HasDeclaration fs => CustomHasDeclaration (Union fs) where From a94f0087a8259054e20a463da53476420a0a155b Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 21 Nov 2017 12:42:37 -0500 Subject: [PATCH 052/133] :fire: an import of Info. --- src/Renderer/Tag.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Renderer/Tag.hs b/src/Renderer/Tag.hs index f59b96a7c..517b5a7c8 100644 --- a/src/Renderer/Tag.hs +++ b/src/Renderer/Tag.hs @@ -7,9 +7,9 @@ import Data.Aeson import Data.Blob import Data.Maybe (mapMaybe) import Data.Record +import Data.Span import Data.Term import GHC.Generics -import Info import qualified Data.Text as T import Renderer.TOC @@ -24,7 +24,7 @@ renderToTags Blob{..} = fmap toJSON . termToC blobPath tagSummary :: (HasField fields (Maybe Declaration), HasField fields Span) => FilePath -> T.Text -> Record fields -> Maybe Tag tagSummary path _ record = case getDeclaration record of Just ErrorDeclaration{} -> Nothing - Just declaration -> Just $ Tag (declarationIdentifier declaration) (T.pack path) (T.pack . show <$> declarationLanguage declaration) (toCategoryName declaration) (declarationText declaration) (sourceSpan record) + Just declaration -> Just $ Tag (declarationIdentifier declaration) (T.pack path) (T.pack . show <$> declarationLanguage declaration) (toCategoryName declaration) (declarationText declaration) (getField record) _ -> Nothing data Tag From 2262de15c9aad76b879b76b7576daad1722b329f Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 21 Nov 2017 12:45:08 -0500 Subject: [PATCH 053/133] syntaxParser is no more. --- src/Semantic.hs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index ded1d76ac..c3e1be335 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -58,10 +58,8 @@ parseBlob renderer blob@Blob{..} = case (renderer, blobLanguage) of parse parser blob >>= decorate constructorLabel . (Nil <$) >>= render renderSExpressionTerm (TagsTermRenderer, lang) - | Just (SomeParser parser) <- lang >>= someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) -> + | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) <$> lang -> parse parser blob >>= decorate (declarationAlgebra blob) >>= render (renderToTags blob) - | Just syntaxParser <- lang >>= syntaxParserForLanguage -> - parse syntaxParser blob >>= decorate (syntaxDeclarationAlgebra blob) >>= render (renderToTags blob) _ -> throwError (SomeException (NoParserForLanguage blobPath blobLanguage)) From e41da0fed41cf60dfae5c4d66e5a268477757291 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 21 Nov 2017 12:45:16 -0500 Subject: [PATCH 054/133] Rename NoParserForLanguage to NoLanguageForBlob. --- src/Semantic.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index c3e1be335..c1f120555 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -61,9 +61,9 @@ parseBlob renderer blob@Blob{..} = case (renderer, blobLanguage) of | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) <$> lang -> parse parser blob >>= decorate (declarationAlgebra blob) >>= render (renderToTags blob) - _ -> throwError (SomeException (NoParserForLanguage blobPath blobLanguage)) + _ -> throwError (SomeException (NoLanguageForBlob blobPath blobLanguage)) -data NoParserForLanguage = NoParserForLanguage FilePath (Maybe Language.Language) +data NoLanguageForBlob = NoLanguageForBlob FilePath (Maybe Language.Language) deriving (Eq, Exception, Ord, Show, Typeable) @@ -89,7 +89,7 @@ diffBlobPair renderer blobs = case (renderer, effectiveLanguage) of | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[ConstructorName, Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) <$> lang -> run (decorate constructorLabel . (Nil <$) <=< parse parser) diffTerms renderSExpressionDiff - _ -> throwError (SomeException (NoParserForLanguage effectivePath effectiveLanguage)) + _ -> throwError (SomeException (NoLanguageForBlob effectivePath effectiveLanguage)) where (effectivePath, effectiveLanguage) = case runJoin blobs of (Blob { blobLanguage = Just lang, blobPath = path }, _) -> (path, Just lang) (_, Blob { blobLanguage = Just lang, blobPath = path }) -> (path, Just lang) From f2a29b35f3783d992f49486fa90fd3e810811cfd Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 21 Nov 2017 12:48:58 -0500 Subject: [PATCH 055/133] :fire: the language field for no lang exceptions. --- src/Semantic.hs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index c1f120555..0ec3708f3 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -24,7 +24,6 @@ import Data.Syntax.Algebra import Data.Term import Data.Typeable import Interpreter -import qualified Language import Parser import Renderer import Semantic.Task as Task @@ -61,9 +60,9 @@ parseBlob renderer blob@Blob{..} = case (renderer, blobLanguage) of | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) <$> lang -> parse parser blob >>= decorate (declarationAlgebra blob) >>= render (renderToTags blob) - _ -> throwError (SomeException (NoLanguageForBlob blobPath blobLanguage)) + _ -> throwError (SomeException (NoLanguageForBlob blobPath)) -data NoLanguageForBlob = NoLanguageForBlob FilePath (Maybe Language.Language) +data NoLanguageForBlob = NoLanguageForBlob FilePath deriving (Eq, Exception, Ord, Show, Typeable) @@ -89,7 +88,7 @@ diffBlobPair renderer blobs = case (renderer, effectiveLanguage) of | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[ConstructorName, Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) <$> lang -> run (decorate constructorLabel . (Nil <$) <=< parse parser) diffTerms renderSExpressionDiff - _ -> throwError (SomeException (NoLanguageForBlob effectivePath effectiveLanguage)) + _ -> throwError (SomeException (NoLanguageForBlob effectivePath)) where (effectivePath, effectiveLanguage) = case runJoin blobs of (Blob { blobLanguage = Just lang, blobPath = path }, _) -> (path, Just lang) (_, Blob { blobLanguage = Just lang, blobPath = path }) -> (path, Just lang) From 1a92152bbf181e0089812e64616ea9461a5416d2 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 21 Nov 2017 12:57:29 -0500 Subject: [PATCH 056/133] Factor out the possibility of failure. --- src/Semantic.hs | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index 0ec3708f3..d67d96570 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -43,24 +43,24 @@ parseBlobs renderer = fmap toOutput . distributeFoldMap (parseBlob renderer) . f -- | A task to parse a 'Blob' and render the resulting 'Term'. parseBlob :: TermRenderer output -> Blob -> Task output -parseBlob renderer blob@Blob{..} = case (renderer, blobLanguage) of - (ToCTermRenderer, lang) - | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) <$> lang -> +parseBlob renderer blob@Blob{ blobLanguage = Just lang } = case renderer of + ToCTermRenderer + | SomeParser parser <- someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) lang -> parse parser blob >>= decorate (declarationAlgebra blob) >>= render (renderToCTerm blob) - (JSONTermRenderer, lang) - | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) <$> lang -> + JSONTermRenderer + | SomeParser parser <- someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) lang -> parse parser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob) - (SExpressionTermRenderer, lang) - | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) <$> lang -> + SExpressionTermRenderer + | SomeParser parser <- someParser (Proxy :: Proxy '[ConstructorName, Foldable, Functor]) lang -> parse parser blob >>= decorate constructorLabel . (Nil <$) >>= render renderSExpressionTerm - (TagsTermRenderer, lang) - | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) <$> lang -> + TagsTermRenderer + | SomeParser parser <- someParser (Proxy :: Proxy '[HasDeclaration, Foldable, Functor]) lang -> parse parser blob >>= decorate (declarationAlgebra blob) >>= render (renderToTags blob) - _ -> throwError (SomeException (NoLanguageForBlob blobPath)) +parseBlob _ Blob { blobPath = blobPath, blobLanguage = Nothing } = throwError (SomeException (NoLanguageForBlob blobPath)) data NoLanguageForBlob = NoLanguageForBlob FilePath deriving (Eq, Exception, Ord, Show, Typeable) @@ -71,30 +71,24 @@ diffBlobPairs renderer = fmap toOutput . distributeFoldMap (diffBlobPair rendere -- | A task to parse a pair of 'Blob's, diff them, and render the 'Diff'. diffBlobPair :: DiffRenderer output -> Both Blob -> Task output -diffBlobPair renderer blobs = case (renderer, effectiveLanguage) of - (ToCDiffRenderer, lang) - | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, HasDeclaration, Show1, Traversable]) <$> lang -> +diffBlobPair renderer blobs@(Join (Blob { blobLanguage = Just lang }, Blob { blobLanguage = Just _ })) = case renderer of + ToCDiffRenderer + | SomeParser parser <- someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, HasDeclaration, Show1, Traversable]) lang -> run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) diffTerms (renderToCDiff blobs) - (JSONDiffRenderer, lang) - | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) <$> lang -> + JSONDiffRenderer + | SomeParser parser <- someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) lang -> run (parse parser) diffTerms (renderJSONDiff blobs) - (PatchDiffRenderer, lang) - | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) <$> lang -> + PatchDiffRenderer + | SomeParser parser <- someParser (Proxy :: Proxy '[Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) lang -> run (parse parser) diffTerms (renderPatch blobs) - (SExpressionDiffRenderer, lang) - | Just (SomeParser parser) <- someParser (Proxy :: Proxy '[ConstructorName, Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) <$> lang -> + SExpressionDiffRenderer + | SomeParser parser <- someParser (Proxy :: Proxy '[ConstructorName, Diffable, Eq1, Foldable, Functor, GAlign, Show1, Traversable]) lang -> run (decorate constructorLabel . (Nil <$) <=< parse parser) diffTerms renderSExpressionDiff - _ -> throwError (SomeException (NoLanguageForBlob effectivePath)) - where (effectivePath, effectiveLanguage) = case runJoin blobs of - (Blob { blobLanguage = Just lang, blobPath = path }, _) -> (path, Just lang) - (_, Blob { blobLanguage = Just lang, blobPath = path }) -> (path, Just lang) - (Blob { blobPath = path }, _) -> (path, Nothing) - - run :: (Foldable syntax, Functor syntax) => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (Diff syntax ann ann -> output) -> Task output + where run :: (Foldable syntax, Functor syntax) => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (Diff syntax ann ann -> output) -> Task output run parse diff renderer = do terms <- distributeFor blobs parse time "diff" languageTag $ do @@ -106,6 +100,9 @@ diffBlobPair renderer blobs = case (renderer, effectiveLanguage) of languageTag = let (a, b) = runJoin blobs in maybe (maybe [] showLanguage (blobLanguage b)) showLanguage (blobLanguage a) +diffBlobPair _ (Join (Blob { blobPath = path, blobLanguage = Nothing }, _)) = throwError (SomeException (NoLanguageForBlob path)) +diffBlobPair _ (Join (_, Blob { blobPath = path, blobLanguage = Nothing })) = throwError (SomeException (NoLanguageForBlob path)) + -- | A task to diff a pair of 'Term's, producing insertion/deletion 'Patch'es for non-existent 'Blob's. diffTermPair :: Functor syntax => Both Blob -> Differ syntax ann1 ann2 -> Term syntax ann1 -> Term syntax ann2 -> Task (Diff syntax ann1 ann2) diffTermPair blobs differ t1 t2 = case runJoin (blobExists <$> blobs) of From 4aa083332c4bea4eeaa0a40ab454a9fc6644c5af Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 21 Nov 2017 15:52:04 -0500 Subject: [PATCH 057/133] =?UTF-8?q?Migrate=20all=20the=20ToC=20specs=20to?= =?UTF-8?q?=20=C3=A0=20la=20carte=20syntax.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/TOCSpec.hs | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index 4ccc214ae..39bf2a82a 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -21,9 +21,13 @@ import Data.Semigroup ((<>)) import Data.Source import Data.Span import Data.Syntax.Algebra (constructorNameAndConstantFields) +import qualified Data.Syntax as Syntax +import qualified Data.Syntax.Declaration as Declaration import Data.Term import Data.Text (Text) +import Data.Text.Encoding (encodeUtf8) import Data.These +import Data.Union import Interpreter import Language import Prelude hiding (readFile) @@ -47,7 +51,7 @@ spec = parallel $ do \ diff -> tableOfContentsBy (const Nothing :: a -> Maybe ()) (diff :: Diff ListableSyntax () ()) `shouldBe` [] prop "produces no entries for identity diffs" $ - \ term -> tableOfContentsBy (Just . termAnnotation) (diffSyntaxTerms term (term :: Term ListableSyntax (Record '[Category]))) `shouldBe` [] + \ term -> tableOfContentsBy (Just . termAnnotation) (diffTerms term (term :: Term ListableSyntax (Record '[Range, Span]))) `shouldBe` [] prop "produces inserted/deleted/replaced entries for relevant nodes within patches" $ \ p -> tableOfContentsBy (Just . termAnnotation) (patch deleting inserting replacing p) @@ -55,7 +59,7 @@ spec = parallel $ do patch (fmap Deleted) (fmap Inserted) (const (fmap Replaced)) (bimap (foldMap pure) (foldMap pure) (p :: Patch (Term ListableSyntax Int) (Term ListableSyntax Int))) prop "produces changed entries for relevant nodes containing irrelevant patches" $ - \ diff -> let diff' = merge (0, 0) (Indexed [bimap (const 1) (const 1) (diff :: Diff ListableSyntax Int Int)]) in + \ diff -> let diff' = merge (0, 0) (inj [bimap (const 1) (const 1) (diff :: Diff ListableSyntax Int Int)]) in tableOfContentsBy (\ (n `In` _) -> if n == (0 :: Int) then Just n else Nothing) diff' `shouldBe` replicate (length (diffPatches diff')) (Changed 0) @@ -184,17 +188,17 @@ numTocSummaries diff = length $ filter isValidSummary (diffTOC diff) -- Return a diff where body is inserted in the expressions of a function. The function is present in both sides of the diff. programWithChange :: Term' -> Diff' -programWithChange body = merge (programInfo, programInfo) (Indexed [ function' ]) +programWithChange body = merge (programInfo, programInfo) (inj [ function' ]) where - function' = merge ((Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo)) (S.Function name' [] [ inserting body ]) - name' = let info = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (Leaf "foo") + function' = merge (Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo) (inj (Declaration.Function [] name' [] (merge (Nothing :. functionInfo, Nothing :. functionInfo) (inj [ inserting body ])))) + name' = let info = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (inj (Syntax.Identifier "foo")) -- Return a diff where term is inserted in the program, below a function found on both sides of the diff. programWithChangeOutsideFunction :: Term' -> Diff' -programWithChangeOutsideFunction term = merge (programInfo, programInfo) (Indexed [ function', term' ]) +programWithChangeOutsideFunction term = merge (programInfo, programInfo) (inj [ function', term' ]) where - function' = merge (Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo) (S.Function name' [] []) - name' = let info = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (Leaf "foo") + function' = merge (Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo) (inj (Declaration.Function [] name' [] (merge (Nothing :. functionInfo, Nothing :. functionInfo) (inj [])))) + name' = let info = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (inj (Syntax.Identifier "foo")) term' = inserting term programWithInsert :: Text -> Term' -> Diff' @@ -207,12 +211,12 @@ programWithReplace :: Text -> Term' -> Diff' programWithReplace name body = programOf $ replacing (functionOf name body) (functionOf (name <> "2") body) programOf :: Diff' -> Diff' -programOf diff = merge (programInfo, programInfo) (Indexed [ diff ]) +programOf diff = merge (programInfo, programInfo) (inj [ diff ]) functionOf :: Text -> Term' -> Term' -functionOf name body = Term $ (Just (FunctionDeclaration name mempty Nothing) :. functionInfo) `In` S.Function name' [] [body] +functionOf name body = termIn (Just (FunctionDeclaration name mempty Nothing) :. functionInfo) (inj (Declaration.Function [] name' [] (termIn (Nothing :. functionInfo) (inj [body])))) where - name' = Term $ (Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil) `In` Leaf name + name' = termIn (Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil) (inj (Syntax.Identifier (encodeUtf8 name))) programInfo :: Record '[Maybe Declaration, Range, Span] programInfo = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil @@ -221,21 +225,18 @@ functionInfo :: Record '[Range, Span] functionInfo = Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil -- Filter tiers for terms that we consider "meaniningful" in TOC summaries. -isMeaningfulTerm :: Term Syntax a -> Bool +isMeaningfulTerm :: Term ListableSyntax a -> Bool isMeaningfulTerm a - | (_:_) <- prj (termOut (unTerm a)) = False - | [] <- prj (termOut (unTerm a)) = False + | Just (_:_) <- prj (termOut (unTerm a)) = False + | Just [] <- prj (termOut (unTerm a)) = False | otherwise = True -- Filter tiers for terms if the Syntax is a Method or a Function. -isMethodOrFunction :: HasField fields Category => Term Syntax (Record fields) -> Bool -isMethodOrFunction a = case unTerm a of - (_ `In` S.Method{}) -> True - (_ `In` S.Function{}) -> True - (a `In` _) | getField a == C.Function -> True - (a `In` _) | getField a == C.Method -> True - (a `In` _) | getField a == C.SingletonMethod -> True - _ -> False +isMethodOrFunction :: Term ListableSyntax ann -> Bool +isMethodOrFunction a + | Just Declaration.Method{} <- prj (termOut (unTerm a)) = True + | Just Declaration.Function{} <- prj (termOut (unTerm a)) = True + | otherwise = False blobsForPaths :: Both FilePath -> IO (Both Blob) blobsForPaths = traverse (readFile . ("test/fixtures/toc/" <>)) @@ -244,7 +245,7 @@ sourceSpanBetween :: (Int, Int) -> (Int, Int) -> Span sourceSpanBetween (s1, e1) (s2, e2) = Span (Pos s1 e1) (Pos s2 e2) blankDiff :: Diff' -blankDiff = merge (arrayInfo, arrayInfo) (Indexed [ inserting (Term $ literalInfo `In` Leaf "\"a\"") ]) +blankDiff = merge (arrayInfo, arrayInfo) (inj [ inserting (termIn literalInfo (inj (Syntax.Identifier "\"a\""))) ]) where arrayInfo = Nothing :. Range 0 3 :. sourceSpanBetween (1, 1) (1, 5) :. Nil literalInfo = Nothing :. Range 1 2 :. sourceSpanBetween (1, 2) (1, 4) :. Nil From 4b07ad44ac60871aba54c6aae4dfe01d0b6bdd35 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 21 Nov 2017 15:56:34 -0500 Subject: [PATCH 058/133] temp --- test/AlignmentSpec.hs | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/test/AlignmentSpec.hs b/test/AlignmentSpec.hs index af2e42fd4..d075a201f 100644 --- a/test/AlignmentSpec.hs +++ b/test/AlignmentSpec.hs @@ -19,9 +19,11 @@ import Data.Record import Data.Semigroup ((<>)) import qualified Data.Source as Source import Data.SplitDiff +import qualified Data.Syntax as Syntax import Data.Term import qualified Data.Text as Text import Data.These +import Data.Union import Test.Hspec (Spec, describe, it, parallel) import Test.Hspec.Expectations.Pretty import Test.Hspec.LeanCheck @@ -63,13 +65,13 @@ spec = parallel $ do describe "alignDiff" $ do it "aligns identical branches on a single line" $ let sources = both (Source.fromText "[ foo ]") (Source.fromText "[ foo ]") in - align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources + align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo") ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ]) (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ])) ] it "aligns identical branches spanning multiple lines" $ let sources = both (Source.fromText "[\nfoo\n]") (Source.fromText "[\nfoo\n]") in - align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources + align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo") ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 2 `In` []) (wrap $ info 0 2 `In` [])) , Join (These (wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ]) @@ -80,7 +82,7 @@ spec = parallel $ do it "aligns reformatted branches" $ let sources = both (Source.fromText "[ foo ]") (Source.fromText "[\nfoo\n]") in - align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ]) `shouldBe` prettyDiff sources + align sources ((info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo") ]) `shouldBe` prettyDiff sources [ Join (That (wrap $ info 0 2 `In` [])) , Join (These (wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ]) (wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ])) @@ -89,7 +91,7 @@ spec = parallel $ do it "aligns nodes following reformatted branches" $ let sources = both (Source.fromText "[ foo ]\nbar\n") (Source.fromText "[\nfoo\n]\nbar\n") in - align sources ((info 0 12, info 0 12) `merge` [ (info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo" ], (info 8 11, info 8 11) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources + align sources ((info 0 12, info 0 12) `merge` [ (info 0 7, info 0 7) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo") ], (info 8 11, info 8 11) `merge` inj (Syntax.Identifier "bar") ]) `shouldBe` prettyDiff sources [ Join (That (wrap $ info 0 2 `In` [ wrap $ info 0 2 `In` [] ])) , Join (These (wrap $ info 0 8 `In` [ wrap $ info 0 7 `In` [ wrap $ info 2 5 `In` [] ] ]) (wrap $ info 2 6 `In` [ wrap $ info 2 6 `In` [ wrap $ info 2 5 `In` [] ] ])) @@ -102,12 +104,12 @@ spec = parallel $ do it "aligns identical branches with multiple children on the same line" $ let sources = pure (Source.fromText "[ foo, bar ]") in - align sources ((info 0 12, info 0 12) `merge` [ (info 2 5, info 2 5) `merge` Leaf "foo", (info 7 10, info 7 10) `merge` Leaf "bar" ]) `shouldBe` prettyDiff sources + align sources ((info 0 12, info 0 12) `merge` [ (info 2 5, info 2 5) `merge` inj (Syntax.Identifier "foo"), (info 7 10, info 7 10) `merge` inj (Syntax.Identifier "bar") ]) `shouldBe` prettyDiff sources [ Join (runBothWith These (pure (wrap $ info 0 12 `In` [ wrap $ info 2 5 `In` [], wrap $ info 7 10 `In` [] ])) ) ] it "aligns insertions" $ let sources = both (Source.fromText "a") (Source.fromText "a\nb") in - align sources ((info 0 1, info 0 3) `merge` [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources + align sources ((info 0 1, info 0 3) `merge` [ (info 0 1, info 0 1) `merge` inj (Syntax.Identifier "a"), inserting (termIn (info 2 3) inj (Syntax.Identifier "b")) ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 1 `In` [ wrap $ info 0 1 `In` [] ]) (wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ])) , Join (That (wrap $ info 2 3 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ])) @@ -115,19 +117,19 @@ spec = parallel $ do it "aligns total insertions" $ let sources = both (Source.fromText "") (Source.fromText "a") in - align sources (inserting (Term (info 0 1 `In` Leaf "a"))) `shouldBe` prettyDiff sources + align sources (inserting (Term (info 0 1 `In` Syntax.Identifier "a"))) `shouldBe` prettyDiff sources [ Join (That (pure (SplitInsert (Term (info 0 1 `In` []))))) ] it "aligns insertions into empty branches" $ let sources = both (Source.fromText "[ ]") (Source.fromText "[a]") in - align sources ((info 0 3, info 0 3) `merge` [ inserting (Term (info 1 2 `In` Leaf "a")) ]) `shouldBe` prettyDiff sources + align sources ((info 0 3, info 0 3) `merge` [ inserting (termIn (info 1 2) (inj (Syntax.Identifier "a"))) ]) `shouldBe` prettyDiff sources [ Join (That (wrap $ info 0 3 `In` [ pure (SplitInsert (Term (info 1 2 `In` []))) ])) , Join (This (wrap $ info 0 3 `In` [])) ] it "aligns symmetrically following insertions" $ let sources = both (Source.fromText "a\nc") (Source.fromText "a\nb\nc") in - align sources ((info 0 3, info 0 5) `merge` [ (info 0 1, info 0 1) `merge` Leaf "a", inserting (Term (info 2 3 `In` Leaf "b")), (info 2 3, info 4 5) `merge` Leaf "c" ]) + align sources ((info 0 3, info 0 5) `merge` [ (info 0 1, info 0 1) `merge` Syntax.Identifier "a", inserting (Term (info 2 3 `In` Syntax.Identifier "b")), (info 2 3, info 4 5) `merge` Syntax.Identifier "c" ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ]) (wrap $ info 0 2 `In` [ wrap $ info 0 1 `In` [] ])) @@ -138,13 +140,13 @@ spec = parallel $ do it "symmetrical nodes force the alignment of asymmetrical nodes on both sides" $ let sources = both (Source.fromText "[ a, b ]") (Source.fromText "[ b, c ]") in - align sources ((info 0 8, info 0 8) `merge` [ deleting (Term (info 2 3 `In` Leaf "a")), (info 5 6, info 2 3) `merge` Leaf "b", inserting (Term (info 5 6 `In` Leaf "c")) ]) `shouldBe` prettyDiff sources - [ Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))), wrap $ info 5 6 `In` [] ]) + align sources ((info 0 8, info 0 8) `merge` [ deleting (termIn (info 2 3) (inj (Syntax.Identifier "a"))), (info 5 6, info 2 3) `merge` inj (Syntax.Identifier "b"), inserting (Term (info 5 6 `In` Syntax.Identifier "c")) ]) `shouldBe` prettyDiff sources + [ Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (termIn (info 2 3) (inj []))), wrap $ info 5 6 `In` [] ]) (wrap $ info 0 8 `In` [ wrap $ info 2 3 `In` [], pure (SplitInsert (Term (info 5 6 `In` []))) ])) ] it "when one of two symmetrical nodes must be split, splits the latter" $ let sources = both (Source.fromText "[ a, b ]") (Source.fromText "[ a\n, b\n]") in - align sources ((info 0 8, info 0 9) `merge` [ (info 2 3, info 2 3) `merge` Leaf "a", (info 5 6, info 6 7) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources + align sources ((info 0 8, info 0 9) `merge` [ (info 2 3, info 2 3) `merge` inj (Syntax.Identifier "a"), (info 5 6, info 6 7) `merge` inj (Syntax.Identifier "b") ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 8 `In` [ wrap $ info 2 3 `In` [], wrap $ info 5 6 `In` [] ]) (wrap $ info 0 4 `In` [ wrap $ info 2 3 `In` [] ])) , Join (That (wrap $ info 4 8 `In` [ wrap $ info 6 7 `In` [] ])) @@ -153,14 +155,14 @@ spec = parallel $ do it "aligns deletions before insertions" $ let sources = both (Source.fromText "[ a ]") (Source.fromText "[ b ]") in - align sources ((info 0 5, info 0 5) `merge` [ deleting (Term (info 2 3 `In` Leaf "a")), inserting (Term (info 2 3 `In` Leaf "b")) ]) `shouldBe` prettyDiff sources + align sources ((info 0 5, info 0 5) `merge` [ deleting (termIn (info 2 3) (inj (Syntax.Identifier "a"))), inserting (termIn (info 2 3) (inj (Syntax.Identifier "b"))) ]) `shouldBe` prettyDiff sources [ Join (This (wrap $ info 0 5 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))) ])) , Join (That (wrap $ info 0 5 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ])) ] it "aligns context-only lines symmetrically" $ let sources = both (Source.fromText "[\n a\n,\n b\n]") (Source.fromText "[\n a, b\n\n\n]") in - align sources ((info 0 13, info 0 12) `merge` [ (info 4 5, info 4 5) `merge` Leaf "a", (info 10 11, info 7 8) `merge` Leaf "b" ]) `shouldBe` prettyDiff sources + align sources ((info 0 13, info 0 12) `merge` [ (info 4 5, info 4 5) `merge` inj (Syntax.Identifier "a"), (info 10 11, info 7 8) `merge` inj (Syntax.Identifier "b") ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 2 `In` []) (wrap $ info 0 2 `In` [])) , Join (These (wrap $ info 2 6 `In` [ wrap $ info 4 5 `In` [] ]) @@ -175,7 +177,7 @@ spec = parallel $ do it "aligns asymmetrical nodes preceding their symmetrical siblings conservatively" $ let sources = both (Source.fromText "[ b, c ]") (Source.fromText "[ a\n, c\n]") in - align sources ((info 0 8, info 0 9) `merge` [ inserting (Term (info 2 3 `In` Leaf "a")), deleting (Term (info 2 3 `In` Leaf "b")), (info 5 6, info 6 7) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources + align sources ((info 0 8, info 0 9) `merge` [ inserting (Term (info 2 3 `In` Syntax.Identifier "a")), deleting (Term (info 2 3 `In` Syntax.Identifier "b")), (info 5 6, info 6 7) `merge` Syntax.Identifier "c" ]) `shouldBe` prettyDiff sources [ Join (That (wrap $ info 0 4 `In` [ pure (SplitInsert (Term (info 2 3 `In` []))) ])) , Join (These (wrap $ info 0 8 `In` [ pure (SplitDelete (Term (info 2 3 `In` []))), wrap $ info 5 6 `In` [] ]) (wrap $ info 4 8 `In` [ wrap $ info 6 7 `In` [] ])) @@ -184,7 +186,7 @@ spec = parallel $ do it "aligns symmetrical reformatted nodes" $ let sources = both (Source.fromText "a [ b ]\nc") (Source.fromText "a [\nb\n]\nc") in - align sources ((info 0 9, info 0 9) `merge` [ (info 0 1, info 0 1) `merge` Leaf "a", (info 2 7, info 2 7) `merge` [ (info 4 5, info 4 5) `merge` Leaf "b" ], (info 8 9, info 8 9) `merge` Leaf "c" ]) `shouldBe` prettyDiff sources + align sources ((info 0 9, info 0 9) `merge` [ (info 0 1, info 0 1) `merge` Syntax.Identifier "a", (info 2 7, info 2 7) `merge` [ (info 4 5, info 4 5) `merge` Syntax.Identifier "b" ], (info 8 9, info 8 9) `merge` Syntax.Identifier "c" ]) `shouldBe` prettyDiff sources [ Join (These (wrap $ info 0 8 `In` [ wrap $ info 0 1 `In` [], wrap $ info 2 7 `In` [ wrap $ info 4 5 `In` [] ] ]) (wrap $ info 0 4 `In` [ wrap $ info 0 1 `In` [], wrap $ info 2 4 `In` [] ])) , Join (That (wrap $ info 4 6 `In` [ wrap $ info 4 6 `In` [ wrap $ info 4 5 `In` [] ] ])) @@ -257,7 +259,7 @@ instance Listable BranchElement where counts :: [Join These (Int, a)] -> Both Int counts numbered = fromMaybe 0 . getLast . mconcat . fmap Last <$> Join (unalign (runJoin . fmap fst <$> numbered)) -align :: Both Source.Source -> Diff Syntax (Record '[Range]) (Record '[Range]) -> PrettyDiff (SplitDiff [] (Record '[Range])) +align :: Both Source.Source -> Diff ListableSyntax (Record '[Range]) (Record '[Range]) -> PrettyDiff (SplitDiff [] (Record '[Range])) align sources = PrettyDiff sources . fmap (fmap (getRange &&& id)) . alignDiff sources info :: Int -> Int -> Record '[Range] From 2ae0aeff169b584801dc0e15ad114e2af54ac266 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 21 Nov 2017 17:35:12 -0500 Subject: [PATCH 059/133] :fire: sourceSpanBetween. --- test/TOCSpec.hs | 51 +++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index 39bf2a82a..db296178b 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -71,49 +71,49 @@ spec = parallel $ do sourceBlobs <- blobsForPaths (both "ruby/methods.A.rb" "ruby/methods.B.rb") diff <- runTask $ diffWithParser rubyParser sourceBlobs diffTOC diff `shouldBe` - [ TOCSummary "Method" "self.foo" (sourceSpanBetween (1, 1) (2, 4)) "added" - , TOCSummary "Method" "bar" (sourceSpanBetween (4, 1) (6, 4)) "modified" - , TOCSummary "Method" "baz" (sourceSpanBetween (4, 1) (5, 4)) "removed" + [ TOCSummary "Method" "self.foo" (Span (Pos 1 1) (Pos 2 4)) "added" + , TOCSummary "Method" "bar" (Span (Pos 4 1) (Pos 6 4)) "modified" + , TOCSummary "Method" "baz" (Span (Pos 4 1) (Pos 5 4)) "removed" ] it "summarizes changed classes" $ do sourceBlobs <- blobsForPaths (both "ruby/classes.A.rb" "ruby/classes.B.rb") diff <- runTask $ diffWithParser rubyParser sourceBlobs diffTOC diff `shouldBe` - [ TOCSummary "Class" "Baz" (sourceSpanBetween (1, 1) (2, 4)) "removed" - , TOCSummary "Class" "Foo" (sourceSpanBetween (1, 1) (3, 4)) "modified" - , TOCSummary "Class" "Bar" (sourceSpanBetween (5, 1) (6, 4)) "added" + [ TOCSummary "Class" "Baz" (Span (Pos 1 1) (Pos 2 4)) "removed" + , TOCSummary "Class" "Foo" (Span (Pos 1 1) (Pos 3 4)) "modified" + , TOCSummary "Class" "Bar" (Span (Pos 5 1) (Pos 6 4)) "added" ] it "dedupes changes in same parent method" $ do sourceBlobs <- blobsForPaths (both "javascript/duplicate-parent.A.js" "javascript/duplicate-parent.B.js") diff <- runTask $ diffWithParser typescriptParser sourceBlobs diffTOC diff `shouldBe` - [ TOCSummary "Function" "myFunction" (sourceSpanBetween (1, 1) (6, 2)) "modified" ] + [ TOCSummary "Function" "myFunction" (Span (Pos 1 1) (Pos 6 2)) "modified" ] it "dedupes similar methods" $ do sourceBlobs <- blobsForPaths (both "javascript/erroneous-duplicate-method.A.js" "javascript/erroneous-duplicate-method.B.js") diff <- runTask $ diffWithParser typescriptParser sourceBlobs diffTOC diff `shouldBe` - [ TOCSummary "Function" "performHealthCheck" (sourceSpanBetween (8, 1) (29, 2)) "modified" ] + [ TOCSummary "Function" "performHealthCheck" (Span (Pos 8 1) (Pos 29 2)) "modified" ] it "summarizes Go methods with receivers with special formatting" $ do sourceBlobs <- blobsForPaths (both "go/method-with-receiver.A.go" "go/method-with-receiver.B.go") diff <- runTask $ diffWithParser goParser sourceBlobs diffTOC diff `shouldBe` - [ TOCSummary "Method" "(*apiClient) CheckAuth" (sourceSpanBetween (3,1) (3,101)) "added" ] + [ TOCSummary "Method" "(*apiClient) CheckAuth" (Span (Pos 3 1) (Pos 3 101)) "added" ] it "summarizes Ruby methods that start with two identifiers" $ do sourceBlobs <- blobsForPaths (both "ruby/method-starts-with-two-identifiers.A.rb" "ruby/method-starts-with-two-identifiers.B.rb") diff <- runTask $ diffWithParser rubyParser sourceBlobs diffTOC diff `shouldBe` - [ TOCSummary "Method" "foo" (sourceSpanBetween (1, 1) (4, 4)) "modified" ] + [ TOCSummary "Method" "foo" (Span (Pos 1 1) (Pos 4 4)) "modified" ] it "handles unicode characters in file" $ do sourceBlobs <- blobsForPaths (both "ruby/unicode.A.rb" "ruby/unicode.B.rb") diff <- runTask $ diffWithParser rubyParser sourceBlobs diffTOC diff `shouldBe` - [ TOCSummary "Method" "foo" (sourceSpanBetween (6, 1) (7, 4)) "added" ] + [ TOCSummary "Method" "foo" (Span (Pos 6 1) (Pos 7 4)) "added" ] it "properly slices source blob that starts with a newline and has multi-byte chars" $ do sourceBlobs <- blobsForPaths (both "javascript/starts-with-newline.js" "javascript/starts-with-newline.js") @@ -151,11 +151,11 @@ spec = parallel $ do describe "TOCSummary" $ do it "encodes modified summaries to JSON" $ do - let summary = TOCSummary "Method" "foo" (sourceSpanBetween (1, 1) (4, 4)) "modified" + let summary = TOCSummary "Method" "foo" (Span (Pos 1 1) (Pos 4 4)) "modified" encode summary `shouldBe` "{\"span\":{\"start\":[1,1],\"end\":[4,4]},\"category\":\"Method\",\"term\":\"foo\",\"changeType\":\"modified\"}" it "encodes added summaries to JSON" $ do - let summary = TOCSummary "Method" "self.foo" (sourceSpanBetween (1, 1) (2, 4)) "added" + let summary = TOCSummary "Method" "self.foo" (Span (Pos 1 1) (Pos 2 4)) "added" encode summary `shouldBe` "{\"span\":{\"start\":[1,1],\"end\":[2,4]},\"category\":\"Method\",\"term\":\"self.foo\",\"changeType\":\"added\"}" describe "diff with ToCDiffRenderer'" $ do @@ -190,15 +190,15 @@ numTocSummaries diff = length $ filter isValidSummary (diffTOC diff) programWithChange :: Term' -> Diff' programWithChange body = merge (programInfo, programInfo) (inj [ function' ]) where - function' = merge (Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo) (inj (Declaration.Function [] name' [] (merge (Nothing :. functionInfo, Nothing :. functionInfo) (inj [ inserting body ])))) - name' = let info = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (inj (Syntax.Identifier "foo")) + function' = merge (Just (FunctionDeclaration "foo" mempty Nothing) :. emptyInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. emptyInfo) (inj (Declaration.Function [] name' [] (merge (Nothing :. emptyInfo, Nothing :. emptyInfo) (inj [ inserting body ])))) + name' = let info = Nothing :. emptyInfo in merge (info, info) (inj (Syntax.Identifier "foo")) -- Return a diff where term is inserted in the program, below a function found on both sides of the diff. programWithChangeOutsideFunction :: Term' -> Diff' programWithChangeOutsideFunction term = merge (programInfo, programInfo) (inj [ function', term' ]) where - function' = merge (Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. functionInfo) (inj (Declaration.Function [] name' [] (merge (Nothing :. functionInfo, Nothing :. functionInfo) (inj [])))) - name' = let info = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil in merge (info, info) (inj (Syntax.Identifier "foo")) + function' = merge (Just (FunctionDeclaration "foo" mempty Nothing) :. emptyInfo, Just (FunctionDeclaration "foo" mempty Nothing) :. emptyInfo) (inj (Declaration.Function [] name' [] (merge (Nothing :. emptyInfo, Nothing :. emptyInfo) (inj [])))) + name' = let info = Nothing :. emptyInfo in merge (info, info) (inj (Syntax.Identifier "foo")) term' = inserting term programWithInsert :: Text -> Term' -> Diff' @@ -214,15 +214,15 @@ programOf :: Diff' -> Diff' programOf diff = merge (programInfo, programInfo) (inj [ diff ]) functionOf :: Text -> Term' -> Term' -functionOf name body = termIn (Just (FunctionDeclaration name mempty Nothing) :. functionInfo) (inj (Declaration.Function [] name' [] (termIn (Nothing :. functionInfo) (inj [body])))) +functionOf name body = termIn (Just (FunctionDeclaration name mempty Nothing) :. emptyInfo) (inj (Declaration.Function [] name' [] (termIn (Nothing :. emptyInfo) (inj [body])))) where - name' = termIn (Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil) (inj (Syntax.Identifier (encodeUtf8 name))) + name' = termIn (Nothing :. emptyInfo) (inj (Syntax.Identifier (encodeUtf8 name))) programInfo :: Record '[Maybe Declaration, Range, Span] -programInfo = Nothing :. Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil +programInfo = Nothing :. emptyInfo -functionInfo :: Record '[Range, Span] -functionInfo = Range 0 0 :. sourceSpanBetween (0,0) (0,0) :. Nil +emptyInfo :: Record '[Range, Span] +emptyInfo = Range 0 0 :. Span (Pos 0 0) (Pos 0 0) :. Nil -- Filter tiers for terms that we consider "meaniningful" in TOC summaries. isMeaningfulTerm :: Term ListableSyntax a -> Bool @@ -241,14 +241,11 @@ isMethodOrFunction a blobsForPaths :: Both FilePath -> IO (Both Blob) blobsForPaths = traverse (readFile . ("test/fixtures/toc/" <>)) -sourceSpanBetween :: (Int, Int) -> (Int, Int) -> Span -sourceSpanBetween (s1, e1) (s2, e2) = Span (Pos s1 e1) (Pos s2 e2) - blankDiff :: Diff' blankDiff = merge (arrayInfo, arrayInfo) (inj [ inserting (termIn literalInfo (inj (Syntax.Identifier "\"a\""))) ]) where - arrayInfo = Nothing :. Range 0 3 :. sourceSpanBetween (1, 1) (1, 5) :. Nil - literalInfo = Nothing :. Range 1 2 :. sourceSpanBetween (1, 2) (1, 4) :. Nil + arrayInfo = Nothing :. Range 0 3 :. Span (Pos 1 1) (Pos 1 5) :. Nil + literalInfo = Nothing :. Range 1 2 :. Span (Pos 1 2) (Pos 1 4) :. Nil blankDiffBlobs :: Both Blob blankDiffBlobs = both (Blob (fromText "[]") nullOid "a.js" (Just defaultPlainBlob) (Just TypeScript)) (Blob (fromText "[a]") nullOid "b.js" (Just defaultPlainBlob) (Just TypeScript)) From 3a335aadafe7f9c4b83f4d0d88e7ae544bef7072 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 22 Nov 2017 09:28:42 -0500 Subject: [PATCH 060/133] Align some things. --- test/TOCSpec.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index 073101798..c2e5dd00c 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -229,14 +229,14 @@ isMeaningfulTerm :: Term ListableSyntax a -> Bool isMeaningfulTerm a | Just (_:_) <- prj (termOut (unTerm a)) = False | Just [] <- prj (termOut (unTerm a)) = False - | otherwise = True + | otherwise = True -- Filter tiers for terms if the Syntax is a Method or a Function. isMethodOrFunction :: Term ListableSyntax ann -> Bool isMethodOrFunction a | Just Declaration.Method{} <- prj (termOut (unTerm a)) = True | Just Declaration.Function{} <- prj (termOut (unTerm a)) = True - | otherwise = False + | otherwise = False blobsForPaths :: Both FilePath -> IO (Both Blob) blobsForPaths = traverse (readFile . ("test/fixtures/toc/" <>)) From c42eb83dbd56e4f90beb8a6e770413617941dcab Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 22 Nov 2017 10:11:07 -0500 Subject: [PATCH 061/133] :fire: a redundant import. --- test/TOCSpec.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index c2e5dd00c..3506205f5 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -10,7 +10,6 @@ import Data.Diff import Data.Functor.Both import Data.Functor.Foldable (cata) import Data.Functor.Listable -import Data.Functor.Foldable (cata) import Data.Maybe (fromMaybe) import Data.Monoid (Last(..)) import Data.Output From 4cb96cd6ea04f4011075000f35b1146ba6686af3 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 22 Nov 2017 10:13:33 -0500 Subject: [PATCH 062/133] Filter out anything with a declaration. --- test/TOCSpec.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index 3506205f5..239ec58e8 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -10,7 +10,7 @@ import Data.Diff import Data.Functor.Both import Data.Functor.Foldable (cata) import Data.Functor.Listable -import Data.Maybe (fromMaybe) +import Data.Maybe (fromMaybe, isJust) import Data.Monoid (Last(..)) import Data.Output import Data.Patch @@ -231,10 +231,11 @@ isMeaningfulTerm a | otherwise = True -- Filter tiers for terms if the Syntax is a Method or a Function. -isMethodOrFunction :: Term ListableSyntax ann -> Bool +isMethodOrFunction :: Term' -> Bool isMethodOrFunction a | Just Declaration.Method{} <- prj (termOut (unTerm a)) = True | Just Declaration.Function{} <- prj (termOut (unTerm a)) = True + | any isJust (foldMap ((:[]) . rhead) a) = True | otherwise = False blobsForPaths :: Both FilePath -> IO (Both Blob) From 738ca371bdba42dc26bc5b02cacfae7471f7c010 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 22 Nov 2017 10:17:32 -0500 Subject: [PATCH 063/133] Filter methods & functions out. --- test/TOCSpec.hs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index 239ec58e8..9d592ffbb 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -119,22 +119,22 @@ spec = parallel $ do diff <- runTask $ diffWithParser rubyParser sourceBlobs diffTOC diff `shouldBe` [] - prop "inserts of methods and functions are summarized" $ - \name body -> + prop "inserts of methods and functions are summarized" . forAll ((not . isMethodOrFunction . Prelude.snd) `filterT` tiers) $ + \(name, body) -> let diff = programWithInsert name body in numTocSummaries diff `shouldBe` 1 - prop "deletes of methods and functions are summarized" $ - \name body -> + prop "deletes of methods and functions are summarized" . forAll ((not . isMethodOrFunction . Prelude.snd) `filterT` tiers) $ + \(name, body) -> let diff = programWithDelete name body in numTocSummaries diff `shouldBe` 1 - prop "replacements of methods and functions are summarized" $ - \name body -> + prop "replacements of methods and functions are summarized" . forAll ((not . isMethodOrFunction . Prelude.snd) `filterT` tiers) $ + \(name, body) -> let diff = programWithReplace name body in numTocSummaries diff `shouldBe` 1 - prop "changes inside methods and functions are summarizied" . forAll (isMeaningfulTerm `filterT` tiers) $ + prop "changes inside methods and functions are summarizied" . forAll (((&&) <$> not . isMethodOrFunction <*> isMeaningfulTerm) `filterT` tiers) $ \body -> let diff = programWithChange body in numTocSummaries diff `shouldBe` 1 From cda112823abc02a73724801ca40710b896a3135c Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 22 Nov 2017 10:19:12 -0500 Subject: [PATCH 064/133] Tidy up the unchanged diffs spec. --- test/TOCSpec.hs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index 9d592ffbb..fb0737a01 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -32,7 +32,6 @@ import Language import Prelude hiding (readFile) import Renderer import Renderer.TOC -import RWS import Semantic import Semantic.Task import Semantic.Util @@ -144,9 +143,8 @@ spec = parallel $ do let diff = programWithChangeOutsideFunction body in numTocSummaries diff `shouldBe` 0 - prop "equal terms produce identity diffs" $ - \a -> let term = defaultFeatureVectorDecorator constructorNameAndConstantFields (a :: Term') in - diffTOC (diffTerms term term) `shouldBe` [] + prop "unchanged diffs aren’t summarized" $ + \term -> diffTOC (diffTerms term (term :: Term')) `shouldBe` [] describe "TOCSummary" $ do it "encodes modified summaries to JSON" $ do From a1a1cf6b07a49441a7b6b7a9c03f1457628d5cb2 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 22 Nov 2017 10:35:05 -0500 Subject: [PATCH 065/133] Define a replaceF constructor for diffs. --- src/Data/Diff.hs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Data/Diff.hs b/src/Data/Diff.hs index 7cd689917..76cb674aa 100644 --- a/src/Data/Diff.hs +++ b/src/Data/Diff.hs @@ -3,6 +3,7 @@ module Data.Diff ( Diff(..) , DiffF(..) , replacing +, replaceF , inserting , insertF , deleting @@ -44,7 +45,11 @@ data DiffF syntax ann1 ann2 recur -- | Constructs a 'Diff' replacing one 'Term' with another recursively. replacing :: Functor syntax => Term syntax ann1 -> Term syntax ann2 -> Diff syntax ann1 ann2 -replacing (Term (In a1 r1)) (Term (In a2 r2)) = Diff (Patch (Replace (In a1 (deleting <$> r1)) (In a2 (inserting <$> r2)))) +replacing (Term (In a1 r1)) (Term (In a2 r2)) = replaceF (In a1 (deleting <$> r1)) (In a2 (inserting <$> r2)) + +-- | Constructs a 'Diff' replacing one 'TermF' populated by further 'Diff's with another. +replaceF :: TermF syntax ann1 (Diff syntax ann1 ann2) -> TermF syntax ann2 (Diff syntax ann1 ann2) -> Diff syntax ann1 ann2 +replaceF t1 t2 = Diff (Patch (Replace t1 t2)) -- | Constructs a 'Diff' inserting a 'Term' recursively. inserting :: Functor syntax => Term syntax ann2 -> Diff syntax ann1 ann2 From 863b07b0876146d57f1bc6b754ee17c919ba9054 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 22 Nov 2017 12:36:34 -0500 Subject: [PATCH 066/133] Correct the patch entries test. --- test/TOCSpec.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/TOCSpec.hs b/test/TOCSpec.hs index fb0737a01..9d9871bb5 100644 --- a/test/TOCSpec.hs +++ b/test/TOCSpec.hs @@ -54,7 +54,7 @@ spec = parallel $ do prop "produces inserted/deleted/replaced entries for relevant nodes within patches" $ \ p -> tableOfContentsBy (Just . termAnnotation) (patch deleting inserting replacing p) `shouldBe` - patch (fmap Deleted) (fmap Inserted) (const (fmap Replaced)) (bimap (foldMap pure) (foldMap pure) (p :: Patch (Term ListableSyntax Int) (Term ListableSyntax Int))) + patch (fmap Deleted) (fmap Inserted) (\ as bs -> Replaced (head bs) : fmap Deleted (tail as) <> fmap Inserted (tail bs)) (bimap (foldMap pure) (foldMap pure) (p :: Patch (Term ListableSyntax Int) (Term ListableSyntax Int))) prop "produces changed entries for relevant nodes containing irrelevant patches" $ \ diff -> let diff' = merge (0, 0) (inj [bimap (const 1) (const 1) (diff :: Diff ListableSyntax Int Int)]) in From d880f229648a4ade9d446cec87bcad3ffaa65e57 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 08:49:06 -0700 Subject: [PATCH 067/133] Stub in a module for a DOT renderer. --- semantic-diff.cabal | 1 + src/Rendering/DOT.hs | 1 + 2 files changed, 2 insertions(+) create mode 100644 src/Rendering/DOT.hs diff --git a/semantic-diff.cabal b/semantic-diff.cabal index ec057552a..bda156924 100644 --- a/semantic-diff.cabal +++ b/semantic-diff.cabal @@ -82,6 +82,7 @@ library , Parsing.TreeSitter , Paths_semantic_diff -- Rendering formats + , Rendering.DOT , Rendering.JSON , Rendering.Renderer , Rendering.SExpression diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs new file mode 100644 index 000000000..99ea94260 --- /dev/null +++ b/src/Rendering/DOT.hs @@ -0,0 +1 @@ +module Rendering.DOT where From 4ef26933dc6929949e84f235192ee7be1ca06e49 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 08:58:06 -0700 Subject: [PATCH 068/133] Stub in functions to render to DOT. --- src/Rendering/DOT.hs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 99ea94260..8938daf53 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -1 +1,11 @@ module Rendering.DOT where + +import qualified Data.ByteString as B +import Data.Diff +import Data.Term + +renderDOTDiff :: Diff syntax ann1 ann2 -> B.ByteString +renderDOTDiff _ = "" + +renderDOTTerm :: Term syntax ann -> B.ByteString +renderDOTTerm _ = "" From 82fc60d52485c3059b277372e7ab420ab2336919 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:00:55 -0700 Subject: [PATCH 069/133] Re-export the DOT rendering functions. --- src/Rendering/Renderer.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Rendering/Renderer.hs b/src/Rendering/Renderer.hs index 3a8784148..4cd35cf93 100644 --- a/src/Rendering/Renderer.hs +++ b/src/Rendering/Renderer.hs @@ -10,6 +10,8 @@ module Rendering.Renderer , renderToCDiff , renderToCTerm , renderToTags +, renderDOTDiff +, renderDOTTerm , Summaries(..) ) where @@ -18,6 +20,7 @@ import Data.ByteString (ByteString) import qualified Data.Map as Map import Data.Output import Data.Text (Text) +import Rendering.DOT as R import Rendering.JSON as R import Rendering.SExpression as R import Rendering.Tag as R From 887ea76454afd7f6be39c953a1295f16a9af99f2 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:01:32 -0700 Subject: [PATCH 070/133] Add DOT term/diff renderers. --- src/Rendering/Renderer.hs | 4 ++++ src/Semantic.hs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Rendering/Renderer.hs b/src/Rendering/Renderer.hs index 4cd35cf93..741b93aef 100644 --- a/src/Rendering/Renderer.hs +++ b/src/Rendering/Renderer.hs @@ -36,6 +36,8 @@ data DiffRenderer output where JSONDiffRenderer :: DiffRenderer (Map.Map Text Value) -- | Render to a 'ByteString' formatted as nested s-expressions with patches indicated. SExpressionDiffRenderer :: DiffRenderer ByteString + -- | Render to a 'ByteString' formatted as a DOT description of the diff. + DOTDiffRenderer :: DiffRenderer ByteString deriving instance Eq (DiffRenderer output) deriving instance Show (DiffRenderer output) @@ -50,6 +52,8 @@ data TermRenderer output where SExpressionTermRenderer :: TermRenderer ByteString -- | Render to a list of tags. TagsTermRenderer :: TermRenderer [Value] + -- | Render to a 'ByteString' formatted as a DOT description of the term. + DOTTermRenderer :: TermRenderer ByteString deriving instance Eq (TermRenderer output) deriving instance Show (TermRenderer output) diff --git a/src/Semantic.hs b/src/Semantic.hs index 74116b213..b296f8972 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -55,6 +55,7 @@ parseBlob renderer blob@Blob{..} JSONTermRenderer -> decorate constructorLabel >=> render (renderJSONTerm blob) SExpressionTermRenderer -> decorate constructorLabel . (Nil <$) >=> render renderSExpressionTerm TagsTermRenderer -> decorate (declarationAlgebra blob) >=> render (renderToTags blob) + DOTTermRenderer -> render renderDOTTerm | Just parser <- blobLanguage >>= syntaxParserForLanguage = parse parser blob >>= case renderer of @@ -62,6 +63,7 @@ parseBlob renderer blob@Blob{..} JSONTermRenderer -> decorate syntaxIdentifierAlgebra >=> render (renderJSONTerm blob) SExpressionTermRenderer -> render renderSExpressionTerm . fmap keepCategory TagsTermRenderer -> decorate (syntaxDeclarationAlgebra blob) >=> render (renderToTags blob) + DOTTermRenderer -> render renderDOTTerm | otherwise = throwError (SomeException (NoParserForLanguage blobPath blobLanguage)) @@ -81,6 +83,7 @@ diffBlobPair renderer blobs ToCDiffRenderer -> run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) diffTerms renderToCDiff JSONDiffRenderer -> run ( parse parser) diffTerms renderJSONDiff SExpressionDiffRenderer -> run ( parse parser >=> decorate constructorLabel . (Nil <$)) diffTerms (const renderSExpressionDiff) + DOTDiffRenderer -> run ( parse parser) diffTerms (const renderDOTDiff) | Just parser <- effectiveLanguage >>= syntaxParserForLanguage = case renderer of @@ -88,6 +91,7 @@ diffBlobPair renderer blobs ToCDiffRenderer -> run (\ blob -> parse parser blob >>= decorate (syntaxDeclarationAlgebra blob)) diffSyntaxTerms renderToCDiff JSONDiffRenderer -> run ( parse parser >=> decorate syntaxIdentifierAlgebra) diffSyntaxTerms renderJSONDiff SExpressionDiffRenderer -> run ( parse parser >=> pure . fmap keepCategory) diffSyntaxTerms (const renderSExpressionDiff) + DOTDiffRenderer -> run ( parse parser) diffSyntaxTerms (const renderDOTDiff) | otherwise = throwError (SomeException (NoParserForLanguage effectivePath effectiveLanguage)) where (effectivePath, effectiveLanguage) = case runJoin blobs of From 7fe9c3b2ea553cb5963e03de2fc308a06770cc0f Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:01:48 -0700 Subject: [PATCH 071/133] Add CLI options for DOT rendering. --- src/Semantic/CLI.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Semantic/CLI.hs b/src/Semantic/CLI.hs index c70e6d25e..cedfbb76b 100644 --- a/src/Semantic/CLI.hs +++ b/src/Semantic/CLI.hs @@ -65,7 +65,8 @@ arguments = info (version <*> helper <*> ((,) <$> optionsParser <*> argumentsPar <$> ( flag (SomeRenderer SExpressionDiffRenderer) (SomeRenderer SExpressionDiffRenderer) (long "sexpression" <> help "Output s-expression diff tree") <|> flag' (SomeRenderer JSONDiffRenderer) (long "json" <> help "Output JSON diff trees") <|> flag' (SomeRenderer OldToCDiffRenderer) (long "toc" <> help "Output JSON table of contents diff summary") - <|> flag' (SomeRenderer ToCDiffRenderer) (long "toc-assignment" <> help "Output JSON table of contents diff summary using the assignment parser") ) + <|> flag' (SomeRenderer ToCDiffRenderer) (long "toc-assignment" <> help "Output JSON table of contents diff summary using the assignment parser") + <|> flag' (SomeRenderer DOTDiffRenderer) (long "dot" <> help "Output the diff as a DOT graph")) <*> ( Right <$> some (both <$> argument filePathReader (metavar "FILE_A") <*> argument filePathReader (metavar "FILE_B")) @@ -76,7 +77,8 @@ arguments = info (version <*> helper <*> ((,) <$> optionsParser <*> argumentsPar <$> ( flag (SomeRenderer SExpressionTermRenderer) (SomeRenderer SExpressionTermRenderer) (long "sexpression" <> help "Output s-expression parse trees (default)") <|> flag' (SomeRenderer JSONTermRenderer) (long "json" <> help "Output JSON parse trees") <|> flag' (SomeRenderer ToCTermRenderer) (long "toc" <> help "Output JSON table of contents summary") - <|> flag' (SomeRenderer TagsTermRenderer) (long "tags" <> help "Output JSON tags/symbols")) + <|> flag' (SomeRenderer TagsTermRenderer) (long "tags" <> help "Output JSON tags/symbols") + <|> flag' (SomeRenderer DOTTermRenderer) (long "dot" <> help "Output the term as a DOT graph")) <*> ( Right <$> some (argument filePathReader (metavar "FILES...")) <|> pure (Left stdin) ) From 9995d527d505d4d9e5a2c545bb8e46694acd9f00 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:03:10 -0700 Subject: [PATCH 072/133] Pass the blobs to the DOT renderers. --- src/Rendering/DOT.hs | 10 ++++++---- src/Semantic.hs | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 8938daf53..9b86b8c26 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -1,11 +1,13 @@ module Rendering.DOT where +import Data.Blob import qualified Data.ByteString as B import Data.Diff +import Data.Functor.Both import Data.Term -renderDOTDiff :: Diff syntax ann1 ann2 -> B.ByteString -renderDOTDiff _ = "" +renderDOTDiff :: Both Blob -> Diff syntax ann1 ann2 -> B.ByteString +renderDOTDiff _ _ = "" -renderDOTTerm :: Term syntax ann -> B.ByteString -renderDOTTerm _ = "" +renderDOTTerm :: Blob -> Term syntax ann -> B.ByteString +renderDOTTerm _ _ = "" diff --git a/src/Semantic.hs b/src/Semantic.hs index b296f8972..17fc61483 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -55,7 +55,7 @@ parseBlob renderer blob@Blob{..} JSONTermRenderer -> decorate constructorLabel >=> render (renderJSONTerm blob) SExpressionTermRenderer -> decorate constructorLabel . (Nil <$) >=> render renderSExpressionTerm TagsTermRenderer -> decorate (declarationAlgebra blob) >=> render (renderToTags blob) - DOTTermRenderer -> render renderDOTTerm + DOTTermRenderer -> render (renderDOTTerm blob) | Just parser <- blobLanguage >>= syntaxParserForLanguage = parse parser blob >>= case renderer of @@ -63,7 +63,7 @@ parseBlob renderer blob@Blob{..} JSONTermRenderer -> decorate syntaxIdentifierAlgebra >=> render (renderJSONTerm blob) SExpressionTermRenderer -> render renderSExpressionTerm . fmap keepCategory TagsTermRenderer -> decorate (syntaxDeclarationAlgebra blob) >=> render (renderToTags blob) - DOTTermRenderer -> render renderDOTTerm + DOTTermRenderer -> render (renderDOTTerm blob) | otherwise = throwError (SomeException (NoParserForLanguage blobPath blobLanguage)) @@ -83,7 +83,7 @@ diffBlobPair renderer blobs ToCDiffRenderer -> run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) diffTerms renderToCDiff JSONDiffRenderer -> run ( parse parser) diffTerms renderJSONDiff SExpressionDiffRenderer -> run ( parse parser >=> decorate constructorLabel . (Nil <$)) diffTerms (const renderSExpressionDiff) - DOTDiffRenderer -> run ( parse parser) diffTerms (const renderDOTDiff) + DOTDiffRenderer -> run ( parse parser) diffTerms renderDOTDiff | Just parser <- effectiveLanguage >>= syntaxParserForLanguage = case renderer of @@ -91,7 +91,7 @@ diffBlobPair renderer blobs ToCDiffRenderer -> run (\ blob -> parse parser blob >>= decorate (syntaxDeclarationAlgebra blob)) diffSyntaxTerms renderToCDiff JSONDiffRenderer -> run ( parse parser >=> decorate syntaxIdentifierAlgebra) diffSyntaxTerms renderJSONDiff SExpressionDiffRenderer -> run ( parse parser >=> pure . fmap keepCategory) diffSyntaxTerms (const renderSExpressionDiff) - DOTDiffRenderer -> run ( parse parser) diffSyntaxTerms (const renderDOTDiff) + DOTDiffRenderer -> run ( parse parser) diffSyntaxTerms renderDOTDiff | otherwise = throwError (SomeException (NoParserForLanguage effectivePath effectiveLanguage)) where (effectivePath, effectiveLanguage) = case runJoin blobs of From 30fce0aaf10bf9df7ba9536422eeb9773cbd7e76 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:14:52 -0700 Subject: [PATCH 073/133] Add an eliminator for ConstructorLabel. --- src/Analysis/ConstructorName.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Analysis/ConstructorName.hs b/src/Analysis/ConstructorName.hs index 07c936b71..a607cbf70 100644 --- a/src/Analysis/ConstructorName.hs +++ b/src/Analysis/ConstructorName.hs @@ -19,7 +19,7 @@ constructorLabel :: ConstructorName syntax => TermF syntax a b -> ConstructorLab constructorLabel (In _ s) = ConstructorLabel $ pack (constructorName s) -newtype ConstructorLabel = ConstructorLabel ByteString +newtype ConstructorLabel = ConstructorLabel { unConstructorLabel :: ByteString } instance Show ConstructorLabel where showsPrec _ (ConstructorLabel s) = showString (unpack s) From 55308e6fc609d8892f35369704a8b1466060e402 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:29:04 -0700 Subject: [PATCH 074/133] Define Graph, Node, & Edge datatypes. --- src/Rendering/DOT.hs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 9b86b8c26..726b57d91 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -11,3 +11,12 @@ renderDOTDiff _ _ = "" renderDOTTerm :: Blob -> Term syntax ann -> B.ByteString renderDOTTerm _ _ = "" + +data Graph = Graph { graphName :: Maybe B.ByteString, graphNodes :: [Node], graphEdges :: [Edge] } + deriving (Eq, Ord, Show) + +data Node = Node { nodeID :: Int, nodeLabel :: B.ByteString } + deriving (Eq, Ord, Show) + +data Edge = Edge { edgeFrom :: Int, edgeTo :: Int } + deriving (Eq, Ord, Show) From d1dd288ec73fde18f432076c114ad2f5fa34203a Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:29:27 -0700 Subject: [PATCH 075/133] Define a Semigroup instance for Graph. --- src/Rendering/DOT.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 726b57d91..1bdc71784 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -1,9 +1,11 @@ module Rendering.DOT where +import Control.Applicative import Data.Blob import qualified Data.ByteString as B import Data.Diff import Data.Functor.Both +import Data.Semigroup import Data.Term renderDOTDiff :: Both Blob -> Diff syntax ann1 ann2 -> B.ByteString @@ -20,3 +22,6 @@ data Node = Node { nodeID :: Int, nodeLabel :: B.ByteString } data Edge = Edge { edgeFrom :: Int, edgeTo :: Int } deriving (Eq, Ord, Show) + +instance Semigroup Graph where + Graph n1 ns1 es1 <> Graph n2 ns2 es2 = Graph (n1 <|> n2) (ns1 <> ns2) (es1 <> es2) From e9e0f142487acda782ef6a991a98bd5a3edf958a Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:29:35 -0700 Subject: [PATCH 076/133] Define a Monoid instance for Graph. --- src/Rendering/DOT.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 1bdc71784..280c35204 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -25,3 +25,7 @@ data Edge = Edge { edgeFrom :: Int, edgeTo :: Int } instance Semigroup Graph where Graph n1 ns1 es1 <> Graph n2 ns2 es2 = Graph (n1 <|> n2) (ns1 <> ns2) (es1 <> es2) + +instance Monoid Graph where + mempty = Graph Nothing [] [] + mappend = (<>) From 08134d6cec8289f17c4db4d62281e71988e55d3c Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:30:06 -0700 Subject: [PATCH 077/133] Define renderers for Graphs, Nodes, & Edges. --- src/Rendering/DOT.hs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 280c35204..bbe327ff4 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -2,7 +2,7 @@ module Rendering.DOT where import Control.Applicative import Data.Blob -import qualified Data.ByteString as B +import qualified Data.ByteString.Char8 as B import Data.Diff import Data.Functor.Both import Data.Semigroup @@ -14,6 +14,17 @@ renderDOTDiff _ _ = "" renderDOTTerm :: Blob -> Term syntax ann -> B.ByteString renderDOTTerm _ _ = "" + +renderGraph :: Graph -> B.ByteString +renderGraph Graph{..} = "digraph " <> maybe "" quote graphName <> " {" <> foldr ((<>) . renderNode) "" graphNodes <> foldr ((<>) . renderEdge) "" graphEdges <> "}" + where quote a = "\"" <> a <> "\"" + +renderNode :: Node -> B.ByteString +renderNode Node{..} = B.pack (show nodeID) <> " [ label = " <> nodeLabel <> " ]" + +renderEdge :: Edge -> B.ByteString +renderEdge Edge{..} = B.pack (show edgeFrom) <> " -> " <> B.pack (show edgeTo) <> ";" + data Graph = Graph { graphName :: Maybe B.ByteString, graphNodes :: [Node], graphEdges :: [Edge] } deriving (Eq, Ord, Show) From 0e4f3cfb56b86532f41987dc5f4fad3dc7c11c2d Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:41:54 -0700 Subject: [PATCH 078/133] Fold terms into graphs. --- src/Rendering/DOT.hs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index bbe327ff4..1fe5a5505 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -1,18 +1,30 @@ module Rendering.DOT where +import Analysis.ConstructorName import Control.Applicative import Data.Blob import qualified Data.ByteString.Char8 as B import Data.Diff -import Data.Functor.Both +import Data.Foldable +import Data.Functor.Both (Both) +import Data.Functor.Foldable hiding (fold) import Data.Semigroup import Data.Term renderDOTDiff :: Both Blob -> Diff syntax ann1 ann2 -> B.ByteString renderDOTDiff _ _ = "" -renderDOTTerm :: Blob -> Term syntax ann -> B.ByteString -renderDOTTerm _ _ = "" +renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Blob -> Term syntax ann -> B.ByteString +renderDOTTerm Blob{..} term = renderGraph (snd (cata graphAlgebra term)) { graphName = Just (B.pack blobPath) } + + +graphAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int, Graph) -> (Int, Graph) +graphAlgebra t = (i, Graph + Nothing + (Node i (unConstructorLabel (constructorLabel t)) : (g >>= graphNodes . snd)) + (map (Edge i . fst) g <> (g >>= graphEdges . snd))) + where g = toList t + i = 0 renderGraph :: Graph -> B.ByteString From dde473abd13f10ca42b311f594b053858f28dfba Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:42:08 -0700 Subject: [PATCH 079/133] Explicitly list the exports. --- src/Rendering/DOT.hs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 1fe5a5505..6fe3ebb20 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -1,4 +1,7 @@ -module Rendering.DOT where +module Rendering.DOT +( renderDOTDiff +, renderDOTTerm +) where import Analysis.ConstructorName import Control.Applicative From 673dd2853791245254a0a7db9ac77fedd1735906 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 09:47:40 -0700 Subject: [PATCH 080/133] Pick IDs for nodes. --- src/Rendering/DOT.hs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 6fe3ebb20..592fff2fd 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -18,16 +18,15 @@ renderDOTDiff :: Both Blob -> Diff syntax ann1 ann2 -> B.ByteString renderDOTDiff _ _ = "" renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Blob -> Term syntax ann -> B.ByteString -renderDOTTerm Blob{..} term = renderGraph (snd (cata graphAlgebra term)) { graphName = Just (B.pack blobPath) } +renderDOTTerm Blob{..} term = renderGraph (snd (cata graphAlgebra term 0)) { graphName = Just (B.pack blobPath) } -graphAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int, Graph) -> (Int, Graph) -graphAlgebra t = (i, Graph +graphAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> (Int, Graph)) -> Int -> (Int, Graph) +graphAlgebra t i = (succ i, Graph Nothing - (Node i (unConstructorLabel (constructorLabel t)) : (g >>= graphNodes . snd)) - (map (Edge i . fst) g <> (g >>= graphEdges . snd))) - where g = toList t - i = 0 + (Node (succ i) (unConstructorLabel (constructorLabel t)) : (g >>= graphNodes . snd)) + (map (Edge (succ i) . fst) g <> (g >>= graphEdges . snd))) + where g = map ($ succ i) (toList t) renderGraph :: Graph -> B.ByteString From 90349b0abb3cf07f33ce90e564e005d928cdfed0 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 10:18:12 -0700 Subject: [PATCH 081/133] Terminate Node renderings with semicolons. --- src/Rendering/DOT.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 592fff2fd..793296cd0 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -34,7 +34,7 @@ renderGraph Graph{..} = "digraph " <> maybe "" quote graphName <> " {" <> foldr where quote a = "\"" <> a <> "\"" renderNode :: Node -> B.ByteString -renderNode Node{..} = B.pack (show nodeID) <> " [ label = " <> nodeLabel <> " ]" +renderNode Node{..} = B.pack (show nodeID) <> " [ label = " <> nodeLabel <> " ];" renderEdge :: Edge -> B.ByteString renderEdge Edge{..} = B.pack (show edgeFrom) <> " -> " <> B.pack (show edgeTo) <> ";" From b0461325f9e74b0b0078b0f61e0c7af0b41028b4 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 13:23:22 -0700 Subject: [PATCH 082/133] Compute unique names for siblings. --- src/Rendering/DOT.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 793296cd0..12c60935f 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -24,9 +24,10 @@ renderDOTTerm Blob{..} term = renderGraph (snd (cata graphAlgebra term 0)) { gra graphAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> (Int, Graph)) -> Int -> (Int, Graph) graphAlgebra t i = (succ i, Graph Nothing - (Node (succ i) (unConstructorLabel (constructorLabel t)) : (g >>= graphNodes . snd)) - (map (Edge (succ i) . fst) g <> (g >>= graphEdges . snd))) - where g = map ($ succ i) (toList t) + (Node (succ i) (unConstructorLabel (constructorLabel t)) : graphNodes g) + (map (Edge (succ i)) is <> graphEdges g)) + where (_, is, g) = foldr combine (succ i, [], mempty) (toList t) + combine f (i, is, gs) = let (i', g) = f i in (maximum (i : map nodeID (graphNodes g)), i' : is, g <> gs) renderGraph :: Graph -> B.ByteString From b7e3ab1274c0b4732ba72e1ec54d0c674a8aac8e Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 13:38:27 -0700 Subject: [PATCH 083/133] Quote the labels. --- src/Rendering/DOT.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 12c60935f..bd18be92d 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -35,7 +35,7 @@ renderGraph Graph{..} = "digraph " <> maybe "" quote graphName <> " {" <> foldr where quote a = "\"" <> a <> "\"" renderNode :: Node -> B.ByteString -renderNode Node{..} = B.pack (show nodeID) <> " [ label = " <> nodeLabel <> " ];" +renderNode Node{..} = B.pack (show nodeID) <> " [ label = \"" <> nodeLabel <> "\" ];" renderEdge :: Edge -> B.ByteString renderEdge Edge{..} = B.pack (show edgeFrom) <> " -> " <> B.pack (show edgeTo) <> ";" From 0bd661b831d0dd4dc94e5360fdc47edc82627bc9 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 6 Dec 2017 13:42:48 -0700 Subject: [PATCH 084/133] Turn on mono local binds. --- src/Rendering/DOT.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index bd18be92d..e86696609 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE MonoLocalBinds #-} module Rendering.DOT ( renderDOTDiff , renderDOTTerm From fd6cc2f05769b85a733af9afcd1dc40cdfe15a49 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 7 Dec 2017 08:40:44 -0700 Subject: [PATCH 085/133] Move the datatypes up a little. --- src/Rendering/DOT.hs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index e86696609..930cd3f9f 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -31,6 +31,16 @@ graphAlgebra t i = (succ i, Graph combine f (i, is, gs) = let (i', g) = f i in (maximum (i : map nodeID (graphNodes g)), i' : is, g <> gs) +data Graph = Graph { graphName :: Maybe B.ByteString, graphNodes :: [Node], graphEdges :: [Edge] } + deriving (Eq, Ord, Show) + +data Node = Node { nodeID :: Int, nodeLabel :: B.ByteString } + deriving (Eq, Ord, Show) + +data Edge = Edge { edgeFrom :: Int, edgeTo :: Int } + deriving (Eq, Ord, Show) + + renderGraph :: Graph -> B.ByteString renderGraph Graph{..} = "digraph " <> maybe "" quote graphName <> " {" <> foldr ((<>) . renderNode) "" graphNodes <> foldr ((<>) . renderEdge) "" graphEdges <> "}" where quote a = "\"" <> a <> "\"" @@ -41,14 +51,6 @@ renderNode Node{..} = B.pack (show nodeID) <> " [ label = \"" <> nodeLabel <> "\ renderEdge :: Edge -> B.ByteString renderEdge Edge{..} = B.pack (show edgeFrom) <> " -> " <> B.pack (show edgeTo) <> ";" -data Graph = Graph { graphName :: Maybe B.ByteString, graphNodes :: [Node], graphEdges :: [Edge] } - deriving (Eq, Ord, Show) - -data Node = Node { nodeID :: Int, nodeLabel :: B.ByteString } - deriving (Eq, Ord, Show) - -data Edge = Edge { edgeFrom :: Int, edgeTo :: Int } - deriving (Eq, Ord, Show) instance Semigroup Graph where Graph n1 ns1 es1 <> Graph n2 ns2 es2 = Graph (n1 <|> n2) (ns1 <> ns2) (es1 <> es2) From d40da054f75617d75bb7d9f29d78eedd55acbf7d Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 7 Dec 2017 08:44:03 -0700 Subject: [PATCH 086/133] Stub in a title for diff graphs. --- src/Rendering/DOT.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 930cd3f9f..3551b9859 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -10,13 +10,15 @@ import Data.Blob import qualified Data.ByteString.Char8 as B import Data.Diff import Data.Foldable -import Data.Functor.Both (Both) +import Data.Function (on) +import Data.Functor.Both (Both, runBothWith) import Data.Functor.Foldable hiding (fold) import Data.Semigroup import Data.Term renderDOTDiff :: Both Blob -> Diff syntax ann1 ann2 -> B.ByteString -renderDOTDiff _ _ = "" +renderDOTDiff blobs _ = renderGraph mempty { graphName = Just (runBothWith (fmap B.pack . (join `on` blobPath)) blobs) } + where join = (++) . (" -> " ++) renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Blob -> Term syntax ann -> B.ByteString renderDOTTerm Blob{..} term = renderGraph (snd (cata graphAlgebra term 0)) { graphName = Just (B.pack blobPath) } From 82483e2015b7663337c79ab0ae6a129fbafca4dc Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 7 Dec 2017 09:25:25 -0700 Subject: [PATCH 087/133] Nodes have a map of attributes. --- src/Rendering/DOT.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 3551b9859..f11b7060c 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -13,6 +13,7 @@ import Data.Foldable import Data.Function (on) import Data.Functor.Both (Both, runBothWith) import Data.Functor.Foldable hiding (fold) +import qualified Data.Map as Map import Data.Semigroup import Data.Term @@ -27,7 +28,7 @@ renderDOTTerm Blob{..} term = renderGraph (snd (cata graphAlgebra term 0)) { gra graphAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> (Int, Graph)) -> Int -> (Int, Graph) graphAlgebra t i = (succ i, Graph Nothing - (Node (succ i) (unConstructorLabel (constructorLabel t)) : graphNodes g) + (Node (succ i) (Map.singleton "label" (unConstructorLabel (constructorLabel t))) : graphNodes g) (map (Edge (succ i)) is <> graphEdges g)) where (_, is, g) = foldr combine (succ i, [], mempty) (toList t) combine f (i, is, gs) = let (i', g) = f i in (maximum (i : map nodeID (graphNodes g)), i' : is, g <> gs) @@ -36,7 +37,7 @@ graphAlgebra t i = (succ i, Graph data Graph = Graph { graphName :: Maybe B.ByteString, graphNodes :: [Node], graphEdges :: [Edge] } deriving (Eq, Ord, Show) -data Node = Node { nodeID :: Int, nodeLabel :: B.ByteString } +data Node = Node { nodeID :: Int, nodeAttributes :: Map.Map B.ByteString B.ByteString } deriving (Eq, Ord, Show) data Edge = Edge { edgeFrom :: Int, edgeTo :: Int } @@ -48,7 +49,7 @@ renderGraph Graph{..} = "digraph " <> maybe "" quote graphName <> " {" <> foldr where quote a = "\"" <> a <> "\"" renderNode :: Node -> B.ByteString -renderNode Node{..} = B.pack (show nodeID) <> " [ label = \"" <> nodeLabel <> "\" ];" +renderNode Node{..} = B.pack (show nodeID) <> " [ " <> foldr (\ (key, value) rest -> key <> " = \"" <> value <> "\" " <> rest) "" (Map.toList nodeAttributes) <> "];" renderEdge :: Edge -> B.ByteString renderEdge Edge{..} = B.pack (show edgeFrom) <> " -> " <> B.pack (show edgeTo) <> ";" From a86a50d98640d05ad93cfe7c9f0c377fa3072432 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 7 Dec 2017 09:36:39 -0700 Subject: [PATCH 088/133] Render diffs to DOT. --- src/Rendering/DOT.hs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index f11b7060c..5cce5dd2b 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -14,16 +14,24 @@ import Data.Function (on) import Data.Functor.Both (Both, runBothWith) import Data.Functor.Foldable hiding (fold) import qualified Data.Map as Map +import Data.Patch import Data.Semigroup import Data.Term -renderDOTDiff :: Both Blob -> Diff syntax ann1 ann2 -> B.ByteString -renderDOTDiff blobs _ = renderGraph mempty { graphName = Just (runBothWith (fmap B.pack . (join `on` blobPath)) blobs) } +renderDOTDiff :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Both Blob -> Diff syntax ann1 ann2 -> B.ByteString +renderDOTDiff blobs diff = renderGraph (snd (cata diffAlgebra diff 0)) { graphName = Just (runBothWith (fmap B.pack . (join `on` blobPath)) blobs) } where join = (++) . (" -> " ++) renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Blob -> Term syntax ann -> B.ByteString renderDOTTerm Blob{..} term = renderGraph (snd (cata graphAlgebra term 0)) { graphName = Just (B.pack blobPath) } +diffAlgebra :: (ConstructorName syntax, Foldable syntax) => DiffF syntax ann1 ann2 (Int -> (Int, Graph)) -> Int -> (Int, Graph) +diffAlgebra (Merge t) i = graphAlgebra t i +diffAlgebra (Patch (Delete t1)) i = graphAlgebra t1 i +diffAlgebra (Patch (Insert t2)) i = graphAlgebra t2 i +diffAlgebra (Patch (Replace t1 t2)) i = let (_, g1) = graphAlgebra t1 i + (_, g2) = graphAlgebra t2 i + in (succ i, g1 <> g2) graphAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> (Int, Graph)) -> Int -> (Int, Graph) graphAlgebra t i = (succ i, Graph From 51affc82a3682ec292085c8e7cafd7f340beb6f3 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 7 Dec 2017 09:47:47 -0700 Subject: [PATCH 089/133] Colourize patches. --- src/Rendering/DOT.hs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 5cce5dd2b..7ab99857f 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -26,12 +26,16 @@ renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Bl renderDOTTerm Blob{..} term = renderGraph (snd (cata graphAlgebra term 0)) { graphName = Just (B.pack blobPath) } diffAlgebra :: (ConstructorName syntax, Foldable syntax) => DiffF syntax ann1 ann2 (Int -> (Int, Graph)) -> Int -> (Int, Graph) -diffAlgebra (Merge t) i = graphAlgebra t i -diffAlgebra (Patch (Delete t1)) i = graphAlgebra t1 i -diffAlgebra (Patch (Insert t2)) i = graphAlgebra t2 i -diffAlgebra (Patch (Replace t1 t2)) i = let (_, g1) = graphAlgebra t1 i - (_, g2) = graphAlgebra t2 i - in (succ i, g1 <> g2) +diffAlgebra d i = case d of + Merge t -> graphAlgebra t i + Patch (Delete t1) -> graphAlgebra t1 i `modifyHeadNode` setColour "red" + Patch (Insert t2) -> graphAlgebra t2 i `modifyHeadNode` setColour "green" + Patch (Replace t1 t2) -> let (_, g1) = graphAlgebra t1 i `modifyHeadNode` setColour "red" + (_, g2) = graphAlgebra t2 i `modifyHeadNode` setColour "green" + in (succ i, g1 <> g2) + where modifyHeadNode (i, g) f | n:ns <- graphNodes g = (i, g { graphNodes = f n : ns }) + | otherwise = (i, g) + setColour c n = n { nodeAttributes = Map.insert "color" c (nodeAttributes n) } graphAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> (Int, Graph)) -> Int -> (Int, Graph) graphAlgebra t i = (succ i, Graph From 0ba3ec6bd1e7a5da5ed8c980f7e7b6ae1929fb95 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 7 Dec 2017 09:53:29 -0700 Subject: [PATCH 090/133] Rename graphAlgebra to termAlgebra. --- src/Rendering/DOT.hs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 7ab99857f..86cdf0c16 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -23,22 +23,22 @@ renderDOTDiff blobs diff = renderGraph (snd (cata diffAlgebra diff 0)) { graphNa where join = (++) . (" -> " ++) renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Blob -> Term syntax ann -> B.ByteString -renderDOTTerm Blob{..} term = renderGraph (snd (cata graphAlgebra term 0)) { graphName = Just (B.pack blobPath) } +renderDOTTerm Blob{..} term = renderGraph (snd (cata termAlgebra term 0)) { graphName = Just (B.pack blobPath) } diffAlgebra :: (ConstructorName syntax, Foldable syntax) => DiffF syntax ann1 ann2 (Int -> (Int, Graph)) -> Int -> (Int, Graph) diffAlgebra d i = case d of - Merge t -> graphAlgebra t i - Patch (Delete t1) -> graphAlgebra t1 i `modifyHeadNode` setColour "red" - Patch (Insert t2) -> graphAlgebra t2 i `modifyHeadNode` setColour "green" - Patch (Replace t1 t2) -> let (_, g1) = graphAlgebra t1 i `modifyHeadNode` setColour "red" - (_, g2) = graphAlgebra t2 i `modifyHeadNode` setColour "green" + Merge t -> termAlgebra t i + Patch (Delete t1) -> termAlgebra t1 i `modifyHeadNode` setColour "red" + Patch (Insert t2) -> termAlgebra t2 i `modifyHeadNode` setColour "green" + Patch (Replace t1 t2) -> let (_, g1) = termAlgebra t1 i `modifyHeadNode` setColour "red" + (_, g2) = termAlgebra t2 i `modifyHeadNode` setColour "green" in (succ i, g1 <> g2) where modifyHeadNode (i, g) f | n:ns <- graphNodes g = (i, g { graphNodes = f n : ns }) | otherwise = (i, g) setColour c n = n { nodeAttributes = Map.insert "color" c (nodeAttributes n) } -graphAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> (Int, Graph)) -> Int -> (Int, Graph) -graphAlgebra t i = (succ i, Graph +termAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> (Int, Graph)) -> Int -> (Int, Graph) +termAlgebra t i = (succ i, Graph Nothing (Node (succ i) (Map.singleton "label" (unConstructorLabel (constructorLabel t))) : graphNodes g) (map (Edge (succ i)) is <> graphEdges g)) From 3b3e5495a155c5974cfb06e6096a624788b58c3a Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 7 Dec 2017 10:14:30 -0700 Subject: [PATCH 091/133] Allow multiple in-edges per iteration. --- src/Rendering/DOT.hs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 86cdf0c16..4bbfaa361 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -25,23 +25,22 @@ renderDOTDiff blobs diff = renderGraph (snd (cata diffAlgebra diff 0)) { graphNa renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Blob -> Term syntax ann -> B.ByteString renderDOTTerm Blob{..} term = renderGraph (snd (cata termAlgebra term 0)) { graphName = Just (B.pack blobPath) } -diffAlgebra :: (ConstructorName syntax, Foldable syntax) => DiffF syntax ann1 ann2 (Int -> (Int, Graph)) -> Int -> (Int, Graph) +diffAlgebra :: (ConstructorName syntax, Foldable syntax) => DiffF syntax ann1 ann2 (Int -> ([Int], Graph)) -> Int -> ([Int], Graph) diffAlgebra d i = case d of Merge t -> termAlgebra t i Patch (Delete t1) -> termAlgebra t1 i `modifyHeadNode` setColour "red" Patch (Insert t2) -> termAlgebra t2 i `modifyHeadNode` setColour "green" - Patch (Replace t1 t2) -> let (_, g1) = termAlgebra t1 i `modifyHeadNode` setColour "red" - (_, g2) = termAlgebra t2 i `modifyHeadNode` setColour "green" - in (succ i, g1 <> g2) + Patch (Replace t1 t2) -> (termAlgebra t1 i `modifyHeadNode` setColour "red") + <> (termAlgebra t2 i `modifyHeadNode` setColour "green") where modifyHeadNode (i, g) f | n:ns <- graphNodes g = (i, g { graphNodes = f n : ns }) | otherwise = (i, g) setColour c n = n { nodeAttributes = Map.insert "color" c (nodeAttributes n) } -termAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> (Int, Graph)) -> Int -> (Int, Graph) -termAlgebra t i = (succ i, Graph +termAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> ([Int], Graph)) -> Int -> ([Int], Graph) +termAlgebra t i = ([succ i], Graph Nothing (Node (succ i) (Map.singleton "label" (unConstructorLabel (constructorLabel t))) : graphNodes g) - (map (Edge (succ i)) is <> graphEdges g)) + (concatMap (map (Edge (succ i))) is <> graphEdges g)) where (_, is, g) = foldr combine (succ i, [], mempty) (toList t) combine f (i, is, gs) = let (i', g) = f i in (maximum (i : map nodeID (graphNodes g)), i' : is, g <> gs) From 1717f2a6a6e117481b62c2099abdbe90085f6e46 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 7 Dec 2017 10:18:44 -0700 Subject: [PATCH 092/133] Replacements use unique node IDs. --- src/Rendering/DOT.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 4bbfaa361..032e6703a 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -30,8 +30,8 @@ diffAlgebra d i = case d of Merge t -> termAlgebra t i Patch (Delete t1) -> termAlgebra t1 i `modifyHeadNode` setColour "red" Patch (Insert t2) -> termAlgebra t2 i `modifyHeadNode` setColour "green" - Patch (Replace t1 t2) -> (termAlgebra t1 i `modifyHeadNode` setColour "red") - <> (termAlgebra t2 i `modifyHeadNode` setColour "green") + Patch (Replace t1 t2) -> let (i', g1) = termAlgebra t1 i `modifyHeadNode` setColour "red" in + (i', g1) <> (termAlgebra t2 (succ (maximum (i : i'))) `modifyHeadNode` setColour "green") where modifyHeadNode (i, g) f | n:ns <- graphNodes g = (i, g { graphNodes = f n : ns }) | otherwise = (i, g) setColour c n = n { nodeAttributes = Map.insert "color" c (nodeAttributes n) } From 27f7a5778f1ae33b07472c2c5ad2571b2f1c2fc6 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 7 Dec 2017 10:52:21 -0700 Subject: [PATCH 093/133] Reformat the replacement rule. --- src/Rendering/DOT.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 032e6703a..5f838b732 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -30,8 +30,8 @@ diffAlgebra d i = case d of Merge t -> termAlgebra t i Patch (Delete t1) -> termAlgebra t1 i `modifyHeadNode` setColour "red" Patch (Insert t2) -> termAlgebra t2 i `modifyHeadNode` setColour "green" - Patch (Replace t1 t2) -> let (i', g1) = termAlgebra t1 i `modifyHeadNode` setColour "red" in - (i', g1) <> (termAlgebra t2 (succ (maximum (i : i'))) `modifyHeadNode` setColour "green") + Patch (Replace t1 t2) -> let (i', g1) = termAlgebra t1 i `modifyHeadNode` setColour "red" + in (i', g1) <> (termAlgebra t2 (succ (maximum (i : i'))) `modifyHeadNode` setColour "green") where modifyHeadNode (i, g) f | n:ns <- graphNodes g = (i, g { graphNodes = f n : ns }) | otherwise = (i, g) setColour c n = n { nodeAttributes = Map.insert "color" c (nodeAttributes n) } From 46cccd5015024a495896f4d91ca34c28308d4fe9 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Fri, 8 Dec 2017 11:42:46 -0700 Subject: [PATCH 094/133] Don't parse blobs that don't exist --- src/Semantic.hs | 13 ++++++------- src/Semantic/Util.hs | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index 74116b213..365801da9 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -108,9 +108,9 @@ diffBlobPair renderer blobs run :: (Foldable syntax, Functor syntax) => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (Both Blob -> Diff syntax ann ann -> output) -> Task output run parse diff renderer = do - terms <- distributeFor blobs parse + terms <- distributeFor blobs (\b -> if blobExists b then Just <$> parse b else pure Nothing) time "diff" languageTag $ do - diff <- runBothWith (diffTermPair blobs diff) terms + diff <- runBothWith (diffTermPair diff) terms writeStat (Stat.count "diff.nodes" (bilength diff) languageTag) render (renderer blobs) diff where @@ -119,11 +119,10 @@ diffBlobPair renderer blobs in maybe (maybe [] showLanguage (blobLanguage b)) showLanguage (blobLanguage a) -- | A task to diff a pair of 'Term's, producing insertion/deletion 'Patch'es for non-existent 'Blob's. -diffTermPair :: Functor syntax => Both Blob -> Differ syntax ann1 ann2 -> Term syntax ann1 -> Term syntax ann2 -> Task (Diff syntax ann1 ann2) -diffTermPair blobs differ t1 t2 = case runJoin (blobExists <$> blobs) of - (True, False) -> pure (deleting t1) - (False, True) -> pure (inserting t2) - _ -> diff differ t1 t2 +diffTermPair :: Functor syntax => Differ syntax ann1 ann2 -> Maybe (Term syntax ann1) -> Maybe (Term syntax ann2) -> Task (Diff syntax ann1 ann2) +diffTermPair _ (Just t1) Nothing = pure (deleting t1) +diffTermPair _ Nothing (Just t2) = pure (inserting t2) +diffTermPair differ (Just t1) (Just t2) = diff differ t1 t2 keepCategory :: HasField fields Category => Record fields -> Record '[Category] keepCategory = (:. Nil) . category diff --git a/src/Semantic/Util.hs b/src/Semantic/Util.hs index e722c1536..ea31f9536 100644 --- a/src/Semantic/Util.hs +++ b/src/Semantic/Util.hs @@ -35,4 +35,4 @@ diffWithParser :: (HasField fields Data.Span.Span, -> Task (Diff syntax (Record (Maybe Declaration ': fields)) (Record (Maybe Declaration ': fields))) diffWithParser parser = run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) where - run parse sourceBlobs = distributeFor sourceBlobs parse >>= runBothWith (diffTermPair sourceBlobs diffTerms) + run parse sourceBlobs = distributeFor sourceBlobs (\b -> if blobExists b then Just <$> parse b else pure Nothing) >>= runBothWith (diffTermPair diffTerms) From ba2159e9405cee3ad340cc02c3de7ecf8862aecb Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Sat, 9 Dec 2017 17:36:48 -0800 Subject: [PATCH 095/133] First attempt at BlobPair as These and bitraversable --- src/Data/Blob.hs | 18 ++++++++++++++++++ src/Rendering/JSON.hs | 2 +- src/Rendering/TOC.hs | 12 ++++++------ src/Semantic.hs | 34 +++++++++++++++++----------------- src/Semantic/IO.hs | 21 +++++++++++++++++---- src/Semantic/Task.hs | 19 ++++++++++++++++--- 6 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/Data/Blob.hs b/src/Data/Blob.hs index a1beae60f..86a3bd2b6 100644 --- a/src/Data/Blob.hs +++ b/src/Data/Blob.hs @@ -1,6 +1,7 @@ module Data.Blob ( Blob(..) , BlobKind(..) +, These(..) , modeToDigits , defaultPlainBlob , emptyBlob @@ -8,15 +9,32 @@ module Data.Blob , blobExists , sourceBlob , nullOid +, BlobPair +, languageForBlobPair +, languageTagForBlobPair ) where import Data.ByteString.Char8 (ByteString, pack) import Data.Language +import Data.These import Data.Maybe (isJust) import Data.Source as Source import Data.Word import Numeric + +type BlobPair = These Blob Blob + +languageForBlobPair :: BlobPair -> Maybe Language +languageForBlobPair (This Blob{..}) = blobLanguage +languageForBlobPair (That Blob{..}) = blobLanguage +languageForBlobPair (These _ Blob{..}) = blobLanguage + +languageTagForBlobPair :: BlobPair -> [(String, String)] +languageTagForBlobPair pair = maybe [] showLanguage (languageForBlobPair pair) + where showLanguage = pure . (,) "language" . show + + -- | The source, oid, path, and Maybe BlobKind of a blob. data Blob = Blob { blobSource :: Source -- ^ The UTF-8 encoded source text of the blob. diff --git a/src/Rendering/JSON.hs b/src/Rendering/JSON.hs index fb99231a9..3d2c202bc 100644 --- a/src/Rendering/JSON.hs +++ b/src/Rendering/JSON.hs @@ -19,7 +19,7 @@ import GHC.Generics -- -- | Render a diff to a string representing its JSON. -renderJSONDiff :: ToJSON a => Both Blob -> a -> Map.Map Text Value +renderJSONDiff :: ToJSON a => BlobPair -> a -> Map.Map Text Value renderJSONDiff blobs diff = Map.fromList [ ("diff", toJSON diff) , ("oids", toJSON (decodeUtf8 . blobOid <$> toList blobs)) diff --git a/src/Rendering/TOC.hs b/src/Rendering/TOC.hs index 772af46f5..d332b7304 100644 --- a/src/Rendering/TOC.hs +++ b/src/Rendering/TOC.hs @@ -160,15 +160,15 @@ recordSummary changeText record = case getDeclaration record of formatIdentifier (MethodDeclaration identifier _ _ (Just receiver)) = receiver <> "." <> identifier formatIdentifier declaration = declarationIdentifier declaration -renderToCDiff :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Both Blob -> Diff f (Record fields) (Record fields) -> Summaries +renderToCDiff :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => BlobPair -> Diff f (Record fields) (Record fields) -> Summaries renderToCDiff blobs = uncurry Summaries . bimap toMap toMap . List.partition isValidSummary . diffTOC where toMap [] = mempty toMap as = Map.singleton summaryKey (toJSON <$> as) - summaryKey = T.pack $ case runJoin (blobPath <$> blobs) of - (before, after) | null before -> after - | null after -> before - | before == after -> after - | otherwise -> before <> " -> " <> after + summaryKey = T.pack $ case bimap blobPath blobPath blobs of + This before -> before + That after -> after + These before after | before == after -> after + | otherwise -> before <> " -> " <> after diffTOC :: (HasField fields (Maybe Declaration), HasField fields Span, Foldable f, Functor f) => Diff f (Record fields) (Record fields) -> [TOCSummary] diffTOC = mapMaybe entrySummary . dedupe . tableOfContentsBy declaration diff --git a/src/Semantic.hs b/src/Semantic.hs index 365801da9..868da693a 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -18,6 +18,7 @@ import Data.Bifoldable import Data.Blob import Data.ByteString (ByteString) import Data.Diff +import Data.Foldable (toList) import Data.Functor.Both as Both import Data.Functor.Classes import Data.JSON.Fields @@ -25,6 +26,7 @@ import qualified Data.Language as Language import Data.Output import Data.Record import Data.Term +import Data.These import Data.Typeable import Diffing.Algorithm (Diffable) import Diffing.Interpreter @@ -69,11 +71,11 @@ data NoParserForLanguage = NoParserForLanguage FilePath (Maybe Language.Language deriving (Eq, Exception, Ord, Show, Typeable) -diffBlobPairs :: Output output => DiffRenderer output -> [Both Blob] -> Task ByteString -diffBlobPairs renderer = fmap toOutput . distributeFoldMap (diffBlobPair renderer) . filter (any blobExists) +diffBlobPairs :: Output output => DiffRenderer output -> [BlobPair] -> Task ByteString +diffBlobPairs renderer = fmap toOutput . distributeFoldMap (diffBlobPair renderer) -- | A task to parse a pair of 'Blob's, diff them, and render the 'Diff'. -diffBlobPair :: DiffRenderer output -> Both Blob -> Task output +diffBlobPair :: DiffRenderer output -> BlobPair -> Task output diffBlobPair renderer blobs | Just (SomeParser parser) <- effectiveLanguage >>= qualify >>= someParser (Proxy :: Proxy '[ConstructorName, Diffable, Eq1, GAlign, HasDeclaration, Show1, ToJSONFields1, Traversable]) = case renderer of @@ -90,10 +92,10 @@ diffBlobPair renderer blobs SExpressionDiffRenderer -> run ( parse parser >=> pure . fmap keepCategory) diffSyntaxTerms (const renderSExpressionDiff) | otherwise = throwError (SomeException (NoParserForLanguage effectivePath effectiveLanguage)) - where (effectivePath, effectiveLanguage) = case runJoin blobs of - (Blob { blobLanguage = Just lang, blobPath = path }, _) -> (path, Just lang) - (_, Blob { blobLanguage = Just lang, blobPath = path }) -> (path, Just lang) - (Blob { blobPath = path }, _) -> (path, Nothing) + where (effectivePath, effectiveLanguage) = case blobs of + This Blob { blobLanguage = Just lang, blobPath = path } -> (path, Just lang) + That Blob { blobLanguage = Just lang, blobPath = path } -> (path, Just lang) + These Blob { blobPath = path } _ -> (path, Nothing) qualify language | OldToCDiffRenderer <- renderer = guard (language `elem` aLaCarteLanguages) *> Just language | otherwise = Just language @@ -106,23 +108,21 @@ diffBlobPair renderer blobs , Language.TypeScript ] - run :: (Foldable syntax, Functor syntax) => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (Both Blob -> Diff syntax ann ann -> output) -> Task output + run :: (Foldable syntax, Functor syntax) => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (These Blob Blob -> Diff syntax ann ann -> output) -> Task output run parse diff renderer = do - terms <- distributeFor blobs (\b -> if blobExists b then Just <$> parse b else pure Nothing) + terms <- bidistributeFor blobs parse parse time "diff" languageTag $ do - diff <- runBothWith (diffTermPair diff) terms + diff <- diffTermPair diff terms writeStat (Stat.count "diff.nodes" (bilength diff) languageTag) render (renderer blobs) diff where - showLanguage = pure . (,) "language" . show - languageTag = let (a, b) = runJoin blobs - in maybe (maybe [] showLanguage (blobLanguage b)) showLanguage (blobLanguage a) + languageTag = languageTagForBlobPair blobs -- | A task to diff a pair of 'Term's, producing insertion/deletion 'Patch'es for non-existent 'Blob's. -diffTermPair :: Functor syntax => Differ syntax ann1 ann2 -> Maybe (Term syntax ann1) -> Maybe (Term syntax ann2) -> Task (Diff syntax ann1 ann2) -diffTermPair _ (Just t1) Nothing = pure (deleting t1) -diffTermPair _ Nothing (Just t2) = pure (inserting t2) -diffTermPair differ (Just t1) (Just t2) = diff differ t1 t2 +diffTermPair :: Functor syntax => Differ syntax ann1 ann2 -> These (Term syntax ann1) (Term syntax ann2) -> Task (Diff syntax ann1 ann2) +diffTermPair _ (This t1) = pure (deleting t1) +diffTermPair _ (That t2) = pure (inserting t2) +diffTermPair differ (These t1 t2) = diff differ t1 t2 keepCategory :: HasField fields Category => Record fields -> Record '[Category] keepCategory = (:. Nil) . category diff --git a/src/Semantic/IO.hs b/src/Semantic/IO.hs index 50ddc7dae..f8c0a763f 100644 --- a/src/Semantic/IO.hs +++ b/src/Semantic/IO.hs @@ -1,6 +1,7 @@ {-# LANGUAGE OverloadedStrings, TypeSynonymInstances, DeriveAnyClass, DuplicateRecordFields, ScopedTypeVariables, TupleSections #-} module Semantic.IO ( readFile +, readFiles , isDirectory , readBlobPairsFromHandle , readBlobsFromHandle @@ -21,6 +22,7 @@ import Data.Source import Data.String import Data.Text import Data.These +import Data.Traversable import GHC.Generics import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL @@ -39,6 +41,18 @@ readFile path language = do raw <- liftIO $ (Just <$> B.readFile path) `catch` (const (pure Nothing) :: IOException -> IO (Maybe B.ByteString)) pure $ fromMaybe (Blob.emptyBlob path) (Blob.sourceBlob path language . fromBytes <$> raw) +readFiles :: forall m. MonadIO m => [Both (FilePath, Maybe Language)] -> m [Blob.BlobPair] +readFiles files = for files (runBothWith readFilesToBlobPair) + where + readFilesToBlobPair :: (FilePath, Maybe Language) -> (FilePath, Maybe Language) -> m Blob.BlobPair + readFilesToBlobPair a b = do + before <- uncurry readFile a + after <- uncurry readFile b + case (Blob.blobExists before, Blob.blobExists after) of + (True, False) -> pure (This before) + (False, True) -> pure (That after) + _ -> pure (These before after) + isDirectory :: MonadIO m => FilePath -> m Bool isDirectory path = liftIO (doesDirectoryExist path) >>= pure @@ -47,12 +61,11 @@ languageForFilePath :: FilePath -> Maybe Language languageForFilePath = languageForType . takeExtension -- | Read JSON encoded blob pairs from a handle. -readBlobPairsFromHandle :: MonadIO m => Handle -> m [Both Blob.Blob] +readBlobPairsFromHandle :: MonadIO m => Handle -> m [Blob.BlobPair] readBlobPairsFromHandle = fmap toBlobPairs . readFromHandle where - toBlobPairs BlobDiff{..} = toBlobPair <$> blobs - toBlobPair blobs = Join (fromThese empty empty (runJoin (toBlob <$> blobs))) - where empty = Blob.emptyBlob (mergeThese const (runJoin (path <$> blobs))) + toBlobPairs :: BlobDiff -> [Blob.BlobPair] + toBlobPairs = undefined -- | Read JSON encoded blobs from a handle. readBlobsFromHandle :: MonadIO m => Handle -> m [Blob.Blob] diff --git a/src/Semantic/Task.hs b/src/Semantic/Task.hs index 9b1b8d3d5..df23cd528 100644 --- a/src/Semantic/Task.hs +++ b/src/Semantic/Task.hs @@ -17,6 +17,8 @@ module Semantic.Task , distribute , distributeFor , distributeFoldMap +, bidistribute +, bidistributeFor , defaultOptions , configureOptionsForHandle , terminalFormatter @@ -41,6 +43,8 @@ import Data.Diff import qualified Data.Error as Error import Data.Foldable (fold, for_) import Data.Functor.Both as Both hiding (snd) +import Data.Bitraversable +import Data.Bifunctor import Data.Functor.Foldable (cata) import Data.Language import Data.Record @@ -61,7 +65,7 @@ import Semantic.Queue data TaskF output where ReadBlobs :: Either Handle [(FilePath, Maybe Language)] -> TaskF [Blob] - ReadBlobPairs :: Either Handle [Both (FilePath, Maybe Language)] -> TaskF [Both Blob] + ReadBlobPairs :: Either Handle [Both (FilePath, Maybe Language)] -> TaskF [BlobPair] WriteToOutput :: Either Handle FilePath -> B.ByteString -> TaskF () WriteLog :: Level -> String -> [(String, String)] -> TaskF () WriteStat :: Stat -> TaskF () @@ -71,6 +75,7 @@ data TaskF output where Diff :: Differ syntax ann1 ann2 -> Term syntax ann1 -> Term syntax ann2 -> TaskF (Diff syntax ann1 ann2) Render :: Renderer input output -> input -> TaskF output Distribute :: Traversable t => t (Task output) -> TaskF (t output) + Bidistribute :: Bitraversable t => t (Task output1) (Task output2) -> TaskF (t output1 output2) -- | For MonadIO. LiftIO :: IO a -> TaskF a @@ -93,7 +98,7 @@ readBlobs :: Either Handle [(FilePath, Maybe Language)] -> Task [Blob] readBlobs from = ReadBlobs from `Then` return -- | A 'Task' which reads a list of pairs of 'Blob's from a 'Handle' or a list of pairs of 'FilePath's optionally paired with 'Language's. -readBlobPairs :: Either Handle [Both (FilePath, Maybe Language)] -> Task [Both Blob] +readBlobPairs :: Either Handle [Both (FilePath, Maybe Language)] -> Task [BlobPair] readBlobPairs from = ReadBlobPairs from `Then` return -- | A 'Task' which writes a 'B.ByteString' to a 'Handle' or a 'FilePath'. @@ -134,12 +139,18 @@ render renderer input = Render renderer input `Then` return distribute :: Traversable t => t (Task output) -> Task (t output) distribute tasks = Distribute tasks `Then` return +bidistribute :: Bitraversable t => t (Task output1) (Task output2) -> Task (t output1 output2) +bidistribute tasks = Bidistribute tasks `Then` return + -- | Distribute the application of a function to each element of a 'Traversable' container of inputs over the available cores (i.e. perform the function concurrently for each element), collecting the results. -- -- This is a concurrent analogue of 'for' or 'traverse' (with the arguments flipped). distributeFor :: Traversable t => t a -> (a -> Task output) -> Task (t output) distributeFor inputs toTask = distribute (fmap toTask inputs) +bidistributeFor :: Bitraversable t => t a b -> (a -> Task output1) -> (b -> Task output2) -> Task (t output1 output2) +bidistributeFor inputs toTask1 toTask2 = bidistribute (bimap toTask1 toTask2 inputs) + -- | Distribute the application of a function to each element of a 'Traversable' container of inputs over the available cores (i.e. perform the function concurrently for each element), combining the results 'Monoid'ally into a final value. -- -- This is a concurrent analogue of 'foldMap'. @@ -180,7 +191,8 @@ runTaskWithOptions options task = do ReadBlobs (Left handle) -> (IO.readBlobsFromHandle handle >>= yield) `catchError` (pure . Left . toException) ReadBlobs (Right paths@[(path, Nothing)]) -> (IO.isDirectory path >>= bool (IO.readBlobsFromPaths paths) (IO.readBlobsFromDir path) >>= yield) `catchError` (pure . Left . toException) ReadBlobs (Right paths) -> (IO.readBlobsFromPaths paths >>= yield) `catchError` (pure . Left . toException) - ReadBlobPairs source -> (either IO.readBlobPairsFromHandle (traverse (traverse (uncurry IO.readFile))) source >>= yield) `catchError` (pure . Left . toException) + ReadBlobPairs source -> (either IO.readBlobPairsFromHandle IO.readFiles source >>= yield) `catchError` (pure . Left . toException) + -- ReadBlobPairs source -> (either IO.readBlobPairsFromHandle (traverse (traverse (uncurry IO.readFile))) source >>= yield) `catchError` (pure . Left . toException) WriteToOutput destination contents -> either B.hPutStr B.writeFile destination contents >>= yield WriteLog level message pairs -> queueLogMessage logger level message pairs >>= yield WriteStat stat -> queue statter stat >>= yield @@ -190,6 +202,7 @@ runTaskWithOptions options task = do Semantic.Task.Diff differ term1 term2 -> pure (differ term1 term2) >>= yield Render renderer input -> pure (renderer input) >>= yield Distribute tasks -> Async.mapConcurrently go tasks >>= either (pure . Left) yield . sequenceA . withStrategy (parTraversable (parTraversable rseq)) + Bidistribute tasks -> Async.runConcurrently (bitraverse (Async.Concurrently . go) (Async.Concurrently . go) tasks) >>= either (pure . Left) yield . bisequenceA LiftIO action -> action >>= yield Throw err -> pure (Left err) Catch during handler -> do From ff1d9591c7da10aece5d4fc0a7e0afafa474e1f3 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Sat, 9 Dec 2017 18:13:19 -0800 Subject: [PATCH 096/133] Take path and lang from after file --- src/Semantic.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index 868da693a..4a6eed356 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -95,7 +95,7 @@ diffBlobPair renderer blobs where (effectivePath, effectiveLanguage) = case blobs of This Blob { blobLanguage = Just lang, blobPath = path } -> (path, Just lang) That Blob { blobLanguage = Just lang, blobPath = path } -> (path, Just lang) - These Blob { blobPath = path } _ -> (path, Nothing) + These _ Blob { blobLanguage = lang, blobPath = path } -> (path, lang) qualify language | OldToCDiffRenderer <- renderer = guard (language `elem` aLaCarteLanguages) *> Just language | otherwise = Just language From 4be8c2a4a1ed80a86242dcc9ebad3152c2abcb17 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Sat, 9 Dec 2017 18:14:17 -0800 Subject: [PATCH 097/133] Implement parBitraversable --- src/Semantic/Task.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Semantic/Task.hs b/src/Semantic/Task.hs index df23cd528..ae01836f4 100644 --- a/src/Semantic/Task.hs +++ b/src/Semantic/Task.hs @@ -192,7 +192,6 @@ runTaskWithOptions options task = do ReadBlobs (Right paths@[(path, Nothing)]) -> (IO.isDirectory path >>= bool (IO.readBlobsFromPaths paths) (IO.readBlobsFromDir path) >>= yield) `catchError` (pure . Left . toException) ReadBlobs (Right paths) -> (IO.readBlobsFromPaths paths >>= yield) `catchError` (pure . Left . toException) ReadBlobPairs source -> (either IO.readBlobPairsFromHandle IO.readFiles source >>= yield) `catchError` (pure . Left . toException) - -- ReadBlobPairs source -> (either IO.readBlobPairsFromHandle (traverse (traverse (uncurry IO.readFile))) source >>= yield) `catchError` (pure . Left . toException) WriteToOutput destination contents -> either B.hPutStr B.writeFile destination contents >>= yield WriteLog level message pairs -> queueLogMessage logger level message pairs >>= yield WriteStat stat -> queue statter stat >>= yield @@ -202,7 +201,7 @@ runTaskWithOptions options task = do Semantic.Task.Diff differ term1 term2 -> pure (differ term1 term2) >>= yield Render renderer input -> pure (renderer input) >>= yield Distribute tasks -> Async.mapConcurrently go tasks >>= either (pure . Left) yield . sequenceA . withStrategy (parTraversable (parTraversable rseq)) - Bidistribute tasks -> Async.runConcurrently (bitraverse (Async.Concurrently . go) (Async.Concurrently . go) tasks) >>= either (pure . Left) yield . bisequenceA + Bidistribute tasks -> Async.runConcurrently (bitraverse (Async.Concurrently . go) (Async.Concurrently . go) tasks) >>= either (pure . Left) yield . bisequenceA . withStrategy (parBitraversable (parTraversable rseq) (parTraversable rseq)) LiftIO action -> action >>= yield Throw err -> pure (Left err) Catch during handler -> do @@ -211,6 +210,9 @@ runTaskWithOptions options task = do Left err -> go (handler err) >>= either (pure . Left) yield Right a -> yield a) . fmap Right + parBitraversable :: Bitraversable t => Strategy a -> Strategy b -> Strategy (t a b) + parBitraversable strat1 strat2 = bitraverse (rparWith strat1) (rparWith strat2) + runParser :: Options -> Blob -> Parser term -> Task term runParser Options{..} blob@Blob{..} = go where From 8dae7da7d47451e2591ef7c743c6023ee385fe3b Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Sat, 9 Dec 2017 18:20:47 -0800 Subject: [PATCH 098/133] Fix reading blobPairs from stdin --- src/Semantic/IO.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Semantic/IO.hs b/src/Semantic/IO.hs index f8c0a763f..a283436ed 100644 --- a/src/Semantic/IO.hs +++ b/src/Semantic/IO.hs @@ -65,7 +65,8 @@ readBlobPairsFromHandle :: MonadIO m => Handle -> m [Blob.BlobPair] readBlobPairsFromHandle = fmap toBlobPairs . readFromHandle where toBlobPairs :: BlobDiff -> [Blob.BlobPair] - toBlobPairs = undefined + toBlobPairs BlobDiff{..} = toBlobPair <$> blobs + toBlobPair blobs = runJoin (toBlob <$> blobs) -- | Read JSON encoded blobs from a handle. readBlobsFromHandle :: MonadIO m => Handle -> m [Blob.Blob] From f644e968ab1cef151ead60ea1e14cf997570f207 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Sat, 9 Dec 2017 18:30:27 -0800 Subject: [PATCH 099/133] Remove imports that aren't needed --- src/Rendering/JSON.hs | 3 +-- src/Rendering/TOC.hs | 3 +-- src/Semantic.hs | 3 --- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Rendering/JSON.hs b/src/Rendering/JSON.hs index 3d2c202bc..f00199bb1 100644 --- a/src/Rendering/JSON.hs +++ b/src/Rendering/JSON.hs @@ -4,10 +4,9 @@ module Rendering.JSON ) where import Data.Aeson (ToJSON, toJSON, object, (.=)) -import Data.Aeson as A hiding (json) +import Data.Aeson as A import Data.Blob import Data.Foldable (toList) -import Data.Functor.Both (Both) import Data.Language import qualified Data.Map as Map import Data.Text (Text) diff --git a/src/Rendering/TOC.hs b/src/Rendering/TOC.hs index d332b7304..a2e518ec9 100644 --- a/src/Rendering/TOC.hs +++ b/src/Rendering/TOC.hs @@ -25,13 +25,12 @@ import Data.Blob import Data.ByteString.Lazy (toStrict) import Data.Diff import Data.Foldable (fold, foldl') -import Data.Functor.Both hiding (fst, snd) import Data.Functor.Foldable (cata) import Data.Function (on) import Data.Language as Language import Data.List (sortOn) import qualified Data.List as List -import qualified Data.Map as Map hiding (null) +import qualified Data.Map as Map import Data.Maybe (fromMaybe, mapMaybe) import Data.Output import Data.Patch diff --git a/src/Semantic.hs b/src/Semantic.hs index 4a6eed356..f63b5f344 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -18,15 +18,12 @@ import Data.Bifoldable import Data.Blob import Data.ByteString (ByteString) import Data.Diff -import Data.Foldable (toList) -import Data.Functor.Both as Both import Data.Functor.Classes import Data.JSON.Fields import qualified Data.Language as Language import Data.Output import Data.Record import Data.Term -import Data.These import Data.Typeable import Diffing.Algorithm (Diffable) import Diffing.Interpreter From 2315a27e8f0c3e65d23f79dcc708019a949dd374 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Sat, 9 Dec 2017 18:30:37 -0800 Subject: [PATCH 100/133] Add pathForBlobPair helper --- src/Data/Blob.hs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Data/Blob.hs b/src/Data/Blob.hs index 86a3bd2b6..d58e971e9 100644 --- a/src/Data/Blob.hs +++ b/src/Data/Blob.hs @@ -12,6 +12,7 @@ module Data.Blob , BlobPair , languageForBlobPair , languageTagForBlobPair +, pathForBlobPair ) where import Data.ByteString.Char8 (ByteString, pack) @@ -30,6 +31,11 @@ languageForBlobPair (This Blob{..}) = blobLanguage languageForBlobPair (That Blob{..}) = blobLanguage languageForBlobPair (These _ Blob{..}) = blobLanguage +pathForBlobPair :: BlobPair -> FilePath +pathForBlobPair (This Blob{..}) = blobPath +pathForBlobPair (That Blob{..}) = blobPath +pathForBlobPair (These _ Blob{..}) = blobPath + languageTagForBlobPair :: BlobPair -> [(String, String)] languageTagForBlobPair pair = maybe [] showLanguage (languageForBlobPair pair) where showLanguage = pure . (,) "language" . show From c3b6e260cb47aac08ecc8e4fe6d45e851d7d4046 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Sat, 9 Dec 2017 18:30:52 -0800 Subject: [PATCH 101/133] Simplify effectivePath/Language --- src/Semantic.hs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index f63b5f344..2e7500ed6 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -89,10 +89,8 @@ diffBlobPair renderer blobs SExpressionDiffRenderer -> run ( parse parser >=> pure . fmap keepCategory) diffSyntaxTerms (const renderSExpressionDiff) | otherwise = throwError (SomeException (NoParserForLanguage effectivePath effectiveLanguage)) - where (effectivePath, effectiveLanguage) = case blobs of - This Blob { blobLanguage = Just lang, blobPath = path } -> (path, Just lang) - That Blob { blobLanguage = Just lang, blobPath = path } -> (path, Just lang) - These _ Blob { blobLanguage = lang, blobPath = path } -> (path, lang) + where effectiveLanguage = languageForBlobPair blobs + effectivePath = pathForBlobPair blobs qualify language | OldToCDiffRenderer <- renderer = guard (language `elem` aLaCarteLanguages) *> Just language | otherwise = Just language From 01ddc29c827e64be19226e20395e8411674d84b9 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Sat, 9 Dec 2017 18:31:01 -0800 Subject: [PATCH 102/133] Fix Util functions --- src/Semantic/Util.hs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Semantic/Util.hs b/src/Semantic/Util.hs index ea31f9536..90897ec47 100644 --- a/src/Semantic/Util.hs +++ b/src/Semantic/Util.hs @@ -7,7 +7,6 @@ import Control.Monad.IO.Class import Data.Align.Generic import Data.Blob import Data.Diff -import Data.Functor.Both import Data.Functor.Classes import Data.Range import Data.Record @@ -31,8 +30,8 @@ diffWithParser :: (HasField fields Data.Span.Span, GAlign syntax, HasDeclaration syntax) => Parser (Term syntax (Record fields)) - -> Both Blob + -> BlobPair -> Task (Diff syntax (Record (Maybe Declaration ': fields)) (Record (Maybe Declaration ': fields))) diffWithParser parser = run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) where - run parse sourceBlobs = distributeFor sourceBlobs (\b -> if blobExists b then Just <$> parse b else pure Nothing) >>= runBothWith (diffTermPair diffTerms) + run parse blobs = bidistributeFor blobs parse parse >>= diffTermPair diffTerms From 24d98ad71c93aa524ef16acf57ab1ba621b473a8 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Sun, 10 Dec 2017 08:46:17 -0800 Subject: [PATCH 103/133] Fix up tests --- src/Rendering/JSON.hs | 6 +++--- src/Semantic/IO.hs | 21 +++++++++------------ src/Semantic/Task.hs | 2 +- test/Rendering/TOC/Spec.hs | 4 ++-- test/Semantic/IO/Spec.hs | 14 +++++++------- test/Semantic/Spec.hs | 12 ++++++------ test/SpecHelpers.hs | 12 +++++++++--- 7 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/Rendering/JSON.hs b/src/Rendering/JSON.hs index f00199bb1..3b2b38b03 100644 --- a/src/Rendering/JSON.hs +++ b/src/Rendering/JSON.hs @@ -6,7 +6,7 @@ module Rendering.JSON import Data.Aeson (ToJSON, toJSON, object, (.=)) import Data.Aeson as A import Data.Blob -import Data.Foldable (toList) +import Data.Bifoldable (biList) import Data.Language import qualified Data.Map as Map import Data.Text (Text) @@ -21,8 +21,8 @@ import GHC.Generics renderJSONDiff :: ToJSON a => BlobPair -> a -> Map.Map Text Value renderJSONDiff blobs diff = Map.fromList [ ("diff", toJSON diff) - , ("oids", toJSON (decodeUtf8 . blobOid <$> toList blobs)) - , ("paths", toJSON (blobPath <$> toList blobs)) + , ("oids", toJSON (decodeUtf8 . blobOid <$> biList blobs)) + , ("paths", toJSON (blobPath <$> biList blobs)) ] data File a = File { filePath :: FilePath, fileLanguage :: Maybe Language, fileContent :: a } diff --git a/src/Semantic/IO.hs b/src/Semantic/IO.hs index a283436ed..b6716ac05 100644 --- a/src/Semantic/IO.hs +++ b/src/Semantic/IO.hs @@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings, TypeSynonymInstances, DeriveAnyClass, DuplicateRecordFields, ScopedTypeVariables, TupleSections #-} module Semantic.IO ( readFile -, readFiles +, readFilePair , isDirectory , readBlobPairsFromHandle , readBlobsFromHandle @@ -41,17 +41,14 @@ readFile path language = do raw <- liftIO $ (Just <$> B.readFile path) `catch` (const (pure Nothing) :: IOException -> IO (Maybe B.ByteString)) pure $ fromMaybe (Blob.emptyBlob path) (Blob.sourceBlob path language . fromBytes <$> raw) -readFiles :: forall m. MonadIO m => [Both (FilePath, Maybe Language)] -> m [Blob.BlobPair] -readFiles files = for files (runBothWith readFilesToBlobPair) - where - readFilesToBlobPair :: (FilePath, Maybe Language) -> (FilePath, Maybe Language) -> m Blob.BlobPair - readFilesToBlobPair a b = do - before <- uncurry readFile a - after <- uncurry readFile b - case (Blob.blobExists before, Blob.blobExists after) of - (True, False) -> pure (This before) - (False, True) -> pure (That after) - _ -> pure (These before after) +readFilePair :: forall m. MonadIO m => (FilePath, Maybe Language) -> (FilePath, Maybe Language) -> m Blob.BlobPair +readFilePair a b = do + before <- uncurry readFile a + after <- uncurry readFile b + case (Blob.blobExists before, Blob.blobExists after) of + (True, False) -> pure (This before) + (False, True) -> pure (That after) + _ -> pure (These before after) isDirectory :: MonadIO m => FilePath -> m Bool isDirectory path = liftIO (doesDirectoryExist path) >>= pure diff --git a/src/Semantic/Task.hs b/src/Semantic/Task.hs index ae01836f4..aafe017ff 100644 --- a/src/Semantic/Task.hs +++ b/src/Semantic/Task.hs @@ -191,7 +191,7 @@ runTaskWithOptions options task = do ReadBlobs (Left handle) -> (IO.readBlobsFromHandle handle >>= yield) `catchError` (pure . Left . toException) ReadBlobs (Right paths@[(path, Nothing)]) -> (IO.isDirectory path >>= bool (IO.readBlobsFromPaths paths) (IO.readBlobsFromDir path) >>= yield) `catchError` (pure . Left . toException) ReadBlobs (Right paths) -> (IO.readBlobsFromPaths paths >>= yield) `catchError` (pure . Left . toException) - ReadBlobPairs source -> (either IO.readBlobPairsFromHandle IO.readFiles source >>= yield) `catchError` (pure . Left . toException) + ReadBlobPairs source -> (either IO.readBlobPairsFromHandle (traverse (runBothWith IO.readFilePair)) source >>= yield) `catchError` (pure . Left . toException) WriteToOutput destination contents -> either B.hPutStr B.writeFile destination contents >>= yield WriteLog level message pairs -> queueLogMessage logger level message pairs >>= yield WriteStat stat -> queue statter stat >>= yield diff --git a/test/Rendering/TOC/Spec.hs b/test/Rendering/TOC/Spec.hs index e8aae8ed3..706a0137a 100644 --- a/test/Rendering/TOC/Spec.hs +++ b/test/Rendering/TOC/Spec.hs @@ -240,8 +240,8 @@ isMethodOrFunction a = case unTerm a of (a `In` _) | getField a == C.SingletonMethod -> True _ -> False -blobsForPaths :: Both FilePath -> IO (Both Blob) -blobsForPaths = traverse (readFile . ("test/fixtures/toc/" <>)) +blobsForPaths :: Both FilePath -> IO BlobPair +blobsForPaths = readFilePair . (fmap ("test/fixtures/toc/" <>)) sourceSpanBetween :: (Int, Int) -> (Int, Int) -> Span sourceSpanBetween (s1, e1) (s2, e2) = Span (Pos s1 e1) (Pos s2 e2) diff --git a/test/Semantic/IO/Spec.hs b/test/Semantic/IO/Spec.hs index e9ee6982b..9232e0b0a 100644 --- a/test/Semantic/IO/Spec.hs +++ b/test/Semantic/IO/Spec.hs @@ -28,34 +28,34 @@ spec = parallel $ do let b = sourceBlob "method.rb" (Just Ruby) "def bar(x); end" it "returns blobs for valid JSON encoded diff input" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff.json" - blobs `shouldBe` [both a b] + blobs `shouldBe` [These a b] it "returns blobs when there's no before" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-no-before.json" - blobs `shouldBe` [both (emptyBlob "method.rb") b] + blobs `shouldBe` [That b] it "returns blobs when there's null before" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-null-before.json" - blobs `shouldBe` [both (emptyBlob "method.rb") b] + blobs `shouldBe` [That b] it "returns blobs when there's no after" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-no-after.json" - blobs `shouldBe` [both a (emptyBlob "method.rb")] + blobs `shouldBe` [This a] it "returns blobs when there's null after" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-null-after.json" - blobs `shouldBe` [both a (emptyBlob "method.rb")] + blobs `shouldBe` [This a] it "returns blobs for unsupported language" $ do h <- openFile "test/fixtures/input/diff-unsupported-language.json" ReadMode blobs <- readBlobPairsFromHandle h let b' = sourceBlob "test.kt" Nothing "fun main(args: Array) {\nprintln(\"hi\")\n}\n" - blobs `shouldBe` [both (emptyBlob "test.kt") b'] + blobs `shouldBe` [That b'] it "detects language based on filepath for empty language" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-empty-language.json" - blobs `shouldBe` [both a b] + blobs `shouldBe` [These a b] it "throws on blank input" $ do h <- openFile "test/fixtures/input/blank.json" ReadMode diff --git a/test/Semantic/Spec.hs b/test/Semantic/Spec.hs index 884b55f60..9176a9fe5 100644 --- a/test/Semantic/Spec.hs +++ b/test/Semantic/Spec.hs @@ -28,13 +28,13 @@ spec = parallel $ do output `shouldBe` "(Program\n (Method\n (Empty)\n (Identifier)\n ([])))\n" describe "diffTermPair" $ do - it "produces an Insert when the first blob is missing" $ do - result <- runTask (diffTermPair (both (emptyBlob "/foo") (sourceBlob "/foo" Nothing "")) replacing (termIn () []) (termIn () [])) - result `shouldBe` Diff (Patch (Insert (In () []))) + it "produces an Insert when the first term is missing" $ do + result <- runTask (diffTermPair replacing (That (termIn () []))) + result `shouldBe` (Diff (Patch (Insert (In () []))) :: Diff [] () ()) - it "produces a Delete when the second blob is missing" $ do - result <- runTask (diffTermPair (both (sourceBlob "/foo" Nothing "") (emptyBlob "/foo")) replacing (termIn () []) (termIn () [])) - result `shouldBe` Diff (Patch (Delete (In () []))) + it "produces a Delete when the second term is missing" $ do + result <- runTask (diffTermPair replacing (This (termIn () []))) + result `shouldBe` (Diff (Patch (Delete (In () []))) :: Diff [] () ()) where methodsBlob = Blob "def foo\nend\n" "ff7bbbe9495f61d9e1e58c597502d152bab1761e" "methods.rb" (Just defaultPlainBlob) (Just Ruby) diff --git a/test/SpecHelpers.hs b/test/SpecHelpers.hs index 90d0abd90..dfbedd460 100644 --- a/test/SpecHelpers.hs +++ b/test/SpecHelpers.hs @@ -3,9 +3,11 @@ module SpecHelpers ( diffFilePaths , parseFilePath , readFile +, readFilePair , languageForFilePath ) where +import Control.Monad ((<=<)) import Control.Exception import Data.Blob import qualified Data.ByteString as B @@ -17,13 +19,17 @@ import Prelude hiding (readFile) import Rendering.Renderer import Semantic import Semantic.Task +import qualified Semantic.IO as IO import System.FilePath +readFilePair :: Both FilePath -> IO BlobPair +readFilePair paths = do + let paths' = fmap (\p -> (p, languageForFilePath p)) paths + runBothWith IO.readFilePair paths' + -- | Returns an s-expression formatted diff for the specified FilePath pair. diffFilePaths :: Both FilePath -> IO B.ByteString -diffFilePaths paths = do - blobs <- traverse readFile paths - runTask (diffBlobPair SExpressionDiffRenderer blobs) +diffFilePaths paths = readFilePair paths >>= runTask . diffBlobPair SExpressionDiffRenderer -- | Returns an s-expression parse tree for the specified FilePath. parseFilePath :: FilePath -> IO B.ByteString From afd82561e984f2450e289c93a542ef3dcd86dbd8 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 08:27:02 -0800 Subject: [PATCH 104/133] Minor doc cleanup --- src/Semantic.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index 2e7500ed6..6308be283 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -113,7 +113,7 @@ diffBlobPair renderer blobs where languageTag = languageTagForBlobPair blobs --- | A task to diff a pair of 'Term's, producing insertion/deletion 'Patch'es for non-existent 'Blob's. +-- | A task to diff 'Term's, producing insertion/deletion 'Patch'es for non-existent 'Blob's. diffTermPair :: Functor syntax => Differ syntax ann1 ann2 -> These (Term syntax ann1) (Term syntax ann2) -> Task (Diff syntax ann1 ann2) diffTermPair _ (This t1) = pure (deleting t1) diffTermPair _ (That t2) = pure (inserting t2) From 148edbc184d372a0d29bc3cab422884b92ddede1 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 08:27:13 -0800 Subject: [PATCH 105/133] Remove spec specific readFile --- test/SpecHelpers.hs | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/test/SpecHelpers.hs b/test/SpecHelpers.hs index dfbedd460..9dec0adeb 100644 --- a/test/SpecHelpers.hs +++ b/test/SpecHelpers.hs @@ -2,7 +2,6 @@ module SpecHelpers ( diffFilePaths , parseFilePath -, readFile , readFilePair , languageForFilePath ) where @@ -15,37 +14,24 @@ import Data.Functor.Both import Data.Language import Data.Maybe (fromMaybe) import Data.Source -import Prelude hiding (readFile) import Rendering.Renderer import Semantic import Semantic.Task import qualified Semantic.IO as IO import System.FilePath -readFilePair :: Both FilePath -> IO BlobPair -readFilePair paths = do - let paths' = fmap (\p -> (p, languageForFilePath p)) paths - runBothWith IO.readFilePair paths' - -- | Returns an s-expression formatted diff for the specified FilePath pair. diffFilePaths :: Both FilePath -> IO B.ByteString diffFilePaths paths = readFilePair paths >>= runTask . diffBlobPair SExpressionDiffRenderer -- | Returns an s-expression parse tree for the specified FilePath. parseFilePath :: FilePath -> IO B.ByteString -parseFilePath path = do - blob <- readFile path - runTask (parseBlob SExpressionTermRenderer blob) +parseFilePath path = IO.readFile path (languageForFilePath path) >>= runTask . parseBlob SExpressionTermRenderer --- | Read a file to a Blob. --- --- NB: This is intentionally duplicated from Command.Files because eventually --- we want to be able to test a core Semantic library that has no knowledge of --- the filesystem or Git. The tests, however, will still leverage reading files. -readFile :: FilePath -> IO Blob -readFile path = do - source <- (Just . fromBytes <$> B.readFile path) `catch` (const (pure Nothing) :: IOException -> IO (Maybe Source)) - pure $ fromMaybe (emptyBlob path) (sourceBlob path (languageForFilePath path) <$> source) +-- | Read two files to a BlobPair. +readFilePair :: Both FilePath -> IO BlobPair +readFilePair paths = let paths' = fmap (\p -> (p, languageForFilePath p)) paths in + runBothWith IO.readFilePair paths' -- | Returns a Maybe Language based on the FilePath's extension. languageForFilePath :: FilePath -> Maybe Language From 844fc3f8b58ef18cf9b3f981938ff687d313bee0 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 09:09:07 -0800 Subject: [PATCH 106/133] Use Join These Blob instead --- src/Data/Blob.hs | 30 +++++++++++++++++++++++------- src/Rendering/JSON.hs | 10 ++++------ src/Rendering/TOC.hs | 3 ++- src/Semantic.hs | 5 +++-- src/Semantic/IO.hs | 8 ++++---- src/Semantic/Util.hs | 3 ++- test/Semantic/IO/Spec.hs | 14 +++++++------- 7 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/Data/Blob.hs b/src/Data/Blob.hs index d58e971e9..198aa8deb 100644 --- a/src/Data/Blob.hs +++ b/src/Data/Blob.hs @@ -10,12 +10,16 @@ module Data.Blob , sourceBlob , nullOid , BlobPair +, blobPairDiffing +, blobPairInserting +, blobPairDeleting , languageForBlobPair , languageTagForBlobPair , pathForBlobPair ) where import Data.ByteString.Char8 (ByteString, pack) +import Data.Bifunctor.Join import Data.Language import Data.These import Data.Maybe (isJust) @@ -24,17 +28,29 @@ import Data.Word import Numeric -type BlobPair = These Blob Blob +-- | Represents a blobs suitable for diffing which can be either a blob to +-- delete, a blob to insert, or a pair of blobs to diff. +type BlobPair = Join These Blob + + +blobPairDiffing :: Blob -> Blob -> BlobPair +blobPairDiffing a b = Join (These a b) + +blobPairInserting :: Blob -> BlobPair +blobPairInserting = Join . That + +blobPairDeleting :: Blob -> BlobPair +blobPairDeleting = Join . This languageForBlobPair :: BlobPair -> Maybe Language -languageForBlobPair (This Blob{..}) = blobLanguage -languageForBlobPair (That Blob{..}) = blobLanguage -languageForBlobPair (These _ Blob{..}) = blobLanguage +languageForBlobPair (Join (This Blob{..})) = blobLanguage +languageForBlobPair (Join (That Blob{..})) = blobLanguage +languageForBlobPair (Join (These _ Blob{..})) = blobLanguage pathForBlobPair :: BlobPair -> FilePath -pathForBlobPair (This Blob{..}) = blobPath -pathForBlobPair (That Blob{..}) = blobPath -pathForBlobPair (These _ Blob{..}) = blobPath +pathForBlobPair (Join (This Blob{..})) = blobPath +pathForBlobPair (Join (That Blob{..})) = blobPath +pathForBlobPair (Join (These _ Blob{..})) = blobPath languageTagForBlobPair :: BlobPair -> [(String, String)] languageTagForBlobPair pair = maybe [] showLanguage (languageForBlobPair pair) diff --git a/src/Rendering/JSON.hs b/src/Rendering/JSON.hs index 3b2b38b03..f386dbbf4 100644 --- a/src/Rendering/JSON.hs +++ b/src/Rendering/JSON.hs @@ -7,22 +7,19 @@ import Data.Aeson (ToJSON, toJSON, object, (.=)) import Data.Aeson as A import Data.Blob import Data.Bifoldable (biList) +import Data.Bifunctor.Join import Data.Language import qualified Data.Map as Map import Data.Text (Text) import Data.Text.Encoding (decodeUtf8) import GHC.Generics --- --- Diffs --- - -- | Render a diff to a string representing its JSON. renderJSONDiff :: ToJSON a => BlobPair -> a -> Map.Map Text Value renderJSONDiff blobs diff = Map.fromList [ ("diff", toJSON diff) - , ("oids", toJSON (decodeUtf8 . blobOid <$> biList blobs)) - , ("paths", toJSON (blobPath <$> biList blobs)) + , ("oids", toJSON (decodeUtf8 . blobOid <$> (biList . runJoin) blobs)) + , ("paths", toJSON (blobPath <$> (biList . runJoin) blobs)) ] data File a = File { filePath :: FilePath, fileLanguage :: Maybe Language, fileContent :: a } @@ -31,5 +28,6 @@ data File a = File { filePath :: FilePath, fileLanguage :: Maybe Language, fileC instance ToJSON a => ToJSON (File a) where toJSON File{..} = object [ "filePath" .= filePath, "language" .= fileLanguage, "programNode" .= fileContent ] +-- | Render a term to a string representing its JSON. renderJSONTerm :: ToJSON a => Blob -> a -> [Value] renderJSONTerm Blob{..} = pure . toJSON . File blobPath blobLanguage diff --git a/src/Rendering/TOC.hs b/src/Rendering/TOC.hs index a2e518ec9..9f5f0ee31 100644 --- a/src/Rendering/TOC.hs +++ b/src/Rendering/TOC.hs @@ -21,6 +21,7 @@ import Data.Aeson import Data.Align (bicrosswalk) import Data.Bifoldable (bifoldMap) import Data.Bifunctor (bimap) +import Data.Bifunctor.Join import Data.Blob import Data.ByteString.Lazy (toStrict) import Data.Diff @@ -163,7 +164,7 @@ renderToCDiff :: (HasField fields (Maybe Declaration), HasField fields Span, Fol renderToCDiff blobs = uncurry Summaries . bimap toMap toMap . List.partition isValidSummary . diffTOC where toMap [] = mempty toMap as = Map.singleton summaryKey (toJSON <$> as) - summaryKey = T.pack $ case bimap blobPath blobPath blobs of + summaryKey = T.pack $ case bimap blobPath blobPath (runJoin blobs) of This before -> before That after -> after These before after | before == after -> after diff --git a/src/Semantic.hs b/src/Semantic.hs index 6308be283..0f61f2e25 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -15,6 +15,7 @@ import Control.Monad ((>=>), guard) import Control.Monad.Error.Class import Data.Align.Generic import Data.Bifoldable +import Data.Bifunctor.Join import Data.Blob import Data.ByteString (ByteString) import Data.Diff @@ -103,9 +104,9 @@ diffBlobPair renderer blobs , Language.TypeScript ] - run :: (Foldable syntax, Functor syntax) => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (These Blob Blob -> Diff syntax ann ann -> output) -> Task output + run :: (Foldable syntax, Functor syntax) => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (Join These Blob -> Diff syntax ann ann -> output) -> Task output run parse diff renderer = do - terms <- bidistributeFor blobs parse parse + terms <- bidistributeFor (runJoin blobs) parse parse time "diff" languageTag $ do diff <- diffTermPair diff terms writeStat (Stat.count "diff.nodes" (bilength diff) languageTag) diff --git a/src/Semantic/IO.hs b/src/Semantic/IO.hs index b6716ac05..cc1327648 100644 --- a/src/Semantic/IO.hs +++ b/src/Semantic/IO.hs @@ -46,9 +46,9 @@ readFilePair a b = do before <- uncurry readFile a after <- uncurry readFile b case (Blob.blobExists before, Blob.blobExists after) of - (True, False) -> pure (This before) - (False, True) -> pure (That after) - _ -> pure (These before after) + (True, False) -> pure (Join (This before)) + (False, True) -> pure (Join (That after)) + _ -> pure (Join (These before after)) isDirectory :: MonadIO m => FilePath -> m Bool isDirectory path = liftIO (doesDirectoryExist path) >>= pure @@ -63,7 +63,7 @@ readBlobPairsFromHandle = fmap toBlobPairs . readFromHandle where toBlobPairs :: BlobDiff -> [Blob.BlobPair] toBlobPairs BlobDiff{..} = toBlobPair <$> blobs - toBlobPair blobs = runJoin (toBlob <$> blobs) + toBlobPair blobs = toBlob <$> blobs -- | Read JSON encoded blobs from a handle. readBlobsFromHandle :: MonadIO m => Handle -> m [Blob.Blob] diff --git a/src/Semantic/Util.hs b/src/Semantic/Util.hs index 90897ec47..610087107 100644 --- a/src/Semantic/Util.hs +++ b/src/Semantic/Util.hs @@ -8,6 +8,7 @@ import Data.Align.Generic import Data.Blob import Data.Diff import Data.Functor.Classes +import Data.Bifunctor.Join import Data.Range import Data.Record import Data.Span @@ -34,4 +35,4 @@ diffWithParser :: (HasField fields Data.Span.Span, -> Task (Diff syntax (Record (Maybe Declaration ': fields)) (Record (Maybe Declaration ': fields))) diffWithParser parser = run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) where - run parse blobs = bidistributeFor blobs parse parse >>= diffTermPair diffTerms + run parse blobs = bidistributeFor (runJoin blobs) parse parse >>= diffTermPair diffTerms diff --git a/test/Semantic/IO/Spec.hs b/test/Semantic/IO/Spec.hs index 9232e0b0a..3f223351e 100644 --- a/test/Semantic/IO/Spec.hs +++ b/test/Semantic/IO/Spec.hs @@ -28,34 +28,34 @@ spec = parallel $ do let b = sourceBlob "method.rb" (Just Ruby) "def bar(x); end" it "returns blobs for valid JSON encoded diff input" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff.json" - blobs `shouldBe` [These a b] + blobs `shouldBe` [blobPairDiffing a b] it "returns blobs when there's no before" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-no-before.json" - blobs `shouldBe` [That b] + blobs `shouldBe` [blobPairInserting b] it "returns blobs when there's null before" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-null-before.json" - blobs `shouldBe` [That b] + blobs `shouldBe` [blobPairInserting b] it "returns blobs when there's no after" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-no-after.json" - blobs `shouldBe` [This a] + blobs `shouldBe` [blobPairDeleting a] it "returns blobs when there's null after" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-null-after.json" - blobs `shouldBe` [This a] + blobs `shouldBe` [blobPairDeleting a] it "returns blobs for unsupported language" $ do h <- openFile "test/fixtures/input/diff-unsupported-language.json" ReadMode blobs <- readBlobPairsFromHandle h let b' = sourceBlob "test.kt" Nothing "fun main(args: Array) {\nprintln(\"hi\")\n}\n" - blobs `shouldBe` [That b'] + blobs `shouldBe` [blobPairInserting b'] it "detects language based on filepath for empty language" $ do blobs <- blobsFromFilePath "test/fixtures/input/diff-empty-language.json" - blobs `shouldBe` [These a b] + blobs `shouldBe` [blobPairDiffing a b] it "throws on blank input" $ do h <- openFile "test/fixtures/input/blank.json" ReadMode From 8ce213fc44d8cff8a2c0cee37385487ae1346481 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 10:51:52 -0800 Subject: [PATCH 107/133] No longer need to track blobKind in Maybe --- src/Data/Blob.hs | 15 +++------------ src/Data/Error.hs | 2 +- src/Semantic.hs | 2 +- src/Semantic/IO.hs | 23 ++++++++++++----------- src/Semantic/Util.hs | 3 ++- test/Rendering/TOC/Spec.hs | 2 +- test/Semantic/CLI/Spec.hs | 1 - test/Semantic/IO/Spec.hs | 9 ++++----- test/Semantic/Spec.hs | 2 +- test/SpecHelpers.hs | 4 ++-- 10 files changed, 27 insertions(+), 36 deletions(-) diff --git a/src/Data/Blob.hs b/src/Data/Blob.hs index 198aa8deb..7a8e9e4ef 100644 --- a/src/Data/Blob.hs +++ b/src/Data/Blob.hs @@ -4,9 +4,7 @@ module Data.Blob , These(..) , modeToDigits , defaultPlainBlob -, emptyBlob , nullBlob -, blobExists , sourceBlob , nullOid , BlobPair @@ -22,7 +20,6 @@ import Data.ByteString.Char8 (ByteString, pack) import Data.Bifunctor.Join import Data.Language import Data.These -import Data.Maybe (isJust) import Data.Source as Source import Data.Word import Numeric @@ -57,12 +54,12 @@ languageTagForBlobPair pair = maybe [] showLanguage (languageForBlobPair pair) where showLanguage = pure . (,) "language" . show --- | The source, oid, path, and Maybe BlobKind of a blob. +-- | The source, oid, path, kind and language of a blob. data Blob = Blob { blobSource :: Source -- ^ The UTF-8 encoded source text of the blob. , blobOid :: ByteString -- ^ The Git object ID (SHA-1) of the blob. , blobPath :: FilePath -- ^ The file path to the blob. - , blobKind :: Maybe BlobKind -- ^ The kind of blob, Nothing denotes a blob that doesn't exist (e.g. on one side of a diff for adding a new file or deleting a file). + , blobKind :: BlobKind -- ^ The kind of blob. , blobLanguage :: Maybe Language -- ^ The language of this blob. Nothing denotes a langauge we don't support yet. } deriving (Show, Eq) @@ -80,17 +77,11 @@ modeToDigits (SymlinkBlob mode) = pack $ showOct mode "" defaultPlainBlob :: BlobKind defaultPlainBlob = PlainBlob 0o100644 -emptyBlob :: FilePath -> Blob -emptyBlob filepath = Blob mempty nullOid filepath Nothing Nothing - nullBlob :: Blob -> Bool nullBlob Blob{..} = blobOid == nullOid || nullSource blobSource -blobExists :: Blob -> Bool -blobExists Blob{..} = isJust blobKind - sourceBlob :: FilePath -> Maybe Language -> Source -> Blob -sourceBlob filepath language source = Blob source nullOid filepath (Just defaultPlainBlob) language +sourceBlob filepath language source = Blob source nullOid filepath defaultPlainBlob language nullOid :: ByteString nullOid = "0000000000000000000000000000000000000000" diff --git a/src/Data/Error.hs b/src/Data/Error.hs index 13dc2dea7..f07756aab 100644 --- a/src/Data/Error.hs +++ b/src/Data/Error.hs @@ -39,7 +39,7 @@ type Colourize = Bool formatError :: IncludeSource -> Colourize -> Blob -> Error String -> String formatError includeSource colourize Blob{..} Error{..} = ($ "") - $ withSGRCode colourize [SetConsoleIntensity BoldIntensity] (showSpan (maybe Nothing (const (Just blobPath)) blobKind) errorSpan . showString ": ") + $ withSGRCode colourize [SetConsoleIntensity BoldIntensity] (showSpan (Just blobPath) errorSpan . showString ": ") . withSGRCode colourize [SetColor Foreground Vivid Red] (showString "error") . showString ": " . showExpectation colourize errorExpected errorActual . showChar '\n' . (if includeSource then showString (unpack context) . (if "\n" `isSuffixOf` context then id else showChar '\n') diff --git a/src/Semantic.hs b/src/Semantic.hs index 0f61f2e25..0cf466f35 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -44,7 +44,7 @@ import Semantic.Task as Task -- - Easy to consume this interface from other application (e.g a cmdline or web server app). parseBlobs :: Output output => TermRenderer output -> [Blob] -> Task ByteString -parseBlobs renderer = fmap toOutput . distributeFoldMap (parseBlob renderer) . filter blobExists +parseBlobs renderer = fmap toOutput . distributeFoldMap (parseBlob renderer) -- | A task to parse a 'Blob' and render the resulting 'Term'. parseBlob :: TermRenderer output -> Blob -> Task output diff --git a/src/Semantic/IO.hs b/src/Semantic/IO.hs index cc1327648..edc5593b4 100644 --- a/src/Semantic/IO.hs +++ b/src/Semantic/IO.hs @@ -10,7 +10,6 @@ module Semantic.IO , languageForFilePath ) where -import Control.Exception (catch, IOException) import Control.Monad.IO.Class import Data.Aeson import qualified Data.Blob as Blob @@ -35,20 +34,21 @@ import System.Directory (doesDirectoryExist) import Text.Read -- | Read a utf8-encoded file to a 'Blob'. -readFile :: forall m. MonadIO m => FilePath -> Maybe Language -> m Blob.Blob -readFile path@"/dev/null" _ = pure (Blob.emptyBlob path) +readFile :: forall m. MonadIO m => FilePath -> Maybe Language -> m (Maybe Blob.Blob) +readFile "/dev/null" _ = pure Nothing readFile path language = do - raw <- liftIO $ (Just <$> B.readFile path) `catch` (const (pure Nothing) :: IOException -> IO (Maybe B.ByteString)) - pure $ fromMaybe (Blob.emptyBlob path) (Blob.sourceBlob path language . fromBytes <$> raw) + raw <- liftIO $ (Just <$> B.readFile path) + pure $ Blob.sourceBlob path language . fromBytes <$> raw readFilePair :: forall m. MonadIO m => (FilePath, Maybe Language) -> (FilePath, Maybe Language) -> m Blob.BlobPair readFilePair a b = do before <- uncurry readFile a after <- uncurry readFile b - case (Blob.blobExists before, Blob.blobExists after) of - (True, False) -> pure (Join (This before)) - (False, True) -> pure (Join (That after)) - _ -> pure (Join (These before after)) + case (before, after) of + (Just a, Nothing) -> pure (Join (This a)) + (Nothing, Just b) -> pure (Join (That b)) + (Just a, Just b) -> pure (Join (These a b)) + _ -> fail "expected file pair with content on at least one side" isDirectory :: MonadIO m => FilePath -> m Bool isDirectory path = liftIO (doesDirectoryExist path) >>= pure @@ -71,13 +71,14 @@ readBlobsFromHandle = fmap toBlobs . readFromHandle where toBlobs BlobParse{..} = fmap toBlob blobs readBlobsFromPaths :: MonadIO m => [(FilePath, Maybe Language)] -> m [Blob.Blob] -readBlobsFromPaths = traverse (uncurry Semantic.IO.readFile) +readBlobsFromPaths files = traverse (uncurry Semantic.IO.readFile) files >>= pure . catMaybes readBlobsFromDir :: MonadIO m => FilePath -> m [Blob.Blob] readBlobsFromDir path = do paths <- liftIO (globDir1 (compile "[^vendor]**/*[.rb|.js|.tsx|.go|.py]") path) let paths' = catMaybes $ fmap (\p -> (p,) . Just <$> languageForFilePath p) paths - traverse (uncurry readFile) paths' + blobs <- traverse (uncurry readFile) paths' + pure (catMaybes blobs) readFromHandle :: (FromJSON a, MonadIO m) => Handle -> m a readFromHandle h = do diff --git a/src/Semantic/Util.hs b/src/Semantic/Util.hs index 610087107..f42972617 100644 --- a/src/Semantic/Util.hs +++ b/src/Semantic/Util.hs @@ -5,6 +5,7 @@ module Semantic.Util where import Analysis.Declaration import Control.Monad.IO.Class import Data.Align.Generic +import Data.Maybe import Data.Blob import Data.Diff import Data.Functor.Classes @@ -21,7 +22,7 @@ import Semantic.IO as IO import Semantic.Task file :: MonadIO m => FilePath -> m Blob -file path = IO.readFile path (languageForFilePath path) +file path = IO.readFile path (languageForFilePath path) >>= pure . fromJust diffWithParser :: (HasField fields Data.Span.Span, HasField fields Range, diff --git a/test/Rendering/TOC/Spec.hs b/test/Rendering/TOC/Spec.hs index 706a0137a..aa704c7ef 100644 --- a/test/Rendering/TOC/Spec.hs +++ b/test/Rendering/TOC/Spec.hs @@ -253,4 +253,4 @@ blankDiff = merge (arrayInfo, arrayInfo) (Indexed [ inserting (Term $ literalInf literalInfo = Nothing :. Range 1 2 :. StringLiteral :. sourceSpanBetween (1, 2) (1, 4) :. Nil blankDiffBlobs :: Both Blob -blankDiffBlobs = both (Blob (fromText "[]") nullOid "a.js" (Just defaultPlainBlob) (Just TypeScript)) (Blob (fromText "[a]") nullOid "b.js" (Just defaultPlainBlob) (Just TypeScript)) +blankDiffBlobs = both (Blob (fromText "[]") nullOid "a.js" defaultPlainBlob (Just TypeScript)) (Blob (fromText "[a]") nullOid "b.js" defaultPlainBlob (Just TypeScript)) diff --git a/test/Semantic/CLI/Spec.hs b/test/Semantic/CLI/Spec.hs index cdf23172a..1d60ab225 100644 --- a/test/Semantic/CLI/Spec.hs +++ b/test/Semantic/CLI/Spec.hs @@ -38,7 +38,6 @@ parseFixtures = , (SomeRenderer JSONTermRenderer, pathMode, jsonParseTreeOutput) , (SomeRenderer JSONTermRenderer, pathMode', jsonParseTreeOutput') , (SomeRenderer JSONTermRenderer, Right [], emptyJsonParseTreeOutput) - , (SomeRenderer JSONTermRenderer, Right [("not-a-file.rb", Just Ruby)], emptyJsonParseTreeOutput) , (SomeRenderer ToCTermRenderer, Right [("test/fixtures/ruby/method-declaration.A.rb", Just Ruby)], tocOutput) ] where pathMode = Right [("test/fixtures/ruby/and-or.A.rb", Just Ruby)] diff --git a/test/Semantic/IO/Spec.hs b/test/Semantic/IO/Spec.hs index 3f223351e..ca08710e0 100644 --- a/test/Semantic/IO/Spec.hs +++ b/test/Semantic/IO/Spec.hs @@ -9,19 +9,18 @@ import Prelude hiding (readFile) import Semantic.IO import System.Exit (ExitCode(..)) import System.IO (IOMode(..), openFile) -import Test.Hspec hiding (shouldBe, shouldNotBe, shouldThrow, errorCall) +import Test.Hspec hiding (shouldBe, shouldNotBe, shouldThrow, errorCall, anyIOException) import Test.Hspec.Expectations.Pretty spec :: Spec spec = parallel $ do describe "readFile" $ do it "returns a blob for extant files" $ do - blob <- readFile "semantic-diff.cabal" Nothing + Just blob <- readFile "semantic-diff.cabal" Nothing blobPath blob `shouldBe` "semantic-diff.cabal" - it "returns a nullBlob for absent files" $ do - blob <- readFile "this file should not exist" Nothing - nullBlob blob `shouldBe` True + it "throws for absent files" $ do + readFile "this file should not exist" Nothing `shouldThrow` anyIOException describe "readBlobPairsFromHandle" $ do let a = sourceBlob "method.rb" (Just Ruby) "def foo; end" diff --git a/test/Semantic/Spec.hs b/test/Semantic/Spec.hs index 9176a9fe5..c417cc54f 100644 --- a/test/Semantic/Spec.hs +++ b/test/Semantic/Spec.hs @@ -37,4 +37,4 @@ spec = parallel $ do result `shouldBe` (Diff (Patch (Delete (In () []))) :: Diff [] () ()) where - methodsBlob = Blob "def foo\nend\n" "ff7bbbe9495f61d9e1e58c597502d152bab1761e" "methods.rb" (Just defaultPlainBlob) (Just Ruby) + methodsBlob = Blob "def foo\nend\n" "ff7bbbe9495f61d9e1e58c597502d152bab1761e" "methods.rb" defaultPlainBlob (Just Ruby) diff --git a/test/SpecHelpers.hs b/test/SpecHelpers.hs index 9dec0adeb..82ea1d181 100644 --- a/test/SpecHelpers.hs +++ b/test/SpecHelpers.hs @@ -12,7 +12,7 @@ import Data.Blob import qualified Data.ByteString as B import Data.Functor.Both import Data.Language -import Data.Maybe (fromMaybe) +import Data.Maybe (fromMaybe, fromJust) import Data.Source import Rendering.Renderer import Semantic @@ -26,7 +26,7 @@ diffFilePaths paths = readFilePair paths >>= runTask . diffBlobPair SExpressionD -- | Returns an s-expression parse tree for the specified FilePath. parseFilePath :: FilePath -> IO B.ByteString -parseFilePath path = IO.readFile path (languageForFilePath path) >>= runTask . parseBlob SExpressionTermRenderer +parseFilePath path = IO.readFile path (languageForFilePath path) >>= pure . fromJust >>= runTask . parseBlob SExpressionTermRenderer -- | Read two files to a BlobPair. readFilePair :: Both FilePath -> IO BlobPair From ad377910f945b5f6f1771e38bbeef985a39f095b Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 10:54:18 -0800 Subject: [PATCH 108/133] Completely remove blobKind --- src/Data/Blob.hs | 8 +------- test/Rendering/TOC/Spec.hs | 2 +- test/Semantic/Spec.hs | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Data/Blob.hs b/src/Data/Blob.hs index 7a8e9e4ef..be7f21fc9 100644 --- a/src/Data/Blob.hs +++ b/src/Data/Blob.hs @@ -3,7 +3,6 @@ module Data.Blob , BlobKind(..) , These(..) , modeToDigits -, defaultPlainBlob , nullBlob , sourceBlob , nullOid @@ -59,7 +58,6 @@ data Blob = Blob { blobSource :: Source -- ^ The UTF-8 encoded source text of the blob. , blobOid :: ByteString -- ^ The Git object ID (SHA-1) of the blob. , blobPath :: FilePath -- ^ The file path to the blob. - , blobKind :: BlobKind -- ^ The kind of blob. , blobLanguage :: Maybe Language -- ^ The language of this blob. Nothing denotes a langauge we don't support yet. } deriving (Show, Eq) @@ -73,15 +71,11 @@ modeToDigits (PlainBlob mode) = pack $ showOct mode "" modeToDigits (ExecutableBlob mode) = pack $ showOct mode "" modeToDigits (SymlinkBlob mode) = pack $ showOct mode "" --- | The default plain blob mode -defaultPlainBlob :: BlobKind -defaultPlainBlob = PlainBlob 0o100644 - nullBlob :: Blob -> Bool nullBlob Blob{..} = blobOid == nullOid || nullSource blobSource sourceBlob :: FilePath -> Maybe Language -> Source -> Blob -sourceBlob filepath language source = Blob source nullOid filepath defaultPlainBlob language +sourceBlob filepath language source = Blob source nullOid filepath language nullOid :: ByteString nullOid = "0000000000000000000000000000000000000000" diff --git a/test/Rendering/TOC/Spec.hs b/test/Rendering/TOC/Spec.hs index aa704c7ef..0fcbef5d2 100644 --- a/test/Rendering/TOC/Spec.hs +++ b/test/Rendering/TOC/Spec.hs @@ -253,4 +253,4 @@ blankDiff = merge (arrayInfo, arrayInfo) (Indexed [ inserting (Term $ literalInf literalInfo = Nothing :. Range 1 2 :. StringLiteral :. sourceSpanBetween (1, 2) (1, 4) :. Nil blankDiffBlobs :: Both Blob -blankDiffBlobs = both (Blob (fromText "[]") nullOid "a.js" defaultPlainBlob (Just TypeScript)) (Blob (fromText "[a]") nullOid "b.js" defaultPlainBlob (Just TypeScript)) +blankDiffBlobs = both (Blob (fromText "[]") nullOid "a.js" (Just TypeScript)) (Blob (fromText "[a]") nullOid "b.js" (Just TypeScript)) diff --git a/test/Semantic/Spec.hs b/test/Semantic/Spec.hs index c417cc54f..6e10ff6b8 100644 --- a/test/Semantic/Spec.hs +++ b/test/Semantic/Spec.hs @@ -37,4 +37,4 @@ spec = parallel $ do result `shouldBe` (Diff (Patch (Delete (In () []))) :: Diff [] () ()) where - methodsBlob = Blob "def foo\nend\n" "ff7bbbe9495f61d9e1e58c597502d152bab1761e" "methods.rb" defaultPlainBlob (Just Ruby) + methodsBlob = Blob "def foo\nend\n" "ff7bbbe9495f61d9e1e58c597502d152bab1761e" "methods.rb" (Just Ruby) From deb7ebadd297d793c7e16df24cb384b14c88c55f Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 10:59:05 -0800 Subject: [PATCH 109/133] :fire: blobOid too --- src/Data/Blob.hs | 23 ++--------------------- src/Rendering/JSON.hs | 2 -- test/Rendering/TOC/Spec.hs | 2 +- test/Semantic/CLI/Spec.hs | 2 +- test/Semantic/Spec.hs | 2 +- 5 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/Data/Blob.hs b/src/Data/Blob.hs index be7f21fc9..0c1312f5d 100644 --- a/src/Data/Blob.hs +++ b/src/Data/Blob.hs @@ -1,11 +1,8 @@ module Data.Blob ( Blob(..) -, BlobKind(..) , These(..) -, modeToDigits , nullBlob , sourceBlob -, nullOid , BlobPair , blobPairDiffing , blobPairInserting @@ -15,13 +12,10 @@ module Data.Blob , pathForBlobPair ) where -import Data.ByteString.Char8 (ByteString, pack) import Data.Bifunctor.Join import Data.Language import Data.These import Data.Source as Source -import Data.Word -import Numeric -- | Represents a blobs suitable for diffing which can be either a blob to @@ -56,26 +50,13 @@ languageTagForBlobPair pair = maybe [] showLanguage (languageForBlobPair pair) -- | The source, oid, path, kind and language of a blob. data Blob = Blob { blobSource :: Source -- ^ The UTF-8 encoded source text of the blob. - , blobOid :: ByteString -- ^ The Git object ID (SHA-1) of the blob. , blobPath :: FilePath -- ^ The file path to the blob. , blobLanguage :: Maybe Language -- ^ The language of this blob. Nothing denotes a langauge we don't support yet. } deriving (Show, Eq) --- | The kind and file mode of a 'Blob'. -data BlobKind = PlainBlob Word32 | ExecutableBlob Word32 | SymlinkBlob Word32 - deriving (Show, Eq) - -modeToDigits :: BlobKind -> ByteString -modeToDigits (PlainBlob mode) = pack $ showOct mode "" -modeToDigits (ExecutableBlob mode) = pack $ showOct mode "" -modeToDigits (SymlinkBlob mode) = pack $ showOct mode "" - nullBlob :: Blob -> Bool -nullBlob Blob{..} = blobOid == nullOid || nullSource blobSource +nullBlob Blob{..} = nullSource blobSource sourceBlob :: FilePath -> Maybe Language -> Source -> Blob -sourceBlob filepath language source = Blob source nullOid filepath language - -nullOid :: ByteString -nullOid = "0000000000000000000000000000000000000000" +sourceBlob filepath language source = Blob source filepath language diff --git a/src/Rendering/JSON.hs b/src/Rendering/JSON.hs index f386dbbf4..41cd0cf5c 100644 --- a/src/Rendering/JSON.hs +++ b/src/Rendering/JSON.hs @@ -11,14 +11,12 @@ import Data.Bifunctor.Join import Data.Language import qualified Data.Map as Map import Data.Text (Text) -import Data.Text.Encoding (decodeUtf8) import GHC.Generics -- | Render a diff to a string representing its JSON. renderJSONDiff :: ToJSON a => BlobPair -> a -> Map.Map Text Value renderJSONDiff blobs diff = Map.fromList [ ("diff", toJSON diff) - , ("oids", toJSON (decodeUtf8 . blobOid <$> (biList . runJoin) blobs)) , ("paths", toJSON (blobPath <$> (biList . runJoin) blobs)) ] diff --git a/test/Rendering/TOC/Spec.hs b/test/Rendering/TOC/Spec.hs index 0fcbef5d2..62a14f507 100644 --- a/test/Rendering/TOC/Spec.hs +++ b/test/Rendering/TOC/Spec.hs @@ -253,4 +253,4 @@ blankDiff = merge (arrayInfo, arrayInfo) (Indexed [ inserting (Term $ literalInf literalInfo = Nothing :. Range 1 2 :. StringLiteral :. sourceSpanBetween (1, 2) (1, 4) :. Nil blankDiffBlobs :: Both Blob -blankDiffBlobs = both (Blob (fromText "[]") nullOid "a.js" (Just TypeScript)) (Blob (fromText "[a]") nullOid "b.js" (Just TypeScript)) +blankDiffBlobs = both (Blob (fromText "[]") "a.js" (Just TypeScript)) (Blob (fromText "[a]") "b.js" (Just TypeScript)) diff --git a/test/Semantic/CLI/Spec.hs b/test/Semantic/CLI/Spec.hs index 1d60ab225..f38cbe124 100644 --- a/test/Semantic/CLI/Spec.hs +++ b/test/Semantic/CLI/Spec.hs @@ -58,6 +58,6 @@ diffFixtures = ] where pathMode = Right [both ("test/fixtures/ruby/method-declaration.A.rb", Just Ruby) ("test/fixtures/ruby/method-declaration.B.rb", Just Ruby)] - jsonOutput = "{\"diff\":{\"merge\":{\"after\":{\"sourceRange\":[0,21],\"sourceSpan\":{\"start\":[1,1],\"end\":[4,1]}},\"children\":[{\"merge\":{\"after\":{\"sourceRange\":[0,20],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,4]}},\"children\":[{\"merge\":{\"after\":{\"sourceRange\":[0,0],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,1]}},\"children\":[],\"before\":{\"sourceRange\":[0,0],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,1]}}}},{\"patch\":{\"replace\":[{\"children\":[],\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}},{\"children\":[],\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}}]}},{\"patch\":{\"insert\":{\"children\":[],\"sourceRange\":[8,9],\"sourceSpan\":{\"start\":[1,9],\"end\":[1,10]}}}},{\"merge\":{\"after\":{\"sourceRange\":[13,16],\"sourceSpan\":{\"start\":[2,3],\"end\":[2,6]}},\"children\":[{\"patch\":{\"insert\":{\"children\":[],\"sourceRange\":[13,16],\"sourceSpan\":{\"start\":[2,3],\"end\":[2,6]}}}}],\"before\":{\"sourceRange\":[8,11],\"sourceSpan\":{\"start\":[2,1],\"end\":[2,4]}}}}],\"before\":{\"sourceRange\":[0,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}}}}],\"before\":{\"sourceRange\":[0,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}}}},\"oids\":[\"0000000000000000000000000000000000000000\",\"0000000000000000000000000000000000000000\"],\"paths\":[\"test/fixtures/ruby/method-declaration.A.rb\",\"test/fixtures/ruby/method-declaration.B.rb\"]}\n" + jsonOutput = "{\"diff\":{\"merge\":{\"after\":{\"sourceRange\":[0,21],\"sourceSpan\":{\"start\":[1,1],\"end\":[4,1]}},\"children\":[{\"merge\":{\"after\":{\"sourceRange\":[0,20],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,4]}},\"children\":[{\"merge\":{\"after\":{\"sourceRange\":[0,0],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,1]}},\"children\":[],\"before\":{\"sourceRange\":[0,0],\"sourceSpan\":{\"start\":[1,1],\"end\":[1,1]}}}},{\"patch\":{\"replace\":[{\"children\":[],\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}},{\"children\":[],\"sourceRange\":[4,7],\"sourceSpan\":{\"start\":[1,5],\"end\":[1,8]}}]}},{\"patch\":{\"insert\":{\"children\":[],\"sourceRange\":[8,9],\"sourceSpan\":{\"start\":[1,9],\"end\":[1,10]}}}},{\"merge\":{\"after\":{\"sourceRange\":[13,16],\"sourceSpan\":{\"start\":[2,3],\"end\":[2,6]}},\"children\":[{\"patch\":{\"insert\":{\"children\":[],\"sourceRange\":[13,16],\"sourceSpan\":{\"start\":[2,3],\"end\":[2,6]}}}}],\"before\":{\"sourceRange\":[8,11],\"sourceSpan\":{\"start\":[2,1],\"end\":[2,4]}}}}],\"before\":{\"sourceRange\":[0,11],\"sourceSpan\":{\"start\":[1,1],\"end\":[2,4]}}}}],\"before\":{\"sourceRange\":[0,12],\"sourceSpan\":{\"start\":[1,1],\"end\":[3,1]}}}},\"paths\":[\"test/fixtures/ruby/method-declaration.A.rb\",\"test/fixtures/ruby/method-declaration.B.rb\"]}\n" sExpressionOutput = "(Program\n (Method\n (Empty)\n { (Identifier)\n ->(Identifier) }\n {+(Identifier)+}\n (\n {+(Identifier)+})))\n" tocOutput = "{\"changes\":{\"test/fixtures/ruby/method-declaration.A.rb -> test/fixtures/ruby/method-declaration.B.rb\":[{\"span\":{\"start\":[1,1],\"end\":[3,4]},\"category\":\"Method\",\"term\":\"bar\",\"changeType\":\"modified\"}]},\"errors\":{}}\n" diff --git a/test/Semantic/Spec.hs b/test/Semantic/Spec.hs index 6e10ff6b8..56d327478 100644 --- a/test/Semantic/Spec.hs +++ b/test/Semantic/Spec.hs @@ -37,4 +37,4 @@ spec = parallel $ do result `shouldBe` (Diff (Patch (Delete (In () []))) :: Diff [] () ()) where - methodsBlob = Blob "def foo\nend\n" "ff7bbbe9495f61d9e1e58c597502d152bab1761e" "methods.rb" (Just Ruby) + methodsBlob = Blob "def foo\nend\n" "methods.rb" (Just Ruby) From 30f5b9bd4b4d25daa2e96e5fdaa6c31c54d27aeb Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 11:09:37 -0800 Subject: [PATCH 110/133] Just moving things around --- src/Data/Blob.hs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Data/Blob.hs b/src/Data/Blob.hs index 0c1312f5d..f7a5c9fa1 100644 --- a/src/Data/Blob.hs +++ b/src/Data/Blob.hs @@ -1,9 +1,9 @@ module Data.Blob ( Blob(..) -, These(..) , nullBlob , sourceBlob , BlobPair +, These(..) , blobPairDiffing , blobPairInserting , blobPairDeleting @@ -18,6 +18,21 @@ import Data.These import Data.Source as Source +-- | The source, oid, path, kind and language of a blob. +data Blob = Blob + { blobSource :: Source -- ^ The UTF-8 encoded source text of the blob. + , blobPath :: FilePath -- ^ The file path to the blob. + , blobLanguage :: Maybe Language -- ^ The language of this blob. Nothing denotes a langauge we don't support yet. + } + deriving (Show, Eq) + +nullBlob :: Blob -> Bool +nullBlob Blob{..} = nullSource blobSource + +sourceBlob :: FilePath -> Maybe Language -> Source -> Blob +sourceBlob filepath language source = Blob source filepath language + + -- | Represents a blobs suitable for diffing which can be either a blob to -- delete, a blob to insert, or a pair of blobs to diff. type BlobPair = Join These Blob @@ -45,18 +60,3 @@ pathForBlobPair (Join (These _ Blob{..})) = blobPath languageTagForBlobPair :: BlobPair -> [(String, String)] languageTagForBlobPair pair = maybe [] showLanguage (languageForBlobPair pair) where showLanguage = pure . (,) "language" . show - - --- | The source, oid, path, kind and language of a blob. -data Blob = Blob - { blobSource :: Source -- ^ The UTF-8 encoded source text of the blob. - , blobPath :: FilePath -- ^ The file path to the blob. - , blobLanguage :: Maybe Language -- ^ The language of this blob. Nothing denotes a langauge we don't support yet. - } - deriving (Show, Eq) - -nullBlob :: Blob -> Bool -nullBlob Blob{..} = nullSource blobSource - -sourceBlob :: FilePath -> Maybe Language -> Source -> Blob -sourceBlob filepath language source = Blob source filepath language From 8d7701fd7fcdf1795e2c77b7dc70ccb9338c82d6 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 11:15:29 -0800 Subject: [PATCH 111/133] Docs --- src/Data/Blob.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Blob.hs b/src/Data/Blob.hs index f7a5c9fa1..f90536478 100644 --- a/src/Data/Blob.hs +++ b/src/Data/Blob.hs @@ -18,7 +18,7 @@ import Data.These import Data.Source as Source --- | The source, oid, path, kind and language of a blob. +-- | The source, path, and language of a blob. data Blob = Blob { blobSource :: Source -- ^ The UTF-8 encoded source text of the blob. , blobPath :: FilePath -- ^ The file path to the blob. From ed47cbc85d59837dc0968b35bdb8ce1af2e7e406 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 12:58:43 -0800 Subject: [PATCH 112/133] Formatting --- src/Semantic.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Semantic.hs b/src/Semantic.hs index 0cf466f35..0c72d083d 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -116,8 +116,8 @@ diffBlobPair renderer blobs -- | A task to diff 'Term's, producing insertion/deletion 'Patch'es for non-existent 'Blob's. diffTermPair :: Functor syntax => Differ syntax ann1 ann2 -> These (Term syntax ann1) (Term syntax ann2) -> Task (Diff syntax ann1 ann2) -diffTermPair _ (This t1) = pure (deleting t1) -diffTermPair _ (That t2) = pure (inserting t2) +diffTermPair _ (This t1 ) = pure (deleting t1) +diffTermPair _ (That t2) = pure (inserting t2) diffTermPair differ (These t1 t2) = diff differ t1 t2 keepCategory :: HasField fields Category => Record fields -> Record '[Category] From 143b1b8a1291d40b50b539807c1966a2e5175507 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 12:58:50 -0800 Subject: [PATCH 113/133] Document Bidistribute --- src/Semantic/Task.hs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Semantic/Task.hs b/src/Semantic/Task.hs index aafe017ff..67174c1f6 100644 --- a/src/Semantic/Task.hs +++ b/src/Semantic/Task.hs @@ -139,6 +139,9 @@ render renderer input = Render renderer input `Then` return distribute :: Traversable t => t (Task output) -> Task (t output) distribute tasks = Distribute tasks `Then` return +-- | Distribute a 'Bitraversable' container of 'Task's over the available cores (i.e. execute them concurrently), collecting their results. +-- +-- This is a concurrent analogue of 'bisequenceA'. bidistribute :: Bitraversable t => t (Task output1) (Task output2) -> Task (t output1 output2) bidistribute tasks = Bidistribute tasks `Then` return @@ -148,6 +151,9 @@ bidistribute tasks = Bidistribute tasks `Then` return distributeFor :: Traversable t => t a -> (a -> Task output) -> Task (t output) distributeFor inputs toTask = distribute (fmap toTask inputs) +-- | Distribute the application of a function to each element of a 'Bitraversable' container of inputs over the available cores (i.e. perform the functions concurrently for each element), collecting the results. +-- +-- This is a concurrent analogue of 'bifor' or 'bitraverse' (with the arguments flipped). bidistributeFor :: Bitraversable t => t a b -> (a -> Task output1) -> (b -> Task output2) -> Task (t output1 output2) bidistributeFor inputs toTask1 toTask2 = bidistribute (bimap toTask1 toTask2 inputs) From 2f6c66989910d4dd83dca57be5173481aff6fc5d Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 12:58:57 -0800 Subject: [PATCH 114/133] Remove extra parens --- test/Rendering/TOC/Spec.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Rendering/TOC/Spec.hs b/test/Rendering/TOC/Spec.hs index 62a14f507..1d02e64b7 100644 --- a/test/Rendering/TOC/Spec.hs +++ b/test/Rendering/TOC/Spec.hs @@ -241,7 +241,7 @@ isMethodOrFunction a = case unTerm a of _ -> False blobsForPaths :: Both FilePath -> IO BlobPair -blobsForPaths = readFilePair . (fmap ("test/fixtures/toc/" <>)) +blobsForPaths = readFilePair . fmap ("test/fixtures/toc/" <>) sourceSpanBetween :: (Int, Int) -> (Int, Int) -> Span sourceSpanBetween (s1, e1) (s2, e2) = Span (Pos s1 e1) (Pos s2 e2) From 47ce5a63c1e8b998d7a0d6e02560596ad6a833d8 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Mon, 11 Dec 2017 12:59:14 -0800 Subject: [PATCH 115/133] Test null on both sides in JSON payload --- test/Semantic/IO/Spec.hs | 4 ++++ test/fixtures/input/diff-null-both-sides.json | 6 ++++++ 2 files changed, 10 insertions(+) create mode 100644 test/fixtures/input/diff-null-both-sides.json diff --git a/test/Semantic/IO/Spec.hs b/test/Semantic/IO/Spec.hs index ca08710e0..6c04703bb 100644 --- a/test/Semantic/IO/Spec.hs +++ b/test/Semantic/IO/Spec.hs @@ -64,6 +64,10 @@ spec = parallel $ do h <- openFile "test/fixtures/input/diff-no-language.json" ReadMode readBlobsFromHandle h `shouldThrow` (== ExitFailure 1) + it "throws if null on before and after" $ do + h <- openFile "test/fixtures/input/diff-null-both-sides.json" ReadMode + readBlobPairsFromHandle h `shouldThrow` (== ExitFailure 1) + describe "readBlobsFromHandle" $ do it "returns blobs for valid JSON encoded parse input" $ do h <- openFile "test/fixtures/input/parse.json" ReadMode diff --git a/test/fixtures/input/diff-null-both-sides.json b/test/fixtures/input/diff-null-both-sides.json new file mode 100644 index 000000000..4de8c1966 --- /dev/null +++ b/test/fixtures/input/diff-null-both-sides.json @@ -0,0 +1,6 @@ +{ + "blobs": [{ + "before": null, + "after": null + }] +} From ca7a81a21e4f810c0f819d35523a642cbcfd6a6e Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Wed, 13 Dec 2017 09:15:08 -0800 Subject: [PATCH 116/133] ++freer-cofreer with gitignore --- vendor/freer-cofreer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/freer-cofreer b/vendor/freer-cofreer index f18b72357..22164cdeb 160000 --- a/vendor/freer-cofreer +++ b/vendor/freer-cofreer @@ -1 +1 @@ -Subproject commit f18b723579f700674dda90ed1519f6e7298e2117 +Subproject commit 22164cdebd939dc9b4a21b41a5e4968f991435d1 From 96c94e7672902d064ae083c5be0c917d3aee221e Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Fri, 1 Dec 2017 13:54:32 -0500 Subject: [PATCH 117/133] =?UTF-8?q?iterFreer=E2=80=99s=20algebra=20takes?= =?UTF-8?q?=20the=20continuation=20&=20instruction=20in=20the=20opposite?= =?UTF-8?q?=20order.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Assigning/Assignment.hs | 10 +++++----- src/Diffing/Interpreter.hs | 2 +- src/Semantic/Task.hs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Assigning/Assignment.hs b/src/Assigning/Assignment.hs index a3ca78d66..fdcecb740 100644 --- a/src/Assigning/Assignment.hs +++ b/src/Assigning/Assignment.hs @@ -218,7 +218,7 @@ nodeError expected Node{..} = Error nodeSpan expected (Just (Right nodeSymbol)) firstSet :: (Enum grammar, Ix grammar) => Assignment ast grammar a -> [grammar] -firstSet = iterFreer (\ (Tracing _ assignment) _ -> case assignment of +firstSet = iterFreer (\ _ (Tracing _ assignment) -> case assignment of Choose table _ _ -> Table.tableAddresses table Label child _ -> firstSet child _ -> []) . ([] <$) @@ -245,11 +245,11 @@ runAssignment source = \ assignment state -> go assignment state >>= requireExha go assignment = iterFreer run ((pure .) . (,) <$> assignment) {-# INLINE go #-} - run :: Tracing (AssignmentF ast grammar) x - -> (x -> State ast grammar -> Either (Error (Either String grammar)) (result, State ast grammar)) + run :: (x -> State ast grammar -> Either (Error (Either String grammar)) (result, State ast grammar)) + -> Tracing (AssignmentF ast grammar) x -> State ast grammar -> Either (Error (Either String grammar)) (result, State ast grammar) - run t yield initialState = state `seq` maybe (anywhere Nothing) atNode (listToMaybe stateNodes) + run yield t initialState = state `seq` maybe (anywhere Nothing) atNode (listToMaybe stateNodes) where atNode (Term (In node f)) = case runTracing t of Location -> yield (nodeLocation node) state CurrentNode -> yield (In node (() <$ f)) state @@ -367,7 +367,7 @@ instance (Enum grammar, Eq1 ast, Ix grammar, Show grammar) => MonadError (Error throwError err = fail (show err) catchError :: HasCallStack => Assignment ast grammar a -> (Error (Either String grammar) -> Assignment ast grammar a) -> Assignment ast grammar a - catchError rule handler = iterFreer (\ (Tracing cs assignment) continue -> case assignment of + catchError rule handler = iterFreer (\ continue (Tracing cs assignment) -> case assignment of Choose choices atEnd Nothing -> Tracing cs (Choose (fmap (>>= continue) choices) (fmap (>>= continue) atEnd) (Just handler)) `Then` return Choose choices atEnd (Just onError) -> Tracing cs (Choose (fmap (>>= continue) choices) (fmap (>>= continue) atEnd) (Just (\ err -> (onError err >>= continue) <|> handler err))) `Then` return _ -> Tracing cs assignment `Then` ((`catchError` handler) . continue)) (fmap pure rule) diff --git a/src/Diffing/Interpreter.hs b/src/Diffing/Interpreter.hs index 8a609e79c..b2ec67a73 100644 --- a/src/Diffing/Interpreter.hs +++ b/src/Diffing/Interpreter.hs @@ -75,7 +75,7 @@ runAlgorithm comparable eqTerms = go (Diff syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2))) result -> m result - go = iterFreerA (\ step yield -> case step of + go = iterFreerA (\ yield step -> case step of Diffing.Algorithm.Diff t1 t2 -> go (algorithmForTerms t1 t2) <|> pure (replacing t1 t2) >>= yield Linear (Term (In ann1 f1)) (Term (In ann2 f2)) -> merge (ann1, ann2) <$> galignWith (go . diffThese) f1 f2 >>= yield RWS as bs -> traverse (go . diffThese) (rws comparable eqTerms as bs) >>= yield diff --git a/src/Semantic/Task.hs b/src/Semantic/Task.hs index 67174c1f6..d101569fc 100644 --- a/src/Semantic/Task.hs +++ b/src/Semantic/Task.hs @@ -193,7 +193,7 @@ runTaskWithOptions options task = do run options logger statter = go where go :: Task a -> IO (Either SomeException a) - go = iterFreerA (\ task yield -> case task of + go = iterFreerA (\ yield task -> case task of ReadBlobs (Left handle) -> (IO.readBlobsFromHandle handle >>= yield) `catchError` (pure . Left . toException) ReadBlobs (Right paths@[(path, Nothing)]) -> (IO.isDirectory path >>= bool (IO.readBlobsFromPaths paths) (IO.readBlobsFromDir path) >>= yield) `catchError` (pure . Left . toException) ReadBlobs (Right paths) -> (IO.readBlobsFromPaths paths >>= yield) `catchError` (pure . Left . toException) From 3df9140c0ad9afc7fee4545374b9698039b8ab98 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 18 Dec 2017 10:54:51 -0500 Subject: [PATCH 118/133] renderDOTDiff takes its blobs in These. --- src/Rendering/DOT.hs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 5f838b732..26de0e4ea 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -6,21 +6,20 @@ module Rendering.DOT import Analysis.ConstructorName import Control.Applicative +import Data.Bifunctor.Join (Join(..)) import Data.Blob import qualified Data.ByteString.Char8 as B import Data.Diff import Data.Foldable -import Data.Function (on) -import Data.Functor.Both (Both, runBothWith) import Data.Functor.Foldable hiding (fold) import qualified Data.Map as Map import Data.Patch import Data.Semigroup import Data.Term +import Data.These (These, mergeThese) -renderDOTDiff :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Both Blob -> Diff syntax ann1 ann2 -> B.ByteString -renderDOTDiff blobs diff = renderGraph (snd (cata diffAlgebra diff 0)) { graphName = Just (runBothWith (fmap B.pack . (join `on` blobPath)) blobs) } - where join = (++) . (" -> " ++) +renderDOTDiff :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Join These Blob -> Diff syntax ann1 ann2 -> B.ByteString +renderDOTDiff blobs diff = renderGraph (snd (cata diffAlgebra diff 0)) { graphName = Just (mergeThese ((<>) . (" -> " <>)) (runJoin (fmap (B.pack . blobPath) blobs))) } renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Blob -> Term syntax ann -> B.ByteString renderDOTTerm Blob{..} term = renderGraph (snd (cata termAlgebra term 0)) { graphName = Just (B.pack blobPath) } From 3aa6333405e05c809567143abddb165c684877f9 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 18 Dec 2017 11:02:31 -0500 Subject: [PATCH 119/133] :fire: redundant parens. --- src/Rendering/DOT.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 26de0e4ea..c9355b5de 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -29,8 +29,8 @@ diffAlgebra d i = case d of Merge t -> termAlgebra t i Patch (Delete t1) -> termAlgebra t1 i `modifyHeadNode` setColour "red" Patch (Insert t2) -> termAlgebra t2 i `modifyHeadNode` setColour "green" - Patch (Replace t1 t2) -> let (i', g1) = termAlgebra t1 i `modifyHeadNode` setColour "red" - in (i', g1) <> (termAlgebra t2 (succ (maximum (i : i'))) `modifyHeadNode` setColour "green") + Patch (Replace t1 t2) -> let (i', g1) = termAlgebra t1 i `modifyHeadNode` setColour "red" + in (i', g1) <> termAlgebra t2 (succ (maximum (i : i'))) `modifyHeadNode` setColour "green" where modifyHeadNode (i, g) f | n:ns <- graphNodes g = (i, g { graphNodes = f n : ns }) | otherwise = (i, g) setColour c n = n { nodeAttributes = Map.insert "color" c (nodeAttributes n) } From ff43062310cc9a4f50a74666e8bc10a5435834c4 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 18 Dec 2017 11:07:40 -0500 Subject: [PATCH 120/133] Correct how the graph title is constructed. --- src/Rendering/DOT.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index c9355b5de..11beb7030 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -19,7 +19,8 @@ import Data.Term import Data.These (These, mergeThese) renderDOTDiff :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Join These Blob -> Diff syntax ann1 ann2 -> B.ByteString -renderDOTDiff blobs diff = renderGraph (snd (cata diffAlgebra diff 0)) { graphName = Just (mergeThese ((<>) . (" -> " <>)) (runJoin (fmap (B.pack . blobPath) blobs))) } +renderDOTDiff blobs diff = renderGraph (snd (cata diffAlgebra diff 0)) { graphName = Just (B.pack (mergeThese combine (runJoin (blobPath <$> blobs)))) } + where combine p1 p2 = p1 <> " -> " <> p2 renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Blob -> Term syntax ann -> B.ByteString renderDOTTerm Blob{..} term = renderGraph (snd (cata termAlgebra term 0)) { graphName = Just (B.pack blobPath) } From 54621da8d698194a968167276bdfaac2ea6b7713 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 18 Dec 2017 11:11:56 -0500 Subject: [PATCH 121/133] Render each node and edge alone on a line. --- src/Rendering/DOT.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 11beb7030..2fcf41441 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -56,14 +56,14 @@ data Edge = Edge { edgeFrom :: Int, edgeTo :: Int } renderGraph :: Graph -> B.ByteString -renderGraph Graph{..} = "digraph " <> maybe "" quote graphName <> " {" <> foldr ((<>) . renderNode) "" graphNodes <> foldr ((<>) . renderEdge) "" graphEdges <> "}" +renderGraph Graph{..} = "digraph " <> maybe "" quote graphName <> " {\n" <> foldr ((<>) . renderNode) "" graphNodes <> foldr ((<>) . renderEdge) "" graphEdges <> "}" where quote a = "\"" <> a <> "\"" renderNode :: Node -> B.ByteString -renderNode Node{..} = B.pack (show nodeID) <> " [ " <> foldr (\ (key, value) rest -> key <> " = \"" <> value <> "\" " <> rest) "" (Map.toList nodeAttributes) <> "];" +renderNode Node{..} = "\t" <> B.pack (show nodeID) <> " [ " <> foldr (\ (key, value) rest -> key <> " = \"" <> value <> "\" " <> rest) "" (Map.toList nodeAttributes) <> "];\n" renderEdge :: Edge -> B.ByteString -renderEdge Edge{..} = B.pack (show edgeFrom) <> " -> " <> B.pack (show edgeTo) <> ";" +renderEdge Edge{..} = "\t" <> B.pack (show edgeFrom) <> " -> " <> B.pack (show edgeTo) <> ";\n" instance Semigroup Graph where From 3ae354b7506badf11b35de2eacb937d05b50e959 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 18 Dec 2017 11:22:03 -0500 Subject: [PATCH 122/133] Bind fewer intermediate variables. --- src/Rendering/DOT.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 2fcf41441..044ac0a05 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -30,8 +30,8 @@ diffAlgebra d i = case d of Merge t -> termAlgebra t i Patch (Delete t1) -> termAlgebra t1 i `modifyHeadNode` setColour "red" Patch (Insert t2) -> termAlgebra t2 i `modifyHeadNode` setColour "green" - Patch (Replace t1 t2) -> let (i', g1) = termAlgebra t1 i `modifyHeadNode` setColour "red" - in (i', g1) <> termAlgebra t2 (succ (maximum (i : i'))) `modifyHeadNode` setColour "green" + Patch (Replace t1 t2) -> let r1 = termAlgebra t1 i `modifyHeadNode` setColour "red" + in r1 <> termAlgebra t2 (succ (maximum (i : fst r1))) `modifyHeadNode` setColour "green" where modifyHeadNode (i, g) f | n:ns <- graphNodes g = (i, g { graphNodes = f n : ns }) | otherwise = (i, g) setColour c n = n { nodeAttributes = Map.insert "color" c (nodeAttributes n) } From 5f49f4589c254d5c9466a73286ae4d930fc83859 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 18 Dec 2017 11:29:34 -0500 Subject: [PATCH 123/133] Replacements advance past the maximal id in the before state. --- src/Rendering/DOT.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs index 044ac0a05..29df8fc5a 100644 --- a/src/Rendering/DOT.hs +++ b/src/Rendering/DOT.hs @@ -30,8 +30,8 @@ diffAlgebra d i = case d of Merge t -> termAlgebra t i Patch (Delete t1) -> termAlgebra t1 i `modifyHeadNode` setColour "red" Patch (Insert t2) -> termAlgebra t2 i `modifyHeadNode` setColour "green" - Patch (Replace t1 t2) -> let r1 = termAlgebra t1 i `modifyHeadNode` setColour "red" - in r1 <> termAlgebra t2 (succ (maximum (i : fst r1))) `modifyHeadNode` setColour "green" + Patch (Replace t1 t2) -> let r1 = termAlgebra t1 i `modifyHeadNode` setColour "red" + in r1 <> termAlgebra t2 (succ (maximum (i : map nodeID (graphNodes (snd r1))))) `modifyHeadNode` setColour "green" where modifyHeadNode (i, g) f | n:ns <- graphNodes g = (i, g { graphNodes = f n : ns }) | otherwise = (i, g) setColour c n = n { nodeAttributes = Map.insert "color" c (nodeAttributes n) } From efe90827e33c018e002c37803ad7e9ad0dbfef74 Mon Sep 17 00:00:00 2001 From: Rick Winfrey Date: Tue, 19 Dec 2017 09:59:20 -0800 Subject: [PATCH 124/133] Bump haskell-tree-sitter: add new named nodes to Go ASTs --- vendor/haskell-tree-sitter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/haskell-tree-sitter b/vendor/haskell-tree-sitter index 3d17d5621..5e0ea38a4 160000 --- a/vendor/haskell-tree-sitter +++ b/vendor/haskell-tree-sitter @@ -1 +1 @@ -Subproject commit 3d17d56214bd7a241a88f11b2ee48de8b5ab3308 +Subproject commit 5e0ea38a438333020740a4b67fd3e6af36aab6dd From 99d9b7c97a963afb0c55fb39833296f3a0f23135 Mon Sep 17 00:00:00 2001 From: joshvera Date: Tue, 19 Dec 2017 13:09:30 -0500 Subject: [PATCH 125/133] =?UTF-8?q?Merge=20master=20into=20=F0=9F=94=A5-mo?= =?UTF-8?q?nolithic-syntax?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- semantic-diff.cabal | 1 + src/Analysis/ConstructorName.hs | 2 +- src/Rendering/DOT.hs | 74 +++++++++++++++++++++++++++++++++ src/Rendering/Renderer.hs | 7 ++++ src/Semantic.hs | 4 +- src/Semantic/CLI.hs | 6 ++- 6 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 src/Rendering/DOT.hs diff --git a/semantic-diff.cabal b/semantic-diff.cabal index 0a81a6f56..173360a8f 100644 --- a/semantic-diff.cabal +++ b/semantic-diff.cabal @@ -80,6 +80,7 @@ library , Parsing.TreeSitter , Paths_semantic_diff -- Rendering formats + , Rendering.DOT , Rendering.JSON , Rendering.Renderer , Rendering.SExpression diff --git a/src/Analysis/ConstructorName.hs b/src/Analysis/ConstructorName.hs index 07c936b71..a607cbf70 100644 --- a/src/Analysis/ConstructorName.hs +++ b/src/Analysis/ConstructorName.hs @@ -19,7 +19,7 @@ constructorLabel :: ConstructorName syntax => TermF syntax a b -> ConstructorLab constructorLabel (In _ s) = ConstructorLabel $ pack (constructorName s) -newtype ConstructorLabel = ConstructorLabel ByteString +newtype ConstructorLabel = ConstructorLabel { unConstructorLabel :: ByteString } instance Show ConstructorLabel where showsPrec _ (ConstructorLabel s) = showString (unpack s) diff --git a/src/Rendering/DOT.hs b/src/Rendering/DOT.hs new file mode 100644 index 000000000..29df8fc5a --- /dev/null +++ b/src/Rendering/DOT.hs @@ -0,0 +1,74 @@ +{-# LANGUAGE MonoLocalBinds #-} +module Rendering.DOT +( renderDOTDiff +, renderDOTTerm +) where + +import Analysis.ConstructorName +import Control.Applicative +import Data.Bifunctor.Join (Join(..)) +import Data.Blob +import qualified Data.ByteString.Char8 as B +import Data.Diff +import Data.Foldable +import Data.Functor.Foldable hiding (fold) +import qualified Data.Map as Map +import Data.Patch +import Data.Semigroup +import Data.Term +import Data.These (These, mergeThese) + +renderDOTDiff :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Join These Blob -> Diff syntax ann1 ann2 -> B.ByteString +renderDOTDiff blobs diff = renderGraph (snd (cata diffAlgebra diff 0)) { graphName = Just (B.pack (mergeThese combine (runJoin (blobPath <$> blobs)))) } + where combine p1 p2 = p1 <> " -> " <> p2 + +renderDOTTerm :: (ConstructorName syntax, Foldable syntax, Functor syntax) => Blob -> Term syntax ann -> B.ByteString +renderDOTTerm Blob{..} term = renderGraph (snd (cata termAlgebra term 0)) { graphName = Just (B.pack blobPath) } + +diffAlgebra :: (ConstructorName syntax, Foldable syntax) => DiffF syntax ann1 ann2 (Int -> ([Int], Graph)) -> Int -> ([Int], Graph) +diffAlgebra d i = case d of + Merge t -> termAlgebra t i + Patch (Delete t1) -> termAlgebra t1 i `modifyHeadNode` setColour "red" + Patch (Insert t2) -> termAlgebra t2 i `modifyHeadNode` setColour "green" + Patch (Replace t1 t2) -> let r1 = termAlgebra t1 i `modifyHeadNode` setColour "red" + in r1 <> termAlgebra t2 (succ (maximum (i : map nodeID (graphNodes (snd r1))))) `modifyHeadNode` setColour "green" + where modifyHeadNode (i, g) f | n:ns <- graphNodes g = (i, g { graphNodes = f n : ns }) + | otherwise = (i, g) + setColour c n = n { nodeAttributes = Map.insert "color" c (nodeAttributes n) } + +termAlgebra :: (ConstructorName syntax, Foldable syntax) => TermF syntax ann (Int -> ([Int], Graph)) -> Int -> ([Int], Graph) +termAlgebra t i = ([succ i], Graph + Nothing + (Node (succ i) (Map.singleton "label" (unConstructorLabel (constructorLabel t))) : graphNodes g) + (concatMap (map (Edge (succ i))) is <> graphEdges g)) + where (_, is, g) = foldr combine (succ i, [], mempty) (toList t) + combine f (i, is, gs) = let (i', g) = f i in (maximum (i : map nodeID (graphNodes g)), i' : is, g <> gs) + + +data Graph = Graph { graphName :: Maybe B.ByteString, graphNodes :: [Node], graphEdges :: [Edge] } + deriving (Eq, Ord, Show) + +data Node = Node { nodeID :: Int, nodeAttributes :: Map.Map B.ByteString B.ByteString } + deriving (Eq, Ord, Show) + +data Edge = Edge { edgeFrom :: Int, edgeTo :: Int } + deriving (Eq, Ord, Show) + + +renderGraph :: Graph -> B.ByteString +renderGraph Graph{..} = "digraph " <> maybe "" quote graphName <> " {\n" <> foldr ((<>) . renderNode) "" graphNodes <> foldr ((<>) . renderEdge) "" graphEdges <> "}" + where quote a = "\"" <> a <> "\"" + +renderNode :: Node -> B.ByteString +renderNode Node{..} = "\t" <> B.pack (show nodeID) <> " [ " <> foldr (\ (key, value) rest -> key <> " = \"" <> value <> "\" " <> rest) "" (Map.toList nodeAttributes) <> "];\n" + +renderEdge :: Edge -> B.ByteString +renderEdge Edge{..} = "\t" <> B.pack (show edgeFrom) <> " -> " <> B.pack (show edgeTo) <> ";\n" + + +instance Semigroup Graph where + Graph n1 ns1 es1 <> Graph n2 ns2 es2 = Graph (n1 <|> n2) (ns1 <> ns2) (es1 <> es2) + +instance Monoid Graph where + mempty = Graph Nothing [] [] + mappend = (<>) diff --git a/src/Rendering/Renderer.hs b/src/Rendering/Renderer.hs index c9a557e83..6cceb394d 100644 --- a/src/Rendering/Renderer.hs +++ b/src/Rendering/Renderer.hs @@ -10,6 +10,8 @@ module Rendering.Renderer , renderToCDiff , renderToCTerm , renderToTags +, renderDOTDiff +, renderDOTTerm , Summaries(..) ) where @@ -18,6 +20,7 @@ import Data.ByteString (ByteString) import qualified Data.Map as Map import Data.Output import Data.Text (Text) +import Rendering.DOT as R import Rendering.JSON as R import Rendering.SExpression as R import Rendering.Tag as R @@ -31,6 +34,8 @@ data DiffRenderer output where JSONDiffRenderer :: DiffRenderer (Map.Map Text Value) -- | Render to a 'ByteString' formatted as nested s-expressions with patches indicated. SExpressionDiffRenderer :: DiffRenderer ByteString + -- | Render to a 'ByteString' formatted as a DOT description of the diff. + DOTDiffRenderer :: DiffRenderer ByteString deriving instance Eq (DiffRenderer output) deriving instance Show (DiffRenderer output) @@ -45,6 +50,8 @@ data TermRenderer output where SExpressionTermRenderer :: TermRenderer ByteString -- | Render to a list of tags. TagsTermRenderer :: TermRenderer [Value] + -- | Render to a 'ByteString' formatted as a DOT description of the term. + DOTTermRenderer :: TermRenderer ByteString deriving instance Eq (TermRenderer output) deriving instance Show (TermRenderer output) diff --git a/src/Semantic.hs b/src/Semantic.hs index f72f08291..3edaae179 100644 --- a/src/Semantic.hs +++ b/src/Semantic.hs @@ -53,7 +53,7 @@ parseBlob renderer blob@Blob{..} JSONTermRenderer -> decorate constructorLabel >=> decorate identifierLabel >=> render (renderJSONTerm blob) SExpressionTermRenderer -> decorate constructorLabel . (Nil <$) >=> render renderSExpressionTerm TagsTermRenderer -> decorate (declarationAlgebra blob) >=> render (renderToTags blob) - + DOTTermRenderer -> render (renderDOTTerm blob) | otherwise = throwError (SomeException (NoLanguageForBlob blobPath)) data NoLanguageForBlob = NoLanguageForBlob FilePath @@ -71,7 +71,7 @@ diffBlobPair renderer blobs ToCDiffRenderer -> run (\ blob -> parse parser blob >>= decorate (declarationAlgebra blob)) diffTerms renderToCDiff JSONDiffRenderer -> run ( parse parser >=> decorate constructorLabel >=> decorate identifierLabel) diffTerms renderJSONDiff SExpressionDiffRenderer -> run ( parse parser >=> decorate constructorLabel . (Nil <$)) diffTerms (const renderSExpressionDiff) - + DOTDiffRenderer -> run ( parse parser) diffTerms renderDOTDiff | otherwise = throwError (SomeException (NoLanguageForBlob effectivePath)) where effectivePath = pathForBlobPair blobs effectiveLanguage = languageForBlobPair blobs diff --git a/src/Semantic/CLI.hs b/src/Semantic/CLI.hs index beffd3349..b6e101e4e 100644 --- a/src/Semantic/CLI.hs +++ b/src/Semantic/CLI.hs @@ -65,7 +65,8 @@ arguments = info (version <*> helper <*> ((,) <$> optionsParser <*> argumentsPar <$> ( flag (SomeRenderer SExpressionDiffRenderer) (SomeRenderer SExpressionDiffRenderer) (long "sexpression" <> help "Output s-expression diff tree") <|> flag' (SomeRenderer JSONDiffRenderer) (long "json" <> help "Output JSON diff trees") <|> flag' (SomeRenderer ToCDiffRenderer) (long "toc" <> help "Output JSON table of contents diff summary") - <|> flag' (SomeRenderer ToCDiffRenderer) (long "toc-assignment" <> help "Output JSON table of contents diff summary using the assignment parser") ) + <|> flag' (SomeRenderer ToCDiffRenderer) (long "toc-assignment" <> help "Output JSON table of contents diff summary using the assignment parser") + <|> flag' (SomeRenderer DOTDiffRenderer) (long "dot" <> help "Output the diff as a DOT graph")) <*> ( Right <$> some (both <$> argument filePathReader (metavar "FILE_A") <*> argument filePathReader (metavar "FILE_B")) @@ -76,7 +77,8 @@ arguments = info (version <*> helper <*> ((,) <$> optionsParser <*> argumentsPar <$> ( flag (SomeRenderer SExpressionTermRenderer) (SomeRenderer SExpressionTermRenderer) (long "sexpression" <> help "Output s-expression parse trees (default)") <|> flag' (SomeRenderer JSONTermRenderer) (long "json" <> help "Output JSON parse trees") <|> flag' (SomeRenderer ToCTermRenderer) (long "toc" <> help "Output JSON table of contents summary") - <|> flag' (SomeRenderer TagsTermRenderer) (long "tags" <> help "Output JSON tags/symbols")) + <|> flag' (SomeRenderer TagsTermRenderer) (long "tags" <> help "Output JSON tags/symbols") + <|> flag' (SomeRenderer DOTTermRenderer) (long "dot" <> help "Output the term as a DOT graph")) <*> ( Right <$> some (argument filePathReader (metavar "FILES...")) <|> pure (Left stdin) ) From 0df164570e56c320b2ce0a6ebc6b2f241f917354 Mon Sep 17 00:00:00 2001 From: Rick Winfrey Date: Tue, 19 Dec 2017 10:40:26 -0800 Subject: [PATCH 126/133] Rename Parameters -> ParameterList --- src/Language/Go/Assignment.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Language/Go/Assignment.hs b/src/Language/Go/Assignment.hs index c26ec8841..39e56f5a3 100644 --- a/src/Language/Go/Assignment.hs +++ b/src/Language/Go/Assignment.hs @@ -376,7 +376,7 @@ functionDeclaration :: Assignment functionDeclaration = makeTerm <$> (symbol FunctionDeclaration <|> symbol FuncLiteral) <*> children (mkFunctionDeclaration <$> (term identifier <|> emptyTerm) <*> manyTerm parameters <*> (term types <|> term identifier <|> term returnParameters <|> emptyTerm) <*> (term block <|> emptyTerm)) where mkFunctionDeclaration name' params' types' block' = Declaration.Function [types'] name' params' block' - returnParameters = makeTerm <$> symbol Parameters <*> children (manyTerm expression) + returnParameters = makeTerm <$> symbol ParameterList <*> children (manyTerm expression) importDeclaration :: Assignment importDeclaration = makeTerm <$> symbol ImportDeclaration <*> children (Declaration.Import <$> manyTerm expression) @@ -390,7 +390,7 @@ indexExpression = makeTerm <$> symbol IndexExpression <*> children (Expression.S methodDeclaration :: Assignment methodDeclaration = makeTerm <$> symbol MethodDeclaration <*> children (mkTypedMethodDeclaration <$> receiver <*> term fieldIdentifier <*> manyTerm parameters <*> ((makeTerm <$> location <*> (manyTermsTill expression (void (symbol Block)))) <|> emptyTerm) <*> (term block <|> emptyTerm)) where - receiver = symbol Parameters *> children ((symbol ParameterDeclaration *> children expressions) <|> expressions) + receiver = symbol ParameterList *> children ((symbol ParameterDeclaration *> children expressions) <|> expressions) mkTypedMethodDeclaration receiver' name' parameters' type'' body' = Declaration.Method [type''] receiver' name' parameters' body' methodSpec :: Assignment @@ -402,7 +402,7 @@ packageClause :: Assignment packageClause = makeTerm <$> symbol PackageClause <*> children (Declaration.Module <$> expression <*> pure []) parameters :: Assignment -parameters = symbol Parameters *> children expressions +parameters = symbol ParameterList *> children expressions parameterDeclaration :: Assignment parameterDeclaration = makeTerm <$> symbol ParameterDeclaration <*> children (manyTerm expression) From 28763d1616a9b436727649846c535f8682a690c3 Mon Sep 17 00:00:00 2001 From: Rick Winfrey Date: Tue, 19 Dec 2017 10:40:36 -0800 Subject: [PATCH 127/133] Assign argument lists --- src/Language/Go/Assignment.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Language/Go/Assignment.hs b/src/Language/Go/Assignment.hs index 39e56f5a3..bce19b100 100644 --- a/src/Language/Go/Assignment.hs +++ b/src/Language/Go/Assignment.hs @@ -117,7 +117,8 @@ expression = term (handleError (choice expressionChoices)) expressionChoices :: [Assignment.Assignment [] Grammar Term] expressionChoices = - [ assignment' + [ argumentList + , assignment' , binaryExpression , block , breakStatement @@ -320,6 +321,9 @@ typeDeclaration = makeTerm <$> symbol TypeDeclaration <*> children (manyTerm ( ( -- Expressions +argumentList :: Assignment +argumentList = symbol ArgumentList *> children expressions + binaryExpression :: Assignment binaryExpression = makeTerm' <$> symbol BinaryExpression <*> children (infixTerm expression expression [ (inj .) . Expression.Plus <$ symbol AnonPlus From 5cc5eb3b8e2da011747c34931365457b573575e3 Mon Sep 17 00:00:00 2001 From: Rick Winfrey Date: Tue, 19 Dec 2017 10:46:24 -0800 Subject: [PATCH 128/133] Assign fieldDeclarationList --- src/Language/Go/Assignment.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Language/Go/Assignment.hs b/src/Language/Go/Assignment.hs index bce19b100..7a55df27d 100644 --- a/src/Language/Go/Assignment.hs +++ b/src/Language/Go/Assignment.hs @@ -139,6 +139,7 @@ expressionChoices = , expressionSwitchStatement , fallThroughStatement , fieldDeclaration + , fieldDeclarationList , fieldIdentifier , floatLiteral , forStatement @@ -286,6 +287,9 @@ fieldDeclaration = mkFieldDeclarationWithTag <$> symbol FieldDeclaration <*> ch | Just tag' <- tag = makeTerm loc (Go.Syntax.Field [tag'] (makeTerm loc fields)) | otherwise = makeTerm loc (Go.Syntax.Field [] (makeTerm loc fields)) +fieldDeclarationList :: Assignment +fieldDeclarationList = symbol FieldDeclarationList *> children expressions + functionType :: Assignment functionType = makeTerm <$> symbol FunctionType <*> children (Type.Function <$> manyTerm parameters <*> (expression <|> emptyTerm)) From 28003f518e173570e560ffffd85198f679c45800 Mon Sep 17 00:00:00 2001 From: Rick Winfrey Date: Tue, 19 Dec 2017 10:46:34 -0800 Subject: [PATCH 129/133] Assign importSpecList --- src/Language/Go/Assignment.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Language/Go/Assignment.hs b/src/Language/Go/Assignment.hs index 7a55df27d..675e12598 100644 --- a/src/Language/Go/Assignment.hs +++ b/src/Language/Go/Assignment.hs @@ -153,6 +153,7 @@ expressionChoices = , identifier , importDeclaration , importSpec + , importSpecList , indexExpression , interpretedStringLiteral , intLiteral @@ -392,6 +393,9 @@ importDeclaration = makeTerm <$> symbol ImportDeclaration <*> children (Declarat importSpec :: Assignment importSpec = symbol ImportSpec *> children expressions +importSpecList :: Assignment +importSpecList = symbol ImportSpecList *> children expressions + indexExpression :: Assignment indexExpression = makeTerm <$> symbol IndexExpression <*> children (Expression.Subscript <$> expression <*> manyTerm expression) From e596fc1b2c0623d52dc8f177881694cf208cbce2 Mon Sep 17 00:00:00 2001 From: Rick Winfrey Date: Tue, 19 Dec 2017 10:58:36 -0800 Subject: [PATCH 130/133] Regenerate tests --- .../go/array-with-implicit-length.diffA-B.txt | 4 +- .../go/array-with-implicit-length.diffB-A.txt | 8 +- test/fixtures/go/assignment-statements.B.go | 20 ++--- .../go/assignment-statements.diffA-B.txt | 26 +++---- .../go/assignment-statements.diffB-A.txt | 34 ++++----- .../go/binary-expressions.diffA-B.txt | 11 +-- .../go/binary-expressions.diffB-A.txt | 11 +-- .../fixtures/go/slice-expressions.diffA-B.txt | 73 ++++++++----------- .../fixtures/go/slice-expressions.diffB-A.txt | 73 ++++++++----------- .../fixtures/go/unary-expressions.diffA-B.txt | 51 ++++++------- .../fixtures/go/unary-expressions.diffB-A.txt | 51 ++++++------- 11 files changed, 157 insertions(+), 205 deletions(-) diff --git a/test/fixtures/go/array-with-implicit-length.diffA-B.txt b/test/fixtures/go/array-with-implicit-length.diffA-B.txt index ce0361f52..ae0923f80 100644 --- a/test/fixtures/go/array-with-implicit-length.diffA-B.txt +++ b/test/fixtures/go/array-with-implicit-length.diffA-B.txt @@ -13,7 +13,7 @@ ( { (Integer) ->(Integer) } - {+(Integer)+} { (Integer) ->(Integer) } - {-(Integer)-}))))) + { (Integer) + ->(Integer) }))))) diff --git a/test/fixtures/go/array-with-implicit-length.diffB-A.txt b/test/fixtures/go/array-with-implicit-length.diffB-A.txt index 42dfe40d9..ae0923f80 100644 --- a/test/fixtures/go/array-with-implicit-length.diffB-A.txt +++ b/test/fixtures/go/array-with-implicit-length.diffB-A.txt @@ -13,7 +13,7 @@ ( { (Integer) ->(Integer) } - {+(Integer)+} - {+(Integer)+} - {-(Integer)-} - {-(Integer)-}))))) + { (Integer) + ->(Integer) } + { (Integer) + ->(Integer) }))))) diff --git a/test/fixtures/go/assignment-statements.B.go b/test/fixtures/go/assignment-statements.B.go index 7fb9d8e47..cc4391a09 100644 --- a/test/fixtures/go/assignment-statements.B.go +++ b/test/fixtures/go/assignment-statements.B.go @@ -1,16 +1,16 @@ package main func main() { -h = 1 -f, g += 2, 3 -e *= 3 -d += 1 -c <<= 1 -b >>= 2 -a /= 2 -z ^= 2 -y %= 2 -x &^= 2 +l = 1 +m, n += 2, 3 +o *= 3 +p += 1 +q <<= 1 +s >>= 2 +t /= 2 +u ^= 2 +v %= 2 +w &^= 2 var pointer *Point2D = &Point2D{x: 1000} } diff --git a/test/fixtures/go/assignment-statements.diffA-B.txt b/test/fixtures/go/assignment-statements.diffA-B.txt index 796e6ec62..fd6997eac 100644 --- a/test/fixtures/go/assignment-statements.diffA-B.txt +++ b/test/fixtures/go/assignment-statements.diffA-B.txt @@ -37,11 +37,15 @@ {+(Plus {+(Identifier)+} {+(Integer)+})+})+} - {+(Assignment - {+(Identifier)+} - {+(LShift + (Assignment + { (Identifier) + ->(Identifier) } + { (Plus + {-(Identifier)-} + {-(Integer)-}) + ->(LShift {+(Identifier)+} - {+(Integer)+})+})+} + {+(Integer)+}) }) {+(Assignment {+(Identifier)+} {+(RShift @@ -50,21 +54,17 @@ (Assignment { (Identifier) ->(Identifier) } - { (Plus + { (LShift {-(Identifier)-} {-(Integer)-}) ->(DividedBy {+(Identifier)+} {+(Integer)+}) }) - (Assignment - { (Identifier) - ->(Identifier) } - { (LShift - {-(Identifier)-} - {-(Integer)-}) - ->(BXOr + {+(Assignment + {+(Identifier)+} + {+(BXOr {+(Identifier)+} - {+(Integer)+}) }) + {+(Integer)+})+})+} {+(Assignment {+(Identifier)+} {+(Modulo diff --git a/test/fixtures/go/assignment-statements.diffB-A.txt b/test/fixtures/go/assignment-statements.diffB-A.txt index 87f619bb9..fd6997eac 100644 --- a/test/fixtures/go/assignment-statements.diffB-A.txt +++ b/test/fixtures/go/assignment-statements.diffB-A.txt @@ -37,21 +37,29 @@ {+(Plus {+(Identifier)+} {+(Integer)+})+})+} - {+(Assignment - {+(Identifier)+} - {+(LShift + (Assignment + { (Identifier) + ->(Identifier) } + { (Plus + {-(Identifier)-} + {-(Integer)-}) + ->(LShift {+(Identifier)+} - {+(Integer)+})+})+} + {+(Integer)+}) }) {+(Assignment {+(Identifier)+} {+(RShift {+(Identifier)+} {+(Integer)+})+})+} - {+(Assignment - {+(Identifier)+} - {+(DividedBy + (Assignment + { (Identifier) + ->(Identifier) } + { (LShift + {-(Identifier)-} + {-(Integer)-}) + ->(DividedBy {+(Identifier)+} - {+(Integer)+})+})+} + {+(Integer)+}) }) {+(Assignment {+(Identifier)+} {+(BXOr @@ -80,16 +88,6 @@ {+(KeyValue {+(Identifier)+} {+(Integer)+})+})+})+})+})+})+} - {-(Assignment - {-(Identifier)-} - {-(Plus - {-(Identifier)-} - {-(Integer)-})-})-} - {-(Assignment - {-(Identifier)-} - {-(LShift - {-(Identifier)-} - {-(Integer)-})-})-} {-(Assignment {-(Identifier)-} {-(RShift diff --git a/test/fixtures/go/binary-expressions.diffA-B.txt b/test/fixtures/go/binary-expressions.diffA-B.txt index 8d88cb7a9..3b7b43359 100644 --- a/test/fixtures/go/binary-expressions.diffA-B.txt +++ b/test/fixtures/go/binary-expressions.diffA-B.txt @@ -22,11 +22,9 @@ ->(Identifier) } { (Identifier) ->(Identifier) })) - (Equal - { (Identifier) - ->(Identifier) } - { (Identifier) - ->(Identifier) }) + {+(Equal + {+(Identifier)+} + {+(Identifier)+})+} {+(Not {+(Equal {+(Identifier)+} @@ -76,6 +74,9 @@ {+(BAnd {+(Identifier)+} {+(Identifier)+})+} + {-(Equal + {-(Identifier)-} + {-(Identifier)-})-} {-(Not {-(Equal {-(Identifier)-} diff --git a/test/fixtures/go/binary-expressions.diffB-A.txt b/test/fixtures/go/binary-expressions.diffB-A.txt index 8d88cb7a9..3b7b43359 100644 --- a/test/fixtures/go/binary-expressions.diffB-A.txt +++ b/test/fixtures/go/binary-expressions.diffB-A.txt @@ -22,11 +22,9 @@ ->(Identifier) } { (Identifier) ->(Identifier) })) - (Equal - { (Identifier) - ->(Identifier) } - { (Identifier) - ->(Identifier) }) + {+(Equal + {+(Identifier)+} + {+(Identifier)+})+} {+(Not {+(Equal {+(Identifier)+} @@ -76,6 +74,9 @@ {+(BAnd {+(Identifier)+} {+(Identifier)+})+} + {-(Equal + {-(Identifier)-} + {-(Identifier)-})-} {-(Not {-(Equal {-(Identifier)-} diff --git a/test/fixtures/go/slice-expressions.diffA-B.txt b/test/fixtures/go/slice-expressions.diffA-B.txt index e7eeed723..084d66f9c 100644 --- a/test/fixtures/go/slice-expressions.diffA-B.txt +++ b/test/fixtures/go/slice-expressions.diffA-B.txt @@ -6,51 +6,36 @@ (Identifier) ([]) ( - {+(Slice - {+(Identifier)+} - {+(Integer)+} - {+(Empty)+} - {+(Empty)+})+} - {+(Slice - {+(Identifier)+} - {+(Empty)+} - {+(Integer)+} - {+(Empty)+})+} - {+(Slice - {+(Identifier)+} - {+(Integer)+} - {+(Integer)+} - {+(Empty)+})+} + (Slice + (Identifier) + { (Integer) + ->(Integer) } + (Empty) + (Empty)) + (Slice + (Identifier) + (Empty) + { (Integer) + ->(Integer) } + (Empty)) + (Slice + (Identifier) + { (Empty) + ->(Integer) } + { (Empty) + ->(Integer) } + (Empty)) + (Slice + (Identifier) + { (Integer) + ->(Integer) } + { (Integer) + ->(Integer) } + { (Integer) + ->(Integer) }) (Slice { (Identifier) ->(Identifier) } (Integer) - { (Empty) - ->(Integer) } - { (Empty) - ->(Integer) }) - {+(Slice - {+(Identifier)+} - {+(Integer)+} - {+(Integer)+} - {+(Empty)+})+} - {-(Slice - {-(Identifier)-} - {-(Empty)-} - {-(Integer)-} - {-(Empty)-})-} - {-(Slice - {-(Identifier)-} - {-(Empty)-} - {-(Empty)-} - {-(Empty)-})-} - {-(Slice - {-(Identifier)-} - {-(Integer)-} - {-(Integer)-} - {-(Integer)-})-} - {-(Slice - {-(Identifier)-} - {-(Integer)-} - {-(Integer)-} - {-(Empty)-})-}))) + (Integer) + (Empty))))) diff --git a/test/fixtures/go/slice-expressions.diffB-A.txt b/test/fixtures/go/slice-expressions.diffB-A.txt index 901da4a7d..d0d377201 100644 --- a/test/fixtures/go/slice-expressions.diffB-A.txt +++ b/test/fixtures/go/slice-expressions.diffB-A.txt @@ -6,51 +6,36 @@ (Identifier) ([]) ( - {+(Slice - {+(Identifier)+} - {+(Integer)+} - {+(Empty)+} - {+(Empty)+})+} - {+(Slice - {+(Identifier)+} - {+(Empty)+} - {+(Integer)+} - {+(Empty)+})+} - {+(Slice - {+(Identifier)+} - {+(Empty)+} - {+(Empty)+} - {+(Empty)+})+} + (Slice + (Identifier) + { (Integer) + ->(Integer) } + (Empty) + (Empty)) + (Slice + (Identifier) + (Empty) + { (Integer) + ->(Integer) } + (Empty)) + (Slice + (Identifier) + { (Integer) + ->(Empty) } + { (Integer) + ->(Empty) } + (Empty)) + (Slice + (Identifier) + { (Integer) + ->(Integer) } + { (Integer) + ->(Integer) } + { (Integer) + ->(Integer) }) (Slice { (Identifier) ->(Identifier) } (Integer) - { (Empty) - ->(Integer) } - { (Empty) - ->(Integer) }) - {+(Slice - {+(Identifier)+} - {+(Integer)+} - {+(Integer)+} - {+(Empty)+})+} - {-(Slice - {-(Identifier)-} - {-(Empty)-} - {-(Integer)-} - {-(Empty)-})-} - {-(Slice - {-(Identifier)-} - {-(Integer)-} - {-(Integer)-} - {-(Empty)-})-} - {-(Slice - {-(Identifier)-} - {-(Integer)-} - {-(Integer)-} - {-(Integer)-})-} - {-(Slice - {-(Identifier)-} - {-(Integer)-} - {-(Integer)-} - {-(Empty)-})-}))) + (Integer) + (Empty))))) diff --git a/test/fixtures/go/unary-expressions.diffA-B.txt b/test/fixtures/go/unary-expressions.diffA-B.txt index 915554cce..da15e099c 100644 --- a/test/fixtures/go/unary-expressions.diffA-B.txt +++ b/test/fixtures/go/unary-expressions.diffA-B.txt @@ -8,33 +8,24 @@ ( { (Identifier) ->(Identifier) } - {+(Negate - {+(Identifier)+})+} - {+(Not - {+(ReceiveOperator - {+(Identifier)+})+})+} - {+(Pointer - {+(Call - {+(Identifier)+} - {+(Empty)+})+})+} - {+(Complement - {+(Identifier)+})+} - {+(Reference - {+(Identifier)+})+} - {+(ReceiveOperator - {+(Identifier)+})+} - {-(Negate - {-(Identifier)-})-} - {-(Not - {-(ReceiveOperator - {-(Identifier)-})-})-} - {-(Pointer - {-(Call - {-(Identifier)-} - {-(Empty)-})-})-} - {-(Complement - {-(Identifier)-})-} - {-(Reference - {-(Identifier)-})-} - {-(ReceiveOperator - {-(Identifier)-})-}))) + (Negate + { (Identifier) + ->(Identifier) }) + (Not + (ReceiveOperator + { (Identifier) + ->(Identifier) })) + (Pointer + (Call + { (Identifier) + ->(Identifier) } + (Empty))) + (Complement + { (Identifier) + ->(Identifier) }) + (Reference + { (Identifier) + ->(Identifier) }) + (ReceiveOperator + { (Identifier) + ->(Identifier) })))) diff --git a/test/fixtures/go/unary-expressions.diffB-A.txt b/test/fixtures/go/unary-expressions.diffB-A.txt index 915554cce..da15e099c 100644 --- a/test/fixtures/go/unary-expressions.diffB-A.txt +++ b/test/fixtures/go/unary-expressions.diffB-A.txt @@ -8,33 +8,24 @@ ( { (Identifier) ->(Identifier) } - {+(Negate - {+(Identifier)+})+} - {+(Not - {+(ReceiveOperator - {+(Identifier)+})+})+} - {+(Pointer - {+(Call - {+(Identifier)+} - {+(Empty)+})+})+} - {+(Complement - {+(Identifier)+})+} - {+(Reference - {+(Identifier)+})+} - {+(ReceiveOperator - {+(Identifier)+})+} - {-(Negate - {-(Identifier)-})-} - {-(Not - {-(ReceiveOperator - {-(Identifier)-})-})-} - {-(Pointer - {-(Call - {-(Identifier)-} - {-(Empty)-})-})-} - {-(Complement - {-(Identifier)-})-} - {-(Reference - {-(Identifier)-})-} - {-(ReceiveOperator - {-(Identifier)-})-}))) + (Negate + { (Identifier) + ->(Identifier) }) + (Not + (ReceiveOperator + { (Identifier) + ->(Identifier) })) + (Pointer + (Call + { (Identifier) + ->(Identifier) } + (Empty))) + (Complement + { (Identifier) + ->(Identifier) }) + (Reference + { (Identifier) + ->(Identifier) }) + (ReceiveOperator + { (Identifier) + ->(Identifier) })))) From 2ef9c72ed2cf2904582e3ea2bb2e86d432d80831 Mon Sep 17 00:00:00 2001 From: Rick Winfrey Date: Tue, 19 Dec 2017 13:57:57 -0800 Subject: [PATCH 131/133] Match ArgumentList alias --- src/Language/Go/Assignment.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Go/Assignment.hs b/src/Language/Go/Assignment.hs index 675e12598..4b1808d76 100644 --- a/src/Language/Go/Assignment.hs +++ b/src/Language/Go/Assignment.hs @@ -327,7 +327,7 @@ typeDeclaration = makeTerm <$> symbol TypeDeclaration <*> children (manyTerm ( ( -- Expressions argumentList :: Assignment -argumentList = symbol ArgumentList *> children expressions +argumentList = (symbol ArgumentList <|> symbol ArgumentList') *> children expressions binaryExpression :: Assignment binaryExpression = makeTerm' <$> symbol BinaryExpression <*> children (infixTerm expression expression From 64149bff77bd8f56acd6d78a3e1b5268c8baa98e Mon Sep 17 00:00:00 2001 From: Rick Winfrey Date: Tue, 19 Dec 2017 13:58:06 -0800 Subject: [PATCH 132/133] Assign MethodSpecLIst --- src/Language/Go/Assignment.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Language/Go/Assignment.hs b/src/Language/Go/Assignment.hs index 4b1808d76..4cdf69dd8 100644 --- a/src/Language/Go/Assignment.hs +++ b/src/Language/Go/Assignment.hs @@ -163,6 +163,7 @@ expressionChoices = , literalValue , methodDeclaration , methodSpec + , methodSpecList , packageClause , packageIdentifier , parameterDeclaration @@ -410,6 +411,9 @@ methodSpec = makeTerm <$> symbol MethodSpec <*> children (mkMethodSpec <$> expr where mkMethodSpec name' params optionalTypeLiteral = Declaration.MethodSignature [optionalTypeLiteral] name' [params] +methodSpecList :: Assignment +methodSpecList = symbol MethodSpecList *> children expressions + packageClause :: Assignment packageClause = makeTerm <$> symbol PackageClause <*> children (Declaration.Module <$> expression <*> pure []) From fddd6e106b13bc8c72acc8b07f1b153f7d05ae02 Mon Sep 17 00:00:00 2001 From: Rick Winfrey Date: Tue, 19 Dec 2017 14:04:48 -0800 Subject: [PATCH 133/133] Regenerate tests --- .../go/array-with-implicit-length.diffA-B.txt | 4 +- .../go/array-with-implicit-length.diffB-A.txt | 8 +- .../go/assignment-statements.diffA-B.txt | 51 +++++++------ .../go/assignment-statements.diffB-A.txt | 58 ++++++++------- .../go/binary-expressions.diffA-B.txt | 11 ++- .../go/binary-expressions.diffB-A.txt | 11 ++- test/fixtures/go/call-expressions.A.go | 1 + test/fixtures/go/call-expressions.diffA-B.txt | 29 +++++--- test/fixtures/go/call-expressions.diffB-A.txt | 29 +++++--- test/fixtures/go/call-expressions.parseA.txt | 19 +++-- test/fixtures/go/call-expressions.parseB.txt | 21 +++--- test/fixtures/go/case-statements.diffA-B.txt | 4 + test/fixtures/go/case-statements.diffB-A.txt | 4 + test/fixtures/go/case-statements.parseB.txt | 4 + test/fixtures/go/channel-types.diffA-B.txt | 3 +- test/fixtures/go/channel-types.diffB-A.txt | 3 +- test/fixtures/go/channel-types.parseA.txt | 3 +- test/fixtures/go/channel-types.parseB.txt | 3 +- test/fixtures/go/constructors.diffA-B.txt | 28 +++---- test/fixtures/go/constructors.diffB-A.txt | 28 +++---- test/fixtures/go/constructors.parseA.txt | 20 ++--- test/fixtures/go/constructors.parseB.txt | 20 ++--- test/fixtures/go/for-statements.diffA-B.txt | 28 +++++-- test/fixtures/go/for-statements.diffB-A.txt | 29 ++++++-- test/fixtures/go/for-statements.parseA.txt | 15 +++- test/fixtures/go/for-statements.parseB.txt | 15 +++- .../go/go-and-defer-statements.diffA-B.txt | 2 + .../go/go-and-defer-statements.diffB-A.txt | 2 + .../go/go-and-defer-statements.parseA.txt | 2 + .../go/go-and-defer-statements.parseB.txt | 2 + .../grouped-import-declarations.diffA-B.txt | 13 ++-- .../grouped-import-declarations.diffB-A.txt | 13 ++-- .../go/grouped-import-declarations.parseA.txt | 9 ++- .../go/grouped-import-declarations.parseB.txt | 9 ++- test/fixtures/go/if-statements.diffA-B.txt | 12 +++ test/fixtures/go/if-statements.diffB-A.txt | 12 +++ test/fixtures/go/if-statements.parseA.txt | 11 +++ test/fixtures/go/if-statements.parseB.txt | 10 +++ .../fixtures/go/import-statements.diffA-B.txt | 17 +++-- .../fixtures/go/import-statements.diffB-A.txt | 17 +++-- test/fixtures/go/import-statements.parseA.txt | 15 ++-- test/fixtures/go/import-statements.parseB.txt | 15 ++-- test/fixtures/go/interface-types.diffA-B.txt | 20 ++--- test/fixtures/go/interface-types.diffB-A.txt | 20 ++--- test/fixtures/go/interface-types.parseA.txt | 20 ++--- test/fixtures/go/interface-types.parseB.txt | 20 ++--- .../go/method-declarations.diffA-B.txt | 18 +++-- .../go/method-declarations.diffB-A.txt | 18 +++-- .../go/method-declarations.parseB.txt | 18 +++-- .../go/selector-expressions.diffA-B.txt | 1 + .../go/selector-expressions.diffB-A.txt | 1 + .../go/selector-expressions.parseA.txt | 1 + .../go/selector-expressions.parseB.txt | 1 + ...gle-line-function-declarations.diffA-B.txt | 5 ++ ...gle-line-function-declarations.diffB-A.txt | 5 ++ ...ngle-line-function-declarations.parseA.txt | 5 ++ ...ngle-line-function-declarations.parseB.txt | 5 ++ .../fixtures/go/slice-expressions.diffA-B.txt | 73 +++++++++++-------- .../fixtures/go/slice-expressions.diffB-A.txt | 73 +++++++++++-------- test/fixtures/go/struct-types.diffA-B.txt | 24 +++--- test/fixtures/go/struct-types.diffB-A.txt | 24 +++--- test/fixtures/go/struct-types.parseA.txt | 24 +++--- test/fixtures/go/struct-types.parseB.txt | 24 +++--- .../fixtures/go/switch-statements.diffA-B.txt | 3 + .../fixtures/go/switch-statements.diffB-A.txt | 3 + test/fixtures/go/switch-statements.parseA.txt | 3 + test/fixtures/go/switch-statements.parseB.txt | 3 + .../fixtures/go/type-declarations.diffA-B.txt | 28 +++---- .../fixtures/go/type-declarations.diffB-A.txt | 28 +++---- test/fixtures/go/type-declarations.parseA.txt | 28 +++---- test/fixtures/go/type-declarations.parseB.txt | 28 +++---- .../go/type-switch-statements.diffA-B.txt | 68 +++++++++-------- .../go/type-switch-statements.diffB-A.txt | 68 +++++++++-------- .../go/type-switch-statements.parseA.txt | 44 ++++++----- .../go/type-switch-statements.parseB.txt | 44 ++++++----- .../fixtures/go/unary-expressions.diffA-B.txt | 53 ++++++++------ .../fixtures/go/unary-expressions.diffB-A.txt | 53 ++++++++------ test/fixtures/go/unary-expressions.parseA.txt | 1 + test/fixtures/go/unary-expressions.parseB.txt | 1 + 79 files changed, 879 insertions(+), 587 deletions(-) diff --git a/test/fixtures/go/array-with-implicit-length.diffA-B.txt b/test/fixtures/go/array-with-implicit-length.diffA-B.txt index ae0923f80..ce0361f52 100644 --- a/test/fixtures/go/array-with-implicit-length.diffA-B.txt +++ b/test/fixtures/go/array-with-implicit-length.diffA-B.txt @@ -13,7 +13,7 @@ ( { (Integer) ->(Integer) } + {+(Integer)+} { (Integer) ->(Integer) } - { (Integer) - ->(Integer) }))))) + {-(Integer)-}))))) diff --git a/test/fixtures/go/array-with-implicit-length.diffB-A.txt b/test/fixtures/go/array-with-implicit-length.diffB-A.txt index ae0923f80..42dfe40d9 100644 --- a/test/fixtures/go/array-with-implicit-length.diffB-A.txt +++ b/test/fixtures/go/array-with-implicit-length.diffB-A.txt @@ -13,7 +13,7 @@ ( { (Integer) ->(Integer) } - { (Integer) - ->(Integer) } - { (Integer) - ->(Integer) }))))) + {+(Integer)+} + {+(Integer)+} + {-(Integer)-} + {-(Integer)-}))))) diff --git a/test/fixtures/go/assignment-statements.diffA-B.txt b/test/fixtures/go/assignment-statements.diffA-B.txt index fd6997eac..7eb02d8f6 100644 --- a/test/fixtures/go/assignment-statements.diffA-B.txt +++ b/test/fixtures/go/assignment-statements.diffA-B.txt @@ -25,41 +25,31 @@ ( (Integer) (Integer)))) - (Assignment - { (Identifier) - ->(Identifier) } - (Times - { (Identifier) - ->(Identifier) } - (Integer))) + {+(Assignment + {+(Identifier)+} + {+(Times + {+(Identifier)+} + {+(Integer)+})+})+} {+(Assignment {+(Identifier)+} {+(Plus {+(Identifier)+} {+(Integer)+})+})+} - (Assignment - { (Identifier) - ->(Identifier) } - { (Plus - {-(Identifier)-} - {-(Integer)-}) - ->(LShift + {+(Assignment + {+(Identifier)+} + {+(LShift {+(Identifier)+} - {+(Integer)+}) }) + {+(Integer)+})+})+} {+(Assignment {+(Identifier)+} {+(RShift {+(Identifier)+} {+(Integer)+})+})+} - (Assignment - { (Identifier) - ->(Identifier) } - { (LShift - {-(Identifier)-} - {-(Integer)-}) - ->(DividedBy + {+(Assignment + {+(Identifier)+} + {+(DividedBy {+(Identifier)+} - {+(Integer)+}) }) + {+(Integer)+})+})+} {+(Assignment {+(Identifier)+} {+(BXOr @@ -88,6 +78,21 @@ {+(KeyValue {+(Identifier)+} {+(Integer)+})+})+})+})+})+})+} + {-(Assignment + {-(Identifier)-} + {-(Times + {-(Identifier)-} + {-(Integer)-})-})-} + {-(Assignment + {-(Identifier)-} + {-(Plus + {-(Identifier)-} + {-(Integer)-})-})-} + {-(Assignment + {-(Identifier)-} + {-(LShift + {-(Identifier)-} + {-(Integer)-})-})-} {-(Assignment {-(Identifier)-} {-(RShift diff --git a/test/fixtures/go/assignment-statements.diffB-A.txt b/test/fixtures/go/assignment-statements.diffB-A.txt index fd6997eac..6e7951859 100644 --- a/test/fixtures/go/assignment-statements.diffB-A.txt +++ b/test/fixtures/go/assignment-statements.diffB-A.txt @@ -25,51 +25,45 @@ ( (Integer) (Integer)))) - (Assignment - { (Identifier) - ->(Identifier) } - (Times - { (Identifier) - ->(Identifier) } - (Integer))) + {+(Assignment + {+(Identifier)+} + {+(Times + {+(Identifier)+} + {+(Integer)+})+})+} {+(Assignment {+(Identifier)+} {+(Plus {+(Identifier)+} {+(Integer)+})+})+} - (Assignment - { (Identifier) - ->(Identifier) } - { (Plus - {-(Identifier)-} - {-(Integer)-}) - ->(LShift + {+(Assignment + {+(Identifier)+} + {+(LShift {+(Identifier)+} - {+(Integer)+}) }) + {+(Integer)+})+})+} {+(Assignment {+(Identifier)+} {+(RShift {+(Identifier)+} {+(Integer)+})+})+} - (Assignment - { (Identifier) - ->(Identifier) } - { (LShift - {-(Identifier)-} - {-(Integer)-}) - ->(DividedBy + {+(Assignment + {+(Identifier)+} + {+(DividedBy {+(Identifier)+} - {+(Integer)+}) }) + {+(Integer)+})+})+} {+(Assignment {+(Identifier)+} {+(BXOr {+(Identifier)+} {+(Integer)+})+})+} - {+(Assignment - {+(Identifier)+} - {+(Modulo + (Assignment + { (Identifier) + ->(Identifier) } + { (Times + {-(Identifier)-} + {-(Integer)-}) + ->(Modulo {+(Identifier)+} - {+(Integer)+})+})+} + {+(Integer)+}) }) {+(Assignment {+(Identifier)+} {+(Not @@ -88,6 +82,16 @@ {+(KeyValue {+(Identifier)+} {+(Integer)+})+})+})+})+})+})+} + {-(Assignment + {-(Identifier)-} + {-(Plus + {-(Identifier)-} + {-(Integer)-})-})-} + {-(Assignment + {-(Identifier)-} + {-(LShift + {-(Identifier)-} + {-(Integer)-})-})-} {-(Assignment {-(Identifier)-} {-(RShift diff --git a/test/fixtures/go/binary-expressions.diffA-B.txt b/test/fixtures/go/binary-expressions.diffA-B.txt index 3b7b43359..8d88cb7a9 100644 --- a/test/fixtures/go/binary-expressions.diffA-B.txt +++ b/test/fixtures/go/binary-expressions.diffA-B.txt @@ -22,9 +22,11 @@ ->(Identifier) } { (Identifier) ->(Identifier) })) - {+(Equal - {+(Identifier)+} - {+(Identifier)+})+} + (Equal + { (Identifier) + ->(Identifier) } + { (Identifier) + ->(Identifier) }) {+(Not {+(Equal {+(Identifier)+} @@ -74,9 +76,6 @@ {+(BAnd {+(Identifier)+} {+(Identifier)+})+} - {-(Equal - {-(Identifier)-} - {-(Identifier)-})-} {-(Not {-(Equal {-(Identifier)-} diff --git a/test/fixtures/go/binary-expressions.diffB-A.txt b/test/fixtures/go/binary-expressions.diffB-A.txt index 3b7b43359..8d88cb7a9 100644 --- a/test/fixtures/go/binary-expressions.diffB-A.txt +++ b/test/fixtures/go/binary-expressions.diffB-A.txt @@ -22,9 +22,11 @@ ->(Identifier) } { (Identifier) ->(Identifier) })) - {+(Equal - {+(Identifier)+} - {+(Identifier)+})+} + (Equal + { (Identifier) + ->(Identifier) } + { (Identifier) + ->(Identifier) }) {+(Not {+(Equal {+(Identifier)+} @@ -74,9 +76,6 @@ {+(BAnd {+(Identifier)+} {+(Identifier)+})+} - {-(Equal - {-(Identifier)-} - {-(Identifier)-})-} {-(Not {-(Equal {-(Identifier)-} diff --git a/test/fixtures/go/call-expressions.A.go b/test/fixtures/go/call-expressions.A.go index 72918e593..a18549171 100644 --- a/test/fixtures/go/call-expressions.A.go +++ b/test/fixtures/go/call-expressions.A.go @@ -4,4 +4,5 @@ func main() { x(b, c...) y(b, c,) z(b,c...,) +a() } diff --git a/test/fixtures/go/call-expressions.diffA-B.txt b/test/fixtures/go/call-expressions.diffA-B.txt index 0e7ef344d..1f6407b27 100644 --- a/test/fixtures/go/call-expressions.diffA-B.txt +++ b/test/fixtures/go/call-expressions.diffA-B.txt @@ -9,20 +9,27 @@ (Call { (Identifier) ->(Identifier) } - (Identifier) - (Variadic + ( + (Identifier) + (Variadic + (Identifier))) + (Empty)) + (Call + { (Identifier) + ->(Identifier) } + ( + (Identifier) (Identifier)) (Empty)) (Call { (Identifier) ->(Identifier) } - (Identifier) - (Identifier) + ( + (Identifier) + (Variadic + (Identifier))) (Empty)) - (Call - { (Identifier) - ->(Identifier) } - (Identifier) - (Variadic - (Identifier)) - (Empty))))) + {-(Call + {-(Identifier)-} + {-([])-} + {-(Empty)-})-}))) diff --git a/test/fixtures/go/call-expressions.diffB-A.txt b/test/fixtures/go/call-expressions.diffB-A.txt index 0e7ef344d..b75b7fade 100644 --- a/test/fixtures/go/call-expressions.diffB-A.txt +++ b/test/fixtures/go/call-expressions.diffB-A.txt @@ -9,20 +9,27 @@ (Call { (Identifier) ->(Identifier) } - (Identifier) - (Variadic + ( + (Identifier) + (Variadic + (Identifier))) + (Empty)) + (Call + { (Identifier) + ->(Identifier) } + ( + (Identifier) (Identifier)) (Empty)) (Call { (Identifier) ->(Identifier) } - (Identifier) - (Identifier) + ( + (Identifier) + (Variadic + (Identifier))) (Empty)) - (Call - { (Identifier) - ->(Identifier) } - (Identifier) - (Variadic - (Identifier)) - (Empty))))) + {+(Call + {+(Identifier)+} + {+([])+} + {+(Empty)+})+}))) diff --git a/test/fixtures/go/call-expressions.parseA.txt b/test/fixtures/go/call-expressions.parseA.txt index cedad1b83..928b1f825 100644 --- a/test/fixtures/go/call-expressions.parseA.txt +++ b/test/fixtures/go/call-expressions.parseA.txt @@ -8,18 +8,25 @@ ( (Call (Identifier) + ( + (Identifier) + (Variadic + (Identifier))) + (Empty)) + (Call (Identifier) - (Variadic + ( + (Identifier) (Identifier)) (Empty)) (Call (Identifier) - (Identifier) - (Identifier) + ( + (Identifier) + (Variadic + (Identifier))) (Empty)) (Call (Identifier) - (Identifier) - (Variadic - (Identifier)) + ([]) (Empty))))) diff --git a/test/fixtures/go/call-expressions.parseB.txt b/test/fixtures/go/call-expressions.parseB.txt index cedad1b83..05e9ba4b2 100644 --- a/test/fixtures/go/call-expressions.parseB.txt +++ b/test/fixtures/go/call-expressions.parseB.txt @@ -8,18 +8,21 @@ ( (Call (Identifier) + ( + (Identifier) + (Variadic + (Identifier))) + (Empty)) + (Call (Identifier) - (Variadic + ( + (Identifier) (Identifier)) (Empty)) (Call (Identifier) - (Identifier) - (Identifier) - (Empty)) - (Call - (Identifier) - (Identifier) - (Variadic - (Identifier)) + ( + (Identifier) + (Variadic + (Identifier))) (Empty))))) diff --git a/test/fixtures/go/case-statements.diffA-B.txt b/test/fixtures/go/case-statements.diffA-B.txt index 3bd64348f..256cfc072 100644 --- a/test/fixtures/go/case-statements.diffA-B.txt +++ b/test/fixtures/go/case-statements.diffA-B.txt @@ -15,6 +15,7 @@ {+(Identifier)+} {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+})+})+} {+(Match {+( @@ -27,9 +28,11 @@ {+( {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+} {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+} {+(Pattern {+(Identifier)+} @@ -38,6 +41,7 @@ {+( {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+} {+(Break {+(Empty)+})+})+})+})+})+}) })) diff --git a/test/fixtures/go/case-statements.diffB-A.txt b/test/fixtures/go/case-statements.diffB-A.txt index 63cc9337e..6a482e8dd 100644 --- a/test/fixtures/go/case-statements.diffB-A.txt +++ b/test/fixtures/go/case-statements.diffB-A.txt @@ -12,6 +12,7 @@ {-(Identifier)-} {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-})-})-} {-(Match {-( @@ -24,9 +25,11 @@ {-( {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-} {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-} {-(Pattern {-(Identifier)-} @@ -35,6 +38,7 @@ {-( {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-} {-(Break {-(Empty)-})-})-})-})-})-}) diff --git a/test/fixtures/go/case-statements.parseB.txt b/test/fixtures/go/case-statements.parseB.txt index b81e12be4..b89a00a6a 100644 --- a/test/fixtures/go/case-statements.parseB.txt +++ b/test/fixtures/go/case-statements.parseB.txt @@ -12,6 +12,7 @@ (Identifier) (Call (Identifier) + ([]) (Empty)))) (Match ( @@ -24,9 +25,11 @@ ( (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty)) (Pattern (Identifier) @@ -35,6 +38,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Break (Empty))))))))) diff --git a/test/fixtures/go/channel-types.diffA-B.txt b/test/fixtures/go/channel-types.diffA-B.txt index 1dd5176fe..36aa83a0d 100644 --- a/test/fixtures/go/channel-types.diffA-B.txt +++ b/test/fixtures/go/channel-types.diffA-B.txt @@ -19,7 +19,8 @@ (SendChannel (SendChannel (Constructor - (Empty))))) + (Empty) + ([]))))) (Type { (Identifier) ->(Identifier) } diff --git a/test/fixtures/go/channel-types.diffB-A.txt b/test/fixtures/go/channel-types.diffB-A.txt index 1dd5176fe..36aa83a0d 100644 --- a/test/fixtures/go/channel-types.diffB-A.txt +++ b/test/fixtures/go/channel-types.diffB-A.txt @@ -19,7 +19,8 @@ (SendChannel (SendChannel (Constructor - (Empty))))) + (Empty) + ([]))))) (Type { (Identifier) ->(Identifier) } diff --git a/test/fixtures/go/channel-types.parseA.txt b/test/fixtures/go/channel-types.parseA.txt index b50395389..1c6733045 100644 --- a/test/fixtures/go/channel-types.parseA.txt +++ b/test/fixtures/go/channel-types.parseA.txt @@ -16,7 +16,8 @@ (SendChannel (SendChannel (Constructor - (Empty))))) + (Empty) + ([]))))) (Type (Identifier) (SendChannel diff --git a/test/fixtures/go/channel-types.parseB.txt b/test/fixtures/go/channel-types.parseB.txt index b50395389..1c6733045 100644 --- a/test/fixtures/go/channel-types.parseB.txt +++ b/test/fixtures/go/channel-types.parseB.txt @@ -16,7 +16,8 @@ (SendChannel (SendChannel (Constructor - (Empty))))) + (Empty) + ([]))))) (Type (Identifier) (SendChannel diff --git a/test/fixtures/go/constructors.diffA-B.txt b/test/fixtures/go/constructors.diffA-B.txt index 22feb3df3..90983b4fa 100644 --- a/test/fixtures/go/constructors.diffA-B.txt +++ b/test/fixtures/go/constructors.diffA-B.txt @@ -14,22 +14,24 @@ (Empty)) (Call (Identifier) - (SendChannel - { (Identifier) - ->(Identifier) }) - (Minus - (Identifier) - (Identifier)) + ( + (SendChannel + { (Identifier) + ->(Identifier) }) + (Minus + (Identifier) + (Identifier))) (Empty)) (Call (Identifier) - (SendChannel - { (Identifier) - ->(Identifier) }) - { (Integer) - ->(Integer) } - { (Integer) - ->(Integer) } + ( + (SendChannel + { (Identifier) + ->(Identifier) }) + { (Integer) + ->(Integer) } + { (Integer) + ->(Integer) }) (Empty)) (Call (Identifier) diff --git a/test/fixtures/go/constructors.diffB-A.txt b/test/fixtures/go/constructors.diffB-A.txt index 22feb3df3..90983b4fa 100644 --- a/test/fixtures/go/constructors.diffB-A.txt +++ b/test/fixtures/go/constructors.diffB-A.txt @@ -14,22 +14,24 @@ (Empty)) (Call (Identifier) - (SendChannel - { (Identifier) - ->(Identifier) }) - (Minus - (Identifier) - (Identifier)) + ( + (SendChannel + { (Identifier) + ->(Identifier) }) + (Minus + (Identifier) + (Identifier))) (Empty)) (Call (Identifier) - (SendChannel - { (Identifier) - ->(Identifier) }) - { (Integer) - ->(Integer) } - { (Integer) - ->(Integer) } + ( + (SendChannel + { (Identifier) + ->(Identifier) }) + { (Integer) + ->(Integer) } + { (Integer) + ->(Integer) }) (Empty)) (Call (Identifier) diff --git a/test/fixtures/go/constructors.parseA.txt b/test/fixtures/go/constructors.parseA.txt index fb8c734fc..45c449aef 100644 --- a/test/fixtures/go/constructors.parseA.txt +++ b/test/fixtures/go/constructors.parseA.txt @@ -13,18 +13,20 @@ (Empty)) (Call (Identifier) - (SendChannel - (Identifier)) - (Minus - (Identifier) - (Identifier)) + ( + (SendChannel + (Identifier)) + (Minus + (Identifier) + (Identifier))) (Empty)) (Call (Identifier) - (SendChannel - (Identifier)) - (Integer) - (Integer) + ( + (SendChannel + (Identifier)) + (Integer) + (Integer)) (Empty)) (Call (Identifier) diff --git a/test/fixtures/go/constructors.parseB.txt b/test/fixtures/go/constructors.parseB.txt index fb8c734fc..45c449aef 100644 --- a/test/fixtures/go/constructors.parseB.txt +++ b/test/fixtures/go/constructors.parseB.txt @@ -13,18 +13,20 @@ (Empty)) (Call (Identifier) - (SendChannel - (Identifier)) - (Minus - (Identifier) - (Identifier)) + ( + (SendChannel + (Identifier)) + (Minus + (Identifier) + (Identifier))) (Empty)) (Call (Identifier) - (SendChannel - (Identifier)) - (Integer) - (Integer) + ( + (SendChannel + (Identifier)) + (Integer) + (Integer)) (Empty)) (Call (Identifier) diff --git a/test/fixtures/go/for-statements.diffA-B.txt b/test/fixtures/go/for-statements.diffA-B.txt index f7aca0464..fbbc74d11 100644 --- a/test/fixtures/go/for-statements.diffA-B.txt +++ b/test/fixtures/go/for-statements.diffA-B.txt @@ -13,6 +13,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Goto (Identifier)))) @@ -22,6 +23,7 @@ {+( {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+} {+(Break {+(Identifier)+})+})+})+} @@ -32,6 +34,7 @@ {+( {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+} {+(Continue {+(Identifier)+})+})+})+} @@ -53,6 +56,7 @@ ( (Call (Identifier) + ([]) (Empty)) {+(Continue {+(Empty)+})+} @@ -76,8 +80,9 @@ {+(Identifier)+} {+(Call {+(Identifier)+} - {+(Identifier)+} - {+(Identifier)+} + {+( + {+(Identifier)+} + {+(Identifier)+})+} {+(Empty)+})+})+} {+(ForEach {+( @@ -86,8 +91,9 @@ {+(Identifier)+} {+(Call {+(Identifier)+} - {+(Identifier)+} - {+(Identifier)+} + {+( + {+(Identifier)+} + {+(Identifier)+})+} {+(Empty)+})+})+} {+(For {+(Empty)+} @@ -97,6 +103,7 @@ {+(Empty)+} {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+})+} {+(ForEach {+(Empty)+} @@ -112,6 +119,7 @@ {-( {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-} {-(Continue {-(Identifier)-})-})-})-} @@ -122,6 +130,7 @@ {-( {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-} {-(Continue {-(Empty)-})-})-})-} @@ -142,8 +151,9 @@ {-(Identifier)-} {-(Call {-(Identifier)-} - {-(Identifier)-} - {-(Identifier)-} + {-( + {-(Identifier)-} + {-(Identifier)-})-} {-(Empty)-})-})-} {-(ForEach {-( @@ -152,8 +162,9 @@ {-(Identifier)-} {-(Call {-(Identifier)-} - {-(Identifier)-} - {-(Identifier)-} + {-( + {-(Identifier)-} + {-(Identifier)-})-} {-(Empty)-})-})-} {-(For {-(Empty)-} @@ -163,6 +174,7 @@ {-(Empty)-} {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-})-} {-(ForEach {-(Empty)-} diff --git a/test/fixtures/go/for-statements.diffB-A.txt b/test/fixtures/go/for-statements.diffB-A.txt index 189b53965..d81b498ac 100644 --- a/test/fixtures/go/for-statements.diffB-A.txt +++ b/test/fixtures/go/for-statements.diffB-A.txt @@ -13,6 +13,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Goto (Identifier)))) @@ -28,6 +29,7 @@ {+( {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+} {+(Break {+(Identifier)+})+})+})+} @@ -41,6 +43,7 @@ {+( {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+} {+(Continue {+(Identifier)+})+})+})+} @@ -51,6 +54,7 @@ {+( {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+} {+(Continue {+(Empty)+})+})+})+} @@ -61,6 +65,7 @@ (Call (Identifier) {+(Identifier)+} + {-([])-} (Empty)) (Break { (Identifier) @@ -72,8 +77,9 @@ {+(Identifier)+} {+(Call {+(Identifier)+} - {+(Identifier)+} - {+(Identifier)+} + {+( + {+(Identifier)+} + {+(Identifier)+})+} {+(Empty)+})+})+} {+(ForEach {+( @@ -82,8 +88,9 @@ {+(Identifier)+} {+(Call {+(Identifier)+} - {+(Identifier)+} - {+(Identifier)+} + {+( + {+(Identifier)+} + {+(Identifier)+})+} {+(Empty)+})+})+} {+(For {+(Empty)+} @@ -93,6 +100,7 @@ {+(Empty)+} {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+})+} {+(ForEach {+(Empty)+} @@ -105,6 +113,7 @@ {-( {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-} {-(Continue {-(Identifier)-})-})-})-} @@ -118,6 +127,7 @@ {-( {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-} {-(Continue {-(Empty)-})-})-})-} @@ -139,8 +149,9 @@ {-(Identifier)-} {-(Call {-(Identifier)-} - {-(Identifier)-} - {-(Identifier)-} + {-( + {-(Identifier)-} + {-(Identifier)-})-} {-(Empty)-})-})-} {-(ForEach {-( @@ -149,8 +160,9 @@ {-(Identifier)-} {-(Call {-(Identifier)-} - {-(Identifier)-} - {-(Identifier)-} + {-( + {-(Identifier)-} + {-(Identifier)-})-} {-(Empty)-})-})-} {-(For {-(Empty)-} @@ -160,6 +172,7 @@ {-(Empty)-} {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-})-} {-(ForEach {-(Empty)-} diff --git a/test/fixtures/go/for-statements.parseA.txt b/test/fixtures/go/for-statements.parseA.txt index 2a2fb153e..53f9aecea 100644 --- a/test/fixtures/go/for-statements.parseA.txt +++ b/test/fixtures/go/for-statements.parseA.txt @@ -13,6 +13,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Goto (Identifier)))) @@ -28,6 +29,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Break (Identifier)))) @@ -41,6 +43,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Continue (Identifier)))) @@ -51,6 +54,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Continue (Empty)))) @@ -71,8 +75,9 @@ (Identifier) (Call (Identifier) - (Identifier) - (Identifier) + ( + (Identifier) + (Identifier)) (Empty))) (ForEach ( @@ -81,8 +86,9 @@ (Identifier) (Call (Identifier) - (Identifier) - (Identifier) + ( + (Identifier) + (Identifier)) (Empty))) (For (Empty) @@ -92,6 +98,7 @@ (Empty) (Call (Identifier) + ([]) (Empty))) (ForEach (Empty) diff --git a/test/fixtures/go/for-statements.parseB.txt b/test/fixtures/go/for-statements.parseB.txt index 1e22d434d..7133cd2a4 100644 --- a/test/fixtures/go/for-statements.parseB.txt +++ b/test/fixtures/go/for-statements.parseB.txt @@ -13,6 +13,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Goto (Identifier)))) @@ -22,6 +23,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Break (Identifier)))) @@ -32,6 +34,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Continue (Identifier)))) @@ -45,6 +48,7 @@ ( (Call (Identifier) + ([]) (Empty)) (Continue (Empty)))) @@ -66,8 +70,9 @@ (Identifier) (Call (Identifier) - (Identifier) - (Identifier) + ( + (Identifier) + (Identifier)) (Empty))) (ForEach ( @@ -76,8 +81,9 @@ (Identifier) (Call (Identifier) - (Identifier) - (Identifier) + ( + (Identifier) + (Identifier)) (Empty))) (For (Empty) @@ -87,6 +93,7 @@ (Empty) (Call (Identifier) + ([]) (Empty))) (ForEach (Empty) diff --git a/test/fixtures/go/go-and-defer-statements.diffA-B.txt b/test/fixtures/go/go-and-defer-statements.diffA-B.txt index a1ad72292..6e4a6f584 100644 --- a/test/fixtures/go/go-and-defer-statements.diffA-B.txt +++ b/test/fixtures/go/go-and-defer-statements.diffA-B.txt @@ -13,6 +13,7 @@ ->(Identifier) } { (Identifier) ->(Identifier) }) + ([]) (Empty))) (Go (Call @@ -21,4 +22,5 @@ ->(Identifier) } { (Identifier) ->(Identifier) }) + ([]) (Empty)))))) diff --git a/test/fixtures/go/go-and-defer-statements.diffB-A.txt b/test/fixtures/go/go-and-defer-statements.diffB-A.txt index a1ad72292..6e4a6f584 100644 --- a/test/fixtures/go/go-and-defer-statements.diffB-A.txt +++ b/test/fixtures/go/go-and-defer-statements.diffB-A.txt @@ -13,6 +13,7 @@ ->(Identifier) } { (Identifier) ->(Identifier) }) + ([]) (Empty))) (Go (Call @@ -21,4 +22,5 @@ ->(Identifier) } { (Identifier) ->(Identifier) }) + ([]) (Empty)))))) diff --git a/test/fixtures/go/go-and-defer-statements.parseA.txt b/test/fixtures/go/go-and-defer-statements.parseA.txt index e8b59defc..b2ff60d81 100644 --- a/test/fixtures/go/go-and-defer-statements.parseA.txt +++ b/test/fixtures/go/go-and-defer-statements.parseA.txt @@ -11,10 +11,12 @@ (MemberAccess (Identifier) (Identifier)) + ([]) (Empty))) (Go (Call (MemberAccess (Identifier) (Identifier)) + ([]) (Empty)))))) diff --git a/test/fixtures/go/go-and-defer-statements.parseB.txt b/test/fixtures/go/go-and-defer-statements.parseB.txt index e8b59defc..b2ff60d81 100644 --- a/test/fixtures/go/go-and-defer-statements.parseB.txt +++ b/test/fixtures/go/go-and-defer-statements.parseB.txt @@ -11,10 +11,12 @@ (MemberAccess (Identifier) (Identifier)) + ([]) (Empty))) (Go (Call (MemberAccess (Identifier) (Identifier)) + ([]) (Empty)))))) diff --git a/test/fixtures/go/grouped-import-declarations.diffA-B.txt b/test/fixtures/go/grouped-import-declarations.diffA-B.txt index ffa6735b1..813ee2e3e 100644 --- a/test/fixtures/go/grouped-import-declarations.diffA-B.txt +++ b/test/fixtures/go/grouped-import-declarations.diffA-B.txt @@ -2,14 +2,15 @@ (Module (Identifier)) (Import - { (TextElement) - ->(TextElement) } - { (TextElement) - ->(TextElement) } ( - (Identifier) { (TextElement) - ->(TextElement) })) + ->(TextElement) } + { (TextElement) + ->(TextElement) } + ( + (Identifier) + { (TextElement) + ->(TextElement) }))) (Function (Empty) (Identifier) diff --git a/test/fixtures/go/grouped-import-declarations.diffB-A.txt b/test/fixtures/go/grouped-import-declarations.diffB-A.txt index ffa6735b1..813ee2e3e 100644 --- a/test/fixtures/go/grouped-import-declarations.diffB-A.txt +++ b/test/fixtures/go/grouped-import-declarations.diffB-A.txt @@ -2,14 +2,15 @@ (Module (Identifier)) (Import - { (TextElement) - ->(TextElement) } - { (TextElement) - ->(TextElement) } ( - (Identifier) { (TextElement) - ->(TextElement) })) + ->(TextElement) } + { (TextElement) + ->(TextElement) } + ( + (Identifier) + { (TextElement) + ->(TextElement) }))) (Function (Empty) (Identifier) diff --git a/test/fixtures/go/grouped-import-declarations.parseA.txt b/test/fixtures/go/grouped-import-declarations.parseA.txt index d2afa1626..14913a0e6 100644 --- a/test/fixtures/go/grouped-import-declarations.parseA.txt +++ b/test/fixtures/go/grouped-import-declarations.parseA.txt @@ -2,11 +2,12 @@ (Module (Identifier)) (Import - (TextElement) - (TextElement) ( - (Identifier) - (TextElement))) + (TextElement) + (TextElement) + ( + (Identifier) + (TextElement)))) (Function (Empty) (Identifier) diff --git a/test/fixtures/go/grouped-import-declarations.parseB.txt b/test/fixtures/go/grouped-import-declarations.parseB.txt index d2afa1626..14913a0e6 100644 --- a/test/fixtures/go/grouped-import-declarations.parseB.txt +++ b/test/fixtures/go/grouped-import-declarations.parseB.txt @@ -2,11 +2,12 @@ (Module (Identifier)) (Import - (TextElement) - (TextElement) ( - (Identifier) - (TextElement))) + (TextElement) + (TextElement) + ( + (Identifier) + (TextElement)))) (Function (Empty) (Identifier) diff --git a/test/fixtures/go/if-statements.diffA-B.txt b/test/fixtures/go/if-statements.diffA-B.txt index 6b4f21e1f..21a36d168 100644 --- a/test/fixtures/go/if-statements.diffA-B.txt +++ b/test/fixtures/go/if-statements.diffA-B.txt @@ -11,9 +11,11 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty))) (Call (Identifier) + ([]) (Empty)) (Empty)) (If @@ -23,10 +25,12 @@ ->(Identifier) } (Call (Identifier) + ([]) (Empty))) (Identifier)) (Call (Identifier) + ([]) (Empty)) (Empty)) (If @@ -34,12 +38,15 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty))) (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty))) (If ( @@ -53,6 +60,7 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty)) {+(Context {+(Comment)+} @@ -65,6 +73,7 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty)) { (Context {-(Comment)-} @@ -72,11 +81,14 @@ {-( {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-})-} {-(Call {-(Identifier)-} + {-([])-} {-(Empty)-})-} {-(Empty)-})-}) ->(Call {+(Identifier)+} + {+([])+} {+(Empty)+}) }))+})))) diff --git a/test/fixtures/go/if-statements.diffB-A.txt b/test/fixtures/go/if-statements.diffB-A.txt index 55dd7108f..8e3649bd3 100644 --- a/test/fixtures/go/if-statements.diffB-A.txt +++ b/test/fixtures/go/if-statements.diffB-A.txt @@ -11,9 +11,11 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty))) (Call (Identifier) + ([]) (Empty)) (Empty)) (If @@ -23,10 +25,12 @@ ->(Identifier) } (Call (Identifier) + ([]) (Empty))) (Identifier)) (Call (Identifier) + ([]) (Empty)) (Empty)) (If @@ -34,12 +38,15 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty))) (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty))) (If ( @@ -53,6 +60,7 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty)) {-(Context {-(Comment)-} @@ -65,9 +73,11 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty)) { (Call {-(Identifier)-} + {-([])-} {-(Empty)-}) ->(Context {+(Comment)+} @@ -75,8 +85,10 @@ {+( {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+})+} {+(Call {+(Identifier)+} + {+([])+} {+(Empty)+})+} {+(Empty)+})+}) }))-})))) diff --git a/test/fixtures/go/if-statements.parseA.txt b/test/fixtures/go/if-statements.parseA.txt index a4c5e69f4..c4a8bc95d 100644 --- a/test/fixtures/go/if-statements.parseA.txt +++ b/test/fixtures/go/if-statements.parseA.txt @@ -10,9 +10,11 @@ ( (Call (Identifier) + ([]) (Empty))) (Call (Identifier) + ([]) (Empty)) (Empty)) (If @@ -21,22 +23,27 @@ (Identifier) (Call (Identifier) + ([]) (Empty))) (Identifier)) (Call (Identifier) + ([]) (Empty)) (Empty)) (If ( (Call (Identifier) + ([]) (Empty))) (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty))) (If ( @@ -48,6 +55,7 @@ (Integer))) (Call (Identifier) + ([]) (Empty)) (If ( @@ -56,6 +64,7 @@ (Integer))) (Call (Identifier) + ([]) (Empty)) (Context (Comment) @@ -63,8 +72,10 @@ ( (Call (Identifier) + ([]) (Empty))) (Call (Identifier) + ([]) (Empty)) (Empty)))))))) diff --git a/test/fixtures/go/if-statements.parseB.txt b/test/fixtures/go/if-statements.parseB.txt index 2a00695b7..c6eb86f33 100644 --- a/test/fixtures/go/if-statements.parseB.txt +++ b/test/fixtures/go/if-statements.parseB.txt @@ -10,9 +10,11 @@ ( (Call (Identifier) + ([]) (Empty))) (Call (Identifier) + ([]) (Empty)) (Empty)) (If @@ -21,22 +23,27 @@ (Identifier) (Call (Identifier) + ([]) (Empty))) (Identifier)) (Call (Identifier) + ([]) (Empty)) (Empty)) (If ( (Call (Identifier) + ([]) (Empty))) (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty))) (If ( @@ -48,6 +55,7 @@ (Integer))) (Call (Identifier) + ([]) (Empty)) (Context (Comment) @@ -58,7 +66,9 @@ (Integer))) (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty)))))))) diff --git a/test/fixtures/go/import-statements.diffA-B.txt b/test/fixtures/go/import-statements.diffA-B.txt index a80b1e2cf..03a3f3486 100644 --- a/test/fixtures/go/import-statements.diffA-B.txt +++ b/test/fixtures/go/import-statements.diffA-B.txt @@ -2,14 +2,15 @@ (Module (Identifier)) (Import - (Context - (Comment) - (Comment) - { (TextElement) - ->(TextElement) }) - (Context - (Comment) - (Empty))) + ( + (Context + (Comment) + (Comment) + { (TextElement) + ->(TextElement) }) + (Context + (Comment) + (Empty)))) (Function (Empty) (Identifier) diff --git a/test/fixtures/go/import-statements.diffB-A.txt b/test/fixtures/go/import-statements.diffB-A.txt index a80b1e2cf..03a3f3486 100644 --- a/test/fixtures/go/import-statements.diffB-A.txt +++ b/test/fixtures/go/import-statements.diffB-A.txt @@ -2,14 +2,15 @@ (Module (Identifier)) (Import - (Context - (Comment) - (Comment) - { (TextElement) - ->(TextElement) }) - (Context - (Comment) - (Empty))) + ( + (Context + (Comment) + (Comment) + { (TextElement) + ->(TextElement) }) + (Context + (Comment) + (Empty)))) (Function (Empty) (Identifier) diff --git a/test/fixtures/go/import-statements.parseA.txt b/test/fixtures/go/import-statements.parseA.txt index 276acb1eb..102ff879c 100644 --- a/test/fixtures/go/import-statements.parseA.txt +++ b/test/fixtures/go/import-statements.parseA.txt @@ -2,13 +2,14 @@ (Module (Identifier)) (Import - (Context - (Comment) - (Comment) - (TextElement)) - (Context - (Comment) - (Empty))) + ( + (Context + (Comment) + (Comment) + (TextElement)) + (Context + (Comment) + (Empty)))) (Function (Empty) (Identifier) diff --git a/test/fixtures/go/import-statements.parseB.txt b/test/fixtures/go/import-statements.parseB.txt index 276acb1eb..102ff879c 100644 --- a/test/fixtures/go/import-statements.parseB.txt +++ b/test/fixtures/go/import-statements.parseB.txt @@ -2,13 +2,14 @@ (Module (Identifier)) (Import - (Context - (Comment) - (Comment) - (TextElement)) - (Context - (Comment) - (Empty))) + ( + (Context + (Comment) + (Comment) + (TextElement)) + (Context + (Comment) + (Empty)))) (Function (Empty) (Identifier) diff --git a/test/fixtures/go/interface-types.diffA-B.txt b/test/fixtures/go/interface-types.diffA-B.txt index 768b9e9ad..8728efd7a 100644 --- a/test/fixtures/go/interface-types.diffA-B.txt +++ b/test/fixtures/go/interface-types.diffA-B.txt @@ -10,7 +10,8 @@ (Type { (Identifier) ->(Identifier) } - (Interface))) + (Interface + ([])))) ( (Type { (Identifier) @@ -24,16 +25,17 @@ { (Identifier) ->(Identifier) } (Interface - (Identifier) - (MemberAccess + ( (Identifier) - (Identifier)) - (MethodSignature - (Identifier) - (Identifier) - ( + (MemberAccess (Identifier) - (Identifier)))))) + (Identifier)) + (MethodSignature + (Identifier) + (Identifier) + ( + (Identifier) + (Identifier))))))) (Context (Comment) ( diff --git a/test/fixtures/go/interface-types.diffB-A.txt b/test/fixtures/go/interface-types.diffB-A.txt index 768b9e9ad..8728efd7a 100644 --- a/test/fixtures/go/interface-types.diffB-A.txt +++ b/test/fixtures/go/interface-types.diffB-A.txt @@ -10,7 +10,8 @@ (Type { (Identifier) ->(Identifier) } - (Interface))) + (Interface + ([])))) ( (Type { (Identifier) @@ -24,16 +25,17 @@ { (Identifier) ->(Identifier) } (Interface - (Identifier) - (MemberAccess + ( (Identifier) - (Identifier)) - (MethodSignature - (Identifier) - (Identifier) - ( + (MemberAccess (Identifier) - (Identifier)))))) + (Identifier)) + (MethodSignature + (Identifier) + (Identifier) + ( + (Identifier) + (Identifier))))))) (Context (Comment) ( diff --git a/test/fixtures/go/interface-types.parseA.txt b/test/fixtures/go/interface-types.parseA.txt index 93b5e9a8b..e44ae0dd5 100644 --- a/test/fixtures/go/interface-types.parseA.txt +++ b/test/fixtures/go/interface-types.parseA.txt @@ -9,7 +9,8 @@ ( (Type (Identifier) - (Interface))) + (Interface + ([])))) ( (Type (Identifier) @@ -21,16 +22,17 @@ (Type (Identifier) (Interface - (Identifier) - (MemberAccess + ( (Identifier) - (Identifier)) - (MethodSignature - (Identifier) - (Identifier) - ( + (MemberAccess (Identifier) - (Identifier)))))) + (Identifier)) + (MethodSignature + (Identifier) + (Identifier) + ( + (Identifier) + (Identifier))))))) (Context (Comment) ( diff --git a/test/fixtures/go/interface-types.parseB.txt b/test/fixtures/go/interface-types.parseB.txt index 93b5e9a8b..e44ae0dd5 100644 --- a/test/fixtures/go/interface-types.parseB.txt +++ b/test/fixtures/go/interface-types.parseB.txt @@ -9,7 +9,8 @@ ( (Type (Identifier) - (Interface))) + (Interface + ([])))) ( (Type (Identifier) @@ -21,16 +22,17 @@ (Type (Identifier) (Interface - (Identifier) - (MemberAccess + ( (Identifier) - (Identifier)) - (MethodSignature - (Identifier) - (Identifier) - ( + (MemberAccess (Identifier) - (Identifier)))))) + (Identifier)) + (MethodSignature + (Identifier) + (Identifier) + ( + (Identifier) + (Identifier))))))) (Context (Comment) ( diff --git a/test/fixtures/go/method-declarations.diffA-B.txt b/test/fixtures/go/method-declarations.diffA-B.txt index 50aab8f85..61013e143 100644 --- a/test/fixtures/go/method-declarations.diffA-B.txt +++ b/test/fixtures/go/method-declarations.diffA-B.txt @@ -55,10 +55,11 @@ {+(MemberAccess {+(Identifier)+} {+(Identifier)+})+} - {+(MemberAccess - {+(Identifier)+} - {+(Identifier)+})+} - {+(Integer)+} + {+( + {+(MemberAccess + {+(Identifier)+} + {+(Identifier)+})+} + {+(Integer)+})+} {+(Empty)+})+} {+(MemberAccess {+(Identifier)+} @@ -67,10 +68,11 @@ {+(MemberAccess {+(Identifier)+} {+(Identifier)+})+} - {+(MemberAccess - {+(Identifier)+} - {+(Identifier)+})+} - {+(Integer)+} + {+( + {+(MemberAccess + {+(Identifier)+} + {+(Identifier)+})+} + {+(Integer)+})+} {+(Empty)+})+}) } { (Times {-(MemberAccess diff --git a/test/fixtures/go/method-declarations.diffB-A.txt b/test/fixtures/go/method-declarations.diffB-A.txt index f99281d20..025698b0e 100644 --- a/test/fixtures/go/method-declarations.diffB-A.txt +++ b/test/fixtures/go/method-declarations.diffB-A.txt @@ -48,10 +48,11 @@ {-(MemberAccess {-(Identifier)-} {-(Identifier)-})-} - {-(MemberAccess - {-(Identifier)-} - {-(Identifier)-})-} - {-(Integer)-} + {-( + {-(MemberAccess + {-(Identifier)-} + {-(Identifier)-})-} + {-(Integer)-})-} {-(Empty)-})-} {-(MemberAccess {-(Identifier)-} @@ -60,10 +61,11 @@ {-(MemberAccess {-(Identifier)-} {-(Identifier)-})-} - {-(MemberAccess - {-(Identifier)-} - {-(Identifier)-})-} - {-(Integer)-} + {-( + {-(MemberAccess + {-(Identifier)-} + {-(Identifier)-})-} + {-(Integer)-})-} {-(Empty)-})-}) ->(Times {+(MemberAccess diff --git a/test/fixtures/go/method-declarations.parseB.txt b/test/fixtures/go/method-declarations.parseB.txt index f78bab518..d841638f3 100644 --- a/test/fixtures/go/method-declarations.parseB.txt +++ b/test/fixtures/go/method-declarations.parseB.txt @@ -44,10 +44,11 @@ (MemberAccess (Identifier) (Identifier)) - (MemberAccess - (Identifier) - (Identifier)) - (Integer) + ( + (MemberAccess + (Identifier) + (Identifier)) + (Integer)) (Empty)) (MemberAccess (Identifier) @@ -56,10 +57,11 @@ (MemberAccess (Identifier) (Identifier)) - (MemberAccess - (Identifier) - (Identifier)) - (Integer) + ( + (MemberAccess + (Identifier) + (Identifier)) + (Integer)) (Empty))) (MemberAccess (Identifier) diff --git a/test/fixtures/go/selector-expressions.diffA-B.txt b/test/fixtures/go/selector-expressions.diffA-B.txt index 069723583..4da52f8a8 100644 --- a/test/fixtures/go/selector-expressions.diffA-B.txt +++ b/test/fixtures/go/selector-expressions.diffA-B.txt @@ -14,4 +14,5 @@ ->(Identifier) }) { (Identifier) ->(Identifier) }) + ([]) (Empty)))) diff --git a/test/fixtures/go/selector-expressions.diffB-A.txt b/test/fixtures/go/selector-expressions.diffB-A.txt index 069723583..4da52f8a8 100644 --- a/test/fixtures/go/selector-expressions.diffB-A.txt +++ b/test/fixtures/go/selector-expressions.diffB-A.txt @@ -14,4 +14,5 @@ ->(Identifier) }) { (Identifier) ->(Identifier) }) + ([]) (Empty)))) diff --git a/test/fixtures/go/selector-expressions.parseA.txt b/test/fixtures/go/selector-expressions.parseA.txt index 6d25e7a42..bec3298a6 100644 --- a/test/fixtures/go/selector-expressions.parseA.txt +++ b/test/fixtures/go/selector-expressions.parseA.txt @@ -11,4 +11,5 @@ (Identifier) (Identifier)) (Identifier)) + ([]) (Empty)))) diff --git a/test/fixtures/go/selector-expressions.parseB.txt b/test/fixtures/go/selector-expressions.parseB.txt index 6d25e7a42..bec3298a6 100644 --- a/test/fixtures/go/selector-expressions.parseB.txt +++ b/test/fixtures/go/selector-expressions.parseB.txt @@ -11,4 +11,5 @@ (Identifier) (Identifier)) (Identifier)) + ([]) (Empty)))) diff --git a/test/fixtures/go/single-line-function-declarations.diffA-B.txt b/test/fixtures/go/single-line-function-declarations.diffA-B.txt index f4cd01488..b4f1299a3 100644 --- a/test/fixtures/go/single-line-function-declarations.diffA-B.txt +++ b/test/fixtures/go/single-line-function-declarations.diffA-B.txt @@ -13,6 +13,7 @@ ([]) (Call (Identifier) + ([]) (Empty))) (Function (Empty) @@ -22,9 +23,11 @@ ( (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty)))) (Function (Empty) @@ -34,7 +37,9 @@ ( (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty))))) diff --git a/test/fixtures/go/single-line-function-declarations.diffB-A.txt b/test/fixtures/go/single-line-function-declarations.diffB-A.txt index f4cd01488..b4f1299a3 100644 --- a/test/fixtures/go/single-line-function-declarations.diffB-A.txt +++ b/test/fixtures/go/single-line-function-declarations.diffB-A.txt @@ -13,6 +13,7 @@ ([]) (Call (Identifier) + ([]) (Empty))) (Function (Empty) @@ -22,9 +23,11 @@ ( (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty)))) (Function (Empty) @@ -34,7 +37,9 @@ ( (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty))))) diff --git a/test/fixtures/go/single-line-function-declarations.parseA.txt b/test/fixtures/go/single-line-function-declarations.parseA.txt index 7e0260a22..dafebdb70 100644 --- a/test/fixtures/go/single-line-function-declarations.parseA.txt +++ b/test/fixtures/go/single-line-function-declarations.parseA.txt @@ -12,6 +12,7 @@ ([]) (Call (Identifier) + ([]) (Empty))) (Function (Empty) @@ -20,9 +21,11 @@ ( (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty)))) (Function (Empty) @@ -31,7 +34,9 @@ ( (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty))))) diff --git a/test/fixtures/go/single-line-function-declarations.parseB.txt b/test/fixtures/go/single-line-function-declarations.parseB.txt index 7e0260a22..dafebdb70 100644 --- a/test/fixtures/go/single-line-function-declarations.parseB.txt +++ b/test/fixtures/go/single-line-function-declarations.parseB.txt @@ -12,6 +12,7 @@ ([]) (Call (Identifier) + ([]) (Empty))) (Function (Empty) @@ -20,9 +21,11 @@ ( (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty)))) (Function (Empty) @@ -31,7 +34,9 @@ ( (Call (Identifier) + ([]) (Empty)) (Call (Identifier) + ([]) (Empty))))) diff --git a/test/fixtures/go/slice-expressions.diffA-B.txt b/test/fixtures/go/slice-expressions.diffA-B.txt index 084d66f9c..e7eeed723 100644 --- a/test/fixtures/go/slice-expressions.diffA-B.txt +++ b/test/fixtures/go/slice-expressions.diffA-B.txt @@ -6,36 +6,51 @@ (Identifier) ([]) ( - (Slice - (Identifier) - { (Integer) - ->(Integer) } - (Empty) - (Empty)) - (Slice - (Identifier) - (Empty) - { (Integer) - ->(Integer) } - (Empty)) - (Slice - (Identifier) - { (Empty) - ->(Integer) } - { (Empty) - ->(Integer) } - (Empty)) - (Slice - (Identifier) - { (Integer) - ->(Integer) } - { (Integer) - ->(Integer) } - { (Integer) - ->(Integer) }) + {+(Slice + {+(Identifier)+} + {+(Integer)+} + {+(Empty)+} + {+(Empty)+})+} + {+(Slice + {+(Identifier)+} + {+(Empty)+} + {+(Integer)+} + {+(Empty)+})+} + {+(Slice + {+(Identifier)+} + {+(Integer)+} + {+(Integer)+} + {+(Empty)+})+} (Slice { (Identifier) ->(Identifier) } (Integer) - (Integer) - (Empty))))) + { (Empty) + ->(Integer) } + { (Empty) + ->(Integer) }) + {+(Slice + {+(Identifier)+} + {+(Integer)+} + {+(Integer)+} + {+(Empty)+})+} + {-(Slice + {-(Identifier)-} + {-(Empty)-} + {-(Integer)-} + {-(Empty)-})-} + {-(Slice + {-(Identifier)-} + {-(Empty)-} + {-(Empty)-} + {-(Empty)-})-} + {-(Slice + {-(Identifier)-} + {-(Integer)-} + {-(Integer)-} + {-(Integer)-})-} + {-(Slice + {-(Identifier)-} + {-(Integer)-} + {-(Integer)-} + {-(Empty)-})-}))) diff --git a/test/fixtures/go/slice-expressions.diffB-A.txt b/test/fixtures/go/slice-expressions.diffB-A.txt index d0d377201..901da4a7d 100644 --- a/test/fixtures/go/slice-expressions.diffB-A.txt +++ b/test/fixtures/go/slice-expressions.diffB-A.txt @@ -6,36 +6,51 @@ (Identifier) ([]) ( - (Slice - (Identifier) - { (Integer) - ->(Integer) } - (Empty) - (Empty)) - (Slice - (Identifier) - (Empty) - { (Integer) - ->(Integer) } - (Empty)) - (Slice - (Identifier) - { (Integer) - ->(Empty) } - { (Integer) - ->(Empty) } - (Empty)) - (Slice - (Identifier) - { (Integer) - ->(Integer) } - { (Integer) - ->(Integer) } - { (Integer) - ->(Integer) }) + {+(Slice + {+(Identifier)+} + {+(Integer)+} + {+(Empty)+} + {+(Empty)+})+} + {+(Slice + {+(Identifier)+} + {+(Empty)+} + {+(Integer)+} + {+(Empty)+})+} + {+(Slice + {+(Identifier)+} + {+(Empty)+} + {+(Empty)+} + {+(Empty)+})+} (Slice { (Identifier) ->(Identifier) } (Integer) - (Integer) - (Empty))))) + { (Empty) + ->(Integer) } + { (Empty) + ->(Integer) }) + {+(Slice + {+(Identifier)+} + {+(Integer)+} + {+(Integer)+} + {+(Empty)+})+} + {-(Slice + {-(Identifier)-} + {-(Empty)-} + {-(Integer)-} + {-(Empty)-})-} + {-(Slice + {-(Identifier)-} + {-(Integer)-} + {-(Integer)-} + {-(Empty)-})-} + {-(Slice + {-(Identifier)-} + {-(Integer)-} + {-(Integer)-} + {-(Integer)-})-} + {-(Slice + {-(Identifier)-} + {-(Integer)-} + {-(Integer)-} + {-(Empty)-})-}))) diff --git a/test/fixtures/go/struct-types.diffA-B.txt b/test/fixtures/go/struct-types.diffA-B.txt index 8ac54c07e..9988d8866 100644 --- a/test/fixtures/go/struct-types.diffA-B.txt +++ b/test/fixtures/go/struct-types.diffA-B.txt @@ -11,7 +11,8 @@ { (Identifier) ->(Identifier) } (Constructor - (Empty)))) + (Empty) + ([])))) ( (Type { (Identifier) @@ -38,13 +39,14 @@ ->(Identifier) } (Constructor (Empty) - (Field - ( - (MemberAccess - (Identifier) - (Identifier)))) - (Field - (Identifier) - (TextElement) - ( - (Identifier))))))))) + ( + (Field + ( + (MemberAccess + (Identifier) + (Identifier)))) + (Field + (Identifier) + (TextElement) + ( + (Identifier)))))))))) diff --git a/test/fixtures/go/struct-types.diffB-A.txt b/test/fixtures/go/struct-types.diffB-A.txt index 8ac54c07e..9988d8866 100644 --- a/test/fixtures/go/struct-types.diffB-A.txt +++ b/test/fixtures/go/struct-types.diffB-A.txt @@ -11,7 +11,8 @@ { (Identifier) ->(Identifier) } (Constructor - (Empty)))) + (Empty) + ([])))) ( (Type { (Identifier) @@ -38,13 +39,14 @@ ->(Identifier) } (Constructor (Empty) - (Field - ( - (MemberAccess - (Identifier) - (Identifier)))) - (Field - (Identifier) - (TextElement) - ( - (Identifier))))))))) + ( + (Field + ( + (MemberAccess + (Identifier) + (Identifier)))) + (Field + (Identifier) + (TextElement) + ( + (Identifier)))))))))) diff --git a/test/fixtures/go/struct-types.parseA.txt b/test/fixtures/go/struct-types.parseA.txt index 9c0601514..aaf3dc258 100644 --- a/test/fixtures/go/struct-types.parseA.txt +++ b/test/fixtures/go/struct-types.parseA.txt @@ -10,7 +10,8 @@ (Type (Identifier) (Constructor - (Empty)))) + (Empty) + ([])))) ( (Type (Identifier) @@ -34,13 +35,14 @@ (Identifier) (Constructor (Empty) - (Field - ( - (MemberAccess - (Identifier) - (Identifier)))) - (Field - (Identifier) - (TextElement) - ( - (Identifier))))))))) + ( + (Field + ( + (MemberAccess + (Identifier) + (Identifier)))) + (Field + (Identifier) + (TextElement) + ( + (Identifier)))))))))) diff --git a/test/fixtures/go/struct-types.parseB.txt b/test/fixtures/go/struct-types.parseB.txt index 9c0601514..aaf3dc258 100644 --- a/test/fixtures/go/struct-types.parseB.txt +++ b/test/fixtures/go/struct-types.parseB.txt @@ -10,7 +10,8 @@ (Type (Identifier) (Constructor - (Empty)))) + (Empty) + ([])))) ( (Type (Identifier) @@ -34,13 +35,14 @@ (Identifier) (Constructor (Empty) - (Field - ( - (MemberAccess - (Identifier) - (Identifier)))) - (Field - (Identifier) - (TextElement) - ( - (Identifier))))))))) + ( + (Field + ( + (MemberAccess + (Identifier) + (Identifier)))) + (Field + (Identifier) + (TextElement) + ( + (Identifier)))))))))) diff --git a/test/fixtures/go/switch-statements.diffA-B.txt b/test/fixtures/go/switch-statements.diffA-B.txt index cbebdad27..b8115a6bf 100644 --- a/test/fixtures/go/switch-statements.diffA-B.txt +++ b/test/fixtures/go/switch-statements.diffA-B.txt @@ -16,6 +16,7 @@ ->(Identifier) }) (Call (Identifier) + ([]) (Empty))) (Pattern (LessThan @@ -27,6 +28,7 @@ {-(Comment)-} (Call (Identifier) + ([]) (Empty)))-}) {-(Context {-(Comment)-} @@ -38,4 +40,5 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty))))-})))) diff --git a/test/fixtures/go/switch-statements.diffB-A.txt b/test/fixtures/go/switch-statements.diffB-A.txt index b52fd8969..4db8ff269 100644 --- a/test/fixtures/go/switch-statements.diffB-A.txt +++ b/test/fixtures/go/switch-statements.diffB-A.txt @@ -16,6 +16,7 @@ ->(Identifier) }) (Call (Identifier) + ([]) (Empty))) (Pattern (LessThan @@ -27,6 +28,7 @@ {+(Comment)+} (Call (Identifier) + ([]) (Empty)))+}) {+(Context {+(Comment)+} @@ -38,4 +40,5 @@ (Call { (Identifier) ->(Identifier) } + ([]) (Empty))))+})))) diff --git a/test/fixtures/go/switch-statements.parseA.txt b/test/fixtures/go/switch-statements.parseA.txt index 7a6987a8a..138f4f549 100644 --- a/test/fixtures/go/switch-statements.parseA.txt +++ b/test/fixtures/go/switch-statements.parseA.txt @@ -14,6 +14,7 @@ (Identifier)) (Call (Identifier) + ([]) (Empty))) (Pattern (LessThan @@ -23,6 +24,7 @@ (Comment) (Call (Identifier) + ([]) (Empty)))) (Context (Comment) @@ -32,4 +34,5 @@ (Integer)) (Call (Identifier) + ([]) (Empty)))))))) diff --git a/test/fixtures/go/switch-statements.parseB.txt b/test/fixtures/go/switch-statements.parseB.txt index 1e7187ff2..52c6e679b 100644 --- a/test/fixtures/go/switch-statements.parseB.txt +++ b/test/fixtures/go/switch-statements.parseB.txt @@ -14,6 +14,7 @@ (Identifier)) (Call (Identifier) + ([]) (Empty))) (Pattern (LessThan @@ -21,6 +22,7 @@ (Identifier)) (Call (Identifier) + ([]) (Empty))) (Pattern (Equal @@ -28,4 +30,5 @@ (Integer)) (Call (Identifier) + ([]) (Empty))))))) diff --git a/test/fixtures/go/type-declarations.diffA-B.txt b/test/fixtures/go/type-declarations.diffA-B.txt index 2e8c965c6..0feaad5b6 100644 --- a/test/fixtures/go/type-declarations.diffA-B.txt +++ b/test/fixtures/go/type-declarations.diffA-B.txt @@ -31,22 +31,24 @@ ->(Identifier) } (Constructor (Empty) - (Field - (Identifier) - ( - (Identifier))) - (Field - (Identifier) - ( - (Identifier))) - (Field - (Identifier) - ( - (Identifier)))))) + ( + (Field + (Identifier) + ( + (Identifier))) + (Field + (Identifier) + ( + (Identifier))) + (Field + (Identifier) + ( + (Identifier))))))) (Type { (Identifier) ->(Identifier) } - (Interface)) + (Interface + ([]))) (Context (Comment) (Empty)))))) diff --git a/test/fixtures/go/type-declarations.diffB-A.txt b/test/fixtures/go/type-declarations.diffB-A.txt index 2e8c965c6..0feaad5b6 100644 --- a/test/fixtures/go/type-declarations.diffB-A.txt +++ b/test/fixtures/go/type-declarations.diffB-A.txt @@ -31,22 +31,24 @@ ->(Identifier) } (Constructor (Empty) - (Field - (Identifier) - ( - (Identifier))) - (Field - (Identifier) - ( - (Identifier))) - (Field - (Identifier) - ( - (Identifier)))))) + ( + (Field + (Identifier) + ( + (Identifier))) + (Field + (Identifier) + ( + (Identifier))) + (Field + (Identifier) + ( + (Identifier))))))) (Type { (Identifier) ->(Identifier) } - (Interface)) + (Interface + ([]))) (Context (Comment) (Empty)))))) diff --git a/test/fixtures/go/type-declarations.parseA.txt b/test/fixtures/go/type-declarations.parseA.txt index a0a135c76..65d429dfc 100644 --- a/test/fixtures/go/type-declarations.parseA.txt +++ b/test/fixtures/go/type-declarations.parseA.txt @@ -24,21 +24,23 @@ (Identifier) (Constructor (Empty) - (Field - (Identifier) - ( - (Identifier))) - (Field - (Identifier) - ( - (Identifier))) - (Field - (Identifier) - ( - (Identifier)))))) + ( + (Field + (Identifier) + ( + (Identifier))) + (Field + (Identifier) + ( + (Identifier))) + (Field + (Identifier) + ( + (Identifier))))))) (Type (Identifier) - (Interface)) + (Interface + ([]))) (Context (Comment) (Empty)))))) diff --git a/test/fixtures/go/type-declarations.parseB.txt b/test/fixtures/go/type-declarations.parseB.txt index a0a135c76..65d429dfc 100644 --- a/test/fixtures/go/type-declarations.parseB.txt +++ b/test/fixtures/go/type-declarations.parseB.txt @@ -24,21 +24,23 @@ (Identifier) (Constructor (Empty) - (Field - (Identifier) - ( - (Identifier))) - (Field - (Identifier) - ( - (Identifier))) - (Field - (Identifier) - ( - (Identifier)))))) + ( + (Field + (Identifier) + ( + (Identifier))) + (Field + (Identifier) + ( + (Identifier))) + (Field + (Identifier) + ( + (Identifier))))))) (Type (Identifier) - (Interface)) + (Interface + ([]))) (Context (Comment) (Empty)))))) diff --git a/test/fixtures/go/type-switch-statements.diffA-B.txt b/test/fixtures/go/type-switch-statements.diffA-B.txt index a15af91cd..163972a2e 100644 --- a/test/fixtures/go/type-switch-statements.diffA-B.txt +++ b/test/fixtures/go/type-switch-statements.diffA-B.txt @@ -32,6 +32,7 @@ (Identifier)) (Call (Identifier) + ([]) (Empty)))) (Pattern (Pointer @@ -59,14 +60,15 @@ (MemberAccess (Identifier) (Identifier)) - { (TextElement) - ->(TextElement) } - {+(DividedBy - {+(Integer)+} - {+(Identifier)+})+} - {-(Times - {-(Identifier)-} - {-(Integer)-})-} + ( + { (TextElement) + ->(TextElement) } + {+(DividedBy + {+(Integer)+} + {+(Identifier)+})+} + {-(Times + {-(Identifier)-} + {-(Integer)-})-}) (Empty))) (Pattern { (Identifier) @@ -75,14 +77,15 @@ (MemberAccess (Identifier) (Identifier)) - { (TextElement) - ->(TextElement) } - {+(Times - {+(Identifier)+} - {+(Integer)+})+} - {-(DividedBy - {-(Integer)-} - {-(Identifier)-})-} + ( + { (TextElement) + ->(TextElement) } + {+(Times + {+(Identifier)+} + {+(Integer)+})+} + {-(DividedBy + {-(Integer)-} + {-(Identifier)-})-}) (Empty))) (Pattern (Identifier) @@ -101,22 +104,23 @@ (MemberAccess (Identifier) (Identifier)) - (TextElement) - (Plus - (Slice - { (Identifier) - ->(Identifier) } - { (Identifier) - ->(Identifier) } - (Empty) - (Empty)) - (Slice - { (Identifier) - ->(Identifier) } - (Empty) - { (Identifier) - ->(Identifier) } - (Empty))) + ( + (TextElement) + (Plus + (Slice + { (Identifier) + ->(Identifier) } + { (Identifier) + ->(Identifier) } + (Empty) + (Empty)) + (Slice + { (Identifier) + ->(Identifier) } + (Empty) + { (Identifier) + ->(Identifier) } + (Empty)))) (Empty)))) (Pattern (DefaultPattern diff --git a/test/fixtures/go/type-switch-statements.diffB-A.txt b/test/fixtures/go/type-switch-statements.diffB-A.txt index 0b4d0c8bb..c6ff94368 100644 --- a/test/fixtures/go/type-switch-statements.diffB-A.txt +++ b/test/fixtures/go/type-switch-statements.diffB-A.txt @@ -32,6 +32,7 @@ (Identifier)) (Call (Identifier) + ([]) (Empty)))) (Pattern (Pointer @@ -59,14 +60,15 @@ (MemberAccess (Identifier) (Identifier)) - { (TextElement) - ->(TextElement) } - {+(Times - {+(Identifier)+} - {+(Integer)+})+} - {-(DividedBy - {-(Integer)-} - {-(Identifier)-})-} + ( + { (TextElement) + ->(TextElement) } + {+(Times + {+(Identifier)+} + {+(Integer)+})+} + {-(DividedBy + {-(Integer)-} + {-(Identifier)-})-}) (Empty))) (Pattern { (Identifier) @@ -75,14 +77,15 @@ (MemberAccess (Identifier) (Identifier)) - { (TextElement) - ->(TextElement) } - {+(DividedBy - {+(Integer)+} - {+(Identifier)+})+} - {-(Times - {-(Identifier)-} - {-(Integer)-})-} + ( + { (TextElement) + ->(TextElement) } + {+(DividedBy + {+(Integer)+} + {+(Identifier)+})+} + {-(Times + {-(Identifier)-} + {-(Integer)-})-}) (Empty))) (Pattern (Identifier) @@ -101,22 +104,23 @@ (MemberAccess (Identifier) (Identifier)) - (TextElement) - (Plus - (Slice - { (Identifier) - ->(Identifier) } - { (Identifier) - ->(Identifier) } - (Empty) - (Empty)) - (Slice - { (Identifier) - ->(Identifier) } - (Empty) - { (Identifier) - ->(Identifier) } - (Empty))) + ( + (TextElement) + (Plus + (Slice + { (Identifier) + ->(Identifier) } + { (Identifier) + ->(Identifier) } + (Empty) + (Empty)) + (Slice + { (Identifier) + ->(Identifier) } + (Empty) + { (Identifier) + ->(Identifier) } + (Empty)))) (Empty)))) (Pattern (DefaultPattern diff --git a/test/fixtures/go/type-switch-statements.parseA.txt b/test/fixtures/go/type-switch-statements.parseA.txt index 642cb413b..3beda28f6 100644 --- a/test/fixtures/go/type-switch-statements.parseA.txt +++ b/test/fixtures/go/type-switch-statements.parseA.txt @@ -29,6 +29,7 @@ (Identifier)) (Call (Identifier) + ([]) (Empty)))) (Pattern (Pointer @@ -48,10 +49,11 @@ (MemberAccess (Identifier) (Identifier)) - (TextElement) - (Times - (Identifier) - (Integer)) + ( + (TextElement) + (Times + (Identifier) + (Integer))) (Empty))) (Pattern (Identifier) @@ -59,10 +61,11 @@ (MemberAccess (Identifier) (Identifier)) - (TextElement) - (DividedBy - (Integer) - (Identifier)) + ( + (TextElement) + (DividedBy + (Integer) + (Identifier))) (Empty))) (Pattern (Identifier) @@ -79,18 +82,19 @@ (MemberAccess (Identifier) (Identifier)) - (TextElement) - (Plus - (Slice - (Identifier) - (Identifier) - (Empty) - (Empty)) - (Slice - (Identifier) - (Empty) - (Identifier) - (Empty))) + ( + (TextElement) + (Plus + (Slice + (Identifier) + (Identifier) + (Empty) + (Empty)) + (Slice + (Identifier) + (Empty) + (Identifier) + (Empty)))) (Empty)))) (Pattern (DefaultPattern diff --git a/test/fixtures/go/type-switch-statements.parseB.txt b/test/fixtures/go/type-switch-statements.parseB.txt index c231ec8cc..2fcae206a 100644 --- a/test/fixtures/go/type-switch-statements.parseB.txt +++ b/test/fixtures/go/type-switch-statements.parseB.txt @@ -29,6 +29,7 @@ (Identifier)) (Call (Identifier) + ([]) (Empty)))) (Pattern (Pointer @@ -53,10 +54,11 @@ (MemberAccess (Identifier) (Identifier)) - (TextElement) - (DividedBy - (Integer) - (Identifier)) + ( + (TextElement) + (DividedBy + (Integer) + (Identifier))) (Empty))) (Pattern (Identifier) @@ -64,10 +66,11 @@ (MemberAccess (Identifier) (Identifier)) - (TextElement) - (Times - (Identifier) - (Integer)) + ( + (TextElement) + (Times + (Identifier) + (Integer))) (Empty))) (Pattern (Identifier) @@ -84,18 +87,19 @@ (MemberAccess (Identifier) (Identifier)) - (TextElement) - (Plus - (Slice - (Identifier) - (Identifier) - (Empty) - (Empty)) - (Slice - (Identifier) - (Empty) - (Identifier) - (Empty))) + ( + (TextElement) + (Plus + (Slice + (Identifier) + (Identifier) + (Empty) + (Empty)) + (Slice + (Identifier) + (Empty) + (Identifier) + (Empty)))) (Empty)))) (Pattern (DefaultPattern diff --git a/test/fixtures/go/unary-expressions.diffA-B.txt b/test/fixtures/go/unary-expressions.diffA-B.txt index da15e099c..e76414ec2 100644 --- a/test/fixtures/go/unary-expressions.diffA-B.txt +++ b/test/fixtures/go/unary-expressions.diffA-B.txt @@ -8,24 +8,35 @@ ( { (Identifier) ->(Identifier) } - (Negate - { (Identifier) - ->(Identifier) }) - (Not - (ReceiveOperator - { (Identifier) - ->(Identifier) })) - (Pointer - (Call - { (Identifier) - ->(Identifier) } - (Empty))) - (Complement - { (Identifier) - ->(Identifier) }) - (Reference - { (Identifier) - ->(Identifier) }) - (ReceiveOperator - { (Identifier) - ->(Identifier) })))) + {+(Negate + {+(Identifier)+})+} + {+(Not + {+(ReceiveOperator + {+(Identifier)+})+})+} + {+(Pointer + {+(Call + {+(Identifier)+} + {+([])+} + {+(Empty)+})+})+} + {+(Complement + {+(Identifier)+})+} + {+(Reference + {+(Identifier)+})+} + {+(ReceiveOperator + {+(Identifier)+})+} + {-(Negate + {-(Identifier)-})-} + {-(Not + {-(ReceiveOperator + {-(Identifier)-})-})-} + {-(Pointer + {-(Call + {-(Identifier)-} + {-([])-} + {-(Empty)-})-})-} + {-(Complement + {-(Identifier)-})-} + {-(Reference + {-(Identifier)-})-} + {-(ReceiveOperator + {-(Identifier)-})-}))) diff --git a/test/fixtures/go/unary-expressions.diffB-A.txt b/test/fixtures/go/unary-expressions.diffB-A.txt index da15e099c..e76414ec2 100644 --- a/test/fixtures/go/unary-expressions.diffB-A.txt +++ b/test/fixtures/go/unary-expressions.diffB-A.txt @@ -8,24 +8,35 @@ ( { (Identifier) ->(Identifier) } - (Negate - { (Identifier) - ->(Identifier) }) - (Not - (ReceiveOperator - { (Identifier) - ->(Identifier) })) - (Pointer - (Call - { (Identifier) - ->(Identifier) } - (Empty))) - (Complement - { (Identifier) - ->(Identifier) }) - (Reference - { (Identifier) - ->(Identifier) }) - (ReceiveOperator - { (Identifier) - ->(Identifier) })))) + {+(Negate + {+(Identifier)+})+} + {+(Not + {+(ReceiveOperator + {+(Identifier)+})+})+} + {+(Pointer + {+(Call + {+(Identifier)+} + {+([])+} + {+(Empty)+})+})+} + {+(Complement + {+(Identifier)+})+} + {+(Reference + {+(Identifier)+})+} + {+(ReceiveOperator + {+(Identifier)+})+} + {-(Negate + {-(Identifier)-})-} + {-(Not + {-(ReceiveOperator + {-(Identifier)-})-})-} + {-(Pointer + {-(Call + {-(Identifier)-} + {-([])-} + {-(Empty)-})-})-} + {-(Complement + {-(Identifier)-})-} + {-(Reference + {-(Identifier)-})-} + {-(ReceiveOperator + {-(Identifier)-})-}))) diff --git a/test/fixtures/go/unary-expressions.parseA.txt b/test/fixtures/go/unary-expressions.parseA.txt index 8ba6a7f3f..bb26ef163 100644 --- a/test/fixtures/go/unary-expressions.parseA.txt +++ b/test/fixtures/go/unary-expressions.parseA.txt @@ -15,6 +15,7 @@ (Pointer (Call (Identifier) + ([]) (Empty))) (Complement (Identifier)) diff --git a/test/fixtures/go/unary-expressions.parseB.txt b/test/fixtures/go/unary-expressions.parseB.txt index 8ba6a7f3f..bb26ef163 100644 --- a/test/fixtures/go/unary-expressions.parseB.txt +++ b/test/fixtures/go/unary-expressions.parseB.txt @@ -15,6 +15,7 @@ (Pointer (Call (Identifier) + ([]) (Empty))) (Complement (Identifier))