From 17cf9c26af7e0719aebe8ef50ac7391ce67c56b6 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Wed, 17 Jan 2018 15:30:46 -0800 Subject: [PATCH] Special handling of ruby require, load, and friends --- src/Language/Ruby/Assignment.hs | 11 ++++++++++- test/fixtures/ruby/require.A.rb | 3 +++ test/fixtures/ruby/require.B.rb | 3 +++ test/fixtures/ruby/require.diffA-B.txt | 14 ++++++++++++++ test/fixtures/ruby/require.diffB-A.txt | 14 ++++++++++++++ test/fixtures/ruby/require.parseA.txt | 8 ++++++++ test/fixtures/ruby/require.parseB.txt | 9 +++++++++ 7 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/ruby/require.A.rb create mode 100644 test/fixtures/ruby/require.B.rb create mode 100644 test/fixtures/ruby/require.diffA-B.txt create mode 100644 test/fixtures/ruby/require.diffB-A.txt create mode 100644 test/fixtures/ruby/require.parseA.txt create mode 100644 test/fixtures/ruby/require.parseB.txt diff --git a/src/Language/Ruby/Assignment.hs b/src/Language/Ruby/Assignment.hs index 5b86870f4..6e07c03d7 100644 --- a/src/Language/Ruby/Assignment.hs +++ b/src/Language/Ruby/Assignment.hs @@ -9,9 +9,11 @@ module Language.Ruby.Assignment import Assigning.Assignment hiding (Assignment, Error) import qualified Assigning.Assignment as Assignment import Data.Maybe (fromMaybe) +import Control.Monad (guard) import Data.Record import Data.Functor (void) import Data.List.NonEmpty (some1) +import Data.List (elem) import Data.Syntax (contextualize, postContextualize, emptyTerm, parseError, handleError, infixContext, makeTerm, makeTerm', makeTerm'', makeTerm1) import qualified Data.Syntax as Syntax import qualified Data.Syntax.Comment as Comment @@ -29,6 +31,7 @@ type Syntax = '[ Comment.Comment , Declaration.Class , Declaration.Function + , Declaration.Import , Declaration.Method , Declaration.Module , Expression.Arithmetic @@ -296,9 +299,15 @@ pair :: Assignment pair = makeTerm <$> symbol Pair <*> children (Literal.KeyValue <$> expression <*> (expression <|> emptyTerm)) methodCall :: Assignment -methodCall = makeTerm <$> symbol MethodCall <*> children (Expression.Call <$> pure [] <*> expression <*> args <*> (block <|> emptyTerm)) +methodCall = makeTerm' <$> symbol MethodCall <*> children (require <|> regularCall) where + regularCall = inj <$> (Expression.Call <$> pure [] <*> expression <*> args <*> (block <|> emptyTerm)) + require = inj <$> (symbol Identifier *> do + s <- source + guard (elem s ["autoload", "load", "require", "require_relative"]) + Declaration.Import <$> args' <*> emptyTerm <*> pure []) args = (symbol ArgumentList <|> symbol ArgumentListWithParens) *> children (many expression) <|> pure [] + args' = makeTerm'' <$> (symbol ArgumentList <|> symbol ArgumentListWithParens) <*> children (many expression) <|> emptyTerm call :: Assignment call = makeTerm <$> symbol Call <*> children (Expression.MemberAccess <$> expression <*> (expression <|> args)) diff --git a/test/fixtures/ruby/require.A.rb b/test/fixtures/ruby/require.A.rb new file mode 100644 index 000000000..5467774c9 --- /dev/null +++ b/test/fixtures/ruby/require.A.rb @@ -0,0 +1,3 @@ +require "json" + +foo(a) diff --git a/test/fixtures/ruby/require.B.rb b/test/fixtures/ruby/require.B.rb new file mode 100644 index 000000000..3c59d4a4f --- /dev/null +++ b/test/fixtures/ruby/require.B.rb @@ -0,0 +1,3 @@ +require "nokogiri" + +autoload(:Bar, "bar.rb") diff --git a/test/fixtures/ruby/require.diffA-B.txt b/test/fixtures/ruby/require.diffA-B.txt new file mode 100644 index 000000000..000634991 --- /dev/null +++ b/test/fixtures/ruby/require.diffA-B.txt @@ -0,0 +1,14 @@ +(Program + (Import + { (TextElement) + ->(TextElement) } + (Empty)) +{+(Import + {+( + {+(Symbol)+} + {+(TextElement)+})+} + {+(Empty)+})+} +{-(Call + {-(Identifier)-} + {-(Identifier)-} + {-(Empty)-})-}) diff --git a/test/fixtures/ruby/require.diffB-A.txt b/test/fixtures/ruby/require.diffB-A.txt new file mode 100644 index 000000000..7ea78ad11 --- /dev/null +++ b/test/fixtures/ruby/require.diffB-A.txt @@ -0,0 +1,14 @@ +(Program + (Import + { (TextElement) + ->(TextElement) } + (Empty)) +{+(Call + {+(Identifier)+} + {+(Identifier)+} + {+(Empty)+})+} +{-(Import + {-( + {-(Symbol)-} + {-(TextElement)-})-} + {-(Empty)-})-}) diff --git a/test/fixtures/ruby/require.parseA.txt b/test/fixtures/ruby/require.parseA.txt new file mode 100644 index 000000000..e4960dafe --- /dev/null +++ b/test/fixtures/ruby/require.parseA.txt @@ -0,0 +1,8 @@ +(Program + (Import + (TextElement) + (Empty)) + (Call + (Identifier) + (Identifier) + (Empty))) diff --git a/test/fixtures/ruby/require.parseB.txt b/test/fixtures/ruby/require.parseB.txt new file mode 100644 index 000000000..1203a16f7 --- /dev/null +++ b/test/fixtures/ruby/require.parseB.txt @@ -0,0 +1,9 @@ +(Program + (Import + (TextElement) + (Empty)) + (Import + ( + (Symbol) + (TextElement)) + (Empty)))