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 25509
Collapse All | Expand All

(-)java.editor/src/org/netbeans/modules/java/editor/resources/Bundle.properties (+2 lines)
Lines 64-69 Link Here
64
# JavadocTokenId categories
64
# JavadocTokenId categories
65
javadoc-tag=Javadoc Tag
65
javadoc-tag=Javadoc Tag
66
html-tag=Javadoc HTML tag
66
html-tag=Javadoc HTML tag
67
javadoc-first-sentence=Javadoc First Sentence
68
javadoc-identifier=Javadoc Identifier
67
69
68
#"Semantic" highlighting:
70
#"Semantic" highlighting:
69
mod-unused=Unused Element
71
mod-unused=Unused Element
(-)java.editor/src/org/netbeans/modules/java/editor/resources/fontsColors.xml (-1 / +7 lines)
Lines 127-136 Link Here
127
    <fontcolor name="javadoc-tag" default="comment">
127
    <fontcolor name="javadoc-tag" default="comment">
128
        <font style="bold" />
128
        <font style="bold" />
129
    </fontcolor>
129
    </fontcolor>
130
    <fontcolor name="html-tag" default="comment">
130
    <fontcolor name="html-tag" default="comment" foreColor="9999FF">
131
        <font style="bold" />
131
        <font style="bold" />
132
    </fontcolor>
132
    </fontcolor>
133
    <fontcolor name="javadoc-first-sentence" default="comment">
134
        <font style="bold" />
135
    </fontcolor>
133
136
137
    <fontcolor name="javadoc-identifier" default="comment" foreColor="000000" >
138
    </fontcolor>
139
134
<!-- XXX: should java module really define these colorings ??
140
<!-- XXX: should java module really define these colorings ??
135
141
136
    <fontcolor name="html-argument" foreColor="ff007c00" default="identifier"/>
142
    <fontcolor name="html-argument" foreColor="ff007c00" default="identifier"/>
(-)java.editor/src/org/netbeans/modules/java/editor/semantic/ColoringAttributes.java (-1 / +3 lines)
Lines 82-89 Link Here
82
82
83
    UNDEFINED,
83
    UNDEFINED,
84
84
85
    MARK_OCCURRENCES;
85
    MARK_OCCURRENCES,
86
    
86
    
87
    JAVADOC_IDENTIFIER;
88
    
87
    public static Coloring empty() {
89
    public static Coloring empty() {
88
        return new Coloring();
90
        return new Coloring();
89
    }
91
    }
(-)java.editor/src/org/netbeans/modules/java/editor/semantic/ColoringManager.java (+1 lines)
Lines 105-110 Link Here
105
        put("mod-deprecated", DEPRECATED);
105
        put("mod-deprecated", DEPRECATED);
106
        put("mod-undefined", UNDEFINED);
106
        put("mod-undefined", UNDEFINED);
107
        put("mod-unused", UNUSED);
107
        put("mod-unused", UNUSED);
108
        put("javadoc-identifier", JAVADOC_IDENTIFIER);
108
    }
109
    }
109
    
110
    
