src/share/classes/com/sun/tools/apt/comp/Apt.java

Tue, 28 Dec 2010 15:54:52 -0800

author
ohair
date
Tue, 28 Dec 2010 15:54:52 -0800
changeset 798
4868a36f6fd8
parent 581
f2fdd52e4e87
child 1135
36553cb94345
permissions
-rw-r--r--

6962318: Update copyright year
Reviewed-by: xdono

duke@1 1 /*
ohair@798 2 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
duke@1 24 */
duke@1 25
duke@1 26 package com.sun.tools.apt.comp;
duke@1 27
duke@1 28 import com.sun.tools.javac.code.*;
duke@1 29 import com.sun.tools.javac.comp.*;
duke@1 30 import com.sun.tools.javac.tree.*;
duke@1 31 import com.sun.tools.javac.util.*;
duke@1 32 import com.sun.tools.javac.tree.TreeScanner;
duke@1 33 import com.sun.tools.javac.util.Context;
duke@1 34 import com.sun.tools.apt.util.Bark;
duke@1 35 import com.sun.tools.javac.util.Position;
duke@1 36
duke@1 37 import java.util.*;
duke@1 38 import java.util.regex.*;
duke@1 39 import java.lang.reflect.*;
duke@1 40 import java.lang.reflect.InvocationTargetException;
duke@1 41 import java.io.IOException;
duke@1 42
duke@1 43 import com.sun.tools.apt.*;
duke@1 44 import com.sun.tools.apt.comp.*;
duke@1 45 import com.sun.tools.javac.code.Symbol.*;
duke@1 46
duke@1 47 import com.sun.mirror.declaration.TypeDeclaration;
duke@1 48 import com.sun.mirror.declaration.AnnotationTypeDeclaration;
duke@1 49 import com.sun.mirror.apt.*;
duke@1 50 // import com.sun.mirror.apt.AnnotationProcessorFactory;
duke@1 51 import com.sun.mirror.apt.AnnotationProcessors;
duke@1 52
duke@1 53 import com.sun.tools.apt.mirror.AptEnv;
duke@1 54 import com.sun.tools.apt.mirror.apt.FilerImpl;
duke@1 55 import com.sun.tools.apt.mirror.apt.AnnotationProcessorEnvironmentImpl;
duke@1 56
duke@1 57
duke@1 58 import static com.sun.tools.apt.mirror.declaration.DeclarationMaker.isJavaIdentifier;
duke@1 59
duke@1 60 /**
duke@1 61 * Apt compiler phase.
duke@1 62 *
jjg@581 63 * <p><b>This is NOT part of any supported API.
duke@1 64 * If you write code that depends on this, you do so at your own
duke@1 65 * risk. This code and its internal interfaces are subject to change
duke@1 66 * or deletion without notice.</b>
duke@1 67 */
darcy@331 68 @SuppressWarnings("deprecation")
duke@1 69 public class Apt extends ListBuffer<Env<AttrContext>> {
duke@1 70 java.util.Set<String> genSourceFileNames = new java.util.LinkedHashSet<String>();
duke@1 71 public java.util.Set<String> getSourceFileNames() {
duke@1 72 return genSourceFileNames;
duke@1 73 }
duke@1 74
duke@1 75 /** List of names of generated class files.
duke@1 76 */
duke@1 77 java.util.Set<String> genClassFileNames = new java.util.LinkedHashSet<String>();
duke@1 78 public java.util.Set<String> getClassFileNames() {
duke@1 79 return genClassFileNames;
duke@1 80 }
duke@1 81
duke@1 82 /* AptEnvironment */
duke@1 83 AptEnv aptenv;
duke@1 84
duke@1 85 private Context context;
duke@1 86
duke@1 87 /** The context key for the todo list. */
duke@1 88
duke@1 89 protected static final Context.Key<Apt> aptKey =
duke@1 90 new Context.Key<Apt>();
duke@1 91
duke@1 92 /** Get the Apt instance for this context. */
duke@1 93 public static Apt instance(Context context) {
duke@1 94 Apt instance = context.get(aptKey);
duke@1 95 if (instance == null)
duke@1 96 instance = new Apt(context);
duke@1 97 return instance;
duke@1 98 }
duke@1 99
duke@1 100 /** Create a new apt list. */
duke@1 101 protected Apt(Context context) {
duke@1 102 this.context = context;
duke@1 103
duke@1 104 context.put(aptKey, this);
duke@1 105 aptenv = AptEnv.instance(context);
duke@1 106 }
duke@1 107
duke@1 108 /**
duke@1 109 * Used to scan javac trees to build data structures needed for
duke@1 110 * bootstrapping the apt environment. In particular:
duke@1 111 *
duke@1 112 * <ul>
duke@1 113 *
duke@1 114 * <li> Generate list of canonical names of annotation types that
duke@1 115 * appear in source files given on the command line
duke@1 116 *
duke@1 117 * <li> Collect list of javac symbols representing source files
duke@1 118 * given on the command line
duke@1 119 *
duke@1 120 * </ul>
duke@1 121 */
duke@1 122 static class AptTreeScanner extends TreeScanner {
duke@1 123
duke@1 124 // Set of fully qualified names of annotation types present in
duke@1 125 // examined source
duke@1 126 private Set<String> annotationSet;
duke@1 127
duke@1 128 // Symbols to build bootstrapping declaration list
duke@1 129 private Collection<ClassSymbol> specifiedDeclCollection;
duke@1 130 private Collection<ClassSymbol> declCollection;
duke@1 131
duke@1 132 public Set<String> getAnnotationSet() {
duke@1 133 return annotationSet;
duke@1 134 }
duke@1 135
duke@1 136 public AptTreeScanner() {
duke@1 137 annotationSet = new LinkedHashSet<String>();
duke@1 138 specifiedDeclCollection = new LinkedHashSet<ClassSymbol>();
duke@1 139 declCollection = new LinkedHashSet<ClassSymbol>();
duke@1 140 }
duke@1 141
duke@1 142 public void visitTopLevel(JCTree.JCCompilationUnit tree) {
duke@1 143 super.visitTopLevel(tree);
duke@1 144 // Print out contents -- what are we dealing with?
duke@1 145
duke@1 146 for(JCTree d: tree.defs) {
duke@1 147 if (d instanceof JCTree.JCClassDecl)
duke@1 148 specifiedDeclCollection.add(((JCTree.JCClassDecl) d).sym);
duke@1 149 }
duke@1 150
duke@1 151 }
duke@1 152
duke@1 153 public void visitBlock(JCTree.JCBlock tree) {
duke@1 154 ; // Do nothing.
duke@1 155 }
duke@1 156
duke@1 157
duke@1 158 // should add nested classes to packages, etc.
duke@1 159 public void visitClassDef(JCTree.JCClassDecl tree) {
duke@1 160 if (tree.sym == null) {
duke@1 161 // could be an anon class w/in an initializer
duke@1 162 return;
duke@1 163 }
duke@1 164
duke@1 165 super.visitClassDef(tree);
duke@1 166
duke@1 167 declCollection.add(tree.sym);
duke@1 168 }
duke@1 169
duke@1 170 public void visitMethodDef(JCTree.JCMethodDecl tree) {
duke@1 171 super.visitMethodDef(tree);
duke@1 172 }
duke@1 173
duke@1 174 public void visitVarDef(JCTree.JCVariableDecl tree) {
duke@1 175 super.visitVarDef(tree);
duke@1 176 }
duke@1 177
duke@1 178 public void visitAnnotation(JCTree.JCAnnotation tree) {
duke@1 179 super.visitAnnotation(tree);
duke@1 180 annotationSet.add(tree.type.tsym.toString());
duke@1 181 }
duke@1 182 }
duke@1 183
duke@1 184 Set<String> computeAnnotationSet(Collection<ClassSymbol> classSymbols) {
duke@1 185 Set<String> annotationSet = new HashSet<String>();
duke@1 186
duke@1 187 for(ClassSymbol classSymbol: classSymbols) {
duke@1 188 computeAnnotationSet(classSymbol, annotationSet);
duke@1 189 }
duke@1 190 return annotationSet;
duke@1 191 }
duke@1 192
duke@1 193 void computeAnnotationSet(Symbol symbol, Set<String> annotationSet) {
duke@1 194 if (symbol != null ) {
duke@1 195 if (symbol.getAnnotationMirrors() != null)
duke@1 196 for(Attribute.Compound compound: symbol.getAnnotationMirrors())
duke@1 197 annotationSet.add(compound.type.tsym.toString()); // should fullName be used instead of toString?
duke@1 198
duke@1 199 if (symbol instanceof Symbol.MethodSymbol) // add parameter annotations
duke@1 200 for(Symbol param: ((MethodSymbol) symbol).params())
duke@1 201 computeAnnotationSet(param, annotationSet);
duke@1 202
duke@1 203 if (symbol.members() != null) {
jjg@419 204 for(Scope.Entry e = symbol.members().elems; e != null; e = e.sibling)
duke@1 205 computeAnnotationSet(e.sym, annotationSet);
duke@1 206 }
duke@1 207 }
duke@1 208 }
duke@1 209
duke@1 210 public void main(com.sun.tools.javac.util.List<JCTree.JCCompilationUnit> treeList,
duke@1 211 ListBuffer<ClassSymbol> classes,
duke@1 212 Map<String, String> origOptions,
duke@1 213 ClassLoader aptCL,
duke@1 214 AnnotationProcessorFactory providedFactory,
duke@1 215 java.util.Set<Class<? extends AnnotationProcessorFactory> > productiveFactories) {
duke@1 216 Bark bark = Bark.instance(context);
duke@1 217 java.io.PrintWriter out = bark.warnWriter;
duke@1 218 Options options = Options.instance(context);
duke@1 219
duke@1 220 Collection<TypeDeclaration> spectypedecls = new LinkedHashSet<TypeDeclaration>();
duke@1 221 Collection<TypeDeclaration> typedecls = new LinkedHashSet<TypeDeclaration>();
duke@1 222 Set<String> unmatchedAnnotations = new LinkedHashSet<String>();
duke@1 223 Set<AnnotationTypeDeclaration> emptyATDS = Collections.emptySet();
duke@1 224 Set<Class<? extends AnnotationProcessorFactory> > currentRoundFactories =
duke@1 225 new LinkedHashSet<Class<? extends AnnotationProcessorFactory> >();
duke@1 226
duke@1 227 // Determine what annotations are present on the input source
duke@1 228 // files, create collections of specified type declarations,
duke@1 229 // and type declarations.
duke@1 230 AptTreeScanner ats = new AptTreeScanner();
duke@1 231 for(JCTree t: treeList) {
duke@1 232 t.accept(ats);
duke@1 233 }
duke@1 234
duke@1 235 // Turn collection of ClassSymbols into Collection of apt decls
duke@1 236 for (ClassSymbol cs : ats.specifiedDeclCollection) {
duke@1 237 TypeDeclaration decl = aptenv.declMaker.getTypeDeclaration(cs);
duke@1 238 spectypedecls.add(decl);
duke@1 239 }
duke@1 240
duke@1 241 for (ClassSymbol cs : ats.declCollection) {
duke@1 242 TypeDeclaration decl = aptenv.declMaker.getTypeDeclaration(cs);
duke@1 243 typedecls.add(decl);
duke@1 244 }
duke@1 245
duke@1 246 unmatchedAnnotations.addAll(ats.getAnnotationSet());
duke@1 247
duke@1 248 // Process input class files
duke@1 249 for(ClassSymbol cs : classes) {
duke@1 250 TypeDeclaration decl = aptenv.declMaker.getTypeDeclaration(cs);
duke@1 251 // System.out.println("Adding a class to spectypedecls");
duke@1 252 spectypedecls.add(decl);
duke@1 253 typedecls.add(decl);
duke@1 254 computeAnnotationSet(cs, unmatchedAnnotations);
duke@1 255 }
duke@1 256
duke@1 257 if (options.get("-XListAnnotationTypes") != null) {
duke@1 258 out.println("Set of annotations found:" +
duke@1 259 (new TreeSet<String>(unmatchedAnnotations)).toString());
duke@1 260 }
duke@1 261
duke@1 262 AnnotationProcessorEnvironmentImpl trivAPE =
duke@1 263 new AnnotationProcessorEnvironmentImpl(spectypedecls, typedecls, origOptions, context);
duke@1 264
duke@1 265 if (options.get("-XListDeclarations") != null) {
duke@1 266 out.println("Set of Specified Declarations:" +
duke@1 267 spectypedecls);
duke@1 268
duke@1 269 out.println("Set of Included Declarations: " +
duke@1 270 typedecls);
duke@1 271 }
duke@1 272
duke@1 273 if (options.get("-print") != null) {
duke@1 274 if (spectypedecls.size() == 0 )
duke@1 275 throw new UsageMessageNeededException();
duke@1 276
duke@1 277 // Run the printing processor
duke@1 278 AnnotationProcessor proc = (new BootstrapAPF()).getProcessorFor(new HashSet<AnnotationTypeDeclaration>(),
duke@1 279 trivAPE);
duke@1 280 proc.process();
duke@1 281 } else {
duke@1 282 // Discovery process
duke@1 283
duke@1 284 // List of annotation processory factory instances
mcimadamore@184 285 java.util.Iterator<AnnotationProcessorFactory> providers = null;
duke@1 286 {
duke@1 287 /*
duke@1 288 * If a factory is provided by the user, the
duke@1 289 * "-factory" and "-factorypath" options are not used.
duke@1 290 *
duke@1 291 * Otherwise, if the "-factory" option is used, search
duke@1 292 * the appropriate path for the named class.
duke@1 293 * Otherwise, use sun.misc.Service to implement the
duke@1 294 * default discovery policy.
duke@1 295 */
duke@1 296
duke@1 297 java.util.List<AnnotationProcessorFactory> list =
duke@1 298 new LinkedList<AnnotationProcessorFactory>();
duke@1 299 String factoryName = options.get("-factory");
duke@1 300
duke@1 301 if (providedFactory != null) {
duke@1 302 list.add(providedFactory);
duke@1 303 providers = list.iterator();
duke@1 304 } else if (factoryName != null) {
duke@1 305 try {
duke@1 306 AnnotationProcessorFactory factory =
duke@1 307 (AnnotationProcessorFactory) (aptCL.loadClass(factoryName).newInstance());
duke@1 308 list.add(factory);
duke@1 309 } catch (ClassNotFoundException cnfe) {
duke@1 310 bark.aptWarning("FactoryNotFound", factoryName);
duke@1 311 } catch (ClassCastException cce) {
duke@1 312 bark.aptWarning("FactoryWrongType", factoryName);
duke@1 313 } catch (Exception e ) {
duke@1 314 bark.aptWarning("FactoryCantInstantiate", factoryName);
duke@1 315 } catch(Throwable t) {
duke@1 316 throw new AnnotationProcessingError(t);
duke@1 317 }
duke@1 318
duke@1 319 providers = list.iterator();
jjg@198 320 } else {
jjg@198 321 @SuppressWarnings("unchecked")
jjg@198 322 Iterator<AnnotationProcessorFactory> iter =
jjg@198 323 sun.misc.Service.providers(AnnotationProcessorFactory.class, aptCL);
jjg@198 324 providers = iter;
jjg@198 325
jjg@198 326 }
duke@1 327 }
duke@1 328
duke@1 329 java.util.Map<AnnotationProcessorFactory, Set<AnnotationTypeDeclaration>> factoryToAnnotation =
duke@1 330 new LinkedHashMap<AnnotationProcessorFactory, Set<AnnotationTypeDeclaration>>();
duke@1 331
duke@1 332 if (!providers.hasNext() && productiveFactories.size() == 0) {
duke@1 333 if (unmatchedAnnotations.size() > 0)
duke@1 334 bark.aptWarning("NoAnnotationProcessors");
duke@1 335 if (spectypedecls.size() == 0)
duke@1 336 throw new UsageMessageNeededException();
duke@1 337 return; // no processors; nothing else to do
duke@1 338 } else {
duke@1 339 // If there are no annotations, still give
duke@1 340 // processors that match everything a chance to
duke@1 341 // run.
duke@1 342
duke@1 343 if(unmatchedAnnotations.size() == 0)
duke@1 344 unmatchedAnnotations.add("");
duke@1 345
duke@1 346 Set<String> emptyStringSet = new HashSet<String>();
duke@1 347 emptyStringSet.add("");
duke@1 348 emptyStringSet = Collections.unmodifiableSet(emptyStringSet);
duke@1 349
duke@1 350 while (providers.hasNext() ) {
duke@1 351 Object provider = providers.next();
duke@1 352 try {
duke@1 353 Set<String> matchedStrings = new HashSet<String>();
duke@1 354
duke@1 355 AnnotationProcessorFactory apf = (AnnotationProcessorFactory) provider;
duke@1 356 Collection<String> supportedTypes = apf.supportedAnnotationTypes();
duke@1 357
duke@1 358 Collection<Pattern> supportedTypePatterns = new LinkedList<Pattern>();
duke@1 359 for(String s: supportedTypes)
duke@1 360 supportedTypePatterns.add(importStringToPattern(s));
duke@1 361
duke@1 362 for(String s: unmatchedAnnotations) {
duke@1 363 for(Pattern p: supportedTypePatterns) {
duke@1 364 if (p.matcher(s).matches()) {
duke@1 365 matchedStrings.add(s);
duke@1 366 break;
duke@1 367 }
duke@1 368 }
duke@1 369 }
duke@1 370
duke@1 371 unmatchedAnnotations.removeAll(matchedStrings);
duke@1 372
duke@1 373 if (options.get("-XPrintFactoryInfo") != null) {
duke@1 374 out.println("Factory " + apf.getClass().getName() +
duke@1 375 " matches " +
duke@1 376 ((matchedStrings.size() == 0)?
duke@1 377 "nothing.": matchedStrings));
duke@1 378 }
duke@1 379
duke@1 380 if (matchedStrings.size() > 0) {
duke@1 381 // convert annotation names to annotation
duke@1 382 // type decls
duke@1 383 Set<AnnotationTypeDeclaration> atds = new HashSet<AnnotationTypeDeclaration>();
duke@1 384
duke@1 385 // If a "*" processor is called on the
duke@1 386 // empty string, pass in an empty set of
duke@1 387 // annotation type declarations.
duke@1 388 if (!matchedStrings.equals(emptyStringSet)) {
duke@1 389 for(String s: matchedStrings) {
duke@1 390 TypeDeclaration decl = aptenv.declMaker.getTypeDeclaration(s);
duke@1 391 AnnotationTypeDeclaration annotdecl;
duke@1 392 if (decl == null) {
duke@1 393 bark.aptError("DeclarationCreation", s);
duke@1 394 } else {
duke@1 395 try {
duke@1 396 annotdecl = (AnnotationTypeDeclaration)decl;
duke@1 397 atds.add(annotdecl);
duke@1 398
duke@1 399 } catch (ClassCastException cce) {
duke@1 400 bark.aptError("BadDeclaration", s);
duke@1 401 }
duke@1 402 }
duke@1 403 }
duke@1 404 }
duke@1 405
duke@1 406 currentRoundFactories.add(apf.getClass());
duke@1 407 productiveFactories.add(apf.getClass());
duke@1 408 factoryToAnnotation.put(apf, atds);
duke@1 409 } else if (productiveFactories.contains(apf.getClass())) {
duke@1 410 // If a factory provided a processor in a
duke@1 411 // previous round but doesn't match any
duke@1 412 // annotations this round, call it with an
duke@1 413 // empty set of declarations.
duke@1 414 currentRoundFactories.add(apf.getClass());
duke@1 415 factoryToAnnotation.put(apf, emptyATDS );
duke@1 416 }
duke@1 417
duke@1 418 if (unmatchedAnnotations.size() == 0)
duke@1 419 break;
duke@1 420
duke@1 421 } catch (ClassCastException cce) {
duke@1 422 bark.aptWarning("BadFactory", cce);
duke@1 423 }
duke@1 424 }
duke@1 425
duke@1 426 unmatchedAnnotations.remove("");
duke@1 427 }
duke@1 428
duke@1 429 // If the set difference of productiveFactories and
duke@1 430 // currentRoundFactories is non-empty, call the remaining
duke@1 431 // productive factories with an empty set of declarations.
duke@1 432 {
duke@1 433 java.util.Set<Class<? extends AnnotationProcessorFactory> > neglectedFactories =
duke@1 434 new LinkedHashSet<Class<? extends AnnotationProcessorFactory>>(productiveFactories);
duke@1 435 neglectedFactories.removeAll(currentRoundFactories);
duke@1 436 for(Class<? extends AnnotationProcessorFactory> working : neglectedFactories) {
duke@1 437 try {
duke@1 438 AnnotationProcessorFactory factory = working.newInstance();
duke@1 439 factoryToAnnotation.put(factory, emptyATDS);
duke@1 440 } catch (Exception e ) {
duke@1 441 bark.aptWarning("FactoryCantInstantiate", working.getName());
duke@1 442 } catch(Throwable t) {
duke@1 443 throw new AnnotationProcessingError(t);
duke@1 444 }
duke@1 445 }
duke@1 446 }
duke@1 447
duke@1 448 if (unmatchedAnnotations.size() > 0)
duke@1 449 bark.aptWarning("AnnotationsWithoutProcessors", unmatchedAnnotations);
duke@1 450
duke@1 451 Set<AnnotationProcessor> processors = new LinkedHashSet<AnnotationProcessor>();
duke@1 452
duke@1 453 // If there were no source files AND no factory matching "*",
duke@1 454 // make sure the usage message is printed
duke@1 455 if (spectypedecls.size() == 0 &&
duke@1 456 factoryToAnnotation.keySet().size() == 0 )
duke@1 457 throw new UsageMessageNeededException();
duke@1 458
duke@1 459 try {
darcy@506 460 for(Map.Entry<AnnotationProcessorFactory, Set<AnnotationTypeDeclaration>> entry :
darcy@506 461 factoryToAnnotation.entrySet()) {
darcy@506 462 AnnotationProcessorFactory apFactory = entry.getKey();
darcy@506 463 AnnotationProcessor processor = apFactory.getProcessorFor(entry.getValue(),
duke@1 464 trivAPE);
duke@1 465 if (processor != null)
duke@1 466 processors.add(processor);
duke@1 467 else
duke@1 468 bark.aptWarning("NullProcessor", apFactory.getClass().getName());
duke@1 469 }
duke@1 470 } catch(Throwable t) {
duke@1 471 throw new AnnotationProcessingError(t);
duke@1 472 }
duke@1 473
duke@1 474 LinkedList<AnnotationProcessor> temp = new LinkedList<AnnotationProcessor>();
duke@1 475 temp.addAll(processors);
duke@1 476
duke@1 477 AnnotationProcessor proc = AnnotationProcessors.getCompositeAnnotationProcessor(temp);
duke@1 478
duke@1 479 try {
duke@1 480 proc.process();
duke@1 481 } catch (Throwable t) {
duke@1 482 throw new AnnotationProcessingError(t);
duke@1 483 }
duke@1 484
duke@1 485 // Invoke listener callback mechanism
duke@1 486 trivAPE.roundComplete();
duke@1 487
duke@1 488 FilerImpl filerimpl = (FilerImpl)trivAPE.getFiler();
duke@1 489 genSourceFileNames = filerimpl.getSourceFileNames();
duke@1 490 genClassFileNames = filerimpl.getClassFileNames();
duke@1 491 filerimpl.flush(); // Make sure new files are written out
duke@1 492 }
duke@1 493 }
duke@1 494
duke@1 495 /**
duke@1 496 * Convert import-style string to regex matching that string. If
duke@1 497 * the string is a valid import-style string, return a regex that
duke@1 498 * won't match anything.
duke@1 499 */
duke@1 500 Pattern importStringToPattern(String s) {
darcy@497 501 if (com.sun.tools.javac.processing.JavacProcessingEnvironment.isValidImportString(s)) {
darcy@497 502 return com.sun.tools.javac.processing.JavacProcessingEnvironment.validImportStringToPattern(s);
duke@1 503 } else {
darcy@497 504 Bark bark = Bark.instance(context);
darcy@497 505 bark.aptWarning("MalformedSupportedString", s);
darcy@497 506 return com.sun.tools.javac.processing.JavacProcessingEnvironment.noMatches;
duke@1 507 }
duke@1 508 }
duke@1 509 }

mercurial