Skip to content

Commit

Permalink
Specify interface for LibGit2 abstract types
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
timholy committed Jun 30, 2020
1 parent 9d71d37 commit b609aa4
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions stdlib/LibGit2/src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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{Cvoid},Ptr{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{Cvoid},Ptr{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{Cvoid}
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{Cvoid}
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),
Expand Down

0 comments on commit b609aa4

Please sign in to comment.