This is an automated email from the ASF dual-hosted git repository. jlahoda pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push: new 1115605 When java.lang is not available, avoid throwing a FatalError, but rather try to report an error to the user and continue. 1115605 is described below commit 11156054b7c12b8e1eaf567010d62d83342ac796 Author: Jan Lahoda <jlah...@netbeans.org> AuthorDate: Sat Oct 9 07:24:09 2021 +0200 When java.lang is not available, avoid throwing a FatalError, but rather try to report an error to the user and continue. --- .../lib/nbjavac/services/NBClassFinder.java | 59 +++++++++ .../lib/nbjavac/services/NBClassFinderTest.java | 139 +++++++++++++++++++++ 2 files changed, 198 insertions(+) diff --git a/java/lib.nbjavac/src/org/netbeans/lib/nbjavac/services/NBClassFinder.java b/java/lib.nbjavac/src/org/netbeans/lib/nbjavac/services/NBClassFinder.java index c43f322..11f67b3 100644 --- a/java/lib.nbjavac/src/org/netbeans/lib/nbjavac/services/NBClassFinder.java +++ b/java/lib.nbjavac/src/org/netbeans/lib/nbjavac/services/NBClassFinder.java @@ -19,7 +19,23 @@ package org.netbeans.lib.nbjavac.services; import com.sun.tools.javac.code.ClassFinder; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Kinds.Kind; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Symbol.Completer; +import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.JCDiagnostic; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; +import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.function.Supplier; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.tools.JavaFileObject; /** @@ -36,8 +52,17 @@ public class NBClassFinder extends ClassFinder { }); } + private final Context context; + private final Names names; + private final JCDiagnostic.Factory diagFactory; + private final Log log; + public NBClassFinder(Context context) { super(context); + this.context = context; + this.names = Names.instance(context); + this.diagFactory = JCDiagnostic.Factory.instance(context); + this.log = Log.instance(context); } @Override @@ -55,4 +80,38 @@ public class NBClassFinder extends ClassFinder { return super.preferredFileObject(a, b); } + private Completer completer; + + @Override + public Completer getCompleter() { + if (completer == null) { + try { + Class.forName("com.sun.tools.javac.model.LazyTreeLoader"); + //patched nb-javac, handles missing java.lang itself: + completer = super.getCompleter(); + } catch (ClassNotFoundException e) { + Completer delegate = super.getCompleter(); + completer = sym -> { + delegate.complete(sym); + if (sym.kind == Kind.PCK && + sym.flatName() == names.java_lang && + sym.members().isEmpty()) { + sym.flags_field |= Flags.EXISTS; + try { + Class<?> dcfhClass = Class.forName("com.sun.tools.javac.code.DeferredCompletionFailureHandler"); + Constructor<CompletionFailure> constr = CompletionFailure.class.getDeclaredConstructor(Symbol.class, Supplier.class, dcfhClass); + Object dcfh = dcfhClass.getDeclaredMethod("instance", Context.class).invoke(null, context); + throw constr.newInstance(sym, (Supplier<JCDiagnostic>) () -> { + return diagFactory.create(log.currentSource(), new SimpleDiagnosticPosition(0), DiagnosticInfo.of(DiagnosticType.ERROR, "compiler", "cant.resolve", "package", "java.lang")); + }, dcfh); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException ex) { + Logger.getLogger(NBClassFinder.class.getName()).log(Level.FINE, null, ex); + } + } + }; + } + } + return completer; + } + } diff --git a/java/lib.nbjavac/test/unit/src/org/netbeans/lib/nbjavac/services/NBClassFinderTest.java b/java/lib.nbjavac/test/unit/src/org/netbeans/lib/nbjavac/services/NBClassFinderTest.java new file mode 100644 index 0000000..8280dc0 --- /dev/null +++ b/java/lib.nbjavac/test/unit/src/org/netbeans/lib/nbjavac/services/NBClassFinderTest.java @@ -0,0 +1,139 @@ +/* + * 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.netbeans.lib.nbjavac.services; + +import com.sun.source.util.JavacTask; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.util.Context; +import java.io.File; +import java.io.StringWriter; +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; +import org.netbeans.junit.NbTestCase; + +/** + * + * @author lahvac + */ +public class NBClassFinderTest extends NbTestCase { + + public NBClassFinderTest(String testName) { + super(testName); + } + + public void testEmptyClassPath() throws Exception { + String code = "package test; public class Test { void t(String s) { Integer i = s; } }"; + if (hasPatchedNbJavac()) { + List<String> expectedErrors; + expectedErrors = + Arrays.asList( + "Test.java:1:1: compiler.err.cant.access: java.lang, (compiler.misc.fatal.err.no.java.lang)", + "Test.java:1:42: compiler.err.cant.resolve.location: kindname.class, String, , , (compiler.misc.location: kindname.class, test.Test, null)" + ); + List<String> actualErrors; + actualErrors = compile(code, "-bootclasspath", "", "--system", "none", "-XDrawDiagnostics", "-source", "8", "-XDide"); + assertEquals(expectedErrors, actualErrors); + actualErrors = compile(code, "-bootclasspath", "", "--system", "none", "-XDrawDiagnostics", "-XDide"); + assertEquals(expectedErrors, actualErrors); + expectedErrors = Arrays.asList("Fatal Error: Unable to find package java.lang in classpath or bootclasspath"); + actualErrors = compile(code, "-bootclasspath", "", "--system", "none", "-XDrawDiagnostics", "-source", "8", "-XDide", "-XDbackgroundCompilation"); + assertEquals(expectedErrors, actualErrors); + actualErrors = compile(code, "-bootclasspath", "", "--system", "none", "-XDrawDiagnostics", "-XDide", "-XDbackgroundCompilation"); + assertEquals(expectedErrors, actualErrors); + } else { + List<String> expectedErrors; + expectedErrors = + Arrays.asList( + "Test.java:1:22: compiler.err.cant.access: java.lang, (compiler.err.cant.resolve: package, java.lang)", + "Test.java:1:42: compiler.err.cant.resolve.location: kindname.class, String, , , (compiler.misc.location: kindname.class, test.Test, null)" + ); + List<String> actualErrors; + actualErrors = compile(code, "-bootclasspath", "", "--system", "none", "-XDrawDiagnostics", "-source", "8", "-XDide"); + assertEquals(expectedErrors, actualErrors); + actualErrors = compile(code, "-bootclasspath", "", "--system", "none", "-XDrawDiagnostics", "-XDide"); + assertEquals(expectedErrors, actualErrors); + expectedErrors = + Arrays.asList( + "Test.java:1:22: compiler.err.cant.access: java.lang, (compiler.err.cant.resolve: package, java.lang)", + "Test.java:1:42: compiler.err.cant.resolve.location: kindname.class, String, , , (compiler.misc.location: kindname.class, test.Test, null)" + ); + actualErrors = compile(code, "-bootclasspath", "", "--system", "none", "-XDrawDiagnostics", "-source", "8", "-XDide", "-XDbackgroundCompilation"); + assertEquals(expectedErrors, actualErrors); + actualErrors = compile(code, "-bootclasspath", "", "--system", "none", "-XDrawDiagnostics", "-XDide", "-XDbackgroundCompilation"); + assertEquals(expectedErrors, actualErrors); + } + } + + private static class MyFileObject extends SimpleJavaFileObject { + private String text; + + public MyFileObject(String text) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + this.text = text; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return text; + } + } + + private File workingDir; + + @Override + protected void setUp() throws Exception { + workingDir = getWorkDir(); + } + + private List<String> compile(String code, String... options) throws Exception { + final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); + assert tool != null; + + StandardJavaFileManager std = tool.getStandardFileManager(null, null, null); + + std.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(workingDir)); + + Context context = new Context(); + NBClassFinder.preRegister(context); + StringWriter sw = new StringWriter(); + List<String> optionsList = Arrays.asList(options); + final JavacTask ct = ((JavacTool)tool).getTask(sw, std, null, optionsList, null, Arrays.asList(new MyFileObject(code)), context); + + ct.analyze(); + + return Arrays.asList(sw.toString().split("\\R")); + } + + private static boolean hasPatchedNbJavac() { + try { + Class.forName("com.sun.tools.javac.model.LazyTreeLoader"); + return true; + } catch (ClassNotFoundException ex) { + return false; + } + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists