Skip to content

Commit

Permalink
Merge pull request #6632 from apache/delivery
Browse files Browse the repository at this point in the history
Sync delivery to release200 for 20-rc3
  • Loading branch information
neilcsmith-net committed Nov 3, 2023
2 parents d30b8ef + a385cb1 commit cbc39f8
Show file tree
Hide file tree
Showing 44 changed files with 303 additions and 1,898 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Expand Up @@ -758,7 +758,7 @@ jobs:
timeout-minutes: 60
strategy:
matrix:
java: [ '11', '17' ]
java: [ '11' ]
steps:

- name: Set up JDK ${{ matrix.java }}
Expand Down
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
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
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
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
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
Expand Up @@ -527,4 +527,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");
}
}
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;
}
}
}
Expand Up @@ -17,4 +17,3 @@

primingBuild.snapshot.goals=install
primingBuild.regular.goals=install
skipTests=true
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
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
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
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
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
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

0 comments on commit cbc39f8

Please sign in to comment.