diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java index f92497562cd2d..6c4729c217a40 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1094,6 +1094,9 @@ public void visitProvides(JCProvides tree) { } finally { env.info.visitingServiceImplementation = prevVisitingServiceImplementation; } + if (!it.hasTag(CLASS)) { + continue; + } ClassSymbol impl = (ClassSymbol) it.tsym; if ((impl.flags_field & PUBLIC) == 0) { log.error(implName.pos(), Errors.NotDefPublic(impl, impl.location())); diff --git a/test/langtools/tools/javac/modules/AnnotationProcessing.java b/test/langtools/tools/javac/modules/AnnotationProcessing.java index 029166b876b0a..961a3f5c31dc3 100644 --- a/test/langtools/tools/javac/modules/AnnotationProcessing.java +++ b/test/langtools/tools/javac/modules/AnnotationProcessing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 8133884 8162711 8133896 8172158 8172262 8173636 8175119 8189747 8236842 8254023 8263432 + * @bug 8133884 8162711 8133896 8172158 8172262 8173636 8175119 8189747 8236842 8254023 8263432 8305225 * @summary Verify that annotation processing works. * @library /tools/lib * @modules @@ -2133,6 +2133,94 @@ public boolean process(Set annotations, RoundEnvironment } + @Test + public void testCreateProvidesWithAP(Path base) throws Exception { + Path src = base.resolve("src"); + Path m1 = src.resolve("m"); + + tb.writeJavaFiles(m1, + """ + module m { + provides api1.Api with test.Test; + uses api1.Api; + uses api2.Api; + } + """); + + Path classes = base.resolve("classes"); + Files.createDirectories(classes); + + List expectedErrors = List.of( + "module-info.java:2:18: compiler.err.doesnt.exist: api1", + "module-info.java:2:32: compiler.err.doesnt.exist: test", + "module-info.java:3:14: compiler.err.doesnt.exist: api1", + "module-info.java:4:14: compiler.err.doesnt.exist: api2", + "4 errors"); + List actualErrors = new JavacTask(tb) + .options("-XDrawDiagnostics") + .outdir(classes) + .files(findJavaFiles(m1)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutputLines(OutputKind.DIRECT); + + tb.checkEqual(expectedErrors, actualErrors); + + new JavacTask(tb) + .options("-processor", CreateProvidesWithAP.class.getName()) + .outdir(classes) + .files(findJavaFiles(m1)) + .run() + .writeAll(); + } + + @SupportedAnnotationTypes("*") + public static final class CreateProvidesWithAP extends AbstractProcessor { + + int round; + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + processingEnv.getElementUtils().getModuleElement("m").getDirectives(); + if (round++ == 0) { + try (Writer w = processingEnv.getFiler().createSourceFile("test.Test").openWriter()) { + w.append(""" + package test; + public class Test implements api1.Api { + } + """); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + try (Writer w = processingEnv.getFiler().createSourceFile("api1.Api").openWriter()) { + w.append(""" + package api1; + public interface Api { + } + """); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + try (Writer w = processingEnv.getFiler().createSourceFile("api2.Api").openWriter()) { + w.append(""" + package api2; + public interface Api { + } + """); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + return false; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + } + private static void assertNonNull(String msg, Object val) { if (val == null) { throw new AssertionError(msg);