Beispiel #1
0
 def _Parse(self, parts: pp.ParseResults):
     self.name = parts.get("vhdlType")
     range = parts.get("range")
     if range is not None:
         self.range = VhdlRange(range)
     else:
         self.range = None
Beispiel #2
0
 def _Parse(self, parts: pp.ParseResults):
     self.left = parts.get("left")
     self.right = parts.get("right")
     self.direction = str(parts.get("dir")).lower()
     if self.direction == "to":
         self.low = self.left
         self.high = self.right
     elif self.direction == "downto":
         self.low = self.right
         self.high = self.left
     else:
         raise Exception("Illegal range: {}".format(self.code))
Beispiel #3
0
 def _Parse(self, parts: pp.ParseResults):
     self.name = parts.get("name")
     if "generics" in parts:
         self.generics = [
             VhdlGenericDeclaration(gd) for gd in parts.get("generics")
         ]
     else:
         self.generics = []
     if "ports" in parts:
         self.ports = [
             VhdlPortDeclaration(pd) for pd in parts.get("ports")
             if pd.getName() == "port"
         ]
     else:
         self.ports = []
Beispiel #4
0
    def from_parsed(parsed: ParseResults):
        name = parsed['sourceName'].lower()

        if 'amount' in parsed:
            amt = parsed['amount']
            if amt == 'ALL': amount = 'all'
            else: amount = int(amt)
        else: amount = None

        # TODO: this is maybe dumb. Simplify ParsedArguments.from_parsed to just the naive version, and ParsedArgs.adapt_to_signature(Signature), or something?
        if name in sources:
            args, _, pre_errors = Arguments.from_parsed(
                parsed.get('args'), sources[name].signature)
        else:
            args, _, pre_errors = Arguments.from_parsed(parsed.get('args'))

        parsedSource = ParsedSource(name, args, amount)
        parsedSource.pre_errors.extend(pre_errors)
        return parsedSource
Beispiel #5
0
    def action(self, tokens: ParseResults) -> str:
        for param, value in tokens.get("params", []):
            if param.lower() == "title":
                prefix = f"> **{value}**\n"
                break
        else:
            prefix = ""

        text = self.markup.transformString("\n".join(
            [line.lstrip() for line in tokens.text.strip().splitlines()]))
        return prefix + "\n".join([f"> {line}" for line in text.splitlines()])
Beispiel #6
0
 def _Parse(self, parts: pp.ParseResults):
     self.name = parts.get("name")
     self.type = VhdlType(parts.get("type"))
     self.direction = parts.get("dir")
     self.default = None
     if parts.get("default") is not None:
         self.default = parts.get("default")[0]
     self.comment = None
     if parts.get("comment") is not None:
         self.comment = parts.get("comment").get("text")
Beispiel #7
0
    def check_function_semantics(self, line: str, position: int,
                                 tokens: ParseResults) -> ParseResults:
        """Raise an exception if the function used on the tokens is wrong.

        :raises: InvalidFunctionSemantic
        """
        concept = tokens.get(CONCEPT)
        if not self._namespace_dict or concept is None:
            return tokens

        namespace, name = concept[NAMESPACE], concept[NAME]

        if namespace in self.concept_parser.namespace_to_pattern:
            return tokens

        if self._allow_naked_names and namespace == DIRTY:  # Don't check dirty names in lenient mode
            return tokens

        valid_functions = set(
            itt.chain.from_iterable(
                belns_encodings.get(encoding, set())
                for encoding in self._namespace_dict[namespace][name]), )

        if not valid_functions:
            raise InvalidEntity(self.get_line_number(), line, position,
                                namespace, name)

        if tokens[FUNCTION] not in valid_functions:
            raise InvalidFunctionSemantic(
                line_number=self.get_line_number(),
                line=line,
                position=position,
                func=tokens[FUNCTION],
                namespace=namespace,
                name=name,
                allowed_functions=valid_functions,
            )

        return tokens
