namespace.py
Go to the documentation of this file.
1 """
2 GTSAM Copyright 2010-2020, Georgia Tech Research Corporation,
3 Atlanta, Georgia 30332-0415
4 All Rights Reserved
5 
6 See LICENSE for the license information
7 
8 Classes and rules to parse a namespace.
9 
10 Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert
11 """
12 
13 # pylint: disable=unnecessary-lambda, expression-not-assigned
14 
15 from typing import List, Union
16 
17 from pyparsing import Forward, ParseResults, ZeroOrMore
18 
19 from .classes import Class, collect_namespaces
20 from .declaration import ForwardDeclaration, Include
21 from .enum import Enum
22 from .function import GlobalFunction
23 from .template import TypedefTemplateInstantiation
24 from .tokens import IDENT, LBRACE, NAMESPACE, RBRACE
25 from .type import Typename
26 from .variable import Variable
27 
28 
29 def find_sub_namespace(namespace: "Namespace",
30  str_namespaces: List["Namespace"]) -> list:
31  """
32  Get the namespaces nested under `namespace`, filtered by a list of namespace strings.
33 
34  Args:
35  namespace: The top-level namespace under which to find sub-namespaces.
36  str_namespaces: The list of namespace strings to filter against.
37  """
38  if not str_namespaces:
39  return [namespace]
40 
41  sub_namespaces = (ns for ns in namespace.content
42  if isinstance(ns, Namespace))
43 
44  found_namespaces = [
45  ns for ns in sub_namespaces if ns.name == str_namespaces[0]
46  ]
47  if not found_namespaces:
48  return []
49 
50  res = []
51  for found_namespace in found_namespaces:
52  ns = find_sub_namespace(found_namespace, str_namespaces[1:])
53  if ns:
54  res += ns
55  return res
56 
57 
58 class Namespace:
59  """Rule for parsing a namespace in the interface file."""
60 
61  rule = Forward()
62  rule << (
63  NAMESPACE #
64  + IDENT("name") #
65  + LBRACE #
66  + ZeroOrMore( # BR
67  ForwardDeclaration.rule #
68  ^ Include.rule #
69  ^ Class.rule #
70  ^ TypedefTemplateInstantiation.rule #
71  ^ GlobalFunction.rule #
72  ^ Enum.rule #
73  ^ Variable.rule #
74  ^ rule #
75  )("content") # BR
76  + RBRACE #
77  ).setParseAction(lambda t: Namespace.from_parse_result(t))
78 
79  def __init__(self, name: str, content: ZeroOrMore, parent=''):
80  self.name = name
81  self.content = content
82  self.parent = parent
83  for child in self.content:
84  child.parent = self
85 
86  @staticmethod
87  def from_parse_result(t: ParseResults):
88  """Return the result of parsing."""
89  if t.content:
90  content = t.content.asList()
91  else:
92  content = []
93  return Namespace(t.name, content)
94 
96  self, typename: Typename) -> Union[Class, GlobalFunction]:
97  """
98  Find the Class or GlobalFunction object given its typename.
99  We have to traverse the tree of namespaces.
100  """
101  found_namespaces = find_sub_namespace(self, typename.namespaces)
102  res = []
103  for namespace in found_namespaces:
104  classes_and_funcs = (c for c in namespace.content
105  if isinstance(c, (Class, GlobalFunction)))
106  res += [c for c in classes_and_funcs if c.name == typename.name]
107  if not res:
108  raise ValueError("Cannot find class {} in module!".format(
109  typename.name))
110  elif len(res) > 1:
111  raise ValueError(
112  "Found more than one classes {} in module!".format(
113  typename.name))
114  else:
115  return res[0]
116 
117  def top_level(self) -> "Namespace":
118  """Return the top leve namespace."""
119  if self.name == '' or self.parent == '':
120  return self
121  else:
122  return self.parent.top_level()
123 
124  def __repr__(self) -> str:
125  return "Namespace: {}\n\t{}".format(self.name, self.content)
126 
127  def full_namespaces(self) -> List["Namespace"]:
128  """Get the full namespace list."""
129  ancestors = collect_namespaces(self)
130  if self.name:
131  ancestors.append(self.name)
132  return ancestors
bool isinstance(handle obj)
Definition: pytypes.h:384
size_t len(handle h)
Definition: pytypes.h:1514


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:43:02