From 66dcf1fcaa41c8bab807558cae5138195808dd9a Mon Sep 17 00:00:00 2001 From: Anthony Johnson Date: Thu, 25 Feb 2016 14:35:09 -0800 Subject: [PATCH 1/4] Add resolution to spec identifiers using docfx references This uses the docfx output references to resolve the spec identifier to a human friendly name. The linking still requires full reference resolution however. Refs #58 --- autoapi/mappers/dotnet.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/autoapi/mappers/dotnet.py b/autoapi/mappers/dotnet.py index d4628cf..9050d5c 100644 --- a/autoapi/mappers/dotnet.py +++ b/autoapi/mappers/dotnet.py @@ -112,8 +112,10 @@ class DotNetSphinxMapper(SphinxMapperBase): def map(self, options=None, **kwargs): '''Trigger find of serialized sources and build objects''' for path, data in self.paths.items(): + references = data['references'] for item in data['items']: - for obj in self.create_class(item, options): + for obj in self.create_class(item, options, + references=references): self.add_object(obj) self.organize_objects() @@ -144,7 +146,7 @@ class DotNetSphinxMapper(SphinxMapperBase): self.app.warn('Unknown type: %s' % data) else: obj = cls(data, jinja_env=self.jinja_env, options=options, - url_root=self.url_root) + url_root=self.url_root, **kwargs) # Append child objects # TODO this should recurse in the case we're getting back more @@ -235,11 +237,18 @@ class DotNetSphinxMapper(SphinxMapperBase): class DotNetPythonMapper(PythonMapperBase): - '''Base .NET object representation''' + """Base .NET object representation + + :param references: object reference list from docfx + :type references: list of dict objects + """ language = 'dotnet' def __init__(self, obj, **kwargs): + self.references = dict((obj.get('uid'), obj) + for obj in kwargs.pop('references', []) + if 'uid' in obj) super(DotNetPythonMapper, self).__init__(obj, **kwargs) # Always exist @@ -271,13 +280,15 @@ class DotNetPythonMapper(PythonMapperBase): if 'id' in param: self.parameters.append({ 'name': param.get('id'), - 'type': param.get('type'), + 'type': self.resolve_spec_identifier(param.get('type')), 'desc': self.transform_doc_comments( param.get('description', '')) }) self.returns = {} - self.returns['type'] = syntax.get('return', {}).get('type') + self.returns['type'] = self.resolve_spec_identifier( + syntax.get('return', {}).get('type') + ) self.returns['description'] = self.transform_doc_comments( syntax.get('return', {}).get('description')) @@ -419,6 +430,15 @@ class DotNetPythonMapper(PythonMapperBase): pass return text + def resolve_spec_identifier(self, obj_name): + """Find reference name based on spec identifier + + Spec identifiers are used in parameter and return type definitions, but + should be a user-friendly version instead. Use docfx ``references`` + lookup mapping for resolution. + """ + return self.references.get(obj_name, {}).get('fullName', obj_name) + class DotNetNamespace(DotNetPythonMapper): type = 'namespace' From b6b1bb0f8bbb51e772684a045dac647f38052d84 Mon Sep 17 00:00:00 2001 From: Anthony Johnson Date: Fri, 26 Feb 2016 15:13:05 -0800 Subject: [PATCH 2/4] Fix missing key issue --- autoapi/mappers/dotnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoapi/mappers/dotnet.py b/autoapi/mappers/dotnet.py index 9050d5c..337be7d 100644 --- a/autoapi/mappers/dotnet.py +++ b/autoapi/mappers/dotnet.py @@ -112,7 +112,7 @@ class DotNetSphinxMapper(SphinxMapperBase): def map(self, options=None, **kwargs): '''Trigger find of serialized sources and build objects''' for path, data in self.paths.items(): - references = data['references'] + references = data.get('references', []) for item in data['items']: for obj in self.create_class(item, options, references=references): From 49af2b252a8b1f62708763a10e4b89cd6d2a1e29 Mon Sep 17 00:00:00 2001 From: Anthony Johnson Date: Fri, 4 Mar 2016 10:05:21 -0800 Subject: [PATCH 3/4] Update reference resolver for nested resolution --- autoapi/mappers/dotnet.py | 37 ++++++++++++++++++++++-- autoapi/templates/dotnet/base_detail.rst | 3 ++ autoapi/templates/dotnet/base_embed.rst | 2 +- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/autoapi/mappers/dotnet.py b/autoapi/mappers/dotnet.py index 337be7d..794645f 100644 --- a/autoapi/mappers/dotnet.py +++ b/autoapi/mappers/dotnet.py @@ -253,7 +253,8 @@ class DotNetPythonMapper(PythonMapperBase): # Always exist self.id = obj.get('uid', obj.get('id')) - self.name = obj.get('fullName', self.id) + self.definition = obj.get('definition', self.id) + self.name = obj.get('fullName', self.definition) # Optional self.fullname = obj.get('fullName') @@ -436,8 +437,40 @@ class DotNetPythonMapper(PythonMapperBase): Spec identifiers are used in parameter and return type definitions, but should be a user-friendly version instead. Use docfx ``references`` lookup mapping for resolution. + + If the spec identifier reference has a ``spec.csharp`` key, this implies + a compound reference that should be linked in a special way. Resolve to + a nested reference, with the corrected nodes. + + .. note:: + This uses a special format that is interpreted by the domain for + parameter type and return type fields. + + :param obj_name: spec identifier to resolve to a correct reference + :returns: resolved string with one or more references + :rtype: str """ - return self.references.get(obj_name, {}).get('fullName', obj_name) + ref = self.references.get(obj_name) + if ref is None: + return obj_name + + resolved = ref.get('fullName', obj_name) + spec = ref.get('spec.csharp', []) + parts = [] + for part in spec: + if part.get('name') == '<': + parts.append('{') + elif part.get('name') == '>': + parts.append('}') + elif 'fullName' in part and 'uid' in part: + parts.append('{fullName}<{uid}>'.format(**part)) + elif 'uid' in part: + parts.append(part['uid']) + elif 'fullName': + parts.append(part['fullName']) + if parts: + resolved = ''.join(parts) + return resolved class DotNetNamespace(DotNetPythonMapper): diff --git a/autoapi/templates/dotnet/base_detail.rst b/autoapi/templates/dotnet/base_detail.rst index fb990da..814e2d6 100644 --- a/autoapi/templates/dotnet/base_detail.rst +++ b/autoapi/templates/dotnet/base_detail.rst @@ -60,6 +60,9 @@ GitHub {% block content %} +.. dn:{{ obj.ref_type }}:: {{ obj.definition }} + :hidden: + .. dn:{{ obj.ref_type }}:: {{ obj.name }} {%- for item_type in obj.item_map.keys() %} diff --git a/autoapi/templates/dotnet/base_embed.rst b/autoapi/templates/dotnet/base_embed.rst index e296241..a59205a 100644 --- a/autoapi/templates/dotnet/base_embed.rst +++ b/autoapi/templates/dotnet/base_embed.rst @@ -7,7 +7,7 @@ {% endif %} {%- for param in obj.parameters %} - + {% if param.desc %} :param {{ param.name }}: {{ param.desc|indent(8) }} {% endif %} From 4fef4ab2c1bdc966b3d36b360aecbb57cee01e41 Mon Sep 17 00:00:00 2001 From: Anthony Johnson Date: Fri, 4 Mar 2016 10:49:01 -0800 Subject: [PATCH 4/4] Complete statement --- autoapi/mappers/dotnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoapi/mappers/dotnet.py b/autoapi/mappers/dotnet.py index 794645f..373d1d5 100644 --- a/autoapi/mappers/dotnet.py +++ b/autoapi/mappers/dotnet.py @@ -466,7 +466,7 @@ class DotNetPythonMapper(PythonMapperBase): parts.append('{fullName}<{uid}>'.format(**part)) elif 'uid' in part: parts.append(part['uid']) - elif 'fullName': + elif 'fullName' in part: parts.append(part['fullName']) if parts: resolved = ''.join(parts)