src/main/java/com/bazaarvoice/jless/ast/node/ScopeNode.java
private void setAdditionVisitor() {
        setAdditionVisitor(new InclusiveNodeVisitor() {
            /**
             * Add parameter set as a child for printing input, but also add each defined value to the variable map.
             */
            @Override
            public boolean add(ParametersNode node) {
                for (VariableDefinitionNode variable : NodeTreeUtils.getChildren(node, VariableDefinitionNode.class)) {
                    _parameterDefinitions.add(variable);
                    add(variable);
                }
                return super.add(node);
            }

            /**
             * Store the rule set's scope by selector group
             */
            @Override
            public boolean add(RuleSetNode node) {
                SelectorGroupNode selectorGroup = NodeTreeUtils.getFirstChild(node, SelectorGroupNode.class);
                for (SelectorNode selectorNode : NodeTreeUtils.getChildren(selectorGroup, SelectorNode.class)) {
                    StringBuilder sb = new StringBuilder();
                    for (Node selectorChild : selectorNode.getChildren()) {
                        sb.append(selectorChild.toString());
                    }
                    String selector = sb.toString();
                    // Mixins lock on first definition
                    if (!_selectorToRuleSetMap.containsKey(selector)) {
                        _selectorToRuleSetMap.put(selector, node);
                    }
                }
                return super.add(node);
            }

            /**
             * Absorb all children of the given scope. This assumes that cloning is not necessary.
             */
            @Override
            public boolean add(ScopeNode node) {
                NodeTreeUtils.moveChildren(node, ScopeNode.this);
                return false; // Don't add the original scope itself
            }

            /**
             * Store variable definitions in a map by name
             */
            @Override
            public boolean add(VariableDefinitionNode node) {
                String name = node.getName();
                // "Variables" lock on first definition
                if (!_variableNameToValueMap.containsKey(name)) {
                    _variableNameToValueMap.put(name, NodeTreeUtils.getFirstChild(node, ExpressionGroupNode.class));
                }
                return super.add(node);
            }

            /**
             * Store property nodes by name. If there are multiple properties for a given name, only retain the last one.
             */
            @Override
            public boolean add(PropertyNode node) {
                String name = node.getName();

                // If this is the IE-specific "filter" property, always add it
                if (name.equals(FILTER_PROPERTY)) {
                    return super.add(node);
                }

                // If the value of this property node is a vendor-specific keyword, always add it
                if (node.getChildren().get(0).toString().startsWith("-")) {
                    return super.add(node);
                }

                // Check if this property has been seen before
                if (_propertyNameToNodeMap.containsKey(name)) {
                    PropertyNode oldPropertyNode = _propertyNameToNodeMap.get(name);
                    int oldPropertyIndex = getChildren().indexOf(oldPropertyNode);

                    if (oldPropertyNode.isVisible()) {
                        // Hide the unneeded property
                        oldPropertyNode.setVisible(false);

                        // Attempt to hide one surrounding white space node
                        if (!hideWhiteSpaceNode(oldPropertyIndex - 1)) {
                            hideWhiteSpaceNode(oldPropertyIndex + 1);
                        }
                    }
                }

                // Store the property as the latest for this name
                _propertyNameToNodeMap.put(name, node);

                return super.add(node);
            }
        });
    }
private void setAdditionVisitor() {
        setAdditionVisitor(new InclusiveNodeVisitor() {
            /**
             * Add parameter set as a child for printing input, but also add each defined value to the variable map.
             */
            @Override
            public boolean add(ParametersNode node) {
                for (VariableDefinitionNode variable : NodeTreeUtils.getChildren(node, VariableDefinitionNode.class)) {
                    _parameterDefinitions.add(variable);
                    add(variable);
                }
                return super.add(node);
            }

            /**
             * Store the rule set's scope by selector group
             */
            @Override
            public boolean add(RuleSetNode node) {
                SelectorGroupNode selectorGroup = NodeTreeUtils.getFirstChild(node, SelectorGroupNode.class);
                for (SelectorNode selectorNode : NodeTreeUtils.getChildren(selectorGroup, SelectorNode.class)) {
                    StringBuilder sb = new StringBuilder();
                    for (Node selectorChild : selectorNode.getChildren()) {
                        sb.append(selectorChild.toString());
                    }
                    String selector = sb.toString();
                    // Mixins lock on first definition
                    if (!_selectorToRuleSetMap.containsKey(selector)) {
                        _selectorToRuleSetMap.put(selector, node);
                    }
                }
                return super.add(node);
            }

            /**
             * Absorb all children of the given scope. This assumes that cloning is not necessary.
             */
            @Override
            public boolean add(ScopeNode node) {
                NodeTreeUtils.moveChildren(node, ScopeNode.this);
                return false; // Don't add the original scope itself
            }

            /**
             * Store variable definitions in a map by name
             */
            @Override
            public boolean add(VariableDefinitionNode node) {
                String name = node.getName();
                // "Variables" lock on first definition
                if (!_variableNameToValueMap.containsKey(name)) {
                    _variableNameToValueMap.put(name, NodeTreeUtils.getFirstChild(node, ExpressionGroupNode.class));
                }
                return super.add(node);
            }

            /**
             * Store property nodes by name. If there are multiple properties for a given name, only retain the last one.
             */
            @Override
            public boolean add(PropertyNode node) {
                String name = node.getName();

                // If this is the IE-specific "filter" property, always add it
                if (name.equals(FILTER_PROPERTY)) {
                    return super.add(node);
                }

                // If the value of this property node is a vendor-specific keyword, always add it
                if (node.getChildren().get(0).toString().startsWith("-")) {
                    return super.add(node);
                }

                // Check if this property has been seen before
                if (_propertyNameToNodeMap.containsKey(name)) {
                    PropertyNode oldPropertyNode = _propertyNameToNodeMap.get(name);
                    int oldPropertyIndex = getChildren().indexOf(oldPropertyNode);

                    if (oldPropertyNode.isVisible()) {
                        // Hide the unneeded property
                        oldPropertyNode.setVisible(false);

                        // Attempt to hide one surrounding white space node
                        if (!hideWhiteSpaceNode(oldPropertyIndex - 1)) {
                            hideWhiteSpaceNode(oldPropertyIndex + 1);
                        }
                    }
                }

                // Store the property as the latest for this name
                _propertyNameToNodeMap.put(name, node);

                return super.add(node);
            }
        });
    }
