JavaParser Source Viewer

Home|JavaParser/com/github/javaparser/printer/lexicalpreservation/LexicalDifferenceCalculator.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.GeneratedJavaParserConstants;
25import com.github.javaparser.ast.Modifier;
26import com.github.javaparser.ast.Node;
27import com.github.javaparser.ast.NodeList;
28import com.github.javaparser.ast.expr.CharLiteralExpr;
29import com.github.javaparser.ast.expr.StringLiteralExpr;
30import com.github.javaparser.ast.expr.TextBlockLiteralExpr;
31import com.github.javaparser.ast.observer.ObservableProperty;
32import com.github.javaparser.ast.stmt.ExpressionStmt;
33import com.github.javaparser.printer.ConcreteSyntaxModel;
34import com.github.javaparser.printer.Printable;
35import com.github.javaparser.printer.SourcePrinter;
36import com.github.javaparser.printer.concretesyntaxmodel.*;
37import com.github.javaparser.printer.lexicalpreservation.changes.Change;
38import com.github.javaparser.printer.lexicalpreservation.changes.ListAdditionChange;
39import com.github.javaparser.printer.lexicalpreservation.changes.ListRemovalChange;
40import com.github.javaparser.printer.lexicalpreservation.changes.ListReplacementChange;
41import com.github.javaparser.printer.lexicalpreservation.changes.NoChange;
42import com.github.javaparser.printer.lexicalpreservation.changes.PropertyChange;
43import com.github.javaparser.utils.LineSeparator;
44
45import java.util.ArrayList;
46import java.util.Collection;
47import java.util.Iterator;
48import java.util.LinkedList;
49import java.util.List;
50import java.util.Optional;
51
52import static com.github.javaparser.TokenTypes.eolTokenKind;
53
54class LexicalDifferenceCalculator {
55
56    /**
57     * The ConcreteSyntaxModel represents the general format. This model is a calculated version of the ConcreteSyntaxModel,
58     * with no condition, no lists, just tokens and node children.
59     */
60    static class CalculatedSyntaxModel {
61        final List<CsmElementelements;
62
63        CalculatedSyntaxModel(List<CsmElementelements) {
64            this.elements = elements;
65        }
66
67        public CalculatedSyntaxModel from(int index) {
68            return new CalculatedSyntaxModel(new ArrayList<>(elements.subList(indexelements.size())));
69        }
70
71        @Override
72        public String toString() {
73            return "CalculatedSyntaxModel{" +
74                    "elements=" + elements +
75                    '}';
76        }
77
78        CalculatedSyntaxModel sub(int startint end) {
79            return new CalculatedSyntaxModel(elements.subList(startend));
80        }
81
82        void removeIndentationElements() {
83            elements.removeIf(el -> el instanceof CsmIndent || el instanceof CsmUnindent);
84        }
85    }
86
87    static class CsmChild implements CsmElement {
88        private final Node child;
89
90        public Node getChild() {
91            return child;
92        }
93
94        CsmChild(Node child) {
95            this.child = child;
96        }
97
98        @Override
99        public void prettyPrint(Node nodeSourcePrinter printer) {
100            throw new UnsupportedOperationException();
101        }
102
103        @Override
104        public String toString() {
105            return "child(" + child.getClass().getSimpleName()+")";
106        }
107
108        @Override
109        public boolean equals(Object o) {
110            if (this == o) return true;
111            if (o == null || getClass() != o.getClass()) return false;
112
113            CsmChild csmChild = (CsmChildo;
114
115            return child.equals(csmChild.child);
116        }
117
118        @Override
119        public int hashCode() {
120            return child.hashCode();
121        }
122    }
123
124    List<DifferenceElementcalculateListRemovalDifference(ObservableProperty observablePropertyNodeList<?> nodeListint index) {
125        Node container = nodeList.getParentNodeForChildren();
126        CsmElement element = ConcreteSyntaxModel.forClass(container.getClass());
127        CalculatedSyntaxModel original = calculatedSyntaxModelForNode(elementcontainer);
128        CalculatedSyntaxModel after = calculatedSyntaxModelAfterListRemoval(elementobservablePropertynodeListindex);
129        return DifferenceElementCalculator.calculate(originalafter);
130    }
131
132    List<DifferenceElementcalculateListAdditionDifference(ObservableProperty observablePropertyNodeList<?> nodeListint indexNode nodeAdded) {
133        Node container = nodeList.getParentNodeForChildren();
134        CsmElement element = ConcreteSyntaxModel.forClass(container.getClass());
135        CalculatedSyntaxModel original = calculatedSyntaxModelForNode(elementcontainer);
136        CalculatedSyntaxModel after = calculatedSyntaxModelAfterListAddition(elementobservablePropertynodeListindexnodeAdded);
137
138        List<DifferenceElementdifferenceElements = DifferenceElementCalculator.calculate(originalafter);
139
140        // Set the line separator character tokens
141        LineSeparator lineSeparator = container.getLineEndingStyleOrDefault(LineSeparator.SYSTEM);
142        replaceEolTokens(differenceElementslineSeparator);
143
144        return differenceElements;
145    }
146
147    private void replaceEolTokens(List<DifferenceElementdifferenceElementsLineSeparator lineSeparator) {
148        for (int i = 0i < differenceElements.size(); i++) {
149            DifferenceElement differenceElement = differenceElements.get(i);
150            if (differenceElement.isAdded()) {
151                CsmElement element = differenceElement.getElement();
152                boolean isWhitespaceToken = element instanceof CsmToken && ((CsmTokenelement).isNewLine();
153                if (isWhitespaceToken) {
154                    differenceElements.set(i, new Added(CsmElement.newline(lineSeparator)));
155                }
156            }
157        }
158    }
159
160    List<DifferenceElementcalculateListReplacementDifference(ObservableProperty observablePropertyNodeList<?> nodeListint indexNode newValue) {
161        Node container = nodeList.getParentNodeForChildren();
162        CsmElement element = ConcreteSyntaxModel.forClass(container.getClass());
163        CalculatedSyntaxModel original = calculatedSyntaxModelForNode(elementcontainer);
164        CalculatedSyntaxModel after = calculatedSyntaxModelAfterListReplacement(elementobservablePropertynodeListindexnewValue);
165        return DifferenceElementCalculator.calculate(originalafter);
166    }
167
168    void calculatePropertyChange(NodeText nodeTextNode observedNodeObservableProperty propertyObject oldValueObject newValue) {
169        if (nodeText == null) {
170            throw new NullPointerException();
171        }
172        CsmElement element = ConcreteSyntaxModel.forClass(observedNode.getClass());
173        CalculatedSyntaxModel original = calculatedSyntaxModelForNode(elementobservedNode);
174        CalculatedSyntaxModel after = calculatedSyntaxModelAfterPropertyChange(elementobservedNodepropertyoldValuenewValue);
175        List<DifferenceElementdifferenceElements = DifferenceElementCalculator.calculate(originalafter);
176        Difference difference = new Difference(differenceElementsnodeTextobservedNode);
177        difference.apply();
178    }
179
180    // Visible for testing
181    CalculatedSyntaxModel calculatedSyntaxModelForNode(CsmElement csmNode node) {
182        List<CsmElementelements = new LinkedList<>();
183        calculatedSyntaxModelForNode(csmnodeelements, new NoChange());
184        return new CalculatedSyntaxModel(elements);
185    }
186
187    CalculatedSyntaxModel calculatedSyntaxModelForNode(Node node) {
188        return calculatedSyntaxModelForNode(ConcreteSyntaxModel.forClass(node.getClass()), node);
189    }
190
191    private void calculatedSyntaxModelForNode(CsmElement csmNode nodeList<CsmElementelementsChange change) {
192        if (csm instanceof CsmSequence) {
193            CsmSequence csmSequence = (CsmSequencecsm;
194            csmSequence.getElements().forEach(e -> calculatedSyntaxModelForNode(enodeelementschange));
195        } else if (csm instanceof CsmComment) {
196            // nothing to do
197        } else if (csm instanceof CsmSingleReference) {
198            CsmSingleReference csmSingleReference = (CsmSingleReference)csm;
199            Node child;
200            if (change instanceof PropertyChange && ((PropertyChange)change).getProperty() == csmSingleReference.getProperty()) {
201                child = (Node)((PropertyChange)change).getNewValue();
202            } else {
203                child = csmSingleReference.getProperty().getValueAsSingleReference(node);
204            }
205            if (child != null) {
206                // fix issue #2374
207                // Add node comment if needed (it's not very elegant but it works)
208                // We need to be sure that the node is an ExpressionStmt because we can meet
209                // this class definition
210                // a line comment <This is my class, with my comment> followed by
211                // class A {}
212                // In this case keyworld [class] is considered as a token and [A] is a child element
213                // So if we don't care that the node is an ExpressionStmt we could try to generate a wrong definition
214                // like this [class // This is my class, with my comment A {}]
215                if (node.getComment().isPresent() && node instanceof ExpressionStmt) {
216                    LineSeparator lineSeparator = node.getLineEndingStyleOrDefault(LineSeparator.SYSTEM);
217                    elements.add(new CsmChild(node.getComment().get()));
218                    elements.add(new CsmToken(eolTokenKind(lineSeparator), lineSeparator.asRawString()));
219                }
220                elements.add(new CsmChild(child));
221            }
222        } else if (csm instanceof CsmNone) {
223            // nothing to do
224        } else if (csm instanceof CsmToken) {
225            elements.add(csm);
226        } else if (csm instanceof CsmOrphanCommentsEnding) {
227            // nothing to do
228        } else if (csm instanceof CsmList) {
229            CsmList csmList = (CsmListcsm;
230            if (csmList.getProperty().isAboutNodes()) {
231                Object rawValue = change.getValue(csmList.getProperty(), node);
232                NodeList<?> nodeList;
233                if (rawValue instanceof Optional) {
234                    Optional<?> optional = (Optional<?>)rawValue;
235                    if (optional.isPresent()) {
236                        if (!(optional.get() instanceof NodeList)) {
237                            throw new IllegalStateException("Expected NodeList, found " + optional.get().getClass().getCanonicalName());
238                        }
239                        nodeList = (NodeList<?>) optional.get();
240                    } else {
241                        nodeList = new NodeList<>();
242                    }
243                } else {
244                    if (!(rawValue instanceof NodeList)) {
245                        throw new IllegalStateException("Expected NodeList, found " + rawValue.getClass().getCanonicalName());
246                    }
247                    nodeList = (NodeList<?>) rawValue;
248                }
249                if (!nodeList.isEmpty()) {
250                    calculatedSyntaxModelForNode(csmList.getPreceeding(), nodeelementschange);
251                    for (int i = 0i < nodeList.size(); i++) {
252                        if (i != 0) {
253                            calculatedSyntaxModelForNode(csmList.getSeparatorPre(), nodeelementschange);
254                        }
255                        elements.add(new CsmChild(nodeList.get(i)));
256                        if (i != (nodeList.size() - 1)) {
257                            calculatedSyntaxModelForNode(csmList.getSeparatorPost(), nodeelementschange);
258                        }
259
260                    }
261                    calculatedSyntaxModelForNode(csmList.getFollowing(), nodeelementschange);
262                }
263            } else {
264                Collection<?> collection = (Collection<?>) change.getValue(csmList.getProperty(), node);
265                if (!collection.isEmpty()) {
266                    calculatedSyntaxModelForNode(csmList.getPreceeding(), nodeelementschange);
267
268                    boolean first = true;
269                    for (Iterator<?> it = collection.iterator(); it.hasNext(); ) {
270                        if (!first) {
271                            calculatedSyntaxModelForNode(csmList.getSeparatorPre(), nodeelementschange);
272                        }
273                        Object value = it.next();
274                        if (value instanceof Modifier) {
275                            Modifier modifier = (Modifier)value;
276                            elements.add(new CsmToken(toToken(modifier)));
277                        } else {
278                            throw new UnsupportedOperationException(it.next().getClass().getSimpleName());
279                        }
280                        if (it.hasNext()) {
281                            calculatedSyntaxModelForNode(csmList.getSeparatorPost(), nodeelementschange);
282                        }
283                        first = false;
284                    }
285                    calculatedSyntaxModelForNode(csmList.getFollowing(), nodeelementschange);
286                }
287            }
288        } else if (csm instanceof CsmConditional) {
289            CsmConditional csmConditional = (CsmConditionalcsm;
290            boolean satisfied = change.evaluate(csmConditionalnode);
291            if (satisfied) {
292                calculatedSyntaxModelForNode(csmConditional.getThenElement(), nodeelementschange);
293            } else {
294                calculatedSyntaxModelForNode(csmConditional.getElseElement(), nodeelementschange);
295            }
296        } else if (csm instanceof CsmIndent) {
297            elements.add(csm);
298        } else if (csm instanceof CsmUnindent) {
299            elements.add(csm);
300        } else if (csm instanceof CsmAttribute) {
301            CsmAttribute csmAttribute = (CsmAttributecsm;
302            Object value = change.getValue(csmAttribute.getProperty(), node);
303            String text = value.toString();
304            if (value instanceof Printable) {
305                text = ((Printablevalue).asString();
306            }
307            elements.add(new CsmToken(csmAttribute.getTokenType(nodevalue.toString(), text), text));
308        } else if ((csm instanceof CsmString) && (node instanceof StringLiteralExpr)) {
309            // fix #2382:
310            // This method calculates the syntax model _after_ the change has been applied.
311            // If the given change is a PropertyChange, the returned model should
312            // contain the new value, otherwise the original/current value should be used.
313            if (change instanceof PropertyChange) {
314                elements.add(new CsmToken(GeneratedJavaParserConstants.STRING_LITERAL,
315                        "\"" + ((PropertyChangechange).getNewValue() + "\""));
316            } else {
317                elements.add(new CsmToken(GeneratedJavaParserConstants.STRING_LITERAL,
318                        "\"" + ((StringLiteralExprnode).getValue() + "\""));
319            }
320        } else if ((csm instanceof CsmString) && (node instanceof TextBlockLiteralExpr)) {
321            // FIXME: csm should be CsmTextBlock -- See also #2677
322            if (change instanceof PropertyChange) {
323                elements.add(new CsmToken(GeneratedJavaParserConstants.TEXT_BLOCK_LITERAL,
324                        "\"\"\"" + ((PropertyChangechange).getNewValue() + "\"\"\""));
325            } else {
326                elements.add(new CsmToken(GeneratedJavaParserConstants.TEXT_BLOCK_LITERAL,
327                        "\"\"\"" + ((TextBlockLiteralExprnode).getValue() + "\"\"\""));
328            }
329        } else if ((csm instanceof CsmChar) && (node instanceof CharLiteralExpr)) {
330            if (change instanceof PropertyChange) {
331                elements.add(new CsmToken(GeneratedJavaParserConstants.CHAR,
332                        "'" + ((PropertyChangechange).getNewValue() + "'"));
333            } else {
334                elements.add(new CsmToken(GeneratedJavaParserConstants.CHAR,
335                        "'" + ((CharLiteralExprnode).getValue() + "'"));
336            }
337        } else if (csm instanceof CsmMix) {
338            CsmMix csmMix = (CsmMix)csm;
339            List<CsmElementmixElements = new LinkedList<>();
340            csmMix.getElements().forEach(e -> calculatedSyntaxModelForNode(enodemixElementschange));
341            elements.add(new CsmMix(mixElements));
342        } else if (csm instanceof CsmChild) {
343            elements.add(csm);
344        } else {
345            throw new UnsupportedOperationException(csm.getClass().getSimpleName()+ " " + csm);
346        }
347    }
348
349    public static int toToken(Modifier modifier) {
350        switch (modifier.getKeyword()) {
351            case PUBLIC:
352                return GeneratedJavaParserConstants.PUBLIC;
353            case PRIVATE:
354                return GeneratedJavaParserConstants.PRIVATE;
355            case PROTECTED:
356                return GeneratedJavaParserConstants.PROTECTED;
357            case STATIC:
358                return GeneratedJavaParserConstants.STATIC;
359            case FINAL:
360                return GeneratedJavaParserConstants.FINAL;
361            case ABSTRACT:
362                return GeneratedJavaParserConstants.ABSTRACT;
363            case TRANSIENT:
364                return GeneratedJavaParserConstants.TRANSIENT;
365            case SYNCHRONIZED:
366                return GeneratedJavaParserConstants.SYNCHRONIZED;
367            case VOLATILE:
368                return GeneratedJavaParserConstants.VOLATILE;
369            case NATIVE:
370                return GeneratedJavaParserConstants.NATIVE;
371            case STRICTFP:
372                return GeneratedJavaParserConstants.STRICTFP;
373            case TRANSITIVE:
374                return GeneratedJavaParserConstants.TRANSITIVE;
375            default:
376                throw new UnsupportedOperationException(modifier.getKeyword().name());
377        }
378    }
379
380    ///
381    /// Methods that calculate CalculatedSyntaxModel
382    ///
383
384    // Visible for testing
385    CalculatedSyntaxModel calculatedSyntaxModelAfterPropertyChange(Node nodeObservableProperty propertyObject oldValueObject newValue) {
386        return calculatedSyntaxModelAfterPropertyChange(ConcreteSyntaxModel.forClass(node.getClass()), nodepropertyoldValuenewValue);
387    }
388
389    // Visible for testing
390    CalculatedSyntaxModel calculatedSyntaxModelAfterPropertyChange(CsmElement csmNode nodeObservableProperty propertyObject oldValueObject newValue) {
391        List<CsmElementelements = new LinkedList<>();
392        calculatedSyntaxModelForNode(csmnodeelements, new PropertyChange(propertyoldValuenewValue));
393        return new CalculatedSyntaxModel(elements);
394    }
395
396    // Visible for testing
397    CalculatedSyntaxModel calculatedSyntaxModelAfterListRemoval(CsmElement csmObservableProperty observablePropertyNodeList<?> nodeListint index) {
398        List<CsmElementelements = new LinkedList<>();
399        Node container = nodeList.getParentNodeForChildren();
400        calculatedSyntaxModelForNode(csmcontainerelements, new ListRemovalChange(observablePropertyindex));
401        return new CalculatedSyntaxModel(elements);
402    }
403
404    // Visible for testing
405    CalculatedSyntaxModel calculatedSyntaxModelAfterListAddition(CsmElement csmObservableProperty observablePropertyNodeList<?> nodeListint indexNode nodeAdded) {
406        List<CsmElementelements = new LinkedList<>();
407        Node container = nodeList.getParentNodeForChildren();
408        calculatedSyntaxModelForNode(csmcontainerelements, new ListAdditionChange(observablePropertyindexnodeAdded));
409        return new CalculatedSyntaxModel(elements);
410    }
411
412    // Visible for testing
413    CalculatedSyntaxModel calculatedSyntaxModelAfterListAddition(Node containerObservableProperty observablePropertyint indexNode nodeAdded) {
414        CsmElement csm = ConcreteSyntaxModel.forClass(container.getClass());
415        Object rawValue = observableProperty.getRawValue(container);
416        if (!(rawValue instanceof NodeList)) {
417            throw new IllegalStateException("Expected NodeList, found " + rawValue.getClass().getCanonicalName());
418        }
419        NodeList<?> nodeList = (NodeList<?>)rawValue;
420        return calculatedSyntaxModelAfterListAddition(csmobservablePropertynodeListindexnodeAdded);
421    }
422
423    // Visible for testing
424    CalculatedSyntaxModel calculatedSyntaxModelAfterListRemoval(Node containerObservableProperty observablePropertyint index) {
425        CsmElement csm = ConcreteSyntaxModel.forClass(container.getClass());
426        Object rawValue = observableProperty.getRawValue(container);
427        if (!(rawValue instanceof NodeList)) {
428            throw new IllegalStateException("Expected NodeList, found " + rawValue.getClass().getCanonicalName());
429        }
430        NodeList<?> nodeList = (NodeList<?>)rawValue;
431        return calculatedSyntaxModelAfterListRemoval(csmobservablePropertynodeListindex);
432    }
433
434    // Visible for testing
435    private CalculatedSyntaxModel calculatedSyntaxModelAfterListReplacement(CsmElement csmObservableProperty observablePropertyNodeList<?> nodeListint indexNode newValue) {
436        List<CsmElementelements = new LinkedList<>();
437        Node container = nodeList.getParentNodeForChildren();
438        calculatedSyntaxModelForNode(csmcontainerelements, new ListReplacementChange(observablePropertyindexnewValue));
439        return new CalculatedSyntaxModel(elements);
440    }
441
442}
443
MembersX
LexicalDifferenceCalculator:calculateListAdditionDifference:Block:original
LexicalDifferenceCalculator:calculateListAdditionDifference:Block:differenceElements
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListRemoval:Block:nodeList
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:csmList
LexicalDifferenceCalculator:CsmChild:equals
LexicalDifferenceCalculator:calculateListReplacementDifference:Block:original
LexicalDifferenceCalculator:CalculatedSyntaxModel:elements
LexicalDifferenceCalculator:calculateListRemovalDifference:Block:original
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListReplacement
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:elements
LexicalDifferenceCalculator:calculatePropertyChange:Block:original
LexicalDifferenceCalculator:calculatePropertyChange:Block:after
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListAddition:Block:container
LexicalDifferenceCalculator:CsmChild:child
LexicalDifferenceCalculator:calculatePropertyChange:Block:differenceElements
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:csmSequence
LexicalDifferenceCalculator:toToken
LexicalDifferenceCalculator:calculateListReplacementDifference:Block:after
LexicalDifferenceCalculator:calculatedSyntaxModelAfterPropertyChange
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:Block:collection
LexicalDifferenceCalculator:CalculatedSyntaxModel:from
LexicalDifferenceCalculator:calculatePropertyChange:Block:element
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:child
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:Block:Block:lineSeparator
LexicalDifferenceCalculator:calculatePropertyChange
LexicalDifferenceCalculator:calculateListReplacementDifference
LexicalDifferenceCalculator:calculateListReplacementDifference:Block:container
LexicalDifferenceCalculator:replaceEolTokens:Block:Block:differenceElement
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListRemoval:Block:csm
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListRemoval:Block:container
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListAddition:Block:rawValue
LexicalDifferenceCalculator:calculateListAdditionDifference:Block:lineSeparator
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:value
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListAddition:Block:nodeList
LexicalDifferenceCalculator:calculatePropertyChange:Block:difference
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:csmSingleReference
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListReplacement:Block:elements
LexicalDifferenceCalculator:calculateListRemovalDifference:Block:container
LexicalDifferenceCalculator:calculateListRemovalDifference:Block:element
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:text
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListRemoval:Block:elements
LexicalDifferenceCalculator:CalculatedSyntaxModel:sub
LexicalDifferenceCalculator:calculateListReplacementDifference:Block:element
LexicalDifferenceCalculator:calculatedSyntaxModelForNode
LexicalDifferenceCalculator:calculateListAdditionDifference:Block:after
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:Block:Block:first
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:csmConditional
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:Block:nodeList
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:satisfied
LexicalDifferenceCalculator:calculateListRemovalDifference
LexicalDifferenceCalculator:calculatedSyntaxModelAfterPropertyChange:Block:elements
LexicalDifferenceCalculator:CsmChild:getChild
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListAddition:Block:csm
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:csmAttribute
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:Block:Block:Block:Block:modifier
LexicalDifferenceCalculator:CsmChild:prettyPrint
LexicalDifferenceCalculator:calculateListAdditionDifference:Block:container
LexicalDifferenceCalculator:calculateListAdditionDifference:Block:element
LexicalDifferenceCalculator:calculateListRemovalDifference:Block:after
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListRemoval:Block:rawValue
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListReplacement:Block:container
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListRemoval
LexicalDifferenceCalculator:CsmChild:toString
LexicalDifferenceCalculator:replaceEolTokens:Block:Block:Block:element
LexicalDifferenceCalculator:replaceEolTokens
LexicalDifferenceCalculator:CalculatedSyntaxModel:CalculatedSyntaxModel
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:mixElements
LexicalDifferenceCalculator:CsmChild:hashCode
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:csmMix
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:Block:rawValue
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:Block:Block:Block:value
LexicalDifferenceCalculator:CalculatedSyntaxModel:toString
LexicalDifferenceCalculator:CalculatedSyntaxModel:removeIndentationElements
LexicalDifferenceCalculator:CsmChild:CsmChild
LexicalDifferenceCalculator:CsmChild:equals:Block:csmChild
LexicalDifferenceCalculator:replaceEolTokens:Block:Block:Block:isWhitespaceToken
LexicalDifferenceCalculator:calculatedSyntaxModelForNode:Block:Block:Block:Block:optional
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListAddition:Block:elements
LexicalDifferenceCalculator:calculatedSyntaxModelAfterListAddition
LexicalDifferenceCalculator:calculateListAdditionDifference
Members
X