Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsing eunit macro ?debugVal fails with Error: function_clause #480

Closed
cypherfox opened this issue Apr 13, 2018 · 18 comments
Closed

Parsing eunit macro ?debugVal fails with Error: function_clause #480

cypherfox opened this issue Apr 13, 2018 · 18 comments

Comments

@cypherfox
Copy link

Linting the following module gives me:

Error: function_clause when loading file "src/elvis_function_fail.erl".
# src/elvis_function_fail.erl [FAIL]
Error: 'function_clause' while applying rule 'no_debug_call'.
Error: 'function_clause' while applying rule 'dont_repeat_yourself'.
[...all the other rules...]

As far as I can tell this only happens with the ?debugVal macro. I use the ?debug* eunit macros quite intensively in my tests and they all work fine.

The complete code of the module is:

-module(elvis_function_fail).
-include_lib("eunit/include/eunit.hrl").
-export([f/0]).

f() ->
    Val = 10,
?debugVal(Val),
ok.

@elbrujohalcon
Copy link
Member

Hi @cypherfox , can you show us your elvis.config and Erlang/OTP version, please?
I tried it in a testing project of mine and it emitted no warnings.

@cypherfox
Copy link
Author

Erlang/OTP: 20

I am using elvis_core (package 0.4.1) via https://github.com/timadorus/rebar3_lint"

elvis.config

[{ elvis,
   [ {config,
      [#{ dirs => ["src", "test"]
          , filter => "*.erl"
          , rules => [{elvis_style, line_length,
                       #{ignore => [],
                         limit => 120,
                         skip_comments => false}},
                      {elvis_style, no_tabs},
                      {elvis_style, no_trailing_whitespace},
                      {elvis_style, macro_names, #{ignore => []}},
                      {elvis_style, macro_module_names},
                      {elvis_style, operator_spaces, #{rules => [{right, ","},
                                                                 {right, "++"},
                                                                 {left, "++"}]}},
                      {elvis_style, nesting_level, #{level => 3}},
                      {elvis_style, god_modules,
                       #{limit => 25,
                         ignore => []}},
                      {elvis_style, no_if_expression},
                      {elvis_style, invalid_dynamic_call,
                       #{ignore => [teu_tree, teu_tree_gen]}},
                      {elvis_style, used_ignored_variable,
                        #{ignore => [teu_async_mock_tests]}},
                      {elvis_style, no_behavior_info},
                      {
                       elvis_style,
                       module_naming_convention,
                       #{regex => "^[a-z]([a-z0-9]*_?)*(_SUITE)?$",
                         ignore => []}
                      },
                      {
                       elvis_style,
                       function_naming_convention,
                       #{ regex => "^([a-z][a-z0-9]*_?)([a-z0-9]*_?)*$"}
                      },
                      {elvis_style, state_record_and_type},
                      {elvis_style, no_spec_with_records},
                      {elvis_style, dont_repeat_yourself, #{min_complexity => 20}},
                      {
                       elvis_style,
                       no_debug_call,
                       #{ ignore => [teu_async_mock, teu_ct, teu_perf_measure]}
                      }
                       ]},
       #{ dirs => ["."]
          , filter => "Makefile"
          , rules => [{elvis_project, no_deps_master_erlang_mk, #{ignore => []}},
                      {elvis_project, protocol_for_deps_erlang_mk, #{ignore => []}}]
        },
       #{ dirs => ["."]
          , filter => "rebar.config"
          , rules => [ {elvis_project, no_deps_master_rebar, #{ignore => []}}
                     ]
        },
       #{ dirs => ["."]
          , filter => "elvis.config"
          , ruleset => elvis_config
        }
      ]}
     , {output_format, plain}
   ]
}].

@cypherfox
Copy link
Author

Never mind. I just realised that I am probably actually running elvis_core 0.3.6 due to rebar.lock file.

I will clean this up and be back if need be.

closing the issue for now. Please excuse the hubub

@cypherfox
Copy link
Author

Ok, I have verified that I am actualy using elvis_core 0.3.9.

The error is still there.

@cypherfox cypherfox reopened this Apr 13, 2018
@elbrujohalcon
Copy link
Member

I created the project that I'm attaching here.
Then I run the following commands:

$ erl -s init stop
Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]

*** ERROR: Shell process terminated! ***
$ elvis rock
# src/elvis_function_fail.erl [FAIL]
  - line_length
    - Line 8 is too long:     _I_added_this_line = to_get_a_warning, % and it's very very very very very long - a really really long long line - very long.
$ elvis --version
   ______     _
  / __/ /  __(_)__
 / _// / |/ / (_-<
/___/_/|___/_/___/
Version: 0.4.1
Elvis Core Version: 0.3.9

Can you do the same?

@cypherfox
Copy link
Author

$ erl -s init stop
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [kernel-poll:false]

Eshell V9.2  (abort with ^G)
1>

