Skip to content

Commit

Permalink
Merge branch 'delivery' into del-master-20rc3
Browse files Browse the repository at this point in the history
  • Loading branch information
neilcsmith-net committed Nov 2, 2023
2 parents c3bd066 + a385cb1 commit 317bc96
Show file tree
Hide file tree
Showing 43 changed files with 302 additions and 1,897 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,9 @@
<bind actionName="jump-list-next" key="O-RIGHT"/>
<bind actionName="jump-list-next" key="O-KP_RIGHT"/>
<bind actionName="jump-list-next" key="MOUSE_BUTTON5"/>
<bind actionName="jump-list-next" key="MOUSE_BUTTON7"/>
<bind actionName="jump-list-prev" key="O-LEFT"/>
<bind actionName="jump-list-prev" key="O-KP_LEFT"/>
<bind actionName="jump-list-prev" key="MOUSE_BUTTON4"/>
<bind actionName="jump-list-prev" key="MOUSE_BUTTON6"/>
<bind actionName="page-down" key="PAGE_DOWN"/>
<bind actionName="page-up" key="PAGE_UP"/>
<bind actionName="paste-formated" key="DS-V"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,10 @@ static void completeOpeningBracket(TypedTextInterceptor.MutableContext context)
return;
}

char insChr = context.getText().charAt(0);

