Skip to content

Commit

Permalink
Inline Decorator.t in Invalid decorator error
Browse files Browse the repository at this point in the history
Reviewed By: kbansal

Differential Revision: D31865846

fbshipit-source-id: d5d25be12f8d4a8bc60cc70cd5ea967e20e8783f
  • Loading branch information
grievejia authored and facebook-github-bot committed Oct 23, 2021
1 parent a6d22bd commit 604f726
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 86 deletions.
89 changes: 51 additions & 38 deletions source/analysis/analysisError.ml
Original file line number Diff line number Diff line change
Expand Up @@ -235,19 +235,32 @@ and tuple_concatenation_problem =
| UnpackingNonIterable of { annotation: Type.t }
[@@deriving compare, eq, sexp, show, hash]

type invalid_decoration = {
decorator: Decorator.t;
reason: invalid_decoration_reason;
}

and invalid_decoration_reason =
| CouldNotResolve
| CouldNotResolveArgument of Expression.t
| NonCallableDecoratorFactory of Type.t
| NonCallableDecorator of Type.t
| DecoratorFactoryFailedToApply of kind option
| ApplicationFailed of kind option
type invalid_decoration =
| CouldNotResolve of Expression.t
| CouldNotResolveArgument of {
name: Reference.t;
argument: Expression.t;
}
| NonCallableDecoratorFactory of {
name: Reference.t;
annotation: Type.t;
}
| NonCallableDecorator of {
name: Reference.t;
has_arguments: bool;
annotation: Type.t;
}
| DecoratorFactoryFailedToApply of {
name: Reference.t;
reason: kind option;
}
| ApplicationFailed of {
name: Reference.t;
has_arguments: bool;
reason: kind option;
}
| SetterNameMismatch of {
name: Reference.t;
actual: string;
expected: string;
}
Expand Down Expand Up @@ -1109,11 +1122,14 @@ let rec messages ~concise ~signature location kind =
variable
unconcatenatable;
])
| InvalidDecoration { decorator = { name; _ }; reason = CouldNotResolve } ->
let name = Node.value name |> Reference.sanitized |> Reference.show in
[Format.asprintf "Pyre was not able to infer the type of the decorator `%s`." name]
| InvalidDecoration { decorator = { name; _ }; reason = CouldNotResolveArgument argument } ->
let name = Node.value name |> Reference.sanitized |> Reference.show in
| InvalidDecoration (CouldNotResolve expression) ->
[
Format.asprintf
"Pyre was not able to infer the type of the decorator `%s`."
(show_sanitized_expression expression);
]
| InvalidDecoration (CouldNotResolveArgument { name; argument }) ->
let name = Reference.sanitized name |> Reference.show in
[
Format.asprintf
"Pyre was not able to infer the type of argument `%s` to decorator factory `%s`."
Expand All @@ -1122,46 +1138,43 @@ let rec messages ~concise ~signature location kind =
"This can usually be worked around by extracting your argument into a global variable and \
providing an explicit type annotation.";
]
| InvalidDecoration { decorator = { name; _ }; reason = NonCallableDecoratorFactory result } ->
let name = Node.value name |> Reference.sanitized |> Reference.show in
| InvalidDecoration (NonCallableDecoratorFactory { name; annotation }) ->
let name = Reference.sanitized name |> Reference.show in
[
Format.asprintf
"Decorator factory `%s` could not be called, because its type `%a` is not callable."
name
pp_type
result;
annotation;
]
| InvalidDecoration { decorator = { name; arguments }; reason = NonCallableDecorator result } ->
let name = Node.value name |> Reference.sanitized |> Reference.show in
let arguments = if Option.is_some arguments then "(...)" else "" in
| InvalidDecoration (NonCallableDecorator { name; has_arguments; annotation }) ->
let name = Reference.sanitized name |> Reference.show in
let arguments = if has_arguments then "(...)" else "" in
[
Format.asprintf
"Decorator `%s%s` could not be called, because its type `%a` is not callable."
name
arguments
pp_type
result;
annotation;
]
| InvalidDecoration
{ decorator = { name; _ }; reason = DecoratorFactoryFailedToApply inner_reason } -> (
let name = Node.value name |> Reference.sanitized |> Reference.show in
| InvalidDecoration (DecoratorFactoryFailedToApply { name; reason }) -> (
let name = Reference.sanitized name |> Reference.show in
let recurse = messages ~concise ~signature location in
match inner_reason >>| recurse >>= List.hd with
match reason >>| recurse >>= List.hd with
| Some inner_message ->
[Format.asprintf "While applying decorator factory `%s`: %s" name inner_message]
| None -> [Format.asprintf "Decorator factory `%s` failed to apply." name])
| InvalidDecoration { decorator = { name; arguments }; reason = ApplicationFailed inner_reason }
-> (
let name = Node.value name |> Reference.sanitized |> Reference.show in
let arguments = if Option.is_some arguments then "(...)" else "" in
| InvalidDecoration (ApplicationFailed { name; has_arguments; reason }) -> (
let name = Reference.sanitized name |> Reference.show in
let arguments = if has_arguments then "(...)" else "" in
let recurse = messages ~concise ~signature location in
match inner_reason >>| recurse >>= List.hd with
match reason >>| recurse >>= List.hd with
| Some inner_message ->
[Format.asprintf "While applying decorator `%s%s`: %s" name arguments inner_message]
| None -> [Format.asprintf "Decorator `%s%s` failed to apply." name arguments])
| InvalidDecoration { decorator = { name; _ }; reason = SetterNameMismatch { expected; actual } }
->
let name = Node.value name |> Reference.sanitized |> Reference.show in
| InvalidDecoration (SetterNameMismatch { name; expected; actual }) ->
let name = Reference.sanitized name |> Reference.show in
[
Format.asprintf
"Invalid property setter `%s`: `%s` does not match decorated method `%s`."
Expand Down Expand Up @@ -3573,8 +3586,8 @@ let suppress ~mode ~ignore_codes error =
| InconsistentOverride
{ override = StrengthenedPrecondition (Found { expected = Type.Variable _; _ }); _ } ->
true
| InvalidDecoration { reason = CouldNotResolve; _ }
| InvalidDecoration { reason = CouldNotResolveArgument _; _ } ->
| InvalidDecoration (CouldNotResolve _)
| InvalidDecoration (CouldNotResolveArgument _) ->
true
| InvalidTypeParameters
{ kind = AttributeResolution.IncorrectNumberOfParameters { actual = 0; _ }; _ } ->
Expand Down
37 changes: 25 additions & 12 deletions source/analysis/analysisError.mli
Original file line number Diff line number Diff line change
Expand Up @@ -226,23 +226,36 @@ and tuple_concatenation_problem =
| UnpackingNonIterable of { annotation: Type.t }
[@@deriving compare, eq, sexp, show, hash]

type invalid_decoration_reason =
| CouldNotResolve
| CouldNotResolveArgument of Expression.t
| NonCallableDecoratorFactory of Type.t
| NonCallableDecorator of Type.t
| DecoratorFactoryFailedToApply of kind option
| ApplicationFailed of kind option
type invalid_decoration =
| CouldNotResolve of Expression.t
| CouldNotResolveArgument of {
name: Reference.t;
argument: Expression.t;
}
| NonCallableDecoratorFactory of {
name: Reference.t;
annotation: Type.t;
}
| NonCallableDecorator of {
name: Reference.t;
has_arguments: bool;
annotation: Type.t;
}
| DecoratorFactoryFailedToApply of {
name: Reference.t;
reason: kind option;
}
| ApplicationFailed of {
name: Reference.t;
has_arguments: bool;
reason: kind option;
}
| SetterNameMismatch of {
name: Reference.t;
actual: string;
expected: string;
}

and invalid_decoration = {
decorator: Statement.Decorator.t;
reason: invalid_decoration_reason;
}

and kind =
| AnalysisFailure of analysis_failure
| ParserFailure of string
Expand Down
24 changes: 2 additions & 22 deletions source/analysis/test/analysisErrorTest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -801,28 +801,8 @@ let test_suppress _ =
assert_not_suppressed Source.Strict (missing_return Type.Any);
assert_not_suppressed Source.Strict (Error.AnalysisFailure (UnexpectedUndefinedType "int"));
assert_suppressed Source.Unsafe (missing_return Type.Top);
assert_not_suppressed
Source.Strict
(Error.InvalidDecoration
{
decorator =
{
Decorator.name = Reference.create "test" |> Node.create_with_default_location;
arguments = None;
};
reason = CouldNotResolve;
});
assert_suppressed
Source.Unsafe
(Error.InvalidDecoration
{
decorator =
{
Decorator.name = Reference.create "test" |> Node.create_with_default_location;
arguments = None;
};
reason = CouldNotResolve;
});
assert_not_suppressed Source.Strict (Error.InvalidDecoration (CouldNotResolve !"test"));
assert_suppressed Source.Unsafe (Error.InvalidDecoration (CouldNotResolve !"test"));

(* Should not be made *)
assert_not_suppressed Source.Unsafe (incompatible_return_type Type.integer Type.Any);
Expand Down
41 changes: 27 additions & 14 deletions source/analysis/typeCheck.ml
Original file line number Diff line number Diff line change
Expand Up @@ -883,12 +883,12 @@ module State (Context : Context) = struct
~location
~kind:
(Error.InvalidDecoration
{
decorator;
reason =
Error.SetterNameMismatch
{ actual = decorated_property_name; expected = Reference.last name };
})
(Error.SetterNameMismatch
{
name = decorator_name;
actual = decorated_property_name;
expected = Reference.last name;
}))
| _ -> errors
else
let { Resolved.errors = decorator_errors; _ } =
Expand Down Expand Up @@ -6644,13 +6644,15 @@ let emit_errors_on_exit (module Context : Context) ~errors_sofar ~resolution ()
else
index
in
let add_error ({ Decorator.name = { Node.location; _ }; arguments } as decorator) =
let add_error
({ Decorator.name = { Node.location; value = name }; arguments } as decorator)
=
let make_error reason =
let error =
Error.create
~location:(Location.with_module ~qualifier:Context.qualifier location)
~define:Context.define
~kind:(Error.InvalidDecoration { decorator; reason })
~kind:(Error.InvalidDecoration reason)
in
error :: errors
in
Expand All @@ -6668,23 +6670,34 @@ let emit_errors_on_exit (module Context : Context) ~errors_sofar ~resolution ()
reason >>| convert >>= List.hd >>| fun (_, kind) -> kind
in
match reason with
| CouldNotResolve -> make_error CouldNotResolve
| CouldNotResolve -> make_error (CouldNotResolve (Decorator.to_expression decorator))
| CouldNotResolveArgument { argument_index } ->
let add_error argument =
let argument, _ = Ast.Expression.Call.Argument.unpack argument in
make_error (CouldNotResolveArgument argument)
make_error (CouldNotResolveArgument { name; argument })
in
arguments
>>= (fun arguments -> List.nth arguments argument_index)
>>| add_error
|> Option.value ~default:errors
| NonCallableDecoratorFactory resolved ->
make_error (NonCallableDecoratorFactory resolved)
| NonCallableDecorator result -> make_error (NonCallableDecorator result)
make_error (NonCallableDecoratorFactory { name; annotation = resolved })
| NonCallableDecorator result ->
make_error
(NonCallableDecorator
{ name; has_arguments = Option.is_some arguments; annotation = result })
| FactorySignatureSelectionFailed { reason; callable } ->
make_error (DecoratorFactoryFailedToApply (extract_error ~reason ~callable))
make_error
(DecoratorFactoryFailedToApply
{ name; reason = extract_error ~reason ~callable })
| ApplicationFailed { reason; callable } ->
make_error (ApplicationFailed (extract_error ~reason ~callable))
make_error
(ApplicationFailed
{
name;
has_arguments = Option.is_some arguments;
reason = extract_error ~reason ~callable;
})
in

let { StatementDefine.Signature.decorators; _ } = signature in
Expand Down

0 comments on commit 604f726

Please sign in to comment.