This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 271070
Collapse All | Expand All

(-)a/spi.editor.hints/apichanges.xml (+15 lines)
Lines 193-198 Link Here
193
             </description>
193
             </description>
194
             <issue number="254375"/>
194
             <issue number="254375"/>
195
        </change>
195
        </change>
196
        
197
        <change id="multiple-annotation-type">
198
             <api name="EditorHintsSPI"/>
199
             <summary>Support multiple ranges for ErrorDescriptor</summary>
200
             <version major="1" minor="42" subsubminor="0"/>
201
             <date day="17" month="7" year="2017"/>
202
             <author login="mromashova"/>
203
             <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
204
             <description>
205
                 Added support for multiple ranges for error/warning. New field added to ErrorDescription  as well as corresponding getter method and new constructor 
206
                 in order to be able to provide multiple ranges support for highlight  particular hint. Added new factory method to
207
                 ErrorDescriptionFactory which uses new ErrorDescription constructor.
208
             </description>
209
             <issue number="271070"/>
210
        </change>        
196
211
197
    </changes>
212
    </changes>
198
213
(-)a/spi.editor.hints/nbproject/project.properties (-1 / +1 lines)
Lines 43-48 Link Here
43
javac.source=1.7
43
javac.source=1.7
44
javadoc.arch=${basedir}/arch.xml
44
javadoc.arch=${basedir}/arch.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
46
spec.version.base=1.41.0
46
spec.version.base=1.42.0
47
47
48
test.config.stableBTD.includes=**/*Test.class
48
test.config.stableBTD.includes=**/*Test.class
(-)a/spi.editor.hints/src/org/netbeans/modules/editor/hints/AnnotationHolder.java (-40 / +48 lines)
Lines 905-950 Link Here
905
            List<int[]> currentHighlights = new ArrayList<int[]>();
905
            List<int[]> currentHighlights = new ArrayList<int[]>();
906
906
907
            for (ErrorDescription e : filteredDescriptions) {
907
            for (ErrorDescription e : filteredDescriptions) {
908
                int beginOffset = e.getRange().getBegin().getPosition().getOffset();
908
                addHighlights(currentHighlights, e.getRange());
909
                int endOffset   = e.getRange().getEnd().getPosition().getOffset();
909
                for (PositionBounds positionBounds : e.getRangeTail()) {
910
910
                    addHighlights(currentHighlights, positionBounds);
911
                if (endOffset < beginOffset) {
912
                    //see issue #112566
913
                    int swap = endOffset;
914
915
                    endOffset = beginOffset;
916
                    beginOffset = swap;
917
918
                    LOG.log(Level.WARNING, "Incorrect highlight in ErrorDescription, attach your messages.log to issue #112566: {0}", e.toString()); //NOI18N
919
                }
920
921
                int[] h = new int[] {beginOffset, endOffset};
922
923
                OUT: for (Iterator<int[]> it = currentHighlights.iterator(); it.hasNext() && h != null; ) {
924
                    int[] hl = it.next();
925
926
                    switch (detectCollisions(hl, h)) {
927
                        case 0:
928
                            break;
929
                        case 1:
930
                            it.remove();
931
                            break;
932
                        case 2:
933
                            h = null; //nothing to add, hl is bigger:
934
                            break OUT;
935
                        case 4:
936
                        case 3:
937
                            int start = Math.min(hl[0], h[0]);
938
                            int end = Math.max(hl[1], h[1]);
939
940
                                h = new int[] {start, end};
941
                                it.remove();
942
                            break;
943
                    }
944
                }
945
946
                if (h != null) {
947
                    currentHighlights.add(h);
948
                }
911
                }
949
            }
912
            }
950
913
Lines 981-986 Link Here
981
        return bag;
944
        return bag;
982
    }
945
    }
