Commit graph

2123 commits

Author SHA1 Message Date
Roberto Aloi
26a098fa38 Upgrade Node 18 -> 20 2025-08-21 16:06:57 +02:00
Roberto Aloi
9e529d113c Update linter docs to use traits
Summary: Update the docs, which contained a SSR-based linter, to use the new trait.

Reviewed By: TD5

Differential Revision: D80527631

fbshipit-source-id: 9a0258b11818f005ebf3f2013b3ebd515512d592
2025-08-19 23:29:48 -07:00
Roberto Aloi
401e1714f5 Update todo comment for unused_function_args linter
Summary: One of the two tasks is completed, so update the comment.

Reviewed By: TD5

Differential Revision: D80527750

fbshipit-source-id: 4e1a7575229f65f24a074b47c333a4672342e86d
2025-08-19 23:29:48 -07:00
Roberto Aloi
9a72d25f08 Convert unnecessary_map_to_list_in_comprehension linter to use the SsrPatternsLinter trait
Summary: Convert the `unnecessary_map_to_list_in_comprehension` linter to use the new trait.

Reviewed By: TD5

Differential Revision: D80521249

fbshipit-source-id: ed4323548de50d7fe2bcad53a168a8d6f7906182
2025-08-19 03:15:24 -07:00
Roberto Aloi
2b1ecb3857 Convert binary_string_to_sigil linter to use SsrPatternsLinter trait
Summary:
Convert the `binary_to_sigil` linter to use the new `SsrPatternsLinter` trait.
This makes the linter code a lot more readable, decoupling the generic logic from the specific parts.

Reviewed By: TD5

Differential Revision: D80518920

fbshipit-source-id: 420a9aa073a41c2767a8d8158fdfe9e31d59888e
2025-08-19 03:15:24 -07:00
Roberto Aloi
5c64a0d01d Introduce SsrPatternsLinter trait
Summary:
Similar to the `FunctionCallLinter` introduced in D80341881, this introduces a `SsrPatternsLinter` trait which abstracts away a lot of the implementation details for Ssr-based linters, allowing the ELP developer to focus on the more important callback functions.

We convert the `UnnecessaryFoldToBuildMap` linter to showcase how the linter can be used in practice.

In the process, fix a few minor bugs in the linter, which emerged from the conversion.

Reviewed By: TD5

Differential Revision: D80462420

fbshipit-source-id: c3d047ff6a020e17194f7a93a0df85775cda6260
2025-08-19 03:15:24 -07:00
Roberto Aloi
b45e1748a2 Use more specific names to indicate function call linters
Summary: In preparation for introducing a new category of SSR-based linters.

Reviewed By: TD5

Differential Revision: D80462418

fbshipit-source-id: f86fcdc6e39a27f5b5175db6047ab4e511fd27d1
2025-08-18 23:34:21 -07:00
Roberto Aloi
7ad39ba252 Split FunctionCallLinter into a generic and a specific part
Summary: In preparation for a `SsrLinter` trait, split the `FunctionCallLinter` into a generic and a specific part, so that the generic part can be used for `SsrLinter`.

Reviewed By: TD5

Differential Revision: D80451562

fbshipit-source-id: 916026c4955ef78d466a568ae9ce51d886c50534
2025-08-18 23:34:21 -07:00
Roberto Aloi
c915855123 Convert the no_eval linter to use the FunctionCallLinter trait
Summary:
Convert the `no_eval` linter to use the new trait, to remove duplication.
The linter had some custom  filtering logic, so extend the trait to allow an optional `should_process_file_id` callback.

Reviewed By: TD5

Differential Revision: D80443713

fbshipit-source-id: 1e971e1e6de1215a1771542a42b829c58ccb7279
2025-08-18 05:20:54 -07:00
Roberto Aloi
7ac2ac08e5 Convert the no_error_logger linter to use the FunctionCallLinter trait
Summary: Convert the `no_error_logger` linter to use the new trait, to showcase the amount of boilerplate removed.

Reviewed By: TD5

Differential Revision: D80347608

fbshipit-source-id: 990ec52b486d2d88b98f81878a70af7eca43f970
2025-08-18 05:20:54 -07:00
Roberto Aloi
7d3938329c Convert the no_size linter to use the FunctionCallLinter trait
Summary: Convert the `no_size` linter to use the new trait, to showcase the amount of boilerplate removed.

Reviewed By: TD5

Differential Revision: D80346647