110
    private static void put(String coloring, ColoringAttributes... attributes) {
111
    private static void put(String coloring, ColoringAttributes... attributes) {
(-)java.editor/src/org/netbeans/modules/java/editor/semantic/LexerBasedHighlightSequence.java (-14 / +21 lines)
Lines 33-38 Link Here
33
import java.util.Map;
33
import java.util.Map;
34
import javax.swing.text.AttributeSet;
34
import javax.swing.text.AttributeSet;
35
import org.netbeans.api.java.lexer.JavaTokenId;
35
import org.netbeans.api.java.lexer.JavaTokenId;
36
import org.netbeans.api.java.lexer.JavadocTokenId;
36
import org.netbeans.api.lexer.Token;
37
import org.netbeans.api.lexer.Token;
37
import org.netbeans.api.lexer.TokenSequence;
38
import org.netbeans.api.lexer.TokenSequence;
38
import org.netbeans.modules.java.editor.semantic.ColoringAttributes.Coloring;
39
import org.netbeans.modules.java.editor.semantic.ColoringAttributes.Coloring;
Lines 47-77 Link Here
47
    private LexerBasedHighlightLayer layer;
48
    private LexerBasedHighlightLayer layer;
48
    private Map<Token, Coloring> colorings;
49
    private Map<Token, Coloring> colorings;
49
    private TokenSequence ts;
50
    private TokenSequence ts;
50
    private boolean started;
51
    private TokenSequence java;
51
    
52
    
52
    public LexerBasedHighlightSequence(LexerBasedHighlightLayer layer, TokenSequence ts, Map<Token, Coloring> colorings) {
53
    public LexerBasedHighlightSequence(LexerBasedHighlightLayer layer, TokenSequence ts, Map<Token, Coloring> colorings) {
53
        this.layer = layer;
54
        this.layer = layer;
54
        this.ts = ts;
55
        this.ts = ts;
56
        this.java = ts;
55
        this.colorings = colorings;
57
        this.colorings = colorings;
56
    }
58
    }
57
    
59
    
58
    private boolean moveNextImpl() {
60
    public boolean moveNext() {
59
        if (started) {
61
        if (ts != java) {
60
            return ts.moveNext();
62
            while (ts.moveNext()) {
61
        } else {
63
                Token t = ts.token();
62
            started = true;
64
                if (t.id() == JavadocTokenId.IDENT && t.getProperty("javadoc-identifier") != null) { //NOI18N
63
            
65
                    return true;
64
            return ts.moveNext();
65
        }
66
        }
66
    }
67
    }
67
68
            ts = java;
68
    public boolean moveNext() {
69
        }
69
        while (moveNextImpl()) {
70
        while (ts.moveNext()) {
70
            Token t = ts.token();
71
            Token t = ts.token();
71
            if (t.id() == JavaTokenId.IDENTIFIER && colorings.containsKey(ts.token()))
72
            if (t.id() == JavaTokenId.JAVADOC_COMMENT) {
73
                ts = ts.embedded();
74
                return moveNext();
75
            }
76
            if (t.id() == JavaTokenId.IDENTIFIER && colorings.containsKey(ts.token())) {
72
                return true;
77
                return true;
73
        }
78
        }
74
        
79
        }
75
        return false;
80
        return false;
76
    }
81
    }
77
    
82
    
Lines 84-90 Link Here
84
    }
89
    }
85
90
86
    public AttributeSet getAttributes() {
91
    public AttributeSet getAttributes() {
92
        if (ts.token().id() == JavadocTokenId.IDENT) {
93
            return layer.getColoring(ColoringAttributes.add(ColoringAttributes.empty(), ColoringAttributes.JAVADOC_IDENTIFIER));
94
        }
87
        return layer.getColoring(colorings.get(ts.token()));
95
        return layer.getColoring(colorings.get(ts.token()));
88
    }
96
    }
89
90
}
97
}
(-)java.lexer/nbproject/project.xml (+1 lines)
Lines 82-87 Link Here
82
                    </test-dependency>
82
                    </test-dependency>
83
                    <test-dependency>
83
                    <test-dependency>
84
                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
84
                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
85
                        <recursive/>
85
                        <compile-dependency/>
86
                        <compile-dependency/>
86
                    </test-dependency>
87
                    </test-dependency>
87
                </test-type>
88
                </test-type>