983
946
947
    private static void addHighlights(List<int[]> currentHighlights, PositionBounds pos) throws IOException {
948
        int beginOffset = pos.getBegin().getPosition().getOffset();
949
        int endOffset = pos.getEnd().getPosition().getOffset();
950
951
        if (endOffset < beginOffset) {
952
            //see issue #112566
953
            int swap = endOffset;
954
955
            endOffset = beginOffset;
956
            beginOffset = swap;
957
958
            LOG.log(Level.WARNING, "Incorrect highlight in ErrorDescription, attach your messages.log to issue #112566: {0}", pos.toString()); //NOI18N
959
        }
960
961
        int[] h = new int[]{beginOffset, endOffset};
962
963
        OUT:
964
        for (Iterator<int[]> it = currentHighlights.iterator(); it.hasNext() && h != null;) {
965
            int[] hl = it.next();
966
967
            switch (detectCollisions(hl, h)) {
968
                case 0:
969
                    break;
970
                case 1:
971
                    it.remove();
972
                    break;
973
                case 2:
974
                    h = null; //nothing to add, hl is bigger:
975
                    break OUT;
976
                case 4:
977
                case 3:
978
                    int start = Math.min(hl[0], h[0]);
979
                    int end = Math.max(hl[1], h[1]);
980
981
                    h = new int[]{start, end};
982
                    it.remove();
983
                    break;
984
            }
985
        }
986
987
        if (h != null) {
988
            currentHighlights.add(h);
989
        }        
990
    }
991
984
    static AttributeSet getColoring(Severity s, Document d) {
992
    static AttributeSet getColoring(Severity s, Document d) {
985
        final String mimeType = DocumentUtilities.getMimeType(d);
993
        final String mimeType = DocumentUtilities.getMimeType(d);
986
        Map<Severity, AttributeSet> coloring = COLORINGS.get(mimeType);
994
        Map<Severity, AttributeSet> coloring = COLORINGS.get(mimeType);
(-)a/spi.editor.hints/src/org/netbeans/spi/editor/hints/ErrorDescription.java (+26 lines)
Lines 44-49 Link Here
44
package org.netbeans.spi.editor.hints;
44
package org.netbeans.spi.editor.hints;
45
45
46
import java.io.IOException;
46
import java.io.IOException;
47
import java.util.ArrayList;
47
import org.netbeans.api.annotations.common.CheckForNull;
48
import org.netbeans.api.annotations.common.CheckForNull;
48
import org.openide.filesystems.FileObject;
49
import org.openide.filesystems.FileObject;
49
import org.openide.text.PositionBounds;
50
import org.openide.text.PositionBounds;
Lines 64-69 Link Here
64
    private final String customType;
65
    private final String customType;
65
    private final LazyFixList fixes;
66
    private final LazyFixList fixes;
66
    private final PositionBounds span;
67
    private final PositionBounds span;
68
    private final ArrayList<PositionBounds> spanTail = new ArrayList<>();
67
    private final FileObject file;
69
    private final FileObject file;
68
70
69
    /**
71
    /**
Lines 81-86 Link Here
81
        this.file        = file;
83
        this.file        = file;
82
    }
84
    }
83
    
85
    
86
    
87
    ErrorDescription(FileObject file, String id, String description, CharSequence details, Severity severity, String customType, LazyFixList fixes, 
88
            PositionBounds span, ArrayList<PositionBounds> spanTail) {
89
        this.id = id;
90
        this.description = description;
91
        this.details = details;
92
        this.severity    = severity;
93
        this.customType = customType;
94
        this.fixes       = fixes;
95
        this.span        = span;
96
        this.spanTail.clear();
97
        this.spanTail.addAll(spanTail);
98
        this.file        = file;
99
    }
100
    
84
    /**
101
    /**
85
     * The constructor is intentionally not public. Use 
102
     * The constructor is intentionally not public. Use 
86
     * {@link ErrorDescriptionFactory} when you need an instance of this class.
103
     * {@link ErrorDescriptionFactory} when you need an instance of this class.
Lines 151-156 Link Here
151
    public PositionBounds getRange() {
168
    public PositionBounds getRange() {
152
        return span;
169
        return span;
153
    }
170
    }
171
    
172
    /**
173
     *  Return range tail: to support multiple ranges for error/warning
174
     * @return 
175
     * @since 1.42
176
     */
177
    public ArrayList<PositionBounds> getRangeTail() {
178
        return spanTail;
179
    }
154
180
155
    /**
181
    /**
156
     * @return associated file or <code>null</code> if there is none
182
     * @return associated file or <code>null</code> if there is none
(-)a/spi.editor.hints/src/org/netbeans/spi/editor/hints/ErrorDescriptionFactory.java (+90 lines)
Lines 43-49 Link Here
43
 */
43
 */
44
package org.netbeans.spi.editor.hints;
44
package org.netbeans.spi.editor.hints;
45
45
46
import java.util.ArrayList;
46
import java.util.List;
47
import java.util.List;
48
import java.util.logging.Level;
49
import java.util.logging.Logger;
47
import javax.swing.text.Document;
50
import javax.swing.text.Document;
48
import javax.swing.text.Position;
51
import javax.swing.text.Position;
49
import org.netbeans.api.annotations.common.NonNull;
52
import org.netbeans.api.annotations.common.NonNull;
Lines 267-272 Link Here
267
        return new ErrorDescription(file, id, description, details, severity, fixes, HintsControllerImpl.linePart(file, start, end));
270
        return new ErrorDescription(file, id, description, details, severity, fixes, HintsControllerImpl.linePart(file, start, end));
268
    }
271
    }
