From 166b9e649667341756efad1550333e558650077a Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Sat, 20 May 2017 09:24:00 -0400
Subject: [PATCH 22/22] FIXME: cleanups in client-side testing

---
 gcc/testsuite/gcc.dg/lsp/test.c  | 12 +++++++
 gcc/testsuite/gcc.dg/lsp/test.py | 76 +++++++++++++++++++++++++++++++++++++---
 2 files changed, 84 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/lsp/test.c

diff --git a/gcc/testsuite/gcc.dg/lsp/test.c b/gcc/testsuite/gcc.dg/lsp/test.c
new file mode 100644
index 0000000..bb80bd0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lsp/test.c
@@ -0,0 +1,12 @@
+/* */
+
+struct foo
+{
+  int color;
+  int shape;
+};
+
+int test (struct foo *ptr)
+{
+  ptr->
+}
diff --git a/gcc/testsuite/gcc.dg/lsp/test.py b/gcc/testsuite/gcc.dg/lsp/test.py
index b08d119..e8450c7 100644
--- a/gcc/testsuite/gcc.dg/lsp/test.py
+++ b/gcc/testsuite/gcc.dg/lsp/test.py
@@ -10,13 +10,57 @@ class Position:
         self.line = line
         self.character = character
 
+    def __repr__(self):
+        return 'Position(%r, %r)' % (self.line, self.character)
+
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__
+
     def to_json(self):
         return {'line': self.line, 'character': self.character}
 
+    @staticmethod
+    def from_json(js):
+        return Position(js['line'], js['character'])
+
+class Range:
+    def __init__(self, start, end):
+        self.start = start
+        self.end = end
+
+    def __repr__(self):
+        return 'Range(%r, %r)' % (self.start, self.end)
+
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__
+
+    @staticmethod
+    def from_json(js):
+        return Range(Position.from_json(js['start']),
+                     Position.from_json(js['end']))
+
+class Location:
+    def __init__(self, uri, range):
+        self.uri = uri
+        self.range = range
+
+    def __repr__(self):
+        return 'Location(%r, %r)' % (self.uri, self.range)
+
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__
+
+    @staticmethod
+    def from_json(js):
+        return Location(js['uri'], Range.from_json(js['range']))
+
 class TextDocumentIdentifier:
     def __init__(self, uri):
         self.uri = uri
 
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__
+
     def to_json(self):
         return {'uri': self.uri}
 
@@ -25,6 +69,13 @@ class TextDocumentPositionParams:
         self.textDocument = textDocument
         self.position = position
 
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__
+
+    def to_json(self):
+        return {"textDocument" : self.textDocument.to_json(),
+                "position" : self.position.to_json()}
+
 # A wrapper for making LSP calls against a server
 
 class LspProxy:
@@ -50,16 +101,33 @@ class LspProxy:
         return response.json()
 
     def goto_definition(self, textDocument, position):
+        params = TextDocumentPositionParams(textDocument, position)
         json_resp = self.post_request('textDocument/definition',
-                                      {"textDocument" : textDocument.to_json(),
-                                       "position" : position.to_json()})
+                                      params.to_json())
         print(json_resp)
+        # Expect either a Location or a list of Location
+        if isinstance(json_resp, list):
+            return [Location.from_json(item) for item in json_resp]
+        else:
+            return Location.from_json(json_resp)
 
 def main():
+    # This assumes that we're running this:
+    # (hardcoding the particular source file for now):
+    # ./xgcc -B. -c ../../src/gcc/testsuite/gcc.dg/lsp/test.c \
+    #    -flsp=4000 -fblt -wrapper gdb,--args
+
     url = "http://localhost:4000/jsonrpc"
     proxy = LspProxy(url)
-    print(proxy.goto_definition(TextDocumentIdentifier('test.c'),
-                                Position(9, 17)))
+    # Ask for the location of a usage of "struct foo"
+    result = proxy.goto_definition(TextDocumentIdentifier('test.c'),
+                                   Position(9, 17))
+
+    # We expect to get back the location of where "struct foo" is defined
+    print(result)
+    # FIXME: filename/uri (currently a particular relative location)
+    assert result == [Location(u'../../src/gcc/testsuite/gcc.dg/lsp/test.c',
+                               Range(Position(3, 1), Position(7, 1)))]
 
 if __name__ == "__main__":
     main()
-- 
1.8.5.3

