Skip to content

Commit cbc39f8

Browse files
Merge pull request #6632 from apache/delivery
Sync delivery to release200 for 20-rc3
2 parents d30b8ef + a385cb1 commit cbc39f8

44 files changed

Lines changed: 303 additions & 1898 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ jobs:
758758
timeout-minutes: 60
759759
strategy:
760760
matrix:
761-
java: [ '11', '17' ]
761+
java: [ '11' ]
762762
steps:
763763

764764
- name: Set up JDK ${{ matrix.java }}

ide/editor/src/org/netbeans/modules/editor/resources/NetBeans-keybindings.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,9 @@
9797
<bind actionName="jump-list-next" key="O-RIGHT"/>
9898
<bind actionName="jump-list-next" key="O-KP_RIGHT"/>
9999
<bind actionName="jump-list-next" key="MOUSE_BUTTON5"/>
100-
<bind actionName="jump-list-next" key="MOUSE_BUTTON7"/>
101100
<bind actionName="jump-list-prev" key="O-LEFT"/>
102101
<bind actionName="jump-list-prev" key="O-KP_LEFT"/>
103102
<bind actionName="jump-list-prev" key="MOUSE_BUTTON4"/>
104-
<bind actionName="jump-list-prev" key="MOUSE_BUTTON6"/>
105103
<bind actionName="page-down" key="PAGE_DOWN"/>
106104
<bind actionName="page-up" key="PAGE_UP"/>
107105
<bind actionName="paste-formated" key="DS-V"/>

java/java.editor/src/org/netbeans/modules/editor/java/TypingCompletion.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,10 @@ static void completeOpeningBracket(TypedTextInterceptor.MutableContext context)
168168
return;
169169
}
170170