269
    
272
    
273
 /**Create a new {@link ErrorDescription} with the given parameters.
274
     *
275
     * Should be called inside document read lock to assure consistency
276
     *
277
     * @param id an optional ID of the {@link ErrorDescription}. Should represent a "type" of an error/warning.
278
     *           It is recommended that providers prefix the ID with their unique prefix.
279
     * @param severity the desired {@link Severity}
280
     * @param customType
281
     * @param description the text of the error/warning
282
     * @param details optional "more details" describing the error/warning
283
     * @param fixes a collection of {@link Fix}es that should be shown for the error/warning
284
     * @param file for which the {@link ErrorDescription} should be created
285
     * @param starts the array of start offsets for error/warning
286
     * @param ends the array of end offsets for error/warning
287
     * @return a newly created {@link ErrorDescription} based on the given parameters
288
     * @since 1.42
289
     */
290
    public static @NonNull ErrorDescription createErrorDescription(@NullAllowed String id, @NonNull Severity severity, 
291
            @NullAllowed String customType, @NonNull String description, @NullAllowed CharSequence details, @NonNull LazyFixList fixes, 
292
            @NonNull FileObject file, int[] starts, int[] ends) {
293
        Parameters.notNull("severity", severity);
294
        Parameters.notNull("description", description);
295
        Parameters.notNull("fixes", fixes);
296
        Parameters.notNull("file", file);
297
        if (starts == null || starts.length == 0 || starts[0] < 0) throw new IndexOutOfBoundsException("start < 0 (" + starts + " < 0)");;//NOI18N
298
        if (ends == null || ends.length == 0 || ends[0] < 0) throw new IndexOutOfBoundsException("end < 0 (" + ends + " < 0)");;//NOI18N
299
        if (ends.length != starts.length) throw new IndexOutOfBoundsException("starts lentgh:" + starts.length + " != " + ends.length + " ends length");//NOI18N
300
        PositionBounds span = HintsControllerImpl.linePart(file, starts[0], ends[0]);
301
        ArrayList<PositionBounds> spanTail = new ArrayList<>();
302
        if (starts.length > 1) {
303
            for (int i = 1; i < starts.length; i++) {
304
                //just skip if starts greater or equals to end
305
                if (starts[i] >= ends[i]) {
306
                    //log and continue
307
                    Logger.getLogger(ErrorDescriptionFactory.class.getName()).log(Level.INFO, "Incorrect span,  start=" + starts[i] + ", end=" + ends[i], new Exception());;//NOI18N
308
                    continue;
309
                }
310
                spanTail.add(HintsControllerImpl.linePart(file, starts[i], ends[i]));
311
            }
312
        }
313
        return new ErrorDescription(file, id, description, details, severity, customType, fixes, span, spanTail);
314
    }    
