123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109(*********************************************************************************)(* Dunolint - A tool to lint and help manage files in dune projects *)(* Copyright (C) 2024-2025 Mathieu Barbin <mathieu.barbin@gmail.com> *)(* *)(* This file is part of Dunolint. *)(* *)(* Dunolint is free software; you can redistribute it and/or modify it *)(* under the terms of the GNU Lesser General Public License as published by *)(* the Free Software Foundation either version 3 of the License, or any later *)(* version, with the LGPL-3.0 Linking Exception. *)(* *)(* Dunolint is distributed in the hope that it will be useful, but WITHOUT *)(* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *)(* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *)(* and the file `NOTICE.md` at the root of this repository for more details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* and the LGPL-3.0 Linking Exception along with this library. If not, see *)(* <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)(*********************************************************************************)moduletypeS=Linter_intf.Stypet=|Unhandled|T:{eval:path:Relative_path.t->predicate:Dunolint.Predicate.t->Dunolint.Trilang.t;enforce:path:Relative_path.t->condition:Dunolint.Predicate.tBlang.t->unit}->tmodulePredicate=structtype'at=|Tof'a|Notof'aletto_blang=function|Ta->Blang.basea|Nota->Blang.not_(Blang.basea);;endletenforce(typepredicate)(moduleHandler_predicate:Handler.Predicatewithtypet=predicate)~eval~(enforce:'t->predicatePredicate.t->Enforce_result.t)=letcheckt~condition=matchDunolint.Trilang.evalcondition~f:(funpredicate->evalt~predicate)with|True|Undefined->()|False->Handler.enforce_failure(moduleHandler_predicate)~loc:Loc.none~conditioninletenforcetpredicate=matchenforcetpredicatewith|Ok|Unapplicable->()|Eval->checkt~condition:(Predicate.to_blangpredicate)|Fail->Handler.enforce_failure(moduleHandler_predicate)~loc:Loc.none~condition:(Predicate.to_blangpredicate)inletrecauxt~condition=match(condition:predicateBlang.t)with|Basepredicate->enforcet(Tpredicate)|Not(Basepredicate)->enforcet(Notpredicate)|And(a,b)->auxt~condition:a;auxt~condition:b|If(if_,then_,else_)->(matchDunolint.Trilang.evalif_~f:(funpredicate->evalt~predicate)with|True->auxt~condition:then_|False->auxt~condition:else_|Undefined->())|(True|False|Not_|Or_)ascondition->checkt~conditioninaux;;letat_positive_enforcing_position(condition:'aBlang.t)=letrecloopacct=match(t:_Blang.t)with|Basea->a::acc|And(a,b)->letacc=loopaccainletacc=loopaccbinacc|If_|True|False|Not_|Or_->accinList.rev(loop[]condition);;letpublic_name_is_prefixname~prefix=(* This helps in cases where the library public name has not the correct
package prefix, in favoring a strategy that proposes to replace it by the
enforced one, rather than producing a proposition with two dots in it. *)matchifString.is_suffixprefix~suffix:"."then(matchString.lsplit2name~on:'.'with|None->None|Some(_,right)->Some(prefix^right))elseNonewith|None->prefix^name|Someresult->result;;