Papierkorb / bindgen

Binding and wrapper generator for C/C++ libraries
GNU General Public License v3.0
179 stars 18 forks source link

Bindgen::Graph::Path edge cases #80

Closed HertzDevil closed 4 years ago

HertzDevil commented 4 years ago

I found a bunch of edge cases in Bindgen::Graph::Path while trying to figure out some namespace-related issues:

describe Bindgen::Graph::Path do
  describe "#lookup" do
    context "given a global path" do
      it "starts lookup from the root" do
        path("::Root::Right::D").lookup(a).should be(d)
        path("::Root::Root::Right::D").lookup(a).should_not be(d) # fails
      end
    end
  end
end

Global path lookup is wrong if the root name is repeated twice.

#              E
#             /
#   f1  -->  F
#           / \
# f2  -->  F   G
#         /     \
#        H       J
e = Bindgen::Graph::Namespace.new("E")
f1 = Bindgen::Graph::Namespace.new("F", e)
f2 = Bindgen::Graph::Namespace.new("F", f1)
g = Bindgen::Graph::Namespace.new("G", f1)
h = Bindgen::Graph::Namespace.new("H", f2)
j = Bindgen::Graph::Namespace.new("J", h)

# these all fail
path("F::G").lookup(f1).should be_nil
path("F::G").lookup(f2).should be_nil
path("F::G").lookup(g).should be_nil
path("F::G").lookup(h).should be_nil
path("F::G").lookup(j).should be_nil

Local path lookup doesn't handle shadowed namespaces properly. (Both Crystal and C++ do this.)

Bindgen::Graph::Path.from("::").last_part # ""

This is really confusing; no places outside Path use the empty string to refer to a top-level / root namespace.

I'll soon submit a refactor that fixes these edge cases.