(-)java.lexer/src/org/netbeans/lib/java/lexer/JavadocLexer.java (-4 / +32 lines)
Lines 50-59 Link Here
50
import org.netbeans.spi.lexer.LexerInput;
50
import org.netbeans.spi.lexer.LexerInput;
51
import org.netbeans.spi.lexer.LexerRestartInfo;
51
import org.netbeans.spi.lexer.LexerRestartInfo;
52
import org.netbeans.spi.lexer.TokenFactory;
52
import org.netbeans.spi.lexer.TokenFactory;
53
import org.netbeans.spi.lexer.TokenPropertyProvider;
53
54
54
/**
55
/**
55
 * Lexical analyzer for javadoc language.
56
 * Lexical analyzer for javadoc language.
56
 *
57
 * @author Miloslav Metelka
57
 * @author Miloslav Metelka
58
 * @version 1.00
58
 * @version 1.00
59
 */
59
 */
Lines 66-79 Link Here
66
    
66
    
67
    private TokenFactory<JavadocTokenId> tokenFactory;
67
    private TokenFactory<JavadocTokenId> tokenFactory;
68
    
68
    
69
    private Integer state = null;
70
    
69
    public JavadocLexer(LexerRestartInfo<JavadocTokenId> info) {
71
    public JavadocLexer(LexerRestartInfo<JavadocTokenId> info) {
70
        this.input = info.input();
72
        this.input = info.input();
71
        this.tokenFactory = info.tokenFactory();
73
        this.tokenFactory = info.tokenFactory();
72
        assert (info.state() == null); // passed argument always null
74
        this.state = (Integer) info.state();        
73
    }
75
    }
74
    
76
    
75
    public Object state() {
77
    public Object state() {
76
        return null;
78
        return state;
77
    }
79
    }
78
    
80
    
79
    public Token<JavadocTokenId> nextToken() {
81
    public Token<JavadocTokenId> nextToken() {
Lines 89-94 Link Here
89
                ;
91
                ;
90
            
92
            
91
            input.backup(1);
93
            input.backup(1);
94
            if (state!=null) {
95
                state = null;
96
                return token(JavadocTokenId.IDENT, "javadoc-identifier"); //NOI18N
97
            }
92
            return token(JavadocTokenId.IDENT);
98
            return token(JavadocTokenId.IDENT);
93
        }
99
        }
94
        
100
        
Lines 106-120 Link Here
106
        
112
        
107
        switch (ch) {
113
        switch (ch) {
108
            case '@':
114
            case '@':
115
                state = null;
116
                String tag = "";
109
                while (true) {
117
                while (true) {
110
                    ch = input.read();
118
                    ch = input.read();
111
                    
112
                    if (!Character.isLetter(ch)) {
119
                    if (!Character.isLetter(ch)) {
120
                        if ("param".equals(tag)) { //NOI18N
121
                            state = 1;
122
                        }
113
                        input.backup(1);
123
                        input.backup(1);
114
                        return tokenFactory.createToken(JavadocTokenId.TAG, input.readLength());
124
                        return tokenFactory.createToken(JavadocTokenId.TAG, input.readLength());
125
                    } else {
126
                        tag+=new String(Character.toChars(ch));
115
                    }
127
                    }
116
                }
128
                }
117
            case '<':
129
            case '<':
130
                state = null;
118
                int backupCounter = 0;
131
                int backupCounter = 0;
119
                boolean newline = false;
132
                boolean newline = false;
120
                boolean asterisk = false;
133
                boolean asterisk = false;
Lines 140-147 Link Here
140
                    }
153
                    }
141
                }
154
                }
142
            case '.':
155
            case '.':
156
                state = null;
143
                return token(JavadocTokenId.DOT);
157
                return token(JavadocTokenId.DOT);
144
            case '#':
158
            case '#':
159
                state = null;
145
                return token(JavadocTokenId.HASH);
160
                return token(JavadocTokenId.HASH);
146
        } // end of switch (ch)
161
        } // end of switch (ch)
147
        
162
        
Lines 154-159 Link Here
154
        return tokenFactory.createToken(id);
169
        return tokenFactory.createToken(id);
155
    }
170
    }