$ elvis rock
Error: function_clause when loading file "src/elvis_function_fail.erl".
# src/elvis_function_fail.erl [FAIL]
Error: 'function_clause' while applying rule 'no_debug_call'.
Error: 'function_clause' while applying rule 'dont_repeat_yourself'.
Error: 'function_clause' while applying rule 'no_spec_with_records'.
Error: 'function_clause' while applying rule 'state_record_and_type'.
Error: 'function_clause' while applying rule 'function_naming_convention'.
Error: 'function_clause' while applying rule 'module_naming_convention'.
Error: 'function_clause' while applying rule 'no_behavior_info'.
Error: 'function_clause' while applying rule 'used_ignored_variable'.
Error: 'function_clause' while applying rule 'invalid_dynamic_call'.
Error: 'function_clause' while applying rule 'no_if_expression'.
Error: 'function_clause' while applying rule 'god_modules'.
Error: 'function_clause' while applying rule 'nesting_level'.
Error: 'function_clause' while applying rule 'operator_spaces'.
Error: 'function_clause' while applying rule 'macro_module_names'.

$ elvis --version
   ______     _
  / __/ /  __(_)__
 / _// / |/ / (_-<
/___/_/|___/_/___/
Version: 0.4.1
Elvis Core Version: 0.3.9

@elbrujohalcon
Copy link
Member

Ok, that looks like your elvis is not properly compiled. Which is weird since you have the same version of elvis that I have. Let's try this: Please replace your elvis executable with the one attached here and run elvis rock again.

elvis.zip

@cypherfox
Copy link
Author

$ elvis rock
# src/elvis_function_fail.erl [FAIL]
  - line_length
    - Line 8 is too long:     _I_added_this_line = to_get_a_warning, % and it's very very very very very long - a really really long long line - very long.

I had my elvis freshly compiled just before running it (git clone; rebar3 escriptize as stated in the Readme.md ). As I nomally only use the rebar3 plugin I had never previously build/installed the actual CLI binary.

@elbrujohalcon
Copy link
Member

I'm not sure what's going on there. I run the following commands here and it worked:

$ git clone git@github.com:inaka/elvis.git
Cloning into 'elvis'...
remote: Counting objects: 2517, done.
remote: Total 2517 (delta 0), reused 0 (delta 0), pack-reused 2517
Receiving objects: 100% (2517/2517), 659.79 KiB | 413.00 KiB/s, done.
Resolving deltas: 100% (1713/1713), done.
$ cd elvis
$ rebar3 escriptize
…lots of output…
$ cd path/to/eff
$ ../path/to/elvis/_build/default/bin/elvis rock
# src/elvis_function_fail.erl [FAIL]
  - line_length
    - Line 8 is too long:     _I_added_this_line = to_get_a_warning, % and it's very very very very very long - a really really long long line - very long.

@elbrujohalcon
Copy link
Member

Maybe you can contact the authors of that rebar3 plugin and check if they're doing something different there.

@jfacorro
Copy link
Contributor

@cypherfox With a repo were we can reproduce the behaviour we could look into what the problem is with that plugin. Would it be possible for you to create it?

@cypherfox
Copy link
Author

@elbrujohalcon: but my local build failed independently of the rebar plugin. I followed the instructions on the elvis Readm to do a fresh install.

I think this may be important: the rebar plugin will pull down elvis_core on each build and compile it fresh. I rust run it on both my local machine (Ubuntu on Windows) as well as my CI/CD Pipeline (the official erlang:latest image), and both created an elvis_core that will throw those errors.

What plattforms are you compiling on?

@elbrujohalcon
Copy link
Member

elbrujohalcon commented Apr 17, 2018

I'm on a macbook pro, with macOS High Sierra Version 10.13.4 and I install Erlang/OTP through kerl.

As you can see above, I also followed the instructions on elvis' README.md, I think.

@cypherfox
Copy link
Author

@jfacorro This replicates the behaviour with the plugin:
https://github.com/cypherfox/elvis_test_build

@jfacorro
Copy link
Contributor

jfacorro commented Apr 18, 2018

@cypherfox Thank you for the example repo! 😄

I've managed to reproduce the problem in katana-code's shell:

1> ktn_code:parse_tree([], "-module(bla).\n-include_lib(\"eunit/include/eunit.hrl\").\n-export([f/0]).\nf() -> Val = 10, ?debugVal(Val).").
** exception error: no function clause matching aleppo:legacy_location({var,[{text,"E"},{location,{232,33}}],'E'}) (/Users/juan.facorro/dev/jfacorro/katana-code/_build/default/lib/aleppo/src/aleppo.erl, line 448)
     in function  aleppo:reverse_and_normalize_token_locations_helper/2 (/Users/juan.facorro/dev/jfacorro/katana-code/_build/default/lib/aleppo/src/aleppo.erl, line 472)
     in call from aleppo:process_tree/2 (/Users/juan.facorro/dev/jfacorro/katana-code/_build/default/lib/aleppo/src/aleppo.erl, line 73)
     in call from ktn_code:parse_tree/3 (/Users/juan.facorro/dev/jfacorro/katana-code/_build/default/lib/katana_code/src/ktn_code.erl, line 112)

I think the problem is in the way aleppo is processing the tokens though, probably the code that does the macro-expansion isn't considering a special case. I will look into it.

@jfacorro
Copy link
Contributor

jfacorro commented Apr 19, 2018

@cypherfox UPDATE: I'm still looking into this. I now suspect the ??E here is the one that is not being handled properly. The debugVal macro does some non-trivial macro things, which aleppo is not handling well.

@jfacorro
Copy link
Contributor

@cypherfox @elbrujohalcon Just opened a PR with a fix in Aleppo, once that's merged it will need to be propagated to elvis_core and elvis.

@elbrujohalcon
Copy link
Member

Since katana-code is already updated with the change, I'll close this issue and open a new one to update dependencies in elvis_core and another one for updating this repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants