Permalink
Browse files

Move checks that can be parse-checks into the parser

Summary:
The check for sealed final already existed and wasn't needed in decl.

The check for sealed enum doesn't really need to be in decl and should just be a straight up parse error.

Reviewed By: vladima

Differential Revision: D13151408

fbshipit-source-id: 5441a5b1c8de2a64283990f3e3181e63524af1ae
  • Loading branch information...
David Snider authored and hhvm-bot committed Nov 22, 2018
1 parent 0f3e12d commit be0bc03d7e2772f50e2e5896a4930cd83cfdc5aa
@@ -494,23 +494,13 @@ and get_sealed_whitelist c =
match Attrs.find SN.UserAttributes.uaSealed c.sc_user_attributes with
| None -> None
| Some {ua_params = params; _} ->
begin match c.sc_kind with
| Ast.Cenum ->
let pos = fst c.sc_name in
let kind = String.capitalize (Ast.string_of_class_kind c.sc_kind) in
Errors.unsealable pos kind;
None
| Ast.Cabstract | Ast.Cinterface | Ast.Cnormal | Ast.Ctrait ->
let p, name = c.sc_name in
if c.sc_final then Errors.sealed_final p name;
let add_class_name names param =
match param with
| _, Class_const ((_, CI cls), (_, name))
when name = SN.Members.mClass ->
SSet.add (get_instantiated_sid_name cls) names
| _ -> names in
Some (List.fold_left params ~f:add_class_name ~init:SSet.empty)
end
let add_class_name names param =
match param with
| _, Class_const ((_, CI cls), (_, name))
when name = SN.Members.mClass ->
SSet.add (get_instantiated_sid_name cls) names
| _ -> names in
Some (List.fold_left params ~f:add_class_name ~init:SSet.empty)
and get_implements env ht =
let _r, (_p, c), paraml = Decl_utils.unwrap_class_type ht in
@@ -472,13 +472,13 @@ module Typing = struct
| DeclOverrideMissingHint
| InvalidConditionallyReactiveCall
| ExtendSealed
| SealedFinal
| SealedFinalDEPRECATED
| ComparisonInvalidTypes
| OptionVoidDEPRECATED
| MutableInNonreactiveContext
| InvalidArgumentOfRxMutableFunction
| LetVarImmutabilityViolation
| Unsealable
| UnsealableDEPRECATED
| ReturnVoidToRxMismatch
| ReturnsVoidToRxAsNonExpressionStatement
| NonawaitedAwaitableInReactiveContext
@@ -2281,13 +2281,6 @@ let extend_ppl
parent_pos, "Declaration is here";
]
let sealed_final pos name =
let name = (strip_ns name) in
add (Typing.err_code Typing.SealedFinal) pos ("Sealed class "^name^" cannot be marked final")
let unsealable pos kind =
add (Typing.err_code Typing.Unsealable) pos (kind^" cannot be sealed")
let read_before_write (pos, v) =
add (Typing.err_code Typing.ReadBeforeWrite) pos (
sl[
@@ -233,8 +233,6 @@ module type S = sig
val extend_final : Pos.t -> Pos.t -> string -> unit
val extend_sealed : Pos.t -> Pos.t -> string -> string -> string -> unit
val extend_ppl : Pos.t -> string -> bool -> Pos.t -> string -> string -> string -> unit
val sealed_final : Pos.t -> string -> unit
val unsealable : Pos.t -> string -> unit
val read_before_write : Pos.t * string -> unit
val interface_final : Pos.t -> unit
val trait_final : Pos.t -> unit
@@ -2517,6 +2517,9 @@ let class_reified_param_errors node parents errors =
:: errors else errors
| _ -> errors
let attr_spec_contains_sealed node =
attribute_specification_contains node SN.UserAttributes.uaSealed
let classish_errors env node parents namespace_name names errors =
match syntax node with
| ClassishDeclaration cd ->
@@ -2557,15 +2560,7 @@ let classish_errors env node parents namespace_name names errors =
| _ -> false in
let classish_is_sealed =
match cd.classish_attribute.syntax with
| AttributeSpecification { attribute_specification_attributes = attrs; _ } ->
let attrs = syntax_to_list_no_separators attrs in
List.exists attrs (fun e ->
match syntax e with
| ConstructorCall {constructor_call_type; _ } ->
text constructor_call_type = SN.UserAttributes.uaSealed
| _ -> false)
| _ -> false in
attr_spec_contains_sealed cd.classish_attribute in
(* Given a ClassishDeclaration node, test whether or not length of
* extends_list is appropriate for the classish_keyword. *)
@@ -3180,7 +3175,7 @@ let mixed_namespace_errors env node parents namespace_type errors =
errors
| _ -> errors
let enum_errors node errors =
let enumerator_errors node errors =
match syntax node with
| Enumerator { enumerator_name = name; enumerator_value = value; _} ->
let errors = if String.lowercase @@ text name = "class" then
@@ -3190,6 +3185,22 @@ let enum_errors node errors =
errors
| _ -> errors
let enum_decl_errors node errors =
match syntax node with
EnumDeclaration
{ enum_attribute_spec = attrs
(*
; enum_name = name
; enum_base = base
; enum_type = constr
; enum_enumerators = enums
*)
; _ } ->
if attr_spec_contains_sealed attrs then
make_error_from_node node SyntaxError.sealed_enum :: errors
else errors
| _ -> errors
let does_binop_create_write_on_left = function
| Some (TokenKind.Equal
| TokenKind.BarEqual
@@ -3521,8 +3532,11 @@ let find_syntax_errors env =
let errors = class_property_visibility_errors env node parents errors in
let errors = class_reified_param_errors node parents errors in
trait_require_clauses, names, errors
| EnumDeclaration _ ->
let errors = enum_decl_errors node errors in
trait_require_clauses, names, errors
| Enumerator _ ->
let errors = enum_errors node errors in
let errors = enumerator_errors node errors in
trait_require_clauses, names, errors
| PostfixUnaryExpression _
| BinaryExpression _
@@ -452,6 +452,7 @@ let for_with_as_expression =
let sealed_val_not_classname = "Values in sealed whitelist must be classname constants."
let sealed_final = "Classes cannot be both final and sealed."
let sealed_enum = "Enums cannot be sealed."
let interface_implements =
"Interfaces may not implement other interfaces or classes"
@@ -259,6 +259,7 @@ val missing_double_quote: string
val for_with_as_expression: string
val sealed_val_not_classname: string
val sealed_final: string
val sealed_enum: string
val interface_implements: string
val memoize_on_lambda: string
val memoize_lsb_on_non_static: string
@@ -466,13 +466,13 @@ CannotReturnBorrowedValueAsImmutable = 4235
DeclOverrideMissingHint = 4236
InvalidConditionallyReactiveCall = 4237
ExtendSealed = 4238
SealedFinal = 4239
SealedFinalDEPRECATED = 4239
ComparisonInvalidTypes = 4240
OptionVoidDEPRECATED = 4241
MutableInNonreactiveContext = 4242
InvalidArgumentOfRxMutableFunction = 4243
LetVarImmutabilityViolation = 4244
Unsealable = 4245
UnsealableDEPRECATED = 4245
ReturnVoidToRxMismatch = 4246
ReturnsVoidToRxAsNonExpressionStatement = 4247
NonawaitedAwaitableInReactiveContext = 4248

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.
@@ -0,0 +1,4 @@
<?hh
<<__Sealed(SomeOtherClass::class)>>
enum SomeSealedEnum: int {}
@@ -0,0 +1 @@
Fatal error: Enums cannot be sealed. in %s/hphp/test/slow/sealed/sealed_classes17.php on line 4

0 comments on commit be0bc03

Please sign in to comment.