156
171
172
    private Token<JavadocTokenId> token(JavadocTokenId id, final Object property) {
173
        return tokenFactory.createPropertyToken(id, input.readLength(), new TokenPropertyProvider<JavadocTokenId>() {
174
175
        @Override
176
        public Object getValue(Token<JavadocTokenId> token, Object key) {
177
            if (property.equals(key)) 
178
                return true; 
179
            return null;
180
        }
181
        
182
    });
183
    }
184
157
    public void release() {
185
    public void release() {
158
    }
186
    }
159
187
(-)java.lexer/test/unit/src/org/netbeans/lib/java/lexer/JavadocLexerTest.java (+5 lines)
Lines 73-92 Link Here
73
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.TAG, "@param");
73
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.TAG, "@param");
74
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " ");
74
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " ");
75
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "aaa");
75
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "aaa");
76
        assertTrue((Boolean) ts.token().getProperty("javadoc-identifier"));
76
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " ");
77
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " ");
77
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.HTML_TAG, "<code>");
78
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.HTML_TAG, "<code>");
78
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "aaa");
79
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "aaa");
80
        assertNull((Boolean) ts.token().getProperty("javadoc-identifier"));
79
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.HTML_TAG, "</code>");
81
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.HTML_TAG, "</code>");
80
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " ");
82
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " ");
81
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "xyz");
83
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "xyz");
84
        assertNull((Boolean) ts.token().getProperty("javadoc-identifier"));
82
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " {");
85
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " {");
83
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.TAG, "@link");
86
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.TAG, "@link");
84
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " ");
87
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, " ");
85
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "org");
88
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "org");
89
        assertNull((Boolean) ts.token().getProperty("javadoc-identifier"));
86
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.DOT, ".");
90
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.DOT, ".");
87
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "Aaa");
91
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "Aaa");
88
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.HASH, "#");
92
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.HASH, "#");
89
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "aaa");
93
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.IDENT, "aaa");
94
        assertNull((Boolean) ts.token().getProperty("javadoc-identifier"));
90
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, "()}");
95
        LexerTestUtilities.assertNextTokenEquals(ts, JavadocTokenId.OTHER_TEXT, "()}");
91
    }
96
    }
92
97
(-)javadoc/nbproject/project.xml (+27 lines)
Lines 112-117 Link Here
112
                    </run-dependency>
112
                    </run-dependency>
113
                </dependency>
113
                </dependency>
114
                <dependency>
114
                <dependency>
115
                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
116
                    <build-prerequisite/>
117
                    <compile-dependency/>
118
                    <run-dependency>
119
                        <release-version>1</release-version>
120
                        <specification-version>1.40</specification-version>
121
                    </run-dependency>
122
                </dependency>
123
                <dependency>
124
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
125
                    <build-prerequisite/>
126
                    <compile-dependency/>
127
                    <run-dependency>
128
                        <release-version>1</release-version>
129
                        <specification-version>1.21</specification-version>
130
                    </run-dependency>
131
                </dependency>
132
                <dependency>
133
                    <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
134
                    <build-prerequisite/>
135
                    <compile-dependency/>
136
                    <run-dependency>
137
                        <release-version>1</release-version>
138
                        <specification-version>1.35</specification-version>
139
                    </run-dependency>
140
                </dependency>
141
                <dependency>
115
                    <code-name-base>org.netbeans.modules.java.hints</code-name-base>
142
                    <code-name-base>org.netbeans.modules.java.hints</code-name-base>
116
                    <build-prerequisite/>
143
                    <build-prerequisite/>
117
                    <compile-dependency/>
144
                    <compile-dependency/>