171+
char insChr = context.getText().charAt(0);
172+
171173
if (isString(currentToken)) {
172-
if (context.getOffset() >= 1 && context.getText().charAt(0) == '{') {
174+
if (context.getOffset() >= 1 && insChr == '{') {
173175
char chr = context.getDocument().getText(context.getOffset() - 1, 1).charAt(0);
174176

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

185+
if (insChr == '{') {
186+
//curly brace should only be matched in string templates:
187+
return ;
188+
}
189+
183190
char chr = context.getDocument().getText(context.getOffset(), 1).charAt(0);
184191

185192
if (chr == ')' || chr == ',' || chr == '\"' || chr == '\'' || chr == ' ' || chr == ']' || chr == '}' || chr == '\n' || chr == '\t' || chr == ';') {
186-
char insChr = context.getText().charAt(0);
187193
context.setText("" + insChr + matching(insChr), 1); // NOI18N
188194
}
189195
}

java/java.editor/test/unit/src/org/netbeans/modules/editor/java/TypingCompletionUnitTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,12 @@ public void testSkipTemplate1() throws Exception {
14131413
ctx.assertDocumentTextEquals("\"\\{}|\"");
14141414
}
14151415

1416+
public void testX() throws Exception {
1417+
Context ctx = new Context(new JavaKit(), "");
1418+
ctx.typeChar('{');
1419+
ctx.assertDocumentTextEquals("{");
1420+
}
1421+
14161422
private boolean isInsideString(String code) throws BadLocationException {
14171423
int pos = code.indexOf('|');
14181424

java/java.hints/src/org/netbeans/modules/java/hints/bugs/Unbalanced.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,10 @@ public static final class Collection {
199199
private static final Set<String> READ_METHODS = new HashSet<>(Arrays.asList(
200200
"get", "getOrDefault", "contains", "remove", "containsAll", "removeAll", "removeIf", "retain", "retainAll", "containsKey",
201201
"containsValue", "iterator", "listIterator", "isEmpty", "size", "toArray", "entrySet", "keySet", "values", "indexOf", "lastIndexOf",
202-
"stream", "parallelStream", "spliterator", "forEach"));
203-
private static final Set<String> WRITE_METHODS = new HashSet<>(Arrays.asList("add", "addAll", "set", "put", "putAll", "putIfAbsent"));
202+
"stream", "parallelStream", "spliterator", "reversed", "getFirst", "getLast", "removeFirst", "removeLast"));
203+
private static final Set<String> STANDALONE_READ_METHODS = new HashSet<>(Arrays.asList(
204+
"forEach"));
205+
private static final Set<String> WRITE_METHODS = new HashSet<>(Arrays.asList("add", "addAll", "set", "put", "putAll", "putIfAbsent", "addFirst", "addLast"));
204206

205207
private static boolean testType(CompilationInfo info, TypeMirror actualType, String superClass) {
206208
TypeElement juCollection = info.getElements().getTypeElement(superClass);
@@ -244,6 +246,9 @@ public static ErrorDescription before(HintContext ctx) {
244246
record(ctx.getInfo(), var, State.READ);
245247
}
246248
return null;
249+
} else if (STANDALONE_READ_METHODS.contains(methodName)) {
250+
record(ctx.getInfo(), var, State.READ);
251+
return null;
247252
} else if (WRITE_METHODS.contains(methodName)) {
248253
if (tp.getParentPath().getParentPath().getParentPath().getLeaf().getKind() != Kind.EXPRESSION_STATEMENT) {
249254
record(ctx.getInfo(), var, State.WRITE, State.READ);

java/java.hints/src/org/netbeans/modules/java/hints/bugs/UnusedAssignmentOrBranch.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.Set;
3232
import javax.lang.model.element.Element;
3333
import javax.lang.model.element.ElementKind;
34+
import javax.lang.model.element.ExecutableElement;
3435
import javax.lang.model.type.TypeKind;
3536
import javax.lang.model.type.TypeMirror;
3637
import org.netbeans.api.java.source.CompilationInfo;
@@ -133,25 +134,44 @@ private static Pair<Set<Tree>, Set<Element>> computeUsedAssignments(final HintCo
133134
@TriggerPattern("$mods$ $type $var = $value;")
134135
})
135136
public static ErrorDescription unusedAssignment(final HintContext ctx) {
137+
final CompilationInfo info = ctx.getInfo();
138+
Element var = info.getTrees().getElement(ctx.getVariables().get("$var"));
139+
140+
if (var == null || !LOCAL_VARIABLES.contains(var.getKind()) ||
141+
isImplicitParamOfRecordCanonicalConstructor(info, var)) {
142+
return null;
143+
}
144+
136145
final String unusedAssignmentLabel = NbBundle.getMessage(UnusedAssignmentOrBranch.class, "LBL_UNUSED_ASSIGNMENT_LABEL");
137146
Pair<Set<Tree>, Set<Element>> computedAssignments = computeUsedAssignments(ctx);
138147

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

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

148-
if (var != null && LOCAL_VARIABLES.contains(var.getKind()) && !usedAssignments.contains(value) && usedVariables.contains(var)) {
155+
if (!usedAssignments.contains(value) && usedVariables.contains(var)) {
149156
return ErrorDescriptionFactory.forTree(ctx, value, unusedAssignmentLabel);
150157
}
151158

152159
return null;
153160
}
154-
161+
162+
private static boolean isImplicitParamOfRecordCanonicalConstructor(CompilationInfo info, Element el) {
163+
Element enclosingElement = el.getEnclosingElement();
164+
165+
if (enclosingElement.getKind() != ElementKind.CONSTRUCTOR) {
166+
return false;
167+
}
168+
169+
ExecutableElement constr = (ExecutableElement) enclosingElement;
170+
171+
return info.getElements().isCompactConstructor(constr) &&
172+
constr.getParameters().contains(el);
173+
}
174+
155175
private static boolean mayHaveSideEffects(HintContext ctx, TreePath path) {
156176
SideEffectVisitor visitor = new SideEffectVisitor(ctx).stopOnUnknownMethods(true);
157177
Tree culprit = null;

java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/UnbalancedTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,4 +527,53 @@ public void testCollectionNegEnhForLoop() throws Exception {
527527
.run(Unbalanced.Collection.class)
528528
.assertWarnings();
529529
}
530+
531+
public void testListForEach() throws Exception {
532+
HintTest
533+
.create()
534+
.input("package test;\n" +
535+
"public class Test {\n" +
536+
" public void t() {\n" +
537+
" java.util.List<String> coll = new java.util.ArrayList<String>();\n" +
538+
" coll.add(\"\");\n" +
539+
" coll.forEach(e -> {});\n" +
540+
" }\n" +
541+
"}\n")
542+
.run(Unbalanced.Collection.class)
543+
.assertWarnings();
544+
}
545+
546+
public void testSequencedCollection1() throws Exception {
547+
HintTest
548+
.create()
549+
.input("package test;\n" +
550+
"public class Test {\n" +
551+
" public void t() {\n" +
552+
" java.util.List<String> coll = new java.util.ArrayList<String>();\n" +
553+
" coll.addFirst(\"\");\n" +
554+
" coll.addLast(\"\");\n" +
555+
" }\n" +
556+
"}\n", false)
557+
.run(Unbalanced.Collection.class)
558+
.assertWarnings("3:31-3:35:verifier:ERR_UnbalancedCollectionWRITE coll");
559+
}
560+
561+
public void testSequencedCollection2() throws Exception {
562+
HintTest
563+
.create()
564+
.input("package test;\n" +
565+
"public class Test {\n" +
566+
" public void t() {\n" +
567+
" java.util.List<String> coll = new java.util.ArrayList<String>();\n" +
568+
" Object sink;\n" +
569+
" sink = coll.reversed();\n" +
570+
" sink = coll.getFirst();\n" +
571+
" sink = coll.getLast();\n" +
572+
" sink = coll.removeFirst();\n" +
573+
" sink = coll.removeLast();\n" +
574+
" }\n" +
575+
"}\n", false)
576+
.run(Unbalanced.Collection.class)
577+
.assertWarnings("3:31-3:35:verifier:ERR_UnbalancedCollectionREAD coll");
578+
}
530579
}

java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/UnusedAssignmentOrBranchTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.netbeans.modules.java.hints.bugs;
2020

21+
import org.junit.Assume;
2122
import org.netbeans.junit.NbTestCase;
2223
import org.netbeans.modules.java.hints.test.api.HintTest;
2324

@@ -211,4 +212,30 @@ public void testImplicitlyStaticFieldWithInitializer() throws Exception {
211212
.run(UnusedAssignmentOrBranch.class)
212213
.assertWarnings();
213214
}
215+
216+
public void testRecordCompactConstructor() throws Exception {
217+
Assume.assumeTrue(isRecordClassPresent());
218+
219+
HintTest
220+
.create()
221+
.input("package test;\n" +
222+
"\n" +
223+
"public record Test(int i, int j) {\n" +
224+
" public Test {\n" +
225+
" i = -i;\n" +
226+
" }\n" +
227+
"}")
228+
.sourceLevel("21")
229+
.run(UnusedAssignmentOrBranch.class)
230+
.assertWarnings();
231+
}
232+
233+
private boolean isRecordClassPresent() {
234+
try {
235+
Class.forName("java.lang.Record");
236+
return true;
237+
} catch (ClassNotFoundException ex) {
238+
return false;
239+
}
240+
}
214241
}

java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/maven.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,3 @@
1717

1818
primingBuild.snapshot.goals=install
1919
primingBuild.regular.goals=install
20-
skipTests=true

java/lib.nbjavac/src/org/netbeans/lib/nbjavac/services/NBClassFinder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import com.sun.tools.javac.code.Symbol;
2525
import com.sun.tools.javac.code.Symbol.Completer;
2626
import com.sun.tools.javac.code.Symbol.CompletionFailure;
27+
import com.sun.tools.javac.code.Symbol.PackageSymbol;
28+
import com.sun.tools.javac.code.Symtab;
2729
import com.sun.tools.javac.util.Context;
2830
import com.sun.tools.javac.util.JCDiagnostic;
2931
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo;
@@ -54,13 +56,15 @@ public ClassFinder make(Context c) {
5456

5557
private final Context context;
5658
private final Names names;
59+
private final Symtab syms;
5760
private final JCDiagnostic.Factory diagFactory;
5861
private final Log log;
5962

6063
public NBClassFinder(Context context) {
6164
super(context);
6265
this.context = context;
6366
this.names = Names.instance(context);
67+
this.syms = Symtab.instance(context);
6468
this.diagFactory = JCDiagnostic.Factory.instance(context);
6569
this.log = Log.instance(context);
6670
}
@@ -95,6 +99,7 @@ public Completer getCompleter() {
9599
delegate.complete(sym);
96100
if (sym.kind == Kind.PCK &&
97101
sym.flatName() == names.java_lang &&
102+
((PackageSymbol) sym).modle == syms.java_base &&
98103
sym.members().isEmpty()) {
99104
sym.flags_field |= Flags.EXISTS;
100105
try {

0 commit comments

Comments
 (0)