This is an automated email from the ASF dual-hosted git repository. khmarbaise pushed a commit to branch JXR-135 in repository https://gitbox.apache.org/repos/asf/maven-jxr.git
commit a02d143266fa9863fba9937f50526790c3010701 Author: Jesper Udby <[email protected]> AuthorDate: Sun Jul 29 17:07:22 2018 +0200 [JXR-135] Invalid representation of inner class --- .../org/apache/maven/jxr/pacman/JavaFileImpl.java | 99 +++++++++++++--------- .../apache/maven/jxr/pacman/JavaFileImplTest.java | 50 +++++++++++ .../apache/maven/jxr/pacman/ClassWithNested.java | 40 +++++++++ 3 files changed, 150 insertions(+), 39 deletions(-) diff --git a/maven-jxr/src/main/java/org/apache/maven/jxr/pacman/JavaFileImpl.java b/maven-jxr/src/main/java/org/apache/maven/jxr/pacman/JavaFileImpl.java index e1594e7..923154d 100644 --- a/maven-jxr/src/main/java/org/apache/maven/jxr/pacman/JavaFileImpl.java +++ b/maven-jxr/src/main/java/org/apache/maven/jxr/pacman/JavaFileImpl.java @@ -70,58 +70,79 @@ public class JavaFileImpl { stok = this.getTokenizer( reader ); - while ( stok.nextToken() != StreamTokenizer.TT_EOF ) - { + parseRecursive( "", stok ); + } + finally + { + stok = null; + } + } - if ( stok.sval == null ) - { - continue; - } + private void parseRecursive( String nestedPrefix, StreamTokenizer stok ) + throws IOException + { + int openBracesCount = 0; + + while ( stok.nextToken() != StreamTokenizer.TT_EOF ) + { - //set the package - if ( "package".equals( stok.sval ) && stok.ttype != '\"' ) + if ( stok.sval == null ) + { + if ( stok.ttype == '{' ) { - stok.nextToken(); - this.setPackageType( new PackageType( stok.sval ) ); + openBracesCount++; } - - //set the imports - if ( "import".equals( stok.sval ) && stok.ttype != '\"' ) + else if ( stok.ttype == '}' ) { - stok.nextToken(); - - String name = stok.sval; - - /* - WARNING: this is a bug/non-feature in the current - StreamTokenizer. We needed to set the comment char as "*" - and packages that are imported with this (ex "test.*") will be - stripped( and become "test." ). Here we need to test for this - and if necessary re-add the char. - */ - if ( name.charAt( name.length() - 1 ) == '.' ) + if ( --openBracesCount == 0 ) { - name = name + '*'; + // break out of recursive + return; } - - this.addImportType( new ImportType( name ) ); } + continue; + } - // Add the class or classes. There can be several classes in one file so - // continue with the while loop to get them all. - if ( ( "class".equals( stok.sval ) || "interface".equals( stok.sval ) || "enum".equals( stok.sval ) ) - && stok.ttype != '\"' ) + //set the package + if ( "package".equals( stok.sval ) && stok.ttype != '\"' ) + { + stok.nextToken(); + this.setPackageType( new PackageType( stok.sval ) ); + } + + //set the imports + if ( "import".equals( stok.sval ) && stok.ttype != '\"' ) + { + stok.nextToken(); + + String name = stok.sval; + + /* + WARNING: this is a bug/non-feature in the current + StreamTokenizer. We needed to set the comment char as "*" + and packages that are imported with this (ex "test.*") will be + stripped( and become "test." ). Here we need to test for this + and if necessary re-add the char. + */ + if ( name.charAt( name.length() - 1 ) == '.' ) { - stok.nextToken(); - this.addClassType( new ClassType( stok.sval, - getFilenameWithoutPathOrExtension( this.getPath() ) ) ); + name = name + '*'; } + this.addImportType( new ImportType( name ) ); } - } - finally - { - stok = null; + + // Add the class or classes. There can be several classes in one file so + // continue with the while loop to get them all. + if ( ( "class".equals( stok.sval ) || "interface".equals( stok.sval ) || "enum".equals( stok.sval ) ) + && stok.ttype != '\"' ) + { + stok.nextToken(); + this.addClassType( new ClassType( nestedPrefix + stok.sval, + getFilenameWithoutPathOrExtension( this.getPath() ) ) ); + parseRecursive( nestedPrefix + stok.sval + ".", stok ); + } + } } diff --git a/maven-jxr/src/test/java/org/apache/maven/jxr/pacman/JavaFileImplTest.java b/maven-jxr/src/test/java/org/apache/maven/jxr/pacman/JavaFileImplTest.java new file mode 100644 index 0000000..ee919ac --- /dev/null +++ b/maven-jxr/src/test/java/org/apache/maven/jxr/pacman/JavaFileImplTest.java @@ -0,0 +1,50 @@ +package org.apache.maven.jxr.pacman; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.junit.Test; + +import java.nio.file.Paths; +import java.util.Iterator; +import java.util.List; + +import static org.junit.Assert.*; + +public class JavaFileImplTest { + @Test + public void testJXR_135_lotsOfNested() + throws Exception + { + JavaFileImpl javaFile = new JavaFileImpl( Paths.get( + "src/test/resources/jxr135/org/apache/maven/jxr/pacman/ClassWithNested.java" ), + "UTF-8" ); + final Iterator<ClassType> classTypes = javaFile.getClassTypes().iterator(); + assertEquals( "ClassWithNested", classTypes.next().getName() ); + assertEquals( "ClassWithNested.NestedInterface", classTypes.next().getName() ); + assertEquals( "ClassWithNested.NestedClassWithEnum", classTypes.next().getName() ); + assertEquals( "ClassWithNested.NestedClassWithEnum.NestedEnum", classTypes.next().getName() ); + assertEquals( "ClassWithNested.NestedClassWithEnum.NestedClass2", classTypes.next().getName() ); + assertEquals( "ClassWithNested.NestedClassWithEnum2", classTypes.next().getName() ); + assertEquals( "ClassWithNested.NestedClassWithEnum2.NestedEnum", classTypes.next().getName() ); + assertEquals( "ClassWithNested.NestedClassWithEnum2.NestedClass2", classTypes.next().getName() ); + assertEquals( "NotNested", classTypes.next().getName() ); + } + +} \ No newline at end of file diff --git a/maven-jxr/src/test/resources/jxr135/org/apache/maven/jxr/pacman/ClassWithNested.java b/maven-jxr/src/test/resources/jxr135/org/apache/maven/jxr/pacman/ClassWithNested.java new file mode 100644 index 0000000..cca3e5c --- /dev/null +++ b/maven-jxr/src/test/resources/jxr135/org/apache/maven/jxr/pacman/ClassWithNested.java @@ -0,0 +1,40 @@ +package org.apache.maven.jxr; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Class part of the test for JXR-135 illustrating the use of nested classes, interfaces and enums + */ +public class ClassWithNested +{ + public interface NestedInterface {} + public static class NestedClassWithEnum { + public enum NestedEnum { } + public class NestedClass2 { + } + } + + public static class NestedClassWithEnum2 { + public enum NestedEnum { } + public class NestedClass2 { + } + } +} +class NotNested {}
