KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > JavaPairMatcher


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Christian Plesner Hansen (plesner@quenta.org) - changed implementation to use DefaultCharacterPairMatcher
11  *******************************************************************************/

12 package org.eclipse.jdt.internal.ui.text;
13
14 import org.eclipse.jface.text.BadLocationException;
15 import org.eclipse.jface.text.IDocument;
16 import org.eclipse.jface.text.IRegion;
17 import org.eclipse.jface.text.TextUtilities;
18 import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
19
20 import org.eclipse.jdt.core.JavaCore;
21
22 import org.eclipse.jdt.ui.text.IJavaPartitions;
23
24 /**
25  * Helper class for match pairs of characters.
26  */

27 public final class JavaPairMatcher extends DefaultCharacterPairMatcher implements ISourceVersionDependent {
28
29     /**
30      * Stores the source version state.
31      * @since 3.1
32      */

33     private boolean fHighlightAngularBrackets= false;
34
35
36     public JavaPairMatcher(char[] pairs) {
37         super(pairs, IJavaPartitions.JAVA_PARTITIONING);
38     }
39
40     /* @see ICharacterPairMatcher#match(IDocument, int) */
41     public IRegion match(IDocument document, int offset) {
42         try {
43             return performMatch(document, offset);
44         } catch (BadLocationException ble) {
45             return null;
46         }
47     }
48     
49     /*
50      * Performs the actual work of matching for #match(IDocument, int).
51      */

52     private IRegion performMatch(IDocument document, int offset) throws BadLocationException {
53         if (offset < 0 || document == null) return null;
54         final char prevChar= document.getChar(Math.max(offset - 1, 0));
55         if ((prevChar == '<' || prevChar == '>') && !fHighlightAngularBrackets)
56             return null;
57         if (prevChar == '<' && isLessThanOperator(document, offset - 1))
58             return null;
59         final IRegion region= super.match(document, offset);
60         if (region == null) return region;
61         if (prevChar == '>') {
62             final int peer= region.getOffset();
63             if (isLessThanOperator(document, peer)) return null;
64         }
65         return region;
66     }
67
68     /**
69      * Returns true if the character at the specified offset is a
70      * less-than sign, rather than an type parameter list open
71      * angle bracket.
72      *
73      * @param document a document
74      * @param offset an offset within the document
75      * @return true if the character at the specified offset is not
76      * a type parameter start bracket
77      * @throws BadLocationException
78      */

79     private boolean isLessThanOperator(IDocument document, int offset) throws BadLocationException {
80         if (offset < 0) return false;
81         JavaHeuristicScanner scanner= new JavaHeuristicScanner(document, IJavaPartitions.JAVA_PARTITIONING, TextUtilities.getContentType(document, IJavaPartitions.JAVA_PARTITIONING, offset, false));
82         return !isTypeParameterBracket(offset, document, scanner);
83     }
84
85     /**
86      * Checks if the angular bracket at <code>offset</code> is a type
87      * parameter bracket.
88      *
89      * @param offset the offset of the opening bracket
90      * @param document the document
91      * @param scanner a java heuristic scanner on <code>document</code>
92      * @return <code>true</code> if the bracket is part of a type parameter,
93      * <code>false</code> otherwise
94      * @since 3.1
95      */

96     private boolean isTypeParameterBracket(int offset, IDocument document, JavaHeuristicScanner scanner) {
97         /*
98          * type parameter come after braces (closing or opening), semicolons, or after
99          * a Type name (heuristic: starts with capital character, or after a modifier
100          * keyword in a method declaration (visibility, static, synchronized, final)
101          */

102
103         try {
104             IRegion line= document.getLineInformationOfOffset(offset);
105
106             int prevToken= scanner.previousToken(offset - 1, line.getOffset());
107             int prevTokenOffset= scanner.getPosition() + 1;
108             String JavaDoc previous= prevToken == Symbols.TokenEOF ? null : document.get(prevTokenOffset, offset - prevTokenOffset).trim();
109
110             if ( prevToken == Symbols.TokenLBRACE
111                     || prevToken == Symbols.TokenRBRACE
112                     || prevToken == Symbols.TokenSEMICOLON
113                     || prevToken == Symbols.TokenSYNCHRONIZED
114                     || prevToken == Symbols.TokenSTATIC
115                     || (prevToken == Symbols.TokenIDENT && isTypeParameterIntroducer(previous))
116                     || prevToken == Symbols.TokenEOF)
117                 return true;
118         } catch (BadLocationException e) {
119             return false;
120         }
121
122         return false;
123     }
124
125     /**
126      * Returns <code>true</code> if <code>identifier</code> is an identifier
127      * that could come right before a type parameter list. It uses a heuristic:
128      * if the identifier starts with an upper case, it is assumed a type name.
129      * Also, if <code>identifier</code> is a method modifier, it is assumed
130      * that the angular bracket is part of the generic type parameter of a
131      * method.
132      *
133      * @param identifier the identifier to check
134      * @return <code>true</code> if the identifier could introduce a type
135      * parameter list
136      * @since 3.1
137      */

138     private boolean isTypeParameterIntroducer(String JavaDoc identifier) {
139         return identifier.length() > 0
140                 && (Character.isUpperCase(identifier.charAt(0))
141                         || identifier.startsWith("final") //$NON-NLS-1$
142
|| identifier.startsWith("public") //$NON-NLS-1$
143
|| identifier.startsWith("public") //$NON-NLS-1$
144
|| identifier.startsWith("protected") //$NON-NLS-1$
145
|| identifier.startsWith("private")); //$NON-NLS-1$
146
}
147
148     /*
149      * @see org.eclipse.jdt.internal.ui.text.ISourceVersionDependent#setSourceVersion(java.lang.String)
150      */

151     public void setSourceVersion(String JavaDoc version) {
152         if (JavaCore.VERSION_1_5.compareTo(version) <= 0)
153             fHighlightAngularBrackets= true;
154         else
155             fHighlightAngularBrackets= false;
156     }
157 }
158
Popular Tags