private void setAdditionVisitor ( ) { setAdditionVisitor ( new InclusiveNodeVisitor ( ) { /**
             * Add parameter set as a child for printing input, but also add each defined value to the variable map.
             */ @ Override public boolean add ( ParametersNode node ) { for ( VariableDefinitionNode variable : NodeTreeUtils . getChildren ( node , VariableDefinitionNode . class ) ) { _parameterDefinitions . add ( variable ) ; add ( variable ) ; } return super . add ( node ) ; } /**
             * Store the rule set's scope by selector group
             */ @ Override public boolean add ( RuleSetNode node ) { SelectorGroupNode selectorGroup = NodeTreeUtils . getFirstChild ( node , SelectorGroupNode . class ) ; for ( SelectorNode selectorNode : NodeTreeUtils . getChildren ( selectorGroup , SelectorNode . class ) ) { StringBuilder sb = new StringBuilder ( ) ; for ( Node selectorChild : selectorNode . getChildren ( ) ) { sb . append ( selectorChild . toString ( ) ) ; } String selector = sb . toString ( ) ; // Mixins lock on first definition if ( ! _selectorToRuleSetMap . containsKey ( selector ) ) { _selectorToRuleSetMap . put ( selector , node ) ; } } return super . add ( node ) ; } /**
             * Absorb all children of the given scope. This assumes that cloning is not necessary.
             */ @ Override public boolean add ( ScopeNode node ) { NodeTreeUtils . moveChildren ( node , ScopeNode . this ) ; return false ; // Don't add the original scope itself } /**
             * Store variable definitions in a map by name
             */ @ Override public boolean add ( VariableDefinitionNode node ) { String name = node . getName ( ) ; // "Variables" lock on first definition if ( ! _variableNameToValueMap . containsKey ( name ) ) { _variableNameToValueMap . put ( name , NodeTreeUtils . getFirstChild ( node , ExpressionGroupNode . class ) ) ; } return super . add ( node ) ; } /**
             * Store property nodes by name. If there are multiple properties for a given name, only retain the last one.
             */ @ Override public boolean add ( PropertyNode node ) { String name = node . getName ( ) ; // If this is the IE-specific "filter" property, always add it if ( name . equals ( FILTER_PROPERTY ) ) { return super . add ( node ) ; } // If the value of this property node is a vendor-specific keyword, always add it if ( node . getChildren ( ) . get ( 0 ) . toString ( ) . startsWith ( "-" ) ) { return super . add ( node ) ; } // Check if this property has been seen before if ( _propertyNameToNodeMap . containsKey ( name ) ) { PropertyNode oldPropertyNode = _propertyNameToNodeMap . get ( name ) ; int oldPropertyIndex = getChildren ( ) . indexOf ( oldPropertyNode ) ; if ( oldPropertyNode . isVisible ( ) ) { // Hide the unneeded property oldPropertyNode . setVisible ( false ) ; // Attempt to hide one surrounding white space node if ( ! hideWhiteSpaceNode ( oldPropertyIndex - 1 ) ) { hideWhiteSpaceNode ( oldPropertyIndex + 1 ) ; } } } // Store the property as the latest for this name _propertyNameToNodeMap . put ( name , node ) ; return super . add ( node ) ; } } ) ; }
Some nodes are captured in additional structures to aid later resolution.
Some nodes are captured in additional structures to aid later resolution .