1 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 27 public final class JavaPairMatcher extends DefaultCharacterPairMatcher implements ISourceVersionDependent { 28 29 33 private boolean fHighlightAngularBrackets= false; 34 35 36 public JavaPairMatcher(char[] pairs) { 37 super(pairs, IJavaPartitions.JAVA_PARTITIONING); 38 } 39 40 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 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 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 96 private boolean isTypeParameterBracket(int offset, IDocument document, JavaHeuristicScanner scanner) { 97 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 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 138 private boolean isTypeParameterIntroducer(String identifier) { 139 return identifier.length() > 0 140 && (Character.isUpperCase(identifier.charAt(0)) 141 || identifier.startsWith("final") || identifier.startsWith("public") || identifier.startsWith("public") || identifier.startsWith("protected") || identifier.startsWith("private")); } 147 148 151 public void setSourceVersion(String version) { 152 if (JavaCore.VERSION_1_5.compareTo(version) <= 0) 153 fHighlightAngularBrackets= true; 154 else 155 fHighlightAngularBrackets= false; 156 } 157 } 158 | Popular Tags |