315
    
270
    /**Create a new {@link ErrorDescription} with the given parameters.
316
    /**Create a new {@link ErrorDescription} with the given parameters.
271
     *
317
     *
272
     * @param id an optional ID of the {@link ErrorDescription}. Should represent a "type" of an error/warning.
318
     * @param id an optional ID of the {@link ErrorDescription}. Should represent a "type" of an error/warning.
Lines 316-321 Link Here
316
        
362
        
317
        return new ErrorDescription(file, id, description, details, severity, customType, new StaticFixList(fixes), HintsControllerImpl.linePart(doc, start, end));
363
        return new ErrorDescription(file, id, description, details, severity, customType, new StaticFixList(fixes), HintsControllerImpl.linePart(doc, start, end));
318
    }
364
    }
365
    
366
    /**Create a new {@link ErrorDescription} with the given parameters.
367
     *
368
     * @param id an optional ID of the {@link ErrorDescription}. Should represent a "type" of an error/warning.
369
     *           It is recommended that providers prefix the ID with their unique prefix.
370
     * @param severity the desired {@link Severity}
371
     * @param customType custom annotation type
372
     * @param description the text of the error/warning
373
     * @param details optional "more details" describing the error/warning
374
     * @param fixes a collection of {@link Fix}es that should be shown for the error/warning
375
     * @param doc document for which the {@link ErrorDescription} should be created
376
     * @param starts the array of start offsets for error/warning
377
     * @param ends the array of end offsets for error/warning
378
     * @return a newly created {@link ErrorDescription} based on the given parameters
379
     * @since 1.42
380
     */
381
    public static @NonNull ErrorDescription createErrorDescription(@NullAllowed String id, @NonNull Severity severity, 
382
            @NullAllowed String customType, @NonNull String description, @NullAllowed CharSequence details,  @NonNull List<Fix> fixes, 
383
            @NonNull Document doc, int[] starts, int[] ends) {
384
        Parameters.notNull("severity", severity);
385
        Parameters.notNull("description", description);
386
        Parameters.notNull("fixes", fixes);
387
        Parameters.notNull("doc", doc);
388
        DataObject od = (DataObject) doc.getProperty(Document.StreamDescriptionProperty);
389
        FileObject file = od != null ? od.getPrimaryFile() : null;
390
        if (starts == null || starts.length == 0 || starts[0] < 0) throw new IndexOutOfBoundsException("start < 0 (" + starts + " < 0)");;//NOI18N
391
        if (ends == null || ends.length == 0 || ends[0] < 0) throw new IndexOutOfBoundsException("end < 0 (" + ends + " < 0)");;//NOI18N
392
        if (ends.length != starts.length) throw new IndexOutOfBoundsException("starts lentgh:" + starts.length + " != " + ends.length + " ends length");//NOI18N
393
        PositionBounds span = HintsControllerImpl.linePart(file, starts[0], ends[0]);
394
        ArrayList<PositionBounds> spanTail = new ArrayList<>();
395
        if (starts.length > 1) {
396
            for (int i = 1; i < starts.length; i++) {
397
                //just skip if starts greater or equals to end
398
                if (starts[i] >= ends[i]) {
399
                    //log and continue
400
                    Logger.getLogger(ErrorDescriptionFactory.class.getName()).log(Level.INFO, "Incorrect span,  start=" + starts[i] + ", end=" + ends[i], new Exception());;//NOI18N
401
                    continue;
402
                }
403
                spanTail.add(HintsControllerImpl.linePart(file, starts[i], ends[i]));
404
            }
405
        }
406
        return new ErrorDescription(file, id, description, details, severity, customType, new StaticFixList(fixes), 
407
                span, spanTail);
408
    }
319
409
320
    /**
410
    /**
321
     * Converts "normal" list of {@link Fix}es into {@link LazyFixList}
411
     * Converts "normal" list of {@link Fix}es into {@link LazyFixList}

Return to bug 271070