From 13fd24aaf547fc4f6db6994a50484100c133f8af Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sat, 27 Jun 2020 07:14:20 -0500 Subject: [PATCH] Specify interface for LibGit2 abstract types This improves inference results for a number LibGit2 operations, and reduces invalidations from methods (notably, `peel`) that operate on the values extracted from these fields. --- stdlib/LibGit2/src/types.jl | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/stdlib/LibGit2/src/types.jl b/stdlib/LibGit2/src/types.jl index 6276544100888..70c2c3e037157 100644 --- a/stdlib/LibGit2/src/types.jl +++ b/stdlib/LibGit2/src/types.jl @@ -966,11 +966,43 @@ function split_cfg_entry(ce::ConfigEntry) end # Abstract object types + +""" + AbstractGitObject + +`AbstractGitObject`s must obey the following interface: +- `obj.owner`, if present, must be a `Union{Nothing,GitRepo,GitTree}` +- `obj.ptr`, if present, must be a `Union{Ptr{Nothing},SignatureStruct}` +""" abstract type AbstractGitObject end + +function Base.getproperty(obj::AbstractGitObject, name::Symbol) + if name === :owner + return getfield(obj, :owner)::Union{Nothing,GitRepo,GitTree} + elseif name === :ptr + return getfield(obj, :ptr)::Union{Ptr{Nothing},SignatureStruct} + else + return getfield(obj, name) + end +end + Base.isempty(obj::AbstractGitObject) = (obj.ptr == C_NULL) +# `GitObject`s must obey the following interface: +# - `obj.owner` must be a `GitRepo` +# - `obj.ptr` must be a Ptr{Nothing} abstract type GitObject <: AbstractGitObject end +function Base.getproperty(obj::GitObject, name::Symbol) + if name === :owner + return getfield(obj, :owner)::GitRepo + elseif name === :ptr + return getfield(obj, :ptr)::Ptr{Nothing} + else + return getfield(obj, name) + end +end + for (typ, owntyp, sup, cname) in [ (:GitRepo, nothing, :AbstractGitObject, :git_repository), (:GitConfig, :(Union{GitRepo, Nothing}), :AbstractGitObject, :git_config),