summaryrefslogtreecommitdiffstats
path: root/powerline/lint/markedjson/resolver.py
diff options
context:
space:
mode:
Diffstat (limited to 'powerline/lint/markedjson/resolver.py')
-rw-r--r--powerline/lint/markedjson/resolver.py131
1 files changed, 131 insertions, 0 deletions
diff --git a/powerline/lint/markedjson/resolver.py b/powerline/lint/markedjson/resolver.py
new file mode 100644
index 0000000..fa8ceaa
--- /dev/null
+++ b/powerline/lint/markedjson/resolver.py
@@ -0,0 +1,131 @@
+# vim:fileencoding=utf-8:noet
+from __future__ import (unicode_literals, division, absolute_import, print_function)
+
+import re
+
+from powerline.lint.markedjson.error import MarkedError
+from powerline.lint.markedjson import nodes
+
+
+class ResolverError(MarkedError):
+ pass
+
+
+class BaseResolver:
+ DEFAULT_SCALAR_TAG = 'tag:yaml.org,2002:str'
+ DEFAULT_SEQUENCE_TAG = 'tag:yaml.org,2002:seq'
+ DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map'
+
+ yaml_implicit_resolvers = {}
+ yaml_path_resolvers = {}
+
+ def __init__(self):
+ self.resolver_exact_paths = []
+ self.resolver_prefix_paths = []
+
+ @classmethod
+ def add_implicit_resolver(cls, tag, regexp, first):
+ if 'yaml_implicit_resolvers' not in cls.__dict__:
+ cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy()
+ if first is None:
+ first = [None]
+ for ch in first:
+ cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp))
+
+ def descend_resolver(self, current_node, current_index):
+ if not self.yaml_path_resolvers:
+ return
+ exact_paths = {}
+ prefix_paths = []
+ if current_node:
+ depth = len(self.resolver_prefix_paths)
+ for path, kind in self.resolver_prefix_paths[-1]:
+ if self.check_resolver_prefix(depth, path, kind, current_node, current_index):
+ if len(path) > depth:
+ prefix_paths.append((path, kind))
+ else:
+ exact_paths[kind] = self.yaml_path_resolvers[path, kind]
+ else:
+ for path, kind in self.yaml_path_resolvers:
+ if not path:
+ exact_paths[kind] = self.yaml_path_resolvers[path, kind]
+ else:
+ prefix_paths.append((path, kind))
+ self.resolver_exact_paths.append(exact_paths)
+ self.resolver_prefix_paths.append(prefix_paths)
+
+ def ascend_resolver(self):
+ if not self.yaml_path_resolvers:
+ return
+ self.resolver_exact_paths.pop()
+ self.resolver_prefix_paths.pop()
+
+ def check_resolver_prefix(self, depth, path, kind, current_node, current_index):
+ node_check, index_check = path[depth - 1]
+ if isinstance(node_check, str):
+ if current_node.tag != node_check:
+ return
+ elif node_check is not None:
+ if not isinstance(current_node, node_check):
+ return
+ if index_check is True and current_index is not None:
+ return
+ if ((index_check is False or index_check is None)
+ and current_index is None):
+ return
+ if isinstance(index_check, str):
+ if not (isinstance(current_index, nodes.ScalarNode) and index_check == current_index.value):
+ return
+ elif isinstance(index_check, int) and not isinstance(index_check, bool):
+ if index_check != current_index:
+ return
+ return True
+
+ def resolve(self, kind, value, implicit, mark=None):
+ if kind is nodes.ScalarNode and implicit[0]:
+ if value == '':
+ resolvers = self.yaml_implicit_resolvers.get('', [])
+ else:
+ resolvers = self.yaml_implicit_resolvers.get(value[0], [])
+ resolvers += self.yaml_implicit_resolvers.get(None, [])
+ for tag, regexp in resolvers:
+ if regexp.match(value):
+ return tag
+ else:
+ self.echoerr(
+ 'While resolving plain scalar', None,
+ 'expected floating-point value, integer, null or boolean, but got %r' % value,
+ mark
+ )
+ return self.DEFAULT_SCALAR_TAG
+ if kind is nodes.ScalarNode:
+ return self.DEFAULT_SCALAR_TAG
+ elif kind is nodes.SequenceNode:
+ return self.DEFAULT_SEQUENCE_TAG
+ elif kind is nodes.MappingNode:
+ return self.DEFAULT_MAPPING_TAG
+
+
+class Resolver(BaseResolver):
+ pass
+
+
+Resolver.add_implicit_resolver(
+ 'tag:yaml.org,2002:bool',
+ re.compile(r'''^(?:true|false)$''', re.X),
+ list('yYnNtTfFoO'))
+
+Resolver.add_implicit_resolver(
+ 'tag:yaml.org,2002:float',
+ re.compile(r'^-?(?:0|[1-9]\d*)(?=[.eE])(?:\.\d+)?(?:[eE][-+]?\d+)?$', re.X),
+ list('-0123456789'))
+
+Resolver.add_implicit_resolver(
+ 'tag:yaml.org,2002:int',
+ re.compile(r'^(?:0|-?[1-9]\d*)$', re.X),
+ list('-0123456789'))
+
+Resolver.add_implicit_resolver(
+ 'tag:yaml.org,2002:null',
+ re.compile(r'^null$', re.X),
+ ['n'])