if (isString(currentToken)) {
if (context.getOffset() >= 1 && context.getText().charAt(0) == '{') {
if (context.getOffset() >= 1 && insChr == '{') {
char chr = context.getDocument().getText(context.getOffset() - 1, 1).charAt(0);

if (chr == '\\') {
Expand All @@ -180,10 +182,14 @@ static void completeOpeningBracket(TypedTextInterceptor.MutableContext context)
return ;
}

if (insChr == '{') {
//curly brace should only be matched in string templates:
return ;
}

char chr = context.getDocument().getText(context.getOffset(), 1).charAt(0);

if (chr == ')' || chr == ',' || chr == '\"' || chr == '\'' || chr == ' ' || chr == ']' || chr == '}' || chr == '\n' || chr == '\t' || chr == ';') {
char insChr = context.getText().charAt(0);
context.setText("" + insChr + matching(insChr), 1); // NOI18N
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,12 @@ public void testSkipTemplate1() throws Exception {
ctx.assertDocumentTextEquals("\"\\{}|\"");
}

public void testX() throws Exception {
Context ctx = new Context(new JavaKit(), "");
ctx.typeChar('{');
ctx.assertDocumentTextEquals("{");
}

private boolean isInsideString(String code) throws BadLocationException {
int pos = code.indexOf('|');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,10 @@ public static final class Collection {
private static final Set<String> READ_METHODS = new HashSet<>(Arrays.asList(
"get", "getOrDefault", "contains", "remove", "containsAll", "removeAll", "removeIf", "retain", "retainAll", "containsKey",
"containsValue", "iterator", "listIterator", "isEmpty", "size", "toArray", "entrySet", "keySet", "values", "indexOf", "lastIndexOf",
"stream", "parallelStream", "spliterator", "forEach"));
private static final Set<String> WRITE_METHODS = new HashSet<>(Arrays.asList("add", "addAll", "set", "put", "putAll", "putIfAbsent"));
"stream", "parallelStream", "spliterator", "reversed", "getFirst", "getLast", "removeFirst", "removeLast"));
private static final Set<String> STANDALONE_READ_METHODS = new HashSet<>(Arrays.asList(
"forEach"));
private static final Set<String> WRITE_METHODS = new HashSet<>(Arrays.asList("add", "addAll", "set", "put", "putAll", "putIfAbsent", "addFirst", "addLast"));

private static boolean testType(CompilationInfo info, TypeMirror actualType, String superClass) {
TypeElement juCollection = info.getElements().getTypeElement(superClass);
Expand Down Expand Up @@ -244,6 +246,9 @@ public static ErrorDescription before(HintContext ctx) {
record(ctx.getInfo(), var, State.READ);
}
return null;
} else if (STANDALONE_READ_METHODS.contains(methodName)) {
record(ctx.getInfo(), var, State.READ);
return null;
} else if (WRITE_METHODS.contains(methodName)) {
if (tp.getParentPath().getParentPath().getParentPath().getLeaf().getKind() != Kind.EXPRESSION_STATEMENT) {
record(ctx.getInfo(), var, State.WRITE, State.READ);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.netbeans.api.java.source.CompilationInfo;
Expand Down Expand Up @@ -133,25 +134,44 @@ private static Pair<Set<Tree>, Set<Element>> computeUsedAssignments(final HintCo
@TriggerPattern("$mods$ $type $var = $value;")
})
public static ErrorDescription unusedAssignment(final HintContext ctx) {
final CompilationInfo info = ctx.getInfo();
Element var = info.getTrees().getElement(ctx.getVariables().get("$var"));

if (var == null || !LOCAL_VARIABLES.contains(var.getKind()) ||
isImplicitParamOfRecordCanonicalConstructor(info, var)) {
return null;
}

final String unusedAssignmentLabel = NbBundle.getMessage(UnusedAssignmentOrBranch.class, "LBL_UNUSED_ASSIGNMENT_LABEL");
Pair<Set<Tree>, Set<Element>> computedAssignments = computeUsedAssignments(ctx);

if (ctx.isCanceled() || computedAssignments == null) return null;

final CompilationInfo info = ctx.getInfo();
final Set<Tree> usedAssignments = computedAssignments.first();
final Set<Element> usedVariables = computedAssignments.second();
Element var = info.getTrees().getElement(ctx.getVariables().get("$var"));
TreePath valuePath = ctx.getVariables().get("$value");
Tree value = (valuePath == null ? ctx.getPath() : valuePath).getLeaf();

if (var != null && LOCAL_VARIABLES.contains(var.getKind()) && !usedAssignments.contains(value) && usedVariables.contains(var)) {
if (!usedAssignments.contains(value) && usedVariables.contains(var)) {
return ErrorDescriptionFactory.forTree(ctx, value, unusedAssignmentLabel);
}

return null;
}


private static boolean isImplicitParamOfRecordCanonicalConstructor(CompilationInfo info, Element el) {
Element enclosingElement = el.getEnclosingElement();

if (enclosingElement.getKind() != ElementKind.CONSTRUCTOR) {
return false;
}

ExecutableElement constr = (ExecutableElement) enclosingElement;

return info.getElements().isCompactConstructor(constr) &&
constr.getParameters().contains(el);
}

private static boolean mayHaveSideEffects(HintContext ctx, TreePath path) {
SideEffectVisitor visitor = new SideEffectVisitor(ctx).stopOnUnknownMethods(true);
Tree culprit = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,4 +412,53 @@ public void testCollectionNegEnhForLoop() throws Exception {
.run(Unbalanced.Collection.class)
.assertWarnings();
}

public void testListForEach() throws Exception {
HintTest
.create()
.input("package test;\n" +
"public class Test {\n" +
" public void t() {\n" +
" java.util.List<String> coll = new java.util.ArrayList<String>();\n" +
" coll.add(\"\");\n" +
" coll.forEach(e -> {});\n" +
" }\n" +
"}\n")
.run(Unbalanced.Collection.class)
.assertWarnings();
}

public void testSequencedCollection1() throws Exception {
HintTest
.create()
.input("package test;\n" +
"public class Test {\n" +
" public void t() {\n" +
" java.util.List<String> coll = new java.util.ArrayList<String>();\n" +
" coll.addFirst(\"\");\n" +
" coll.addLast(\"\");\n" +
" }\n" +
"}\n", false)
.run(Unbalanced.Collection.class)
.assertWarnings("3:31-3:35:verifier:ERR_UnbalancedCollectionWRITE coll");
}

public void testSequencedCollection2() throws Exception {
HintTest
.create()
.input("package test;\n" +
"public class Test {\n" +
" public void t() {\n" +
" java.util.List<String> coll = new java.util.ArrayList<String>();\n" +
" Object sink;\n" +
" sink = coll.reversed();\n" +
" sink = coll.getFirst();\n" +
" sink = coll.getLast();\n" +
" sink = coll.removeFirst();\n" +
" sink = coll.removeLast();\n" +
" }\n" +
"}\n", false)
.run(Unbalanced.Collection.class)
.assertWarnings("3:31-3:35:verifier:ERR_UnbalancedCollectionREAD coll");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.netbeans.modules.java.hints.bugs;

import org.junit.Assume;
import org.netbeans.junit.NbTestCase;
import org.netbeans.modules.java.hints.test.api.HintTest;

Expand Down Expand Up @@ -211,4 +212,30 @@ public void testImplicitlyStaticFieldWithInitializer() throws Exception {
.run(UnusedAssignmentOrBranch.class)
.assertWarnings();
}

public void testRecordCompactConstructor() throws Exception {
Assume.assumeTrue(isRecordClassPresent());

HintTest
.create()
.input("package test;\n" +
"\n" +
"public record Test(int i, int j) {\n" +
" public Test {\n" +
" i = -i;\n" +
" }\n" +
"}")
.sourceLevel("21")
.run(UnusedAssignmentOrBranch.class)
.assertWarnings();
}

private boolean isRecordClassPresent() {
try {
Class.forName("java.lang.Record");
return true;
} catch (ClassNotFoundException ex) {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,3 @@

primingBuild.snapshot.goals=install
primingBuild.regular.goals=install
skipTests=true
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
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.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo;
Expand Down Expand Up @@ -54,13 +56,15 @@ public ClassFinder make(Context c) {

private final Context context;
private final Names names;
private final Symtab syms;
private final JCDiagnostic.Factory diagFactory;
private final Log log;

public NBClassFinder(Context context) {
super(context);
this.context = context;
this.names = Names.instance(context);
this.syms = Symtab.instance(context);
this.diagFactory = JCDiagnostic.Factory.instance(context);
this.log = Log.instance(context);
}
Expand Down Expand Up @@ -95,6 +99,7 @@ public Completer getCompleter() {
delegate.complete(sym);
if (sym.kind == Kind.PCK &&
sym.flatName() == names.java_lang &&
((PackageSymbol) sym).modle == syms.java_base &&
sym.members().isEmpty()) {
sym.flags_field |= Flags.EXISTS;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ public void testEmptyClassPath() throws Exception {
assertEquals(expectedErrors, actualErrors);
}

public void testEmptyClassPath2() throws Exception {
String code = "package java.lang.nb.test; public class Test { String t(String s) { return s.toString(); } }";
List<String> expectedErrors;
expectedErrors = Arrays.asList("");
List<String> actualErrors;
actualErrors = compile(code, "-XDrawDiagnostics", "-XDide", "-Xlint:-options");
assertEquals(expectedErrors, actualErrors);
}

private static class MyFileObject extends SimpleJavaFileObject {
private String text;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ public Set<OutputProcessor> createProcessorsSet(Project project, RunConfig confi
if (config.getGoals().contains("test") //NOI18N
|| config.getGoals().contains("integration-test") //NOI18N
|| config.getGoals().contains("surefire:test") //NOI81N
|| config.getGoals().contains("failsafe:integration-test") //NOI18N
|| config.getGoals().contains("verify")) { //NOI18N
Set<OutputProcessor> toReturn = new HashSet<OutputProcessor>();
Set<OutputProcessor> toReturn = new HashSet<>();
if (project != null) {
toReturn.add(new JUnitOutputListenerProvider(config));
}
Expand Down
14 changes: 0 additions & 14 deletions java/maven/apichanges.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,6 @@ is the proper place.
<!-- ACTUAL CHANGES BEGIN HERE: -->

<changes>
<change id="partial-maven-project">
<api name="general"/>
<summary>Support for partially loaded projects</summary>
<version major="2" minor="161"/>
<date day="3" month="10" year="2023"/>
<author login="sdedic"/>
<compatibility addition="yes" semantic="compatible"/>
<description>
Added a <a href="@TOP@/org/netbeans/modules/maven/api/NbMavenProject.html#getPartialProject-org.apache.maven.project.MavenProject-">
getPratialProject</a> that returns potentially incompletely loaded project instead of a mocked-up fallback (see <a href="@TOP@/org/netbeans/modules/maven/api/NbMavenProject.html#isErrorPlaceholder-org.apache.maven.project.MavenProject-">isErrorPlaceholder()</a>.
Also added a <a href="@TOP@/org/netbeans/modules/maven/api/NbMavenProject.html#isIncomplete-org.apache.maven.project.MavenProject-">isIncomplete()</a> check that checks project's status.
</description>
<class package="org.netbeans.modules.maven.api" name="NbMavenProject"/>
</change>
<change id="runutils-createconfig-action">
<api name="general"/>
<summary></summary>
Expand Down
3 changes: 1 addition & 2 deletions java/maven/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@
<package-artifact-from-dir jarbasename="test-lib3-12.6" relpath="projects/dependencies/repo/grp/test-lib3/12.6"/>
<package-artifact-from-dir jarbasename="test-lib4-12.6" relpath="projects/dependencies/repo/grp/test-lib4/12.6"/>
<package-artifact-from-dir jarbasename="test-processor-12.6" relpath="projects/dependencies/repo/grp/test-processor/12.6"/>

<chmod file="${build.test.unit.dir}/data/projects/multiproject/democa/mvnw" perm="ugo+rwx"/>

</target>

</project>
2 changes: 1 addition & 1 deletion java/maven/nbproject/project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ javadoc.apichanges=${basedir}/apichanges.xml
javadoc.arch=${basedir}/arch.xml
javahelp.hs=maven.hs
extra.module.files=maven-nblib/
spec.version.base=2.161.0
spec.version.base=2.160.0

# The CPExtender test fails in library processing (not randomly) since NetBeans 8.2; disabling.
test.excludes=**/CPExtenderTest.class
Expand Down
49 changes: 0 additions & 49 deletions java/maven/src/org/netbeans/modules/maven/NbArtifactFixer.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.maven.artifact.DefaultArtifact;
Expand Down Expand Up @@ -106,10 +105,6 @@ public class NbArtifactFixer implements ArtifactFixer {
//instead of workarounds down the road, we set the artifact's file here.
// some stacktraces to maven/aether do set it after querying our code, but some don't for reasons unknown to me.
artifact.setFile(f);
Set<Artifact> s = CAPTURE_FAKE_ARTIFACTS.get();
if (s != null) {
s.add(artifact);
}
return f;
} catch (IOException x) {
Exceptions.printStackTrace(x);
Expand Down Expand Up @@ -154,48 +149,4 @@ private static synchronized File createFallbackPOM(String groupId, String artifa
return fallbackPOM;
}

public interface ExceptionCallable<T, E extends Throwable> {
public T call() throws E;
}

@SuppressWarnings("unchecked")
private static <T extends Throwable> void sneakyThrow(Throwable exception) throws T {
throw (T) exception;
}

/**
* Collects faked artifacts, which would be otherwise hidden in maven infrastructure. The value is only valid during {@link #collectFallbackArtifacts}, which
* can be invoked recursively.
*/
private static ThreadLocal<Set<Artifact>> CAPTURE_FAKE_ARTIFACTS = new ThreadLocal<Set<Artifact>>();

/**
* Performs an operation and collects forged artifacts created during that operation. The invocation can be nested; each invocation gets only artifacts from its own 'level',
* not those from possible nested invocations. The function passes on all runtime exceptions and checked exception thrown by the operation.
*
* @param <T> value produced by the executed operation
* @param <E> exception thrown from the operation
* @param code the operation to call and monitor
* @param collector callback that will get collected artifacts.
* @return
* @throws E
*/
public static <T, E extends Throwable> T collectFallbackArtifacts(ExceptionCallable<T, E> code, Consumer<Set<Artifact>> collector) throws E {
Set<Artifact> save = CAPTURE_FAKE_ARTIFACTS.get();
try {
CAPTURE_FAKE_ARTIFACTS.set(new HashSet<>());
return code.call();
} catch (Error | RuntimeException r) {
throw r;
} catch (Exception ex) {
sneakyThrow(ex);
// unreachable
throw new Error();
} finally {
if (collector != null) {
collector.accept(CAPTURE_FAKE_ARTIFACTS.get());
}
CAPTURE_FAKE_ARTIFACTS.set(save);
}
}
}
Loading

0 comments on commit 317bc96

Please sign in to comment.