fbshipit-source-id: 201901a737a16740c0a2c3504e65a2cb84b2a1c6
2025-08-18 05:20:54 -07:00
Roberto Aloi
11b9e643f1 Convert the no_garbage_collect to use the FunctionCallLinter trait
Summary: Convert the `no_garbage_collect` linter to use the new trait, to showcase the amount of boilerplate removed.

Reviewed By: TD5

Differential Revision: D80344745

fbshipit-source-id: a8f42a2c844ba65d52e8ac89fcdd69f3172342d5
2025-08-18 03:55:13 -07:00
Roberto Aloi
91079b1b33 Introduce lazy_function_matches macro to avoid duplication
Summary:
# Context
Diagnostics are calculated for every `file_id` (i.e. module) in the system, causing multiple calls to extract the function matches. To avoid the overhead, the `lazy_static` macro is usually used.
# Problem
The code required to specify matches is quite verbose.
# Solution
Create a helper macro that minimizes the amount of code written by the lint author.

Note: ideally, we'd get rid of the multiple calls in the first place. That could be done as a next step.

Reviewed By: TD5

Differential Revision: D80342732

fbshipit-source-id: 4cd2f8635b12e083feb37c369f0703cace9b7c56
2025-08-18 03:02:58 -07:00
Roberto Aloi
831ba8c5af Introduce FunctionCallLinter trait
Summary:
# Context

Today, adding a linter to ELP today relies on [quite a bit of non-obvious boilerplate](https://whatsapp.github.io/erlang-language-platform/docs/contributing/linters/). Furthermore, each linter performs its own logical traversal of an Erlang module.

# Problem

Some time ago, a somewhat experimental [`DiagnosticTemplate`](https://www.internalfb.com/code/fbsource/[bc7dd2289948f9c9c392c27c6c8db79cf81421b1]/fbcode/whatsapp/elp/crates/ide/src/diagnostics/helpers.rs?lines=28) mechanism was introduced, to reduce the amount of boilerplate required, but the approach has certain limitations:

* It still requires specifying a number of details even when default behaviours are good enough
* It still requires the developer to traverse the module, assuming knowledge about `def_map` and `find_call_in_function`

# Solution

By leveraging a trait, we can limit the amount of boilerplate (and knowledge!) required by an ELP developer to add a new linter.

Given that a good number of the existing linters detect function call applications, I am starting here by factoring out the common code into a `FunctionCallLinter`, which can eventually be generalized further, to allow additional types of linters.

This diff introduces the new linter, and converts a first linter (`sets_version_v2`) to use the new trait.

To keep the changes minimal, I am copying the logic from `diagnostics_from_descriptors` to `diagnostics_from_linters`. Specifically, the extraction of the `is_generated` and `is_test`, populating the same `Descriptor` as before (just, in a transparent way to the user).

The extra filtering which was present in `diagnostics_from_linters` is not necessary in the new version, where we can assume a 1:1 relation between a linter and a code.

Finally, the `find_call_in_function` API is only called once, at the top level, once all the linter "specifications" are extracted.

Reviewed By: TD5

Differential Revision: D80341881

fbshipit-source-id: 68b972f32202309f28f7bcdaddd641513ac90d9f
2025-08-18 03:02:58 -07:00
Roberto Aloi
cc6748b955 Limit check_used_functions to function definitions local to the module
Summary:
The helper function is used in a number of `DiagnosticTemplate` linters (`no_size`, `no_error_logger`, etc) to detect function calls matching a given spec.

By using the extended `def_map`, we also include calls in included file (via `-include` or `-include_lib`). This is most likely a non-desired behaviour, since we'd end up returning diagnostics for included files, too, with incorrect ranges.

This also makes the linters behaviour consistent with the other linters (e.g. `debugging_function`, `atoms_exhaustion`, etc) which use a local `def_map_local`.

This is a step in preparation of the factoring out of the linters boilerplate code into a single method.

Reviewed By: TD5

Differential Revision: D80243757

fbshipit-source-id: a0d4145639fc10179b6e53ce88c3e18bdd101015
2025-08-18 03:02:58 -07:00
Roberto Aloi
f6094dcae3 Auto-completion for --diagnostic-code argument
Summary: Small quality of life, so that users of the ELP CLI can auto-complete diagnostic codes. Both codes and labels are presented. We could perform some fuzzy matching, but for now let's keep things simple and match on the prefix provided.

Reviewed By: TD5

Differential Revision: D80093860

fbshipit-source-id: d2a97409c8f6f1e9cf548b47cd0c276d85b513e0
2025-08-12 09:22:54 -07:00
Roberto Aloi
18befb9e0f Add documentation on how to create a new linter
Reviewed By: TD5

Differential Revision: D80079152

fbshipit-source-id: 6ce3ec9eebff72c6c1ffd78a6a93ff90f338017b
2025-08-12 07:30:27 -07:00
Tom Davies
41f2e8799d Improve handling puralisation of CLI output
Summary: No need to have "Applying fix(es)" in our output when we know whether there's one or more elements. Instead, we can just pick the correct form.

Reviewed By: robertoaloi

Differential Revision: D79890374

fbshipit-source-id: f9604db74004619703c801c28477fb17b6b0015a
2025-08-12 04:34:33 -07:00
Roberto Aloi
88fc8ec7d8 Fix formatting
Summary: I noticed CI was broken on GitHub.

Reviewed By: jcpetruzza

Differential Revision: D80002359

fbshipit-source-id: 06db89f7a7b70116203ef98eb1c761ca401989a5
2025-08-11 08:47:57 -07:00
Roberto Aloi
5089e30270 Add malformed_include linter
Reviewed By: TD5

Differential Revision: D79645138

fbshipit-source-id: 58ccc18749c01501013d7b3ad2c9c1c21a816bdb
2025-08-06 05:30:34 -07:00
Roberto Aloi
4319e99c86 Add no_nowarn_suppressions linter
Summary: Raises a warning if a compile directive of type `nowarn_*` is used.

Reviewed By: TD5

Differential Revision: D79635553

fbshipit-source-id: 369c38f5b80bfa7cd3830cbef22da59aa8eed380
2025-08-06 05:30:34 -07:00
Victor Lanvin
f1bb7738ae Revert D75066592
Summary: Revert Salsa 0.19 migration in an attempt to diagnose S546488

Reviewed By: robertoaloi

Differential Revision: D79442869

fbshipit-source-id: 4bc73d2cfc14a9fc5832b08cd3014681dd7721e1
2025-08-01 07:35:06 -07:00
ZeeWanderer
e49ff321bd windows initial support (#111)
Summary:
This makes it compile on Windows and work from the command line, but still can't get it to work properly with Windows VS Code extension.

```shell
[2025-07-17T18:47:44.619Z] [ERROR elp_ide_db::docs] Unknown application - could not load app_data to determine whether file is on OTP
[2025-07-17T18:47:44.619Z] [ERROR elp_ide_db::docs] No corresponding appdata found for file, so no docs can be loaded
[Error - 9:47:44 PM] [elp_ide_db::docs] Unknown application - could not load app_data to determine whether file is on OTP
[Error - 9:47:44 PM] [elp_ide_db::docs] No corresponding appdata found for file, so no docs can be loaded
[2025-07-17T19:06:47.466Z] [ERROR elp_ide_db::docs] Unknown application - could not load app_data to determine whether file is on OTP
[2025-07-17T19:06:47.466Z] [ERROR elp_ide_db::docs] No corresponding appdata found for file, so no docs can be loaded
[Error - 10:06:47 PM] [elp_ide_db::docs] Unknown application - could not load app_data to determine whether file is on OTP
[Error - 10:06:47 PM] [elp_ide_db::docs] No corresponding appdata found for file, so no docs can be loaded
```

~~and when running `elp shell`~~ Turns out `watchman` was not installed. Haven't seen it in setup docs.
```shell
Could not find project. Are you in an Erlang project directory, or is one specified using --project?
```

[build_info.json](https://github.com/user-attachments/files/21303371/build_info.json) and [project_imfo.json](https://github.com/user-attachments/files/21303726/project_imfo.json) for the newly generated rebar3 project

https://github.com/WhatsApp/erlang-language-platform/issues/26

Pull Request resolved: https://github.com/WhatsApp/erlang-language-platform/pull/111

Reviewed By: TheGeorge

Differential Revision: D78658932

Pulled By: alanz

fbshipit-source-id: 0477ad649a6dc4542d5494360d9c8c0a8374a0ba
2025-07-23 08:40:59 -07:00
Alan Zimmerman
2472efbec9 Add instructions for elp shell, and need for watchman
Summary:
`elp shell` relies on watchman to monitor for changes.

Document this fact in the web site

Reviewed By: Balajiganapathi

Differential Revision: D78660276

fbshipit-source-id: 03e8b5fdc8b5cbb8fca0b8b008a8003d221b7c2b
2025-07-23 02:13:47 -07:00
Alan Zimmerman
5fe199720c BE: fix clippy warnings
Summary: As title

Reviewed By: TD5

Differential Revision: D78731905

fbshipit-source-id: 23a69471d82d61a218471d838c17cb4cf18831c3
2025-07-22 03:25:01 -07:00
Alan Zimmerman
726ece4274 Provide error message if watchman not installed for elp shell
Summary: Explicitly check if watchman is available when starting up, and bail if not.

Reviewed By: michalmuskala

Differential Revision: D78662213

fbshipit-source-id: 0d648e0f5f6d84c8f275c067f4c25a0790e61956
2025-07-21 07:33:12 -07:00
Rahul Jain
8eebcbf793 Add tests for Indexing on FoldBody
Summary:
We have added Index impl for FoldBody with and without using references.
This diff adds unit tests for both the implementations.

Reviewed By: alanz

Differential Revision: D78659116

fbshipit-source-id: 404144735399c82a8a2d265298ff35ac9bd0a672
2025-07-21 06:09:18 -07:00
Rahul Jain
94c793c852 Add body index implementation on references
Reviewed By: alanz

Differential Revision: D78551538

fbshipit-source-id: c5e294bede1b13eccb7ed2979232b74fcd70cd33
2025-07-21 06:09:18 -07:00
Alan Zimmerman
c33cffe102 local include via deps
Summary:
The Erlang local include processing is intended to search in the include path of the initial application, then the include paths of all dependencies.

This is also how it works in buck2.

This diff aligns ELP with this by

- Include the app name in the local include key for the include mapping
- If the initial lookup fails, walk the tree of dependencies looking for a result

Reviewed By: TD5

Differential Revision: D78488506

fbshipit-source-id: 5ec98a0ecde04883db480b9adecae19ea0e784c6
2025-07-21 04:58:39 -07:00
Alan Zimmerman
d1475ea856 resolve OTP includes
Summary:
The `buck::IncludeMapping` keeps a map from the include(_lib) directive to the appropriate file path for all buck targets in the project.

This does not, however include the ones from OTP.

This diff remedies that.

Reviewed By: TheGeorge

Differential Revision: D78487455

fbshipit-source-id: 4d69541133fc3b0afd6b1afa07db80c13f61c5eb
2025-07-21 04:58:39 -07:00
Alan Zimmerman
c46e6934af Use buck dependencies when resolving include_lib
Summary:
It is time to explicitly check that the application referred to in an `include_lib` directive is part of the (transitive) dependencies of the originating file application (== buck target).

This processing is currently only applied to buck projects, so the `basedb::include` processing is updated to distinguish between the case where there is a mapping, and where there is not. Prior to this it tried the include mapping and fell back to more lax processing. This is no longer valid, as we may explicitly decide that an `include_lib` should **not** be resolved, in which case there should be no fallback processing.

We also need to clearly distinguish between a local lookup and an `include_lib` lookup in the `IncludeMapping`.  We do so by encoding the key into the hashmap of include strings to paths with an `L:` or 'R:` for the two cases.

An alternative would be to store a tuple of `(IncludeMappingScope, <lookup_path>)`.

Reviewed By: TheGeorge

Differential Revision: D77937818

fbshipit-source-id: bb3827b0ead94103025f784c4ff713991418f944
2025-07-21 04:58:39 -07:00
Alan Zimmerman
f8f557a105 BE: fix tests on master
Summary: As title.

Reviewed By: TD5

Differential Revision: D78657388

fbshipit-source-id: e6d535c895ce71eec404a88324bcb72d7cc918e8
2025-07-21 04:20:42 -07:00
Alan Zimmerman
9fd2bc40aa Bump extension version to 0.38
Summary: As title, preparing for release

Reviewed By: Balajiganapathi

Differential Revision: D78654847

fbshipit-source-id: 0b1f3c93dc5bafc4bfd724a726e149a1411f0b9f
2025-07-21 03:23:34 -07:00
Alan Zimmerman
f8fa366113 BE: inline buck::load_from_config_bxl
Summary: It is only used in one place. This prepares for changes to the calculation in the next diff.

Reviewed By: TheGeorge

Differential Revision: D78486961

fbshipit-source-id: c01cb401a3eb6bb36c8b55e75b02ce04a8309928
2025-07-21 02:59:01 -07:00
Alan Zimmerman
4d0fad71fd BE: move update_mapping_from_path to IncludeMapping
Summary:
As title. It is now a struct, this is the natural home.
And it will simplify adding OTP paths in a later diff.

Reviewed By: TheGeorge

Differential Revision: D78486867

fbshipit-source-id: ce012c07ae13ab0276a00f0dcd69d589c73d811c
2025-07-21 02:59:01 -07:00
Alan Zimmerman
69cfea0b3d Track original file when resolving includes
Summary:
When `erlc` resolves an `-include_lib(..)` directive it does so with the search path of the original file.

Up to now ELP has been taking a lenient approach to include file resolution, and has not precisely resolved according to the explicit dependencies of a given application. The application is determined from the originating `FileId`.

This diff keeps track of the originating `FileId`, so it can be used for more precise tracking in a later diff

Reviewed By: TD5

Differential Revision: D78165061

fbshipit-source-id: 225c1af47abea00616fc2763a26c6c89ae2db55f
2025-07-21 02:59:01 -07:00
Jonathan Arns
9927c3bb20 .elp.toml: add eqwalizer option ignore modules (#108)
Summary:
As the title says and as proposed in https://github.com/WhatsApp/erlang-language-platform/issues/67, this adds a config option that allows ignoring specific modules for `eqwalize-all`.

I think it would be nice to also allow some form of patterns (regex or shell-style globs) in addition to plain module names, e.g.
```
[eqwalizer]
ignore_modules = ["some_module", "some_app_*_pb"]
```
Q: Would patterns also be acceptable or does that violate some project rules or conventions?

Closes https://github.com/WhatsApp/erlang-language-platform/issues/67

Pull Request resolved: https://github.com/WhatsApp/erlang-language-platform/pull/108

Reviewed By: TheGeorge

Differential Revision: D77657335

Pulled By: alanz

fbshipit-source-id: 74b8e37e998d436485137c978758793bfe805334
2025-07-21 01:15:08 -07:00
Alan Zimmerman
ddbb00c34b Fix tests on master
Summary:
Some new modules were added to the buck2 directory, they affect expected results for one of the ELP tests.

Fix them

Reviewed By: mapoulin

Differential Revision: D78558795

fbshipit-source-id: 3e3b0b9b7c8c70699e91735fa0baa349ebf6c01a
2025-07-18 08:15:38 -07:00
Alan Zimmerman
5ab3f58c74 Tweak elp_development.md
Summary:
- Add some metadata indicating the files it applies to
- Fix the formatting

Reviewed By: TD5

Differential Revision: D78276191

fbshipit-source-id: f8c47162dea2dd97574fb34de9ba436496aef9fb
2025-07-18 07:21:05 -07:00
Alan Zimmerman
14facfe54d fix dependabot alert for on-headers
Summary: As title

Reviewed By: TheGeorge

Differential Revision: D78550118

fbshipit-source-id: 59b8ea42df653fd71793949bd8b79745d87aff88
2025-07-18 05:50:19 -07:00
David Ansari
d93e9b69f1 Document ELP in Neovim example config (#109)
Summary:
Add an example config for ELP in Neovim without using `mason.nvim` as discussed in https://github.com/WhatsApp/erlang-language-platform/issues/87#issuecomment-2967196399

Pull Request resolved: https://github.com/WhatsApp/erlang-language-platform/pull/109

Reviewed By: alanz, TheGeorge

Differential Revision: D77920015

Pulled By: robertoaloi

fbshipit-source-id: dc408c179910bb74b2111b34c056754993ccae56
2025-07-18 05:47:55 -07:00
Greg Cowan
e306e28e01 Handle long application in elp lint CLI
Summary:
TSIA
Followed https://www.internalfb.com/wiki/WhatsApp/Eng/Infra/Development/Environment_%28IDE%29/VSCode/How_the_Erlang_extension_works/Contributing_to_ELP/

Reviewed By: alanz

Differential Revision: D78359675

fbshipit-source-id: 8e13a7dc63eb1d4a76a0897e4b446af223d1f63c
2025-07-18 05:42:04 -07:00
Alan Zimmerman
8a2e70ffcc remove --buck-generated CLI arg, it is no longer used
Summary: As title

Reviewed By: TheGeorge

Differential Revision: D78403971

fbshipit-source-id: 4f7df06440465bbc2c5f0227c8506f6864e96fe7
2025-07-16 05:47:25 -07:00
Alan Zimmerman
401145b43c BE: improve check for path being in mem_docs
Summary: As title

Reviewed By: TheGeorge

Differential Revision: D78333441

fbshipit-source-id: 22cae1907a9520bd8fcf9e02e4817c5c22ab1f57
2025-07-16 02:41:27 -07:00
Alan Zimmerman
748ecf93ec BE: Fix new clippy warnings from rust 1.88.0
Summary:
We have moved to `cargo 1.88.0 (873a06493 2025-05-10)` internally.  This has enabled a check for `uninlined_format_args`.

Update the local clippy.toml to match this, and run

```
cargo clippy --workspace --tests --fix
```

to generate this diff

This may be related to https://github.com/rust-lang/rust-clippy/issues/14694

Reviewed By: TD5

Differential Revision: D78345648

fbshipit-source-id: a218be720e34b06ed08c52b5f7db936940bc2c37
2025-07-15 09:59:27 -07:00
Alan Zimmerman
8d73b1dc45 Properly clear diagnostics when a file is closed
Summary:
When we process a `DidCloseTextDocument` we sent a `PublishDocuments` notification with empty diagnostics to the server, to clear its diagnostic store.

But if at the time of closing the file we are calculating diagnostics for it, these will be sent when the diagnostic calculation ends.

This diff ensures we clear all current diagnostics (except eqwalizer project ones, if enabled) when we close the file, and does not send diagnostics for unopened files.

Reviewed By: TD5

Differential Revision: D78275536

fbshipit-source-id: f4d380e0022102dcb74151f027df4d5b0cdd58c5
2025-07-14 09:36:14 -07:00
Alan Zimmerman
babe31bb6f Keep original buck TargetFullName in AppData
Summary:
We use `AppData` as our general representation of an Erlang application in ELP, originally in the rebar3 sense.

The ELP design standardises on this information, whatever the origin of the project data in an ELP Project.

For a buck2 project, we use the last part of a buck2 target as the `AppData::name`.

So the buck target `cell/path/to/app:app_name` would give rise to "app_name".

In some circumstances involving test fixtures we cannot guarantee that the derived "app_name" is unique.

This diff adds the original full buck target name to `AppData`, so this can be used as needed.  It is used in a later diff, still unpublished.

Reviewed By: TD5

Differential Revision: D78160505

fbshipit-source-id: 3b14d50709328b53079d648c5eb2ae6a86311d6d
2025-07-14 03:12:31 -07:00
Victor Lanvin
e78a8d99b3 Migrate to Salsa 0.19
Summary:
Migrate ELP to Salsa 0.19, featuring a completely new API. Overall, the migration follows closely the one of [rust-analyzer](74620e64ec (diff-5828430af308cfce455219d40dac23f272baf89378ada6febee5d6a186ffe0fb))

Major changes:
- Bump `rust-analyzer` to 2025-03-17
- Use `ra_ap_query-group-macro` to emulate the old `query_group` macro.
- `SourceDatabase` is split into two, `RootQueryDb` containing queries inside a `query_group` and `SourceDatabase` which deals with salsa inputs only.
- All parameterized inputs (`FileText`, `SourceRoot`, ...) are extracted as structs, and a read/write API is provided according to Salsa 0.19 principles. This API was previously automatically derived by Salsa.
- Cycle handling functions signatures are modified.
- Create structs for all interned values, also following Salsa 0.19 guidelines.

Reviewed By: alanz

Differential Revision: D75066592

fbshipit-source-id: 233e626ca3c3c9004241e2064d2bcf7e2d0106ed
2025-07-11 01:35:47 -07:00
Alan Zimmerman
6040dcbfe5 fix duplicate undefined macro duplicate actions
Summary:
As title.

Since we currently can have multiple macro definitions, we put candidates in a set to filter them out.

Reviewed By: michalmuskala

Differential Revision: D78087578

fbshipit-source-id: 084db136f7842185cd840c1d13a00cb75d2e8e00
2025-07-10 05:37:15 -07:00
Alan Zimmerman
d0cffb1399 Add failing test to show undefined macro duplicate actions
Summary:
Because ELP does not (yet) properly process conditional macros, a macro defined with conditional alternatives will show up multiple times.

Add a test to demonstrate this case, which will be fixed in the next diff.

Reviewed By: michalmuskala

Differential Revision: D78087402

fbshipit-source-id: e450a3d8f1cbd08b3040a5b70f114bafd8227800
2025-07-10 05:37:15 -07:00