Beispiel #8
0
 def _prepare_args_completions(self, parsed_command: pp.ParseResults,
                               last_token) -> Iterable[Completion]:
     assert parsed_command is not None
     args_meta = self.meta.arguments.values()
     # are we expecting a sub command?
     if self.cmd.super_command:
         # We have a sub-command (supposedly)
         subcommand = parsed_command.get("__subcommand__")
         assert subcommand
         sub_meta = self.cmd.subcommand_metadata(subcommand)
         if not sub_meta:
             logging.debug("Parsing unknown sub-command failed!")
             return []
         # we did find the sub-command, yay!
         # In this case we chain the arguments from super and the
         # sub-command together
         args_meta = itertools.chain(args_meta, sub_meta.arguments.values())
     # Now let's see if we can figure which argument we are talking about
     args_meta = self._filter_arguments_by_prefix(last_token, args_meta)
     # Which arguments did we fully parse already? let's avoid printing them
     # in completions
     parsed_keys = parsed_command.asDict().get("kv", [])
     # We are either completing an argument name, argument value, or
     # positional value.
     # Dissect the last_token and figure what is the right completion
     parsed_token = TokenParse(last_token)
     if parsed_token.is_positional:
         # TODO: Handle positional argument completions too
         # To figure which positional we are in right now, we need to run the
         # same logic that figures if all required arguments has been
         # supplied and how many positionals have been processed and which
         # one is next.
         # This code is already in cmdbase.py run_interactive but needs to be
         # refactored to be reusable here.
         pass
     elif parsed_token.is_argument:
         argument_name = parsed_token.argument_name
         arg = self._find_argument_by_name(argument_name)
         if not arg or arg.choices in [False, None]:
             return []
         # TODO: Support dictionary keys/named tuples completion
         if parsed_token.is_dict:
             return []
         # We are completing a value, in this case, we need to get the last
         # meaninful piece of the token `x=[Tr` => `Tr`
         return [
             Completion(
                 text=str(choice),
                 start_position=-len(parsed_token.last_value),
             ) for choice in arg.choices if str(choice).lower().startswith(
                 parsed_token.last_value.lower())
         ]
     # We are completing arguments, or positionals.
     # TODO: We would like to only show positional choices if we exhaust all
     # required arguments. This will make it easier for the user to figure
     # that there are still required named arguments. After that point we
     # will show optional arguments and positionals as possible completions
     ret = [
         Completion(
             text=arg_meta.name + "=",
             start_position=-len(last_token),
             display_meta=self._get_arg_help(arg_meta),
         ) for arg_meta in args_meta if arg_meta.name not in parsed_keys
     ]
     return ret
