JavaParser Source Viewer

Home|JavaParser/com/github/javaparser/printer/lexicalpreservation/PhantomNodeLogic.java
1/*
2 * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser.
3 * Copyright (C) 2011, 2013-2020 The JavaParser Team.
4 *
5 * This file is part of JavaParser.
6 *
7 * JavaParser can be used either under the terms of
8 * a) the GNU Lesser General Public License as published by
9 *     the Free Software Foundation, either version 3 of the License, or
10 *     (at your option) any later version.
11 * b) the terms of the Apache License
12 *
13 * You should have received a copy of both licenses in LICENCE.LGPL and
14 * LICENCE.APACHE. Please refer to those files for details.
15 *
16 * JavaParser is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 */
21
22package com.github.javaparser.printer.lexicalpreservation;
23
24import com.github.javaparser.ast.Node;
25import com.github.javaparser.ast.observer.AstObserver;
26import com.github.javaparser.ast.observer.AstObserverAdapter;
27import com.github.javaparser.ast.type.UnknownType;
28
29import java.util.IdentityHashMap;
30import java.util.Map;
31
32import static java.util.Collections.synchronizedMap;
33
34/**
35 * We want to recognize and ignore "phantom" nodes, like the fake type of variable in FieldDeclaration
36 */
37public class PhantomNodeLogic {
38
39    private static final int LEVELS_TO_EXPLORE = 3;
40
41    private static final Map<NodeBooleanisPhantomNodeCache = synchronizedMap(new IdentityHashMap<>());
42
43    private static final AstObserver cacheCleaner = new AstObserverAdapter() {
44        @Override
45        public void parentChange(Node observedNodeNode previousParentNode newParent) {
46            isPhantomNodeCache.remove(observedNode);
47        }
48    };
49
50    static boolean isPhantomNode(Node node) {
51        if (isPhantomNodeCache.containsKey(node)) {
52            return isPhantomNodeCache.get(node);
53        } else {
54            if (node instanceof UnknownType) {
55                return true;
56            }
57            boolean res = (node.getParentNode().isPresent() &&
58                    !node.getParentNode().get().getRange().get().contains(node.getRange().get())
59                    || inPhantomNode(nodeLEVELS_TO_EXPLORE));
60            isPhantomNodeCache.put(noderes);
61            node.register(cacheCleaner);
62            return res;
63        }
64    }
65
66    /**
67     * A node contained in a phantom node is also a phantom node. We limit how many levels up we check just for performance reasons.
68     */
69    private static boolean inPhantomNode(Node nodeint levels) {
70        return node.getParentNode().isPresent() &&
71                (isPhantomNode(node.getParentNode().get())
72                        || inPhantomNode(node.getParentNode().get(), levels - 1));
73    }
74
75    /**
76     * Clean up the cache used by the LexicalPreserving logic. This should only be used once you're done printing all parsed data with
77     * a JavaParser's configuration setLexicalPreservationEnabled=true.
78     */
79    public static void cleanUpCache() {
80        isPhantomNodeCache.clear();
81    }
82}
83
MembersX
PhantomNodeLogic:isPhantomNode
PhantomNodeLogic:isPhantomNodeCache
PhantomNodeLogic:cacheCleaner
PhantomNodeLogic:isPhantomNode:Block:Block:res
PhantomNodeLogic:inPhantomNode
PhantomNodeLogic:cleanUpCache
PhantomNodeLogic:LEVELS_TO_EXPLORE
PhantomNodeLogic:parentChange
Members
X