From 4771e710d260bed8ae332cb745ede45670e430dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikko=20V=C3=A4rri?= Date: Sun, 12 Mar 2017 03:47:51 +0200 Subject: [PATCH 1/2] GROOVY-8117: Add test. --- .../tools/groovydoc/GroovyDocToolTest.java | 40 +++++++++++++++++-- .../testfiles/alias/FooAdapter.groovy | 32 +++++++++++++++ .../groovydoc/testfiles/alias/api/Foo.java | 26 ++++++++++++ .../groovydoc/testfiles/alias/lib/Foo.java | 26 ++++++++++++ 4 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/FooAdapter.groovy create mode 100644 subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/api/Foo.java create mode 100644 subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/lib/Foo.java diff --git a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java index 6b68ef4ebcd..7e31ca1e500 100644 --- a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java +++ b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/GroovyDocToolTest.java @@ -21,9 +21,7 @@ import groovy.util.GroovyTestCase; import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -658,6 +656,42 @@ public void testClassAliasing() throws Exception { assertEquals("There has to be a reference to class ArrayList", "ArrayList", m.group(2)); } + public void testImplementedInterfaceWithAlias() throws Exception { + // FooAdapter imports both api.Foo and lib.Foo, using "lib.Foo as FooImpl" to disambiguate. + // lib.Foo is imported later that api.Foo, so groovydoc tries to resolve to lib.Foo first. + htmlTool.add(Arrays.asList( + "org/codehaus/groovy/tools/groovydoc/testfiles/alias/api/Foo.java", + "org/codehaus/groovy/tools/groovydoc/testfiles/alias/lib/Foo.java", + "org/codehaus/groovy/tools/groovydoc/testfiles/alias/FooAdapter.groovy" + )); + + final MockOutputTool output = new MockOutputTool(); + htmlTool.renderToOutput(output, MOCK_DIR); + final String fooAdapterDoc = output.getText(MOCK_DIR + "/org/codehaus/groovy/tools/groovydoc/testfiles/alias/FooAdapter.html"); + + // "Interfaces and Traits" section should show "Foo" as one of the implemented interfaces, + // and that should link to api/Foo.html, not to lib/Foo.html. + final Matcher interfacesAndTraits = Pattern.compile( + "
All Implemented Interfaces and Traits:
\\s*" + + "
(Foo|FooImpl)
" + ).matcher(fooAdapterDoc); + + // Constructor is actually "FooAdapter(FooImpl foo)", + // but it should show "Foo" as the link text, not "FooImpl". + // The Foo parameter type should link to lib/Foo.html, not api/Foo.html. + final Matcher constructor = Pattern.compile( + "FooAdapter()*\\((Foo|FooImpl) foo\\)" + ).matcher(fooAdapterDoc); + + assertTrue("Interfaces and Traits pattern should match for this test to make sense", interfacesAndTraits.find()); + assertTrue("Constructor pattern should match for this test to make sense", constructor.find()); + + assertEquals("The implemented interface should link to api.Foo", "api", interfacesAndTraits.group(1)); + assertEquals("The implemented interface link text should be Foo", "Foo", interfacesAndTraits.group(2)); + assertEquals("The constructor parameter should link to lib.Foo", "lib", constructor.group(2)); + assertEquals("The constructor parameter link text should be Foo", "Foo", constructor.group(3)); + } + public void testScript() throws Exception { List srcList = new ArrayList(); srcList.add("org/codehaus/groovy/tools/groovydoc/testfiles/Script.groovy"); diff --git a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/FooAdapter.groovy b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/FooAdapter.groovy new file mode 100644 index 00000000000..70da911afd4 --- /dev/null +++ b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/FooAdapter.groovy @@ -0,0 +1,32 @@ +/* + * 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. + */ +package org.codehaus.groovy.tools.groovydoc.testfiles.alias + +import org.codehaus.groovy.tools.groovydoc.testfiles.alias.api.Foo +import org.codehaus.groovy.tools.groovydoc.testfiles.alias.lib.Foo as FooImpl + +/** + * An adapter class that makes an instance of + * {@link org.codehaus.groovy.tools.groovydoc.testfiles.alias.lib.Foo library Foo} + * appear to be an instance of + * {@link org.codehaus.groovy.tools.groovydoc.testfiles.alias.api.Foo API Foo}. + */ +class FooAdapter implements Foo { + FooAdapter(FooImpl foo) {} +} diff --git a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/api/Foo.java b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/api/Foo.java new file mode 100644 index 00000000000..97d0bd3130f --- /dev/null +++ b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/api/Foo.java @@ -0,0 +1,26 @@ +/* + * 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. + */ +package org.codehaus.groovy.tools.groovydoc.testfiles.alias.api; + +/** + * A Foo type defined by some API, unrelated to the + * {@link org.codehaus.groovy.tools.groovydoc.testfiles.alias.lib.Foo library Foo}. + */ +public interface Foo { +} diff --git a/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/lib/Foo.java b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/lib/Foo.java new file mode 100644 index 00000000000..05e218416c0 --- /dev/null +++ b/subprojects/groovy-groovydoc/src/test/groovy/org/codehaus/groovy/tools/groovydoc/testfiles/alias/lib/Foo.java @@ -0,0 +1,26 @@ +/* + * 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. + */ +package org.codehaus.groovy.tools.groovydoc.testfiles.alias.lib; + +/** + * A Foo type defined by some library, unrelated to the + * {@link org.codehaus.groovy.tools.groovydoc.testfiles.alias.api.Foo API Foo}. + */ +public class Foo { +} From 67fbd902268a9809a9f4cebb26757b70f3062895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikko=20V=C3=A4rri?= Date: Sun, 12 Mar 2017 03:48:40 +0200 Subject: [PATCH 2/2] GROOVY-8117: Do not resolve aliased imports early. --- .../groovy/tools/groovydoc/SimpleGroovyClassDocAssembler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDocAssembler.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDocAssembler.java index 7439ea7ed50..8e4fca423c5 100644 --- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDocAssembler.java +++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDocAssembler.java @@ -742,7 +742,7 @@ private static String getText(GroovySourceAST node) { return returnValue; } - // preempt resolve as info is partially available here (star imports won't match here) + // preempt resolve as info is partially available here (aliases and star imports won't match here) private String extractName(GroovySourceAST typeNode) { String typeName = buildName(typeNode); if (!typeName.contains("/")) { @@ -750,7 +750,7 @@ private String extractName(GroovySourceAST typeNode) { // Groovy currently resolves this to last found so traverse in reverse order for (int i = importedClassesAndPackages.size() - 1; i >= 0; i--) { String name = importedClassesAndPackages.get(i); - if (name.endsWith(slashName)) { + if (!aliases.containsValue(name) && name.endsWith(slashName)) { typeName = name; break; }