(-)javadoc/src/org/netbeans/modules/javadoc/highlighting/Factory.java (+69 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.javadoc.highlighting;
44
45
import org.netbeans.spi.editor.highlighting.HighlightsLayer;
46
import org.netbeans.spi.editor.highlighting.HighlightsLayerFactory;
47
import org.netbeans.spi.editor.highlighting.ZOrder;
48
49
/**
50
 * The highlights layer factory.
51
 * 
52
 * @author Vita Stejskal
53
 */
54
public class Factory implements HighlightsLayerFactory {
55
    
56
    /** Creates a new instance of Factory */
57
    public Factory() {
58
    }
59
60
    public HighlightsLayer[] createLayers(HighlightsLayerFactory.Context context) {
61
        return new HighlightsLayer [] { HighlightsLayer.create(
62
            Highlighting.class.getName(), 
63
            ZOrder.SYNTAX_RACK, //NOI18N
64
            true, 
65
            new Highlighting(context.getDocument())
66
        )};
67
    }
68
    
69
}
(-)javadoc/src/org/netbeans/modules/javadoc/highlighting/Highlighting.java (+328 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.javadoc.highlighting;
44
45
import java.util.ArrayList;
46
import java.util.ConcurrentModificationException;
47
import java.util.List;
48
import java.util.NoSuchElementException;
49
import java.util.logging.Level;
50
import java.util.logging.Logger;
51
import javax.swing.text.AttributeSet;
52
import javax.swing.text.BadLocationException;
53
import javax.swing.text.Document;
54
import javax.swing.text.Element;
55
import org.netbeans.api.editor.mimelookup.MimeLookup;
56
import org.netbeans.api.editor.mimelookup.MimePath;
57
import org.netbeans.api.editor.settings.FontColorSettings;
58
import org.netbeans.api.java.lexer.JavadocTokenId;
59
import org.netbeans.api.lexer.TokenChange;
60
import org.netbeans.api.lexer.TokenHierarchy;
61
import org.netbeans.api.lexer.TokenHierarchyEvent;
62
import org.netbeans.api.lexer.TokenHierarchyListener;
63
import org.netbeans.api.lexer.TokenId;
64
import org.netbeans.api.lexer.TokenSequence;
65
import org.netbeans.spi.editor.highlighting.HighlightsSequence;
66
import org.netbeans.spi.editor.highlighting.support.AbstractHighlightsContainer;
67
import org.openide.util.WeakListeners;
68
69
/**
70
 * @author Jan Becicka
71
 */
72
public class Highlighting extends AbstractHighlightsContainer implements TokenHierarchyListener {
73
74
    private static final Logger LOG = Logger.getLogger(Highlighting.class.getName());
75
    
76
    public static final String LAYER_ID = "org.netbeans.modules.javadoc.highlighting"; //NOI18N
77
    
78
    private static AttributeSet fontColor = MimeLookup.getLookup(MimePath.get("text/x-java")).lookup(FontColorSettings.class).getTokenFontColors("javadoc-first-sentence");
79
    
80
    
81
    private Document document;
82
    private TokenHierarchy<? extends Document> hierarchy = null;
83
    private long version = 0;
84
    
85
    /** Creates a new instance of Highlighting */
86
    public Highlighting(Document doc) {
87
        this.document = doc;
88
    }
89
90
    public HighlightsSequence getHighlights(int startOffset, int endOffset) {
91
        synchronized (this) {
92
            if (hierarchy == null) {
93
                hierarchy = TokenHierarchy.get(document);
94
                if (hierarchy != null) {
95
                    hierarchy.addTokenHierarchyListener(WeakListeners.create(TokenHierarchyListener.class, this, hierarchy));
96
                }
97
            }
98
99
            if (hierarchy != null) {
100
                return new HSImpl(version, hierarchy, startOffset, endOffset);
101
            } else {
102
                return HighlightsSequence.EMPTY;
103
            }
104
        }
105
    }
106
107
    // ----------------------------------------------------------------------
108
    //  TokenHierarchyListener implementation
109
    // ----------------------------------------------------------------------
110
111
    public void tokenHierarchyChanged(TokenHierarchyEvent evt) {
112
        TokenChange<?> tc = evt.tokenChange();
113
        int affectedArea [] = null;
114
        
115
        TokenSequence<? extends TokenId> seq = tc.currentTokenSequence();
116
        if (seq.language().equals(JavadocTokenId.language())) {
117
            // Change inside javadoc
118
            int [] firstSentence = findFirstSentence(seq);
119
            if (firstSentence != null) {
120
                if (tc.offset() <= firstSentence[1]) {
121
                    // Change before the end of the first sentence
122
                    affectedArea = firstSentence;
123
                }
124
            } else {
125
                // XXX: need the embedding token (i.e. JavaTokenId.JAVADOC_COMMENT*)
126
                // and fire a change in its whole area
127
                affectedArea = new int [] { tc.offset(), Integer.MAX_VALUE };
128
            }
129
        } else {
130
            // The change may or may not involve javadoc, so reset everyting.
131
            // It would be more efficient to traverse the changed area and
132
            // find out whether it really involves javadoc or not.
133
            affectedArea = new int [] { tc.offset(), Integer.MAX_VALUE };
134
        }
135
        
136
        if (affectedArea != null) {
137
            synchronized (this) {
138
                version++;
139
            }
140
141
            fireHighlightsChange(affectedArea[0], affectedArea[1]);
142
        }
143
    }
144
145
    // ----------------------------------------------------------------------
146
    //  Private implementation
147
    // ----------------------------------------------------------------------
148
149
    private int [] findFirstSentence(TokenSequence<? extends TokenId> seq) {
150
        seq.moveStart();
151
        if (seq.moveNext()) {
152
            int start = seq.offset();
153
            do {
154
                if (seq.token().id() == JavadocTokenId.DOT) {
155
                    return new int [] { start, seq.offset() };
156
                }
157
            } while (seq.moveNext());
158
        }
159
        
160
        return null;
161
    }
162
163
    private final class HSImpl implements HighlightsSequence {
164
        
165
        private long version;
166
        private TokenHierarchy<? extends Document> scanner;
167
        private List<TokenSequence<? extends TokenId>> sequences;
168
        private int startOffset;
169
        private int endOffset;
170
        
171
        private List<Integer> lines = null;
172
        private int linesIdx = -1;
173
        
174
        public HSImpl(long version, TokenHierarchy<? extends Document> scanner, int startOffset, int endOffset) {
175
            this.version = version;
176
            this.scanner = scanner;
177
            this.startOffset = startOffset;
178
            this.endOffset = endOffset;
179
            this.sequences = null;
180
        }
181
182
        public boolean moveNext() {
183
            synchronized (Highlighting.this) {
184
                checkVersion();
185
                
186
                if (sequences == null) {
187
                    // initialize
188
                    TokenSequence<?> seq = scanner.tokenSequence().subSequence(startOffset, endOffset);
189
                    sequences = new ArrayList<TokenSequence<? extends TokenId>>();
190
                    sequences.add(seq);
191
                }
192
193
                if (lines != null) {
194
                    if (linesIdx + 2 < lines.size()) {
195
                        linesIdx += 2;
196
                        return true;
197
                    }
198
                    
199
                    lines = null;
200
                    linesIdx = -1;
201
                }
202
                
203
                while (!sequences.isEmpty()) {
204
                    TokenSequence<? extends TokenId> seq = sequences.get(sequences.size() - 1);
205
206
                    if (seq.language().equals(JavadocTokenId.language())) {
207
                        int [] firstSentence = findFirstSentence(seq);
208
                        sequences.remove(sequences.size() - 1);
209
210
                        if (firstSentence != null) {
211
                            lines = splitByLines(firstSentence[0], firstSentence[1]);
212
                            if (lines != null) {
213
                                linesIdx = 0;
214
                                return true;
215
                            }
216
                        }
217
                    } else {
218
                        boolean hasNextToken;
219
220
                        while (true == (hasNextToken = seq.moveNext())) {
221
                            TokenSequence<?> embeddedSeq = seq.embedded();
222
                            if (embeddedSeq != null) {
223
                                sequences.add(sequences.size(), embeddedSeq);
224
                                break;
225
                            }
226
                        }
227
228
                        if (!hasNextToken) {
229
                            sequences.remove(sequences.size() - 1);
230
                        }
231
                    }
232
                }
233
234
                return false;
235
            }
236
        }
237
238
        public int getStartOffset() {
239
            synchronized (Highlighting.this) {
240
                checkVersion();
241
                
242
                if (sequences == null) {
243
                    throw new NoSuchElementException("Call moveNext() first."); //NOI18N
244
                }
245
246
                if (lines != null) {
247
                    return lines.get(linesIdx);
248
                } else {
249
                    throw new NoSuchElementException();
250
                }
251
            }
252
        }
253
254
        public int getEndOffset() {
255
            synchronized (Highlighting.this) {
256
                checkVersion();
257
                
258
                if (sequences == null) {
259
                    throw new NoSuchElementException("Call moveNext() first."); //NOI18N
260
                }
261
262
                if (lines != null) {
263
                    return lines.get(linesIdx + 1);
264
                } else {
265
                    throw new NoSuchElementException();
266
                }
267
            }
268
        }
269
270
        public AttributeSet getAttributes() {
271
            synchronized (Highlighting.this) {
272
                checkVersion();
273
                
274
                if (sequences == null) {
275
                    throw new NoSuchElementException("Call moveNext() first."); //NOI18N
276
                }
277
278
                if (lines != null) {
279
                    return fontColor;
280
                } else {
281
                    throw new NoSuchElementException();
282
                }
283
            }
284
        }
285
        
286
        private void checkVersion() {
287
            if (this.version != Highlighting.this.version) {
288
                throw new ConcurrentModificationException();
289
            }
290
        }
291
        
292
        private List<Integer> splitByLines(int sentenceStart, int sentenceEnd) {
293
            ArrayList<Integer> lines = new ArrayList<Integer>();
294
            int offset = sentenceStart;
295
            
296
            try {
297
                while (offset < sentenceEnd) {
298
                    Element lineElement = document.getDefaultRootElement().getElement(
299
                        document.getDefaultRootElement().getElementIndex(offset));
300
301
                    int rowStart = offset == sentenceStart ? offset : lineElement.getStartOffset();
302
                    int rowEnd = lineElement.getEndOffset();
303
304
                    String line = document.getText(rowStart, rowEnd - rowStart);
305
                    int idx = 0;
306
                    while (idx < line.length() && 
307
                        (line.charAt(idx) == ' ' || 
308
                        line.charAt(idx) == '\t' || 
309
                        line.charAt(idx) == '*'))
310
                    {
311
                        idx++;
312
                    }
313
314
                    if (rowStart + idx < rowEnd) {
315
                        lines.add(rowStart + idx);
316
                        lines.add(Math.min(rowEnd, sentenceEnd));
317
                    }
318
319
                    offset = rowEnd + 1;
320
                }
321
            } catch (BadLocationException e) {
322
                LOG.log(Level.WARNING, "Can't determine javadoc first sentence", e);
323
            }
324
            
325
            return lines.isEmpty() ? null : lines;
326
        }
327
    } // End of HSImpl class
328
}
(-)javadoc/src/org/netbeans/modules/javadoc/resources/mf-layer.xml (+3 lines)
Lines 119-123 Link Here
119
            </folder>
119
            </folder>
120
        </folder>
120
        </folder>
121
    </folder>
121
    </folder>
122
    <folder name="Editors">
123
        <file name="org-netbeans-modules-javadoc-highlighting-Factory.instance" />
124
    </folder>
122
    
125
    
123
</filesystem>
126
</filesystem>

Return to bug 25509