2525
2626package com .sun .tools .javac .code ;
2727
28- import java .util .ArrayList ;
29- import java .util .Comparator ;
3028import java .util .HashMap ;
3129import java .util .Iterator ;
30+ import java .util .LinkedList ;
3231import java .util .List ;
3332import java .util .Map ;
34- import java .util .Objects ;
3533import java .util .Optional ;
3634import java .util .function .Consumer ;
37- import java .util .stream .Stream ;
3835
39- import javax .tools .DiagnosticListener ;
4036import javax .tools .JavaFileObject ;
4137
4238import com .sun .tools .javac .tree .EndPosTable ;
@@ -126,9 +122,10 @@ public boolean isKnown(JavaFileObject sourceFile) {
126122 */
127123 public Optional <Lint > lintAt (JavaFileObject sourceFile , DiagnosticPosition pos ) {
128124 initializeIfNeeded ();
129- return Optional .of (sourceFile )
130- .map (fileInfoMap ::get )
131- .flatMap (fileInfo -> fileInfo .lintAt (pos ));
125+ FileInfo fileInfo = fileInfoMap .get (sourceFile );
126+ if (fileInfo != null )
127+ return fileInfo .lintAt (pos );
128+ return Optional .empty ();
132129 }
133130
134131 /**
@@ -180,15 +177,15 @@ public void finishParsingFile(JCCompilationUnit tree) {
180177 private static class FileInfo {
181178
182179 final LintRange rootRange ; // the root LintRange (covering the entire source file)
183- final List <Span > unmappedDecls = new ArrayList <>(); // unmapped top-level declarations awaiting attribution
180+ final List <Span > unmappedDecls = new LinkedList <>(); // unmapped top-level declarations awaiting attribution
184181
185182 // After parsing: Add top-level declarations to our "unmappedDecls" list
186183 FileInfo (Lint rootLint , JCCompilationUnit tree ) {
187184 rootRange = new LintRange (rootLint );
188- tree .defs . stream ()
189- . filter ( this :: isTopLevelDecl )
190- . map ( decl -> new Span (decl , tree .endPositions ))
191- . forEach ( unmappedDecls :: add );
185+ for ( JCTree decl : tree .defs ) {
186+ if ( isTopLevelDecl ( decl ) )
187+ unmappedDecls . add ( new Span (decl , tree .endPositions ));
188+ }
192189 }
193190
194191 // After attribution: Discard the span from "unmappedDecls" and populate the declaration's subtree under "rootRange"
@@ -205,8 +202,11 @@ void afterAttr(JCTree tree, EndPosTable endPositions) {
205202
206203 // Find the most specific Lint configuration applying to the given position, unless the position has not been mapped yet
207204 Optional <Lint > lintAt (DiagnosticPosition pos ) {
208- boolean mapped = unmappedDecls .stream ().noneMatch (span -> span .contains (pos ));
209- return mapped ? Optional .of (rootRange .bestMatch (pos ).lint ) : Optional .empty ();
205+ for (Span span : unmappedDecls ) {
206+ if (span .contains (pos ))
207+ return Optional .empty ();
208+ }
209+ return Optional .of (rootRange .bestMatch (pos ).lint );
210210 }
211211
212212 boolean isTopLevelDecl (JCTree tree ) {
@@ -252,21 +252,27 @@ private record LintRange(
252252
253253 // Create a node representing the entire file, using the root lint configuration
254254 LintRange (Lint rootLint ) {
255- this (Span .MAXIMAL , rootLint , new ArrayList <>());
255+ this (Span .MAXIMAL , rootLint , new LinkedList <>());
256256 }
257257
258258 // Create a node representing the given declaration and its corresponding Lint configuration
259259 LintRange (JCTree tree , EndPosTable endPositions , Lint lint ) {
260- this (new Span (tree , endPositions ), lint , new ArrayList <>());
260+ this (new Span (tree , endPositions ), lint , new LinkedList <>());
261261 }
262262
263263 // Find the most specific node in this tree (including me) that contains the given position, if any
264264 LintRange bestMatch (DiagnosticPosition pos ) {
265- return children .stream ()
266- .map (child -> child .bestMatch (pos ))
267- .filter (Objects ::nonNull )
268- .reduce ((a , b ) -> a .span .contains (b .span ) ? b : a )
269- .orElseGet (() -> span .contains (pos ) ? this : null );
265+ LintRange bestMatch = null ;
266+ for (LintRange child : children ) {
267+ if (!child .span .contains (pos )) // don't recurse unless necessary
268+ continue ;
269+ LintRange childBestMatch = child .bestMatch (pos );
270+ if (childBestMatch != null && (bestMatch == null || bestMatch .span .contains (childBestMatch .span )))
271+ bestMatch = childBestMatch ;
272+ }
273+ if (bestMatch == null )
274+ bestMatch = span .contains (pos ) ? this : null ;
275+ return bestMatch ;
270276 }
271277
272278 // Populate a sparse subtree corresponding to the given nested declaration.
0 commit comments