Skip to content

Commit 4986189

Browse files
vassilmladenovmeta-codesync[bot]
authored andcommitted
well-formedness checks on if package expressions
Summary: Analogously to `__RequirePackage('xxx')`, `package xxx` should only be allowed if `xxx` includes the package the current file belongs to. Reviewed By: mheiber Differential Revision: D94566454 fbshipit-source-id: bf19fd0b775d50dc6db2dc03d86f85e281a72e4e
1 parent da370c0 commit 4986189

33 files changed

Lines changed: 834 additions & 469 deletions

File tree

hphp/hack/src/diagnostics/error_codes.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ module NastCheck = struct
285285
| NamedInTransformedPseudofunction [@value 3106]
286286
| RequirePackageStrictInclusion [@value 3107]
287287
| ClassSealedWithTrait [@value 3108]
288+
| PackageExpressionStrictInclusion [@value 3109]
288289
(* Add new NastCheck codes here! Comment out when deprecating. *)
289290
[@@deriving enum, show { with_path = false }]
290291

hphp/hack/src/hackc/compile/compile.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ fn emit_fatal_nast_check_error(err: &NastCheckError) -> Result<Unit, Error> {
564564
NastCheckError::AttributeImplementedByRestriction { .. } => todo!(),
565565
NastCheckError::RequirePackageStrictInclusion { .. } => todo!(),
566566
NastCheckError::ClassSealedWithTrait { .. } => todo!(),
567+
NastCheckError::PackageExpressionStrictInclusion { .. } => todo!(),
567568
}
568569
}
569570

hphp/hack/src/oxidized/gen/error_codes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// This source code is licensed under the MIT license found in the
44
// LICENSE file in the "hack" directory of this source tree.
55
//
6-
// @generated SignedSource<<e8f3018ac482cee215fbdf70aca4ce8e>>
6+
// @generated SignedSource<<afdd1e05969146f6f213408ba49a6645>>
77
//
88
// To regenerate this file, run:
99
// buck run @fbcode//mode/dev-nosan-lg fbcode//hphp/hack/src:oxidized_regen
@@ -226,6 +226,7 @@ pub enum NastCheck {
226226
NamedInTransformedPseudofunction = 3106,
227227
RequirePackageStrictInclusion = 3107,
228228
ClassSealedWithTrait = 3108,
229+
PackageExpressionStrictInclusion = 3109,
229230
}
230231
impl TrivialDrop for NastCheck {}
231232
arena_deserializer::impl_deserialize_in_arena!(NastCheck);

hphp/hack/src/oxidized/gen/nast_check_error.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// This source code is licensed under the MIT license found in the
44
// LICENSE file in the "hack" directory of this source tree.
55
//
6-
// @generated SignedSource<<88a1d0face0230950853fb28a36ecce6>>
6+
// @generated SignedSource<<66b597028816448e23941b4407e36a65>>
77
//
88
// To regenerate this file, run:
99
// buck run @fbcode//mode/dev-nosan-lg fbcode//hphp/hack/src:oxidized_regen
@@ -330,4 +330,38 @@ pub enum NastCheckError {
330330
soft_included: bool,
331331
current_package_assignment_kind: String,
332332
},
333+
#[rust_to_ocaml(name = "Package_expression_strict_inclusion")]
334+
PackageExpressionStrictInclusion {
335+
pkg_pos: pos::Pos,
336+
pkg: String,
337+
def_pos: pos_or_decl::PosOrDecl,
338+
current: String,
339+
current_pos: pos::Pos,
340+
soft_included: bool,
341+
current_package_assignment_kind: String,
342+
},
343+
}
344+
345+
/// Context for package strict inclusion errors
346+
#[derive(
347+
Clone,
348+
Debug,
349+
Deserialize,
350+
Eq,
351+
EqModuloPos,
352+
FromOcamlRep,
353+
Hash,
354+
NoPosHash,
355+
Ord,
356+
PartialEq,
357+
PartialOrd,
358+
Serialize,
359+
ToOcamlRep
360+
)]
361+
#[repr(C, u8)]
362+
pub enum PackageStrictInclusionContext {
363+
#[rust_to_ocaml(name = "Ctx_require_package")]
364+
CtxRequirePackage(String),
365+
#[rust_to_ocaml(name = "Ctx_package_expression")]
366+
CtxPackageExpression,
333367
}

hphp/hack/src/typing/nast_check/nast_check_error.ml

Lines changed: 87 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,20 @@ type t =
209209
soft_included: bool;
210210
current_package_assignment_kind: string;
211211
}
212+
| Package_expression_strict_inclusion of {
213+
pkg_pos: Pos.t;
214+
pkg: string;
215+
def_pos: Pos_or_decl.t;
216+
current: string;
217+
current_pos: Pos.t;
218+
soft_included: bool;
219+
current_package_assignment_kind: string;
220+
}
221+
222+
(** Context for package strict inclusion errors *)
223+
type package_strict_inclusion_context =
224+
| Ctx_require_package of string (* attribute name *)
225+
| Ctx_package_expression
212226

213227
let repeated_record_field_name pos name prev_pos =
214228
User_diagnostic.make_err
@@ -873,40 +887,62 @@ let class_sealed_with_trait pos class_name trait_name =
873887
(Markdown_lite.md_codify @@ Render.strip_ns trait_name) );
874888
]
875889

876-
let require_package_strict_inclusion
877-
required_pos
878-
required
879-
def_pos
880-
current
881-
current_pos
882-
attribute_name
883-
soft_included
884-
current_package_assignment_kind =
890+
(** Unified function for package strict inclusion errors.
891+
[ctx] determines whether this is a __RequirePackage attribute or a package expression check. *)
892+
let package_strict_inclusion
893+
~pos
894+
~pkg
895+
~def_pos
896+
~current
897+
~current_pos
898+
~soft_included
899+
~current_package_assignment_kind
900+
~(ctx : package_strict_inclusion_context) =
901+
let (error_code, primary_msg, location_msg) =
902+
match ctx with
903+
| Ctx_require_package attribute_name ->
904+
( Error_code.(to_enum RequirePackageStrictInclusion),
905+
Printf.sprintf "Invalid %s" attribute_name,
906+
Printf.sprintf
907+
"This function is defined in package `%s` by this %s"
908+
current
909+
current_package_assignment_kind )
910+
| Ctx_package_expression ->
911+
( Error_code.(to_enum PackageExpressionStrictInclusion),
912+
"Invalid package expression",
913+
Printf.sprintf
914+
"This code is in package `%s` by %s"
915+
current
916+
current_package_assignment_kind )
917+
in
918+
let (pkg_label, soft_includes_label) =
919+
match ctx with
920+
| Ctx_require_package _ -> ("required", "required")
921+
| Ctx_package_expression -> ("checked", "checked")
922+
in
885923
let last_reason =
886924
if soft_included then
887925
( def_pos,
888926
Printf.sprintf
889-
"`%s` soft-includes the required package `%s`, so this requirement is not allowed"
927+
"`%s` soft-includes the %s package `%s`, so this %s is not allowed"
890928
current
891-
required )
929+
pkg_label
930+
pkg
931+
(match ctx with
932+
| Ctx_require_package _ -> "requirement"
933+
| Ctx_package_expression -> "check") )
892934
else
893935
( def_pos,
894936
Printf.sprintf
895-
"The required package `%s` must strictly include (i.e. cannot equal) `%s`"
896-
required
937+
"The %s package `%s` must strictly include (i.e. cannot equal) `%s`"
938+
soft_includes_label
939+
pkg
897940
current )
898941
in
899942
User_diagnostic.make_err
900-
Error_code.(to_enum RequirePackageStrictInclusion)
901-
(required_pos, Printf.sprintf "Invalid %s" attribute_name)
902-
[
903-
( Pos_or_decl.of_raw_pos current_pos,
904-
Printf.sprintf
905-
"This function is defined in package `%s` by this %s"
906-
current
907-
current_package_assignment_kind );
908-
last_reason;
909-
]
943+
error_code
944+
(pos, primary_msg)
945+
[(Pos_or_decl.of_raw_pos current_pos, location_msg); last_reason]
910946

911947
(* --------------------------------------------- *)
912948
let to_user_diagnostic t =
@@ -1025,14 +1061,33 @@ let to_user_diagnostic t =
10251061
soft_included;
10261062
current_package_assignment_kind;
10271063
} ->
1028-
require_package_strict_inclusion
1029-
required_pos
1030-
required
1031-
def_pos
1032-
current
1033-
current_pos
1034-
attribute_name
1035-
soft_included
1036-
current_package_assignment_kind
1064+
package_strict_inclusion
1065+
~pos:required_pos
1066+
~pkg:required
1067+
~def_pos
1068+
~current
1069+
~current_pos
1070+
~soft_included
1071+
~current_package_assignment_kind
1072+
~ctx:(Ctx_require_package attribute_name)
1073+
| Package_expression_strict_inclusion
1074+
{
1075+
pkg_pos;
1076+
pkg;
1077+
def_pos;
1078+
current;
1079+
current_pos;
1080+
soft_included;
1081+
current_package_assignment_kind;
1082+
} ->
1083+
package_strict_inclusion
1084+
~pos:pkg_pos
1085+
~pkg
1086+
~def_pos
1087+
~current
1088+
~current_pos
1089+
~soft_included
1090+
~current_package_assignment_kind
1091+
~ctx:Ctx_package_expression
10371092
in
10381093
f Explanation.empty

hphp/hack/src/typing/nast_check/nast_check_error.mli

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,5 +208,14 @@ type t =
208208
soft_included: bool;
209209
current_package_assignment_kind: string;
210210
}
211+
| Package_expression_strict_inclusion of {
212+
pkg_pos: Pos.t;
213+
pkg: string;
214+
def_pos: Pos_or_decl.t;
215+
current: string;
216+
current_pos: Pos.t;
217+
soft_included: bool;
218+
current_package_assignment_kind: string;
219+
}
211220

212221
val to_user_diagnostic : t -> (Pos.t, Pos_or_decl.t) User_diagnostic.t

0 commit comments

Comments
 (0)