Repository: mandiant/capa
File: capa/engine.py (Python)

Code before:
        if hasattr(self, "children"):
            for child in self.children:
                assert isinstance(child, (Statement, Feature))
                yield child

    def replace_child(self, existing, new):
        if hasattr(self, "child"):
            # this really confuses mypy because the property may not exist
            # since its defined in the subclasses.
            if self.child is existing:  # type: ignore
                self.child = new

        if hasattr(self, "children"):
            children = self.children
            for i, child in enumerate(children):
                if child is existing:
                    children[i] = new

    def get_all_features(self) -> Set[Feature]:
        """
        recursively extracts all feature statements from a given rule statement.

        returns:
            set: A set of all feature statements contained within the given feature statement.
        """
        feature_set: set = set()

        for child in self.get_children():
            if isinstance(child, Statement):
                feature_set.update(child.get_all_features())
            else:
                feature_set.add(child)
        return feature_set


class And(Statement):
    """
    match if all of the children evaluate to True.

    the order of evaluation is dictated by the property
    `And.children` (type: List[Statement|Feature]).
    a query optimizer may safely manipulate the order of these children.
    """

    def __init__(self, children, description=None):
        super().__init__(description=description)
        self.children = children

    def evaluate(self, ctx, short_circuit=True):
        capa.perf.counters["evaluate.feature"] += 1
        capa.perf.counters["evaluate.feature.and"] += 1

Review comment (suggestion):
```suggestion
        feature_set: Set[Feature] = set()
```

Code after:
        if hasattr(self, "children"):
            for child in self.children:
                assert isinstance(child, (Statement, Feature))
                yield child

    def replace_child(self, existing, new):
        if hasattr(self, "child"):
            # this really confuses mypy because the property may not exist
            # since its defined in the subclasses.
            if self.child is existing:  # type: ignore
                self.child = new

        if hasattr(self, "children"):
            children = self.children
            for i, child in enumerate(children):
                if child is existing:
                    children[i] = new


class And(Statement):
    """
    match if all of the children evaluate to True.

    the order of evaluation is dictated by the property
    `And.children` (type: List[Statement|Feature]).
    a query optimizer may safely manipulate the order of these children.
    """

    def __init__(self, children, description=None):
        super().__init__(description=description)
        self.children = children

    def evaluate(self, ctx, short_circuit=True):
        capa.perf.counters["evaluate.feature"] += 1
        capa.perf.counters["evaluate.feature.and"] += 1

        if short_circuit:
            results = []
            for child in self.children:
                result = child.evaluate(ctx, short_circuit=short_circuit)
                results.append(result)
                if not result:
                    # short circuit
                    return Result(False, self, results)

            return Result(True, self, results)
        else:
            results = [child.evaluate(ctx, short_circuit=short_circuit) for child in self.children]
            success = all(results)
            return Result(success, self, results)