Beispiel #9
0
    def partition_to_model(cls, presult: ParseResults) -> models.PartitionConfig:
        # Convert ParseResults from parsing a partitions config into a
        # model. This can throw a PartitionParseError
        mytype = presult.get("part_type", None)
        mysubtype = presult.get("p_subtype", None)

        if (
            (not mytype and not mysubtype)
            or mytype not in models.PartitionConfig.KNOWN_PARTITION_TYPES
            or (
                mysubtype is not None
                and mysubtype not in models.PartitionConfig.KNOWN_PARTITION_SUBTYPES
            )
        ):
            raise PartitionParseError(
                "partition_to_model Cannot init mode.PartitionConfig: "
                f"type {mytype} subtype {mysubtype}"
            )

        pc = models.PartitionConfig()

        pc.part_type = mytype
        pc.p_subtype = mysubtype

        def _strip_ticks(fields: Union[str, List[str]]) -> Union[str, List[str]]:
            if isinstance(fields, str):
                return fields.replace("`", "")
            return [_strip_ticks(f) for f in fields]

        if presult.get("invalid_partition_prefix"):
            raise PartitionParseError(
                f"Partition type {pc.part_type} cannot "
                "have invalid partition number prefix defined"
            )

        # set fields_or_expr, full_type
        if (
            pc.part_type == models.PartitionConfig.PTYPE_LIST
            or pc.part_type == models.PartitionConfig.PTYPE_RANGE
        ):
            pc.num_partitions = len(presult.get("part_defs", []))
            if pc.num_partitions == 0:
                raise PartitionParseError(
                    f"Partition type {pc.part_type} MUST have partitions defined"
                )
            pc.part_defs = _process_partition_definitions(presult.part_defs)
            if not pc.p_subtype:
                pc.full_type = pc.part_type
                pc.via_nested_expr = (
                    "via_nested_expr" in presult and "via_list" not in presult
                )
                pc.fields_or_expr = presult.p_expr.asList()

                if pc.via_nested_expr:
                    # strip backticks e.g. to_days(`date`) -> [to_days, [date]]
                    pc.fields_or_expr = _strip_ticks(pc.fields_or_expr)
            else:
                pc.full_type = f"{pc.part_type} {pc.p_subtype}"
                pc.fields_or_expr = presult.field_list.asList()
        elif pc.part_type == models.PartitionConfig.PTYPE_KEY:
            pc.full_type = (
                pc.part_type if not pc.p_subtype else f"{pc.p_subtype} {pc.part_type}"
            )
            pc.num_partitions = int(presult.get("num_partitions", 1))
            fl = presult.get("field_list", None)
            pc.fields_or_expr = fl.asList() if fl else []
            # This is the only place p_algo is valid. algorithm_for_key
            algo_result = presult.get("p_algo")
            if algo_result and len(algo_result.asList()) > 0:
                pc.algorithm_for_key = int(algo_result.asList()[0])
        elif pc.part_type == models.PartitionConfig.PTYPE_HASH:
            pc.full_type = (
                pc.part_type if not pc.p_subtype else f"{pc.p_subtype} {pc.part_type}"
            )
            pc.num_partitions = int(presult.get("num_partitions", 1))
            hexpr = presult.get("p_hash_expr", None)
            if not hexpr:
                raise PartitionParseError(
                    f"Partition type {pc.part_type} MUST have p_hash_expr defined"
                )
            pc.fields_or_expr = _strip_ticks(hexpr.asList())
        else:
            # unreachable since we checked for all part_types earlier.
            raise PartitionParseError(f"Unknown partition type {pc.part_type}")

        # We avoid escaping fields/expr in partitions with backticks since
        # its tricky to distinguish between a list of columns and an expression
        # e.g. unix_timestamp(ts) - ts could be escaped but unix_ts cannot.
        # Our parser will strip out backticks wherever possible. For nestedExpr
        # usecases, this is done via _strip_ticks instead.
        def _has_backticks(fields: Union[str, List[str]]) -> bool:
            if isinstance(fields, list):
                return any(_has_backticks(f) for f in fields)
            return "`" in fields if isinstance(fields, str) else False

        if _has_backticks(pc.fields_or_expr):
            raise PartitionParseError(
                f"field_or_expr cannot have backticks {pc.fields_or_expr}"
            )

        if len(pc.part_defs) > 0 and any(
            pd.pdef_name.upper() == "NULL" for pd in pc.part_defs
        ):
            # We will disallow this even if raw sql passed in as e.g.
            # PARTITION `null` VALUES IN ...
            raise PartitionParseError("Partition names may not be literal `null`")

        return pc
Beispiel #10
0
 def _Parse(self, parts: pp.ParseResults):
     self.library = parts.get("library")
     self.element = parts.get("element")
     self.object = parts.get("object")
Beispiel #11
0
 def _Parse(self, parts: pp.ParseResults):
     self.left = parts.get("left")
     self.right = parts.get("right")
     self.direction = str(parts.get("dir")).lower()
Beispiel #12
0
 def __init__(self, item: ParseResults):
     self.carrots = len(item.get('carrots', ''))
     self.explicitlyIndexed = ('index' in item)
     self.index = int(item['index']) if 'index' in item else None
     self.bang = item.get('bang', '') == '!'