1 11 package org.eclipse.jdt.internal.core.search.matching; 12 13 import org.eclipse.core.runtime.CoreException; 14 15 import org.eclipse.jdt.core.IJavaElement; 16 import org.eclipse.jdt.core.IPackageFragment; 17 import org.eclipse.jdt.core.IPackageFragmentRoot; 18 import org.eclipse.jdt.core.JavaModelException; 19 import org.eclipse.jdt.core.search.SearchPattern; 20 import org.eclipse.jdt.core.compiler.CharOperation; 21 import org.eclipse.jdt.internal.compiler.ast.*; 22 import org.eclipse.jdt.internal.compiler.lookup.*; 23 import org.eclipse.jdt.internal.compiler.util.Util; 24 25 public class PackageReferenceLocator extends PatternLocator { 26 27 protected PackageReferencePattern pattern; 28 29 public static boolean isDeclaringPackageFragment(IPackageFragment packageFragment, ReferenceBinding typeBinding) { 31 char[] fileName = typeBinding.getFileName(); 32 if (fileName != null) { 33 fileName = CharOperation.replaceOnCopy(fileName, '/', '\\'); fileName = CharOperation.lastSegment(fileName, '\\'); 36 37 try { 38 switch (packageFragment.getKind()) { 39 case IPackageFragmentRoot.K_SOURCE : 40 if (!org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(fileName) || !packageFragment.getCompilationUnit(new String (fileName)).exists()) { 41 return false; } 43 break; 44 case IPackageFragmentRoot.K_BINARY : 45 if (!Util.isClassFileName(fileName) || !packageFragment.getClassFile(new String (fileName)).exists()) { 51 return false; } 53 break; 54 } 55 } catch(JavaModelException e) { 56 } 58 } 59 return true; } 61 62 public PackageReferenceLocator(PackageReferencePattern pattern) { 63 super(pattern); 64 65 this.pattern = pattern; 66 } 67 public int match(ASTNode node, MatchingNodeSet nodeSet) { if (!(node instanceof ImportReference)) return IMPOSSIBLE_MATCH; 69 70 return nodeSet.addMatch(node, matchLevel((ImportReference) node)); 71 } 72 public int match(Reference node, MatchingNodeSet nodeSet) { if (!(node instanceof QualifiedNameReference)) return IMPOSSIBLE_MATCH; 79 80 return nodeSet.addMatch(node, matchLevelForTokens(((QualifiedNameReference) node).tokens)); 81 } 82 public int match(TypeReference node, MatchingNodeSet nodeSet) { if (node instanceof JavadocSingleTypeReference) { 85 char[][] tokens = new char[][] { ((JavadocSingleTypeReference) node).token }; 86 return nodeSet.addMatch(node, matchLevelForTokens(tokens)); 87 } 88 if (!(node instanceof QualifiedTypeReference)) return IMPOSSIBLE_MATCH; 89 return nodeSet.addMatch(node, matchLevelForTokens(((QualifiedTypeReference) node).tokens)); 90 } 91 92 protected int matchLevel(ImportReference importRef) { 93 return matchLevelForTokens(importRef.tokens); 94 } 95 protected int matchLevelForTokens(char[][] tokens) { 96 if (this.pattern.pkgName == null) return ACCURATE_MATCH; 97 98 char[] packageName = null; 99 if (this.isCamelCase) { 100 packageName = CharOperation.concatWith(tokens, '.'); 101 if (CharOperation.camelCaseMatch(this.pattern.pkgName, packageName)) { 102 return POSSIBLE_MATCH; 103 } 104 } 105 switch (this.matchMode) { 106 case SearchPattern.R_EXACT_MATCH: 107 case SearchPattern.R_PREFIX_MATCH: 108 if (packageName==null) packageName = CharOperation.concatWith(tokens, '.'); 109 if (CharOperation.prefixEquals(this.pattern.pkgName, packageName, this.isCaseSensitive)) { 110 return POSSIBLE_MATCH; 111 } 112 break; 113 case SearchPattern.R_PATTERN_MATCH: 114 char[] patternName = this.pattern.pkgName[this.pattern.pkgName.length - 1] == '*' 115 ? this.pattern.pkgName 116 : CharOperation.concat(this.pattern.pkgName, ".*".toCharArray()); if (packageName==null) packageName = CharOperation.concatWith(tokens, '.'); 118 if (CharOperation.match(patternName, packageName, this.isCaseSensitive)) { 119 return POSSIBLE_MATCH; 120 } 121 break; 122 case SearchPattern.R_REGEXP_MATCH : 123 break; 125 } 126 return IMPOSSIBLE_MATCH; 127 } 128 131 protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException { 132 Binding refBinding = binding; 133 if (importRef.isStatic()) { 134 if (binding instanceof FieldBinding) { 137 FieldBinding fieldBinding = (FieldBinding) binding; 138 if (!fieldBinding.isStatic()) return; 139 refBinding = fieldBinding.declaringClass; 140 } else if (binding instanceof MethodBinding) { 141 MethodBinding methodBinding = (MethodBinding) binding; 142 if (!methodBinding.isStatic()) return; 143 refBinding = methodBinding.declaringClass; 144 } else if (binding instanceof MemberTypeBinding) { 145 MemberTypeBinding memberBinding = (MemberTypeBinding) binding; 146 if (!memberBinding.isStatic()) return; 147 } 148 } 149 super.matchLevelAndReportImportRef(importRef, refBinding, locator); 150 } 151 protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException { 152 if (binding == null) { 153 this.matchReportReference(importRef, element, null, accuracy, locator); 154 } else { 155 if (locator.encloses(element)) { 156 long[] positions = importRef.sourcePositions; 157 int last = positions.length - 1; 158 if (binding instanceof ProblemReferenceBinding) 159 binding = ((ProblemReferenceBinding) binding).closestMatch(); 160 if (binding instanceof ReferenceBinding) { 161 PackageBinding pkgBinding = ((ReferenceBinding) binding).fPackage; 162 if (pkgBinding != null) 163 last = pkgBinding.compoundName.length; 164 } 165 if (binding instanceof PackageBinding) 166 last = ((PackageBinding) binding).compoundName.length; 167 int start = (int) (positions[0] >>> 32); 168 int end = (int) positions[last - 1]; 169 match = locator.newPackageReferenceMatch(element, accuracy, start, end-start+1, importRef); 170 locator.report(match); 171 } 172 } 173 } 174 protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { 175 long[] positions = null; 176 int last = -1; 177 if (reference instanceof ImportReference) { 178 ImportReference importRef = (ImportReference) reference; 179 positions = importRef.sourcePositions; 180 last = (importRef.bits & ASTNode.OnDemand) != 0 ? positions.length : positions.length - 1; 181 } else { 182 TypeBinding typeBinding = null; 183 if (reference instanceof QualifiedNameReference) { 184 QualifiedNameReference qNameRef = (QualifiedNameReference) reference; 185 positions = qNameRef.sourcePositions; 186 switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) { 187 case Binding.FIELD : typeBinding = qNameRef.actualReceiverType; 189 break; 190 case Binding.TYPE : if (qNameRef.binding instanceof TypeBinding) 192 typeBinding = (TypeBinding) qNameRef.binding; 193 break; 194 case Binding.VARIABLE : case Binding.TYPE | Binding.VARIABLE : 196 Binding binding = qNameRef.binding; 197 if (binding instanceof TypeBinding) { 198 typeBinding = (TypeBinding) binding; 199 } else if (binding instanceof ProblemFieldBinding) { 200 typeBinding = qNameRef.actualReceiverType; 201 last = qNameRef.tokens.length - (qNameRef.otherBindings == null ? 2 : qNameRef.otherBindings.length + 2); 202 } else if (binding instanceof ProblemBinding) { 203 ProblemBinding pbBinding = (ProblemBinding) binding; 204 typeBinding = pbBinding.searchType; 205 last = CharOperation.occurencesOf('.', pbBinding.name); 206 } 207 break; 208 } 209 } else if (reference instanceof QualifiedTypeReference) { 210 QualifiedTypeReference qTypeRef = (QualifiedTypeReference) reference; 211 positions = qTypeRef.sourcePositions; 212 typeBinding = qTypeRef.resolvedType; 213 } else if (reference instanceof JavadocSingleTypeReference) { 214 JavadocSingleTypeReference jsTypeRef = (JavadocSingleTypeReference) reference; 215 positions = new long[1]; 216 positions[0] = (((long)jsTypeRef.sourceStart) << 32) + jsTypeRef.sourceEnd; 217 typeBinding = jsTypeRef.resolvedType; 218 } 219 if (positions == null) return; 220 if (typeBinding instanceof ArrayBinding) 221 typeBinding = ((ArrayBinding) typeBinding).leafComponentType; 222 if (typeBinding instanceof ProblemReferenceBinding) 223 typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch(); 224 if (typeBinding instanceof ReferenceBinding) { 225 PackageBinding pkgBinding = ((ReferenceBinding) typeBinding).fPackage; 226 if (pkgBinding != null) 227 last = pkgBinding.compoundName.length; 228 } 229 ReferenceBinding enclosingType = typeBinding == null ? null: typeBinding.enclosingType(); 232 if (enclosingType != null) { 233 int length = positions.length; 234 while (enclosingType != null && length > 0) { 235 length--; 236 enclosingType = enclosingType.enclosingType(); 237 } 238 if (length <= 1) return; 239 } 240 } 241 if (last == -1) { 242 last = this.pattern.segments.length; 243 } 244 if (last == 0) return; 245 if (last > positions.length) last = positions.length; 246 int sourceStart = (int) (positions[0] >>> 32); 247 int sourceEnd = ((int) positions[last - 1]); 248 match = locator.newPackageReferenceMatch(element, accuracy, sourceStart, sourceEnd-sourceStart+1, reference); 249 locator.report(match); 250 } 251 protected int referenceType() { 252 return IJavaElement.PACKAGE_FRAGMENT; 253 } 254 public int resolveLevel(ASTNode node) { 255 if (node instanceof JavadocQualifiedTypeReference) { 256 JavadocQualifiedTypeReference qualifRef = (JavadocQualifiedTypeReference) node; 257 if (qualifRef.packageBinding != null) 258 return resolveLevel(qualifRef.packageBinding); 259 return resolveLevel(qualifRef.resolvedType); 260 } 261 if (node instanceof JavadocSingleTypeReference) { 262 JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) node; 263 if (singleRef.packageBinding != null) 264 return resolveLevel(singleRef.packageBinding); 265 return IMPOSSIBLE_MATCH; 266 } 267 if (node instanceof QualifiedTypeReference) 268 return resolveLevel(((QualifiedTypeReference) node).resolvedType); 269 if (node instanceof QualifiedNameReference) 270 return this.resolveLevel((QualifiedNameReference) node); 271 return IMPOSSIBLE_MATCH; 273 } 274 public int resolveLevel(Binding binding) { 275 if (binding == null) return INACCURATE_MATCH; 276 277 char[][] compoundName = null; 278 if (binding instanceof ImportBinding) { 279 compoundName = ((ImportBinding) binding).compoundName; 280 } else if (binding instanceof PackageBinding) { 281 compoundName = ((PackageBinding) binding).compoundName; 282 } else { 283 if (binding instanceof ArrayBinding) 284 binding = ((ArrayBinding) binding).leafComponentType; 285 if (binding instanceof ProblemReferenceBinding) 286 binding = ((ProblemReferenceBinding) binding).closestMatch(); 287 if (binding == null) return INACCURATE_MATCH; 288 289 if (binding instanceof ReferenceBinding) { 290 PackageBinding pkgBinding = ((ReferenceBinding) binding).fPackage; 291 if (pkgBinding == null) return INACCURATE_MATCH; 292 compoundName = pkgBinding.compoundName; 293 } 294 } 295 if (compoundName != null && matchesName(this.pattern.pkgName, CharOperation.concatWith(compoundName, '.'))) { 296 if (((InternalSearchPattern) this.pattern).focus instanceof IPackageFragment && binding instanceof ReferenceBinding) { 297 if (!isDeclaringPackageFragment((IPackageFragment)((InternalSearchPattern) this.pattern).focus, (ReferenceBinding)binding)) 299 return IMPOSSIBLE_MATCH; 300 } 301 return ACCURATE_MATCH; 302 } else { 303 return IMPOSSIBLE_MATCH; 304 } 305 } 306 protected int resolveLevel(QualifiedNameReference qNameRef) { 307 TypeBinding typeBinding = null; 308 switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) { 309 case Binding.FIELD : if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 3 : qNameRef.otherBindings.length + 3)) 311 return IMPOSSIBLE_MATCH; typeBinding = qNameRef.actualReceiverType; 313 break; 314 case Binding.LOCAL : return IMPOSSIBLE_MATCH; case Binding.TYPE : if (qNameRef.binding instanceof TypeBinding) 318 typeBinding = (TypeBinding) qNameRef.binding; 319 break; 320 324 case Binding.VARIABLE : case Binding.TYPE | Binding.VARIABLE : 326 Binding binding = qNameRef.binding; 327 if (binding instanceof ProblemReferenceBinding) { 328 typeBinding = (TypeBinding) binding; 329 } else if (binding instanceof ProblemFieldBinding) { 330 if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 3 : qNameRef.otherBindings.length + 3)) 331 return IMPOSSIBLE_MATCH; typeBinding = qNameRef.actualReceiverType; 333 } else if (binding instanceof ProblemBinding) { 334 ProblemBinding pbBinding = (ProblemBinding) binding; 335 if (CharOperation.occurencesOf('.', pbBinding.name) <= 0) return INACCURATE_MATCH; 337 typeBinding = pbBinding.searchType; 338 } 339 break; 340 } 341 return resolveLevel(typeBinding); 342 } 343 public String toString() { 344 return "Locator for " + this.pattern.toString(); } 346 } 347 | Popular Tags |