From 9a228915f61892f6ba99fcf1e42e42e1e2622a00 Mon Sep 17 00:00:00 2001 From: Danny van Bruggen Date: Wed, 24 Jan 2018 23:52:36 +0100 Subject: [PATCH] Deal with no common type for variables being available. --- .../ast/body/VariableDeclarator.java | 6 ++-- .../ast/nodeTypes/NodeWithVariables.java | 19 +++++----- .../printer/PrettyPrintVisitor.java | 36 +++++++++---------- .../LexicalPreservingPrinter.java | 25 ++++++------- .../contexts/FieldAccessContext.java | 10 ++---- .../printer/PrettyPrintVisitorTest.java | 10 +++--- 6 files changed, 52 insertions(+), 54 deletions(-) diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/VariableDeclarator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/VariableDeclarator.java index 45b4959455..de728cdc3c 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/body/VariableDeclarator.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/VariableDeclarator.java @@ -118,7 +118,7 @@ public void propertyChange(Node observedNode, ObservableProperty property, Objec if (vd.getParentNode().isPresent() && vd.getParentNode().get() instanceof NodeWithVariables) { NodeWithVariables nodeWithVariables = (NodeWithVariables) vd.getParentNode().get(); // We calculate the value the property will assume after the change will be completed - Type currentMaxCommonType = nodeWithVariables.getMaximumCommonType(); + Optional currentMaxCommonType = nodeWithVariables.getMaximumCommonType(); List types = new LinkedList<>(); int index = nodeWithVariables.getVariables().indexOf(vd); for (int i = 0; i < nodeWithVariables.getVariables().size(); i++) { @@ -128,8 +128,8 @@ public void propertyChange(Node observedNode, ObservableProperty property, Objec types.add(nodeWithVariables.getVariable(i).getType()); } } - Type newMaxCommonType = NodeWithVariables.calculateMaximumCommonType(types); - ((Node) nodeWithVariables).notifyPropertyChange(ObservableProperty.MAXIMUM_COMMON_TYPE, currentMaxCommonType, newMaxCommonType); + Optional newMaxCommonType = NodeWithVariables.calculateMaximumCommonType(types); + ((Node) nodeWithVariables).notifyPropertyChange(ObservableProperty.MAXIMUM_COMMON_TYPE, currentMaxCommonType.orElse(null), newMaxCommonType.orElse(null)); } } } diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java index 5cce28f5b6..5daf38a14b 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java @@ -29,6 +29,7 @@ import com.github.javaparser.metamodel.DerivedProperty; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -109,28 +110,28 @@ default Type getElementType() { *
For int[] a[][],b[],c[][]; this is int[][]. */ @DerivedProperty - default Type getMaximumCommonType() { - return calculateMaximumCommonType(this.getVariables().stream().map(v -> v.getType()).collect(Collectors.toList())); + default Optional getMaximumCommonType() { + return calculateMaximumCommonType(getVariables().stream().map(v -> v.getType()).collect(Collectors.toList())); } - static Type calculateMaximumCommonType(List types) { + static Optional calculateMaximumCommonType(List types) { // we use a local class because we cannot use an helper static method in an interface class Helper { // Conceptually: given a type we start from the Element Type and get as many array levels as indicated // From the implementation point of view we start from the actual type and we remove how many array // levels as needed to get the target level of arrays // It returns null if the type has less array levels then the desired target - private Type toArrayLevel(Type type, int level) { + private Optional toArrayLevel(Type type, int level) { if (level > type.getArrayLevel()) { - return null; + return Optional.empty(); } for (int i = type.getArrayLevel(); i > level; i--) { if (!(type instanceof ArrayType)) { - throw new AssertionError("The variables do not have a common type."); + return Optional.empty(); } type = ((ArrayType) type).getComponentType(); } - return type; + return Optional.of(type); } } @@ -145,8 +146,8 @@ private Type toArrayLevel(Type type, int level) { // the pretty-printed string got for a node. We just check all them are the same and if they // are we just just is not null Object[] values = types.stream().map(v -> { - Type t = helper.toArrayLevel(v, currentLevel); - return t == null ? null : t.toString(); + Optional t = helper.toArrayLevel(v, currentLevel); + return t.map(Node::toString).orElse(null); }).distinct().toArray(); if (values.length == 1 && values[0] != null) { level++; diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrintVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrintVisitor.java index 9b8d56b749..58a304d5e6 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrintVisitor.java +++ b/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrintVisitor.java @@ -482,7 +482,7 @@ public void visit(final FieldDeclaration n, final Void arg) { printMemberAnnotations(n.getAnnotations(), arg); printModifiers(n.getModifiers()); if (!n.getVariables().isEmpty()) { - n.getMaximumCommonType().accept(this, arg); + n.getMaximumCommonType().ifPresent(t -> t.accept(this, arg)); } printer.print(" "); @@ -502,25 +502,25 @@ public void visit(final VariableDeclarator n, final Void arg) { printComment(n.getComment(), arg); n.getName().accept(this, arg); - Optional ancestor = n.getAncestorOfType(NodeWithVariables.class); - if (!ancestor.isPresent()) { - throw new RuntimeException("Unable to work with VariableDeclarator not owned by a NodeWithVariables"); - } - Type commonType = ancestor.get().getMaximumCommonType(); + n.getAncestorOfType(NodeWithVariables.class).ifPresent(ancestor -> { + Optional maximumCommonType = ancestor.getMaximumCommonType(); + maximumCommonType.ifPresent(commonType -> { - Type type = n.getType(); + Type type = n.getType(); - ArrayType arrayType = null; + ArrayType arrayType = null; - for (int i = commonType.getArrayLevel(); i < type.getArrayLevel(); i++) { - if (arrayType == null) { - arrayType = (ArrayType) type; - } else { - arrayType = (ArrayType) arrayType.getComponentType(); - } - printAnnotations(arrayType.getAnnotations(), true, arg); - printer.print("[]"); - } + for (int i = commonType.getArrayLevel(); i < type.getArrayLevel(); i++) { + if (arrayType == null) { + arrayType = (ArrayType) type; + } else { + arrayType = (ArrayType) arrayType.getComponentType(); + } + printAnnotations(arrayType.getAnnotations(), true, arg); + printer.print("[]"); + } + }); + }); if (n.getInitializer().isPresent()) { printer.print(" = "); @@ -913,7 +913,7 @@ public void visit(final VariableDeclarationExpr n, final Void arg) { printModifiers(n.getModifiers()); if (!n.getVariables().isEmpty()) { - n.getMaximumCommonType().accept(this, arg); + n.getMaximumCommonType().ifPresent(t -> t.accept(this, arg)); } printer.print(" "); diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java index c874345e1d..a435dc4ea4 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java +++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java @@ -57,7 +57,7 @@ /** * A Lexical Preserving Printer is used to capture all the lexical information while parsing, update them when - * operating on the AST and then used them to reproduce the source code + * operating on the AST and then used them to reproduce the source code * in its original formatting including the AST changes. */ public class LexicalPreservingPrinter { @@ -110,7 +110,7 @@ public static N setup(N node) { }); return node; } - + // // Constructor and setup // @@ -401,16 +401,17 @@ private static NodeText interpret(Node node, CsmElement csm, NodeText nodeText) // Array brackets are a pain... we do not have a way to represent them explicitly in the AST // so they have to be handled in a special way if (node instanceof VariableDeclarator) { - VariableDeclarator variableDeclarator = (VariableDeclarator)node; - if (!variableDeclarator.getParentNode().isPresent()) { - throw new RuntimeException("VariableDeclarator without parent: I cannot handle the array levels"); - } - NodeWithVariables nodeWithVariables = (NodeWithVariables)variableDeclarator.getParentNode().get(); - int extraArrayLevels = variableDeclarator.getType().getArrayLevel() - nodeWithVariables.getMaximumCommonType().getArrayLevel(); - for (int i=0; i { + NodeWithVariables nodeWithVariables = (NodeWithVariables) parent; + nodeWithVariables.getMaximumCommonType().ifPresent(mct -> { + int extraArrayLevels = variableDeclarator.getType().getArrayLevel() - mct.getArrayLevel(); + for (int i = 0; i < extraArrayLevels; i++) { + nodeText.addElement(new TokenTextElement(LBRACKET)); + nodeText.addElement(new TokenTextElement(RBRACKET)); + } + }); + }); } return nodeText; } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java index 860fe6bc4e..65ccedf009 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java +++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java @@ -53,7 +53,7 @@ public FieldAccessContext(FieldAccessExpr wrappedNode, TypeSolver typeSolver) { @Override public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { - if (wrappedNode.getField().toString().equals(name)) { + if (wrappedNode.getName().toString().equals(name)) { if (wrappedNode.getScope() instanceof ThisExpr) { ResolvedType typeOfThis = JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode); return new SymbolSolver(typeSolver).solveSymbolInType(typeOfThis.asReferenceType().getTypeDeclaration(), name); @@ -75,18 +75,14 @@ public SymbolReference solveMethod(String name, List< @Override public Optional solveSymbolAsValue(String name, TypeSolver typeSolver) { Expression scope = wrappedNode.getScope(); - if (wrappedNode.getField().toString().equals(name)) { + if (wrappedNode.getName().toString().equals(name)) { ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getType(scope); if (typeOfScope.isArray() && name.equals(ARRAY_LENGTH_FIELD_NAME)) { return Optional.of(new Value(ResolvedPrimitiveType.INT, ARRAY_LENGTH_FIELD_NAME)); } if (typeOfScope.isReferenceType()) { Optional typeUsage = typeOfScope.asReferenceType().getFieldType(name); - if (typeUsage.isPresent()) { - return Optional.of(new Value(typeUsage.get(), name)); - } else { - return Optional.empty(); - } + return typeUsage.map(resolvedType -> new Value(resolvedType, name)); } else { return Optional.empty(); } diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrintVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrintVisitorTest.java index b8c95a6ac3..dd8738ab0f 100644 --- a/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrintVisitorTest.java +++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrintVisitorTest.java @@ -42,22 +42,22 @@ public class PrettyPrintVisitorTest { @Test public void getMaximumCommonTypeWithoutAnnotations() { VariableDeclarationExpr vde1 = JavaParser.parseVariableDeclarationExpr("int a[], b[]"); - assertEquals("int[]", vde1.getMaximumCommonType().toString()); + assertEquals("int[]", vde1.getMaximumCommonType().get().toString()); VariableDeclarationExpr vde2 = JavaParser.parseVariableDeclarationExpr("int[][] a[], b[]"); - assertEquals("int[][][]", vde2.getMaximumCommonType().toString()); + assertEquals("int[][][]", vde2.getMaximumCommonType().get().toString()); VariableDeclarationExpr vde3 = JavaParser.parseVariableDeclarationExpr("int[][] a, b[]"); - assertEquals("int[][]", vde3.getMaximumCommonType().toString()); + assertEquals("int[][]", vde3.getMaximumCommonType().get().toString()); } @Test public void getMaximumCommonTypeWithAnnotations() { VariableDeclarationExpr vde1 = JavaParser.parseVariableDeclarationExpr("int a @Foo [], b[]"); - assertEquals("int", vde1.getMaximumCommonType().toString()); + assertEquals("int", vde1.getMaximumCommonType().get().toString()); VariableDeclarationExpr vde2 = JavaParser.parseVariableDeclarationExpr("int[]@Foo [] a[], b[]"); - assertEquals("int[] @Foo [][]", vde2.getMaximumCommonType().toString()); + assertEquals("int[] @Foo [][]", vde2.getMaximumCommonType().get().toString()); } private String print(Node node) {