7021650: fix Context issues

Fri, 25 Feb 2011 12:09:33 -0800

author
jjg
date
Fri, 25 Feb 2011 12:09:33 -0800
changeset 893
8f0dcb9499db
parent 892
3e30c95da3c6
child 894
23b64ad3eec8

7021650: fix Context issues
Reviewed-by: mcimadamore

src/share/classes/com/sun/tools/apt/util/Bark.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/api/JavacTool.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/file/JavacFileManager.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/main/JavaCompiler.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/Context.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javadoc/JavadocEnter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javadoc/JavadocTodo.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javadoc/Messager.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/ArgTypeCompilerFactory.java file | annotate | diff | comparison | revisions
test/tools/javac/diags/Example.java file | annotate | diff | comparison | revisions
test/tools/javac/util/context/T7021650.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/apt/util/Bark.java	Thu Feb 24 08:40:49 2011 -0800
     1.2 +++ b/src/share/classes/com/sun/tools/apt/util/Bark.java	Fri Feb 25 12:09:33 2011 -0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -48,15 +48,15 @@
    1.11       * Preregisters factories to create and use a Bark object for use as
    1.12       * both a Log and a Bark.
    1.13       */
    1.14 -    public static void preRegister(final Context context) {
    1.15 +    public static void preRegister(Context context) {
    1.16          context.put(barkKey, new Context.Factory<Bark>() {
    1.17 -            public Bark make() {
    1.18 -                return new Bark(context);
    1.19 +            public Bark make(Context c) {
    1.20 +                return new Bark(c);
    1.21              }
    1.22          });
    1.23          context.put(Log.logKey, new Context.Factory<Log>() {
    1.24 -            public Log make() {
    1.25 -                return Bark.instance(context);
    1.26 +            public Log make(Context c) {
    1.27 +                return Bark.instance(c);
    1.28              }
    1.29          });
    1.30      }
     2.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Thu Feb 24 08:40:49 2011 -0800
     2.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Fri Feb 25 12:09:33 2011 -0800
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -157,19 +157,19 @@
    2.11      /**
    2.12       * Register that a compilation is about to start.
    2.13       */
    2.14 -    void beginContext(final Context context) {
    2.15 +    void beginContext(Context context) {
    2.16          if (compilationInProgress)
    2.17              throw new IllegalStateException("Compilation in progress");
    2.18          compilationInProgress = true;
    2.19          final JavaFileManager givenFileManager = context.get(JavaFileManager.class);
    2.20          context.put(JavaFileManager.class, (JavaFileManager)null);
    2.21          context.put(JavaFileManager.class, new Context.Factory<JavaFileManager>() {
    2.22 -            public JavaFileManager make() {
    2.23 +            public JavaFileManager make(Context c) {
    2.24                  if (givenFileManager != null) {
    2.25 -                    context.put(JavaFileManager.class, givenFileManager);
    2.26 +                    c.put(JavaFileManager.class, givenFileManager);
    2.27                      return givenFileManager;
    2.28                  } else {
    2.29 -                    return new JavacFileManager(context, true, null);
    2.30 +                    return new JavacFileManager(c, true, null);
    2.31                  }
    2.32              }
    2.33          });
     3.1 --- a/src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java	Thu Feb 24 08:40:49 2011 -0800
     3.2 +++ b/src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java	Fri Feb 25 12:09:33 2011 -0800
     3.3 @@ -44,13 +44,13 @@
     3.4  public class CacheFSInfo extends FSInfo {
     3.5  
     3.6      /**
     3.7 -     * Register a Context.Factory to create a singleton CacheFSInfo.
     3.8 +     * Register a Context.Factory to create a CacheFSInfo.
     3.9       */
    3.10 -    public static void preRegister(final Context context) {
    3.11 +    public static void preRegister(Context context) {
    3.12          context.put(FSInfo.class, new Context.Factory<FSInfo>() {
    3.13 -            public FSInfo make() {
    3.14 +            public FSInfo make(Context c) {
    3.15                  FSInfo instance = new CacheFSInfo();
    3.16 -                context.put(FSInfo.class, instance);
    3.17 +                c.put(FSInfo.class, instance);
    3.18                  return instance;
    3.19              }
    3.20          });
     4.1 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Thu Feb 24 08:40:49 2011 -0800
     4.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Fri Feb 25 12:09:33 2011 -0800
     4.3 @@ -129,10 +129,10 @@
     4.4      /**
     4.5       * Register a Context.Factory to create a JavacFileManager.
     4.6       */
     4.7 -    public static void preRegister(final Context context) {
     4.8 +    public static void preRegister(Context context) {
     4.9          context.put(JavaFileManager.class, new Context.Factory<JavaFileManager>() {
    4.10 -            public JavaFileManager make() {
    4.11 -                return new JavacFileManager(context, true, null);
    4.12 +            public JavaFileManager make(Context c) {
    4.13 +                return new JavacFileManager(c, true, null);
    4.14              }
    4.15          });
    4.16      }
     5.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Feb 24 08:40:49 2011 -0800
     5.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Feb 25 12:09:33 2011 -0800
     5.3 @@ -312,7 +312,7 @@
     5.4  
     5.5      /** Construct a new compiler using a shared context.
     5.6       */
     5.7 -    public JavaCompiler(final Context context) {
     5.8 +    public JavaCompiler(Context context) {
     5.9          this.context = context;
    5.10          context.put(compilerKey, this);
    5.11  
     6.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu Feb 24 08:40:49 2011 -0800
     6.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri Feb 25 12:09:33 2011 -0800
     6.3 @@ -1045,7 +1045,7 @@
     6.4           * other values are implicitly reset.
     6.5           */
     6.6          private Context nextContext() {
     6.7 -            Context next = new Context();
     6.8 +            Context next = new Context(context);
     6.9  
    6.10              Options options = Options.instance(context);
    6.11              Assert.checkNonNull(options);
     7.1 --- a/src/share/classes/com/sun/tools/javac/util/Context.java	Thu Feb 24 08:40:49 2011 -0800
     7.2 +++ b/src/share/classes/com/sun/tools/javac/util/Context.java	Fri Feb 25 12:09:33 2011 -0800
     7.3 @@ -108,7 +108,7 @@
     7.4       * instance.
     7.5       */
     7.6      public static interface Factory<T> {
     7.7 -        T make();
     7.8 +        T make(Context c);
     7.9      };
    7.10  
    7.11      /**
    7.12 @@ -124,6 +124,8 @@
    7.13          Object old = ht.put(key, fac);
    7.14          if (old != null)
    7.15              throw new AssertionError("duplicate context value");
    7.16 +        checkState(ft);
    7.17 +        ft.put(key, fac); // cannot be duplicate if unique in ht
    7.18      }
    7.19  
    7.20      /** Set the value for the key in this context. */
    7.21 @@ -142,7 +144,7 @@
    7.22          Object o = ht.get(key);
    7.23          if (o instanceof Factory<?>) {
    7.24              Factory<?> fac = (Factory<?>)o;
    7.25 -            o = fac.make();
    7.26 +            o = fac.make(this);
    7.27              if (o instanceof Factory<?>)
    7.28                  throw new AssertionError("T extends Context.Factory");
    7.29              Assert.check(ht.get(key) == o);
    7.30 @@ -158,6 +160,20 @@
    7.31  
    7.32      public Context() {}
    7.33  
    7.34 +    /**
    7.35 +     * The table of preregistered factories.
    7.36 +     */
    7.37 +    private Map<Key<?>,Factory<?>> ft = new HashMap<Key<?>,Factory<?>>();
    7.38 +
    7.39 +    public Context(Context prev) {
    7.40 +        kt.putAll(prev.kt);     // retain all implicit keys
    7.41 +        ft.putAll(prev.ft);     // retain all factory objects
    7.42 +        ht.putAll(prev.ft);     // init main table with factories
    7.43 +    }
    7.44 +
    7.45 +    /*
    7.46 +     * The key table, providing a unique Key<T> for each Class<T>.
    7.47 +     */
    7.48      private Map<Class<?>, Key<?>> kt = new HashMap<Class<?>, Key<?>>();
    7.49  
    7.50      private <T> Key<T> key(Class<T> clss) {
    7.51 @@ -198,6 +214,7 @@
    7.52      public void clear() {
    7.53          ht = null;
    7.54          kt = null;
    7.55 +        ft = null;
    7.56      }
    7.57  
    7.58      private static void checkState(Map<?,?> t) {
     8.1 --- a/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java	Thu Feb 24 08:40:49 2011 -0800
     8.2 +++ b/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java	Fri Feb 25 12:09:33 2011 -0800
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
     8.6 + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
     8.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.8   *
     8.9   * This code is free software; you can redistribute it and/or modify it
    8.10 @@ -44,10 +44,10 @@
    8.11          return (JavadocClassReader)instance;
    8.12      }
    8.13  
    8.14 -    public static void preRegister(final Context context) {
    8.15 +    public static void preRegister(Context context) {
    8.16          context.put(classReaderKey, new Context.Factory<ClassReader>() {
    8.17 -            public ClassReader make() {
    8.18 -                return new JavadocClassReader(context);
    8.19 +            public ClassReader make(Context c) {
    8.20 +                return new JavadocClassReader(c);
    8.21              }
    8.22          });
    8.23      }
     9.1 --- a/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java	Thu Feb 24 08:40:49 2011 -0800
     9.2 +++ b/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java	Fri Feb 25 12:09:33 2011 -0800
     9.3 @@ -1,5 +1,5 @@
     9.4  /*
     9.5 - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
     9.6 + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
     9.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.8   *
     9.9   * This code is free software; you can redistribute it and/or modify it
    9.10 @@ -48,10 +48,10 @@
    9.11          return (JavadocEnter)instance;
    9.12      }
    9.13  
    9.14 -    public static void preRegister(final Context context) {
    9.15 +    public static void preRegister(Context context) {
    9.16          context.put(enterKey, new Context.Factory<Enter>() {
    9.17 -               public Enter make() {
    9.18 -                   return new JavadocEnter(context);
    9.19 +               public Enter make(Context c) {
    9.20 +                   return new JavadocEnter(c);
    9.21                 }
    9.22          });
    9.23      }
    10.1 --- a/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java	Thu Feb 24 08:40:49 2011 -0800
    10.2 +++ b/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java	Fri Feb 25 12:09:33 2011 -0800
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
    10.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
    10.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.8   *
    10.9   * This code is free software; you can redistribute it and/or modify it
   10.10 @@ -46,10 +46,10 @@
   10.11          return (JavadocMemberEnter)instance;
   10.12      }
   10.13  
   10.14 -    public static void preRegister(final Context context) {
   10.15 +    public static void preRegister(Context context) {
   10.16          context.put(memberEnterKey, new Context.Factory<MemberEnter>() {
   10.17 -               public MemberEnter make() {
   10.18 -                   return new JavadocMemberEnter(context);
   10.19 +               public MemberEnter make(Context c) {
   10.20 +                   return new JavadocMemberEnter(c);
   10.21                 }
   10.22          });
   10.23      }
    11.1 --- a/src/share/classes/com/sun/tools/javadoc/JavadocTodo.java	Thu Feb 24 08:40:49 2011 -0800
    11.2 +++ b/src/share/classes/com/sun/tools/javadoc/JavadocTodo.java	Fri Feb 25 12:09:33 2011 -0800
    11.3 @@ -1,5 +1,5 @@
    11.4  /*
    11.5 - * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
    11.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
    11.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.8   *
    11.9   * This code is free software; you can redistribute it and/or modify it
   11.10 @@ -34,10 +34,10 @@
   11.11   *  @author Neal Gafter
   11.12   */
   11.13  public class JavadocTodo extends Todo {
   11.14 -    public static void preRegister(final Context context) {
   11.15 +    public static void preRegister(Context context) {
   11.16          context.put(todoKey, new Context.Factory<Todo>() {
   11.17 -               public Todo make() {
   11.18 -                   return new JavadocTodo(context);
   11.19 +               public Todo make(Context c) {
   11.20 +                   return new JavadocTodo(c);
   11.21                 }
   11.22          });
   11.23      }
    12.1 --- a/src/share/classes/com/sun/tools/javadoc/Messager.java	Thu Feb 24 08:40:49 2011 -0800
    12.2 +++ b/src/share/classes/com/sun/tools/javadoc/Messager.java	Fri Feb 25 12:09:33 2011 -0800
    12.3 @@ -1,5 +1,5 @@
    12.4  /*
    12.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    12.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    12.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.8   *
    12.9   * This code is free software; you can redistribute it and/or modify it
   12.10 @@ -57,23 +57,23 @@
   12.11          return (Messager)instance;
   12.12      }
   12.13  
   12.14 -    public static void preRegister(final Context context,
   12.15 +    public static void preRegister(Context context,
   12.16                                     final String programName) {
   12.17          context.put(logKey, new Context.Factory<Log>() {
   12.18 -            public Log make() {
   12.19 -                return new Messager(context,
   12.20 +            public Log make(Context c) {
   12.21 +                return new Messager(c,
   12.22                                      programName);
   12.23              }
   12.24          });
   12.25      }
   12.26 -    public static void preRegister(final Context context,
   12.27 +    public static void preRegister(Context context,
   12.28                                     final String programName,
   12.29                                     final PrintWriter errWriter,
   12.30                                     final PrintWriter warnWriter,
   12.31                                     final PrintWriter noticeWriter) {
   12.32          context.put(logKey, new Context.Factory<Log>() {
   12.33 -            public Log make() {
   12.34 -                return new Messager(context,
   12.35 +            public Log make(Context c) {
   12.36 +                return new Messager(c,
   12.37                                      programName,
   12.38                                      errWriter,
   12.39                                      warnWriter,
    13.1 --- a/test/tools/javac/diags/ArgTypeCompilerFactory.java	Thu Feb 24 08:40:49 2011 -0800
    13.2 +++ b/test/tools/javac/diags/ArgTypeCompilerFactory.java	Fri Feb 25 12:09:33 2011 -0800
    13.3 @@ -34,6 +34,7 @@
    13.4  import com.sun.tools.javac.code.*;
    13.5  import com.sun.tools.javac.file.*;
    13.6  import com.sun.tools.javac.main.Main;
    13.7 +import com.sun.tools.javac.main.JavaCompiler;
    13.8  import com.sun.tools.javac.parser.Token;
    13.9  import com.sun.tools.javac.util.*;
   13.10  import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
   13.11 @@ -107,8 +108,7 @@
   13.12              JavacTaskImpl t = (JavacTaskImpl) tool.getTask(out, fm, null, opts, null, fos);
   13.13              Context c = t.getContext();
   13.14              ArgTypeMessages.preRegister(c);
   13.15 -            Options options = Options.instance(c);
   13.16 -            Log.instance(c).setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
   13.17 +            ArgTypeJavaCompiler.preRegister(c);
   13.18              Boolean ok = t.call();
   13.19  
   13.20              return ok;
   13.21 @@ -144,7 +144,7 @@
   13.22                  }
   13.23              };
   13.24              JavacFileManager.preRegister(c); // can't create it until Log has been set up
   13.25 -            ArgTypeDiagnosticFormatter.preRegister(c);
   13.26 +            ArgTypeJavaCompiler.preRegister(c);
   13.27              ArgTypeMessages.preRegister(c);
   13.28              int result = main.compile(args.toArray(new String[args.size()]), c);
   13.29  
   13.30 @@ -170,7 +170,7 @@
   13.31  
   13.32              Context c = new Context();
   13.33              JavacFileManager.preRegister(c); // can't create it until Log has been set up
   13.34 -            ArgTypeDiagnosticFormatter.preRegister(c);
   13.35 +            ArgTypeJavaCompiler.preRegister(c);
   13.36              ArgTypeMessages.preRegister(c);
   13.37              com.sun.tools.javac.main.Main m = new com.sun.tools.javac.main.Main("javac", out);
   13.38              int rc = m.compile(args.toArray(new String[args.size()]), c);
   13.39 @@ -189,17 +189,6 @@
   13.40       * arg types.
   13.41       */
   13.42      static class ArgTypeDiagnosticFormatter extends AbstractDiagnosticFormatter {
   13.43 -        static void preRegister(final Context context) {
   13.44 -            context.put(Log.logKey, new Context.Factory<Log>() {
   13.45 -                public Log make() {
   13.46 -                    Log log = new Log(context) { };
   13.47 -                    Options options = Options.instance(context);
   13.48 -                    log.setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
   13.49 -                    return log;
   13.50 -                }
   13.51 -            });
   13.52 -
   13.53 -        }
   13.54  
   13.55          ArgTypeDiagnosticFormatter(Options options) {
   13.56              super(null, new SimpleConfiguration(options,
   13.57 @@ -246,14 +235,37 @@
   13.58      }
   13.59  
   13.60      /**
   13.61 +     * Trivial subtype of JavaCompiler to get access to the protected compilerKey field.
   13.62 +     * The factory is used to ensure that the log is initialized with an instance of
   13.63 +     * ArgTypeDiagnosticFormatter before we create the required JavaCompiler.
   13.64 +     */
   13.65 +    static class ArgTypeJavaCompiler extends JavaCompiler {
   13.66 +        static void preRegister(Context context) {
   13.67 +            context.put(compilerKey, new Context.Factory<JavaCompiler>() {
   13.68 +                public JavaCompiler make(Context c) {
   13.69 +                    Log log = Log.instance(c);
   13.70 +                    Options options = Options.instance(c);
   13.71 +                    log.setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
   13.72 +                    return new JavaCompiler(c);
   13.73 +                }
   13.74 +            });
   13.75 +        }
   13.76 +
   13.77 +        // not used
   13.78 +        private ArgTypeJavaCompiler() {
   13.79 +            super(null);
   13.80 +        }
   13.81 +    }
   13.82 +
   13.83 +    /**
   13.84       * Diagnostic formatter which "localizes" a message as a line
   13.85       * containing a key, and a possibly empty set of descriptive strings for the
   13.86       * arg types.
   13.87       */
   13.88      static class ArgTypeMessages extends JavacMessages {
   13.89 -        static void preRegister(final Context c) {
   13.90 -            c.put(JavacMessages.messagesKey, new Context.Factory<JavacMessages>() {
   13.91 -                public JavacMessages make() {
   13.92 +        static void preRegister(Context context) {
   13.93 +            context.put(JavacMessages.messagesKey, new Context.Factory<JavacMessages>() {
   13.94 +                public JavacMessages make(Context c) {
   13.95                      return new ArgTypeMessages(c) {
   13.96                          @Override
   13.97                          public String getLocalizedString(Locale l, String key, Object... args) {
    14.1 --- a/test/tools/javac/diags/Example.java	Thu Feb 24 08:40:49 2011 -0800
    14.2 +++ b/test/tools/javac/diags/Example.java	Fri Feb 25 12:09:33 2011 -0800
    14.3 @@ -522,10 +522,10 @@
    14.4                  super(context);
    14.5              }
    14.6  
    14.7 -            static void preRegister(final Context c, final Set<String> keys) {
    14.8 +            static void preRegister(Context c, final Set<String> keys) {
    14.9                  if (keys != null) {
   14.10                      c.put(JavacMessages.messagesKey, new Context.Factory<JavacMessages>() {
   14.11 -                        public JavacMessages make() {
   14.12 +                        public JavacMessages make(Context c) {
   14.13                              return new MessageTracker(c) {
   14.14                                  @Override
   14.15                                  public String getLocalizedString(Locale l, String key, Object... args) {
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/test/tools/javac/util/context/T7021650.java	Fri Feb 25 12:09:33 2011 -0800
    15.3 @@ -0,0 +1,216 @@
    15.4 +/*
    15.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.
   15.11 + *
   15.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.15 + * version 2 for more details (a copy is included in the LICENSE file that
   15.16 + * accompanied this code).
   15.17 + *
   15.18 + * You should have received a copy of the GNU General Public License version
   15.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.21 + *
   15.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.23 + * or visit www.oracle.com if you need additional information or have any
   15.24 + * questions.
   15.25 + */
   15.26 +
   15.27 +/**
   15.28 + * @test
   15.29 + * @bug 7021650
   15.30 + * @summary Fix Context issues
   15.31 + * @library ../../lib
   15.32 + * @build JavacTestingAbstractProcessor T7021650
   15.33 + * @run main T7021650
   15.34 + */
   15.35 +
   15.36 +import java.io.*;
   15.37 +import java.net.*;
   15.38 +import java.util.*;
   15.39 +import javax.annotation.processing.*;
   15.40 +import javax.lang.model.element.*;
   15.41 +import javax.tools.*;
   15.42 +
   15.43 +import com.sun.tools.javac.comp.Attr;
   15.44 +import com.sun.tools.javac.file.JavacFileManager;
   15.45 +import com.sun.tools.javac.main.Main;
   15.46 +import com.sun.tools.javac.processing.JavacProcessingEnvironment;
   15.47 +import com.sun.tools.javac.util.Context;
   15.48 +
   15.49 +public class T7021650 extends JavacTestingAbstractProcessor {
   15.50 +    public static void main(String... args) throws Exception {
   15.51 +        new T7021650().run();
   15.52 +    }
   15.53 +
   15.54 +    static File testSrc = new File(System.getProperty("test.src"));
   15.55 +    static final int MAX_ROUNDS = 3;
   15.56 +
   15.57 +    /**
   15.58 +     * Perform a compilation with custom factories registered in the context,
   15.59 +     * and verify that corresponding objects are created in each round.
   15.60 +     */
   15.61 +    void run() throws Exception {
   15.62 +        Counter demoCounter = new Counter();
   15.63 +        Counter myAttrCounter = new Counter();
   15.64 +
   15.65 +        Context context = new Context();
   15.66 +        // Use a custom file manager which creates classloaders for annotation
   15.67 +        // processors with a sensible delegation parent, so that all instances
   15.68 +        // of test classes come from the same class loader. This is important
   15.69 +        // because the test performs class checks on the instances of classes
   15.70 +        // found in the context for each round or processing.
   15.71 +        context.put(JavaFileManager.class, new Context.Factory<JavaFileManager>() {
   15.72 +            public JavaFileManager make(Context c) {
   15.73 +                return new JavacFileManager(c, true, null) {
   15.74 +                    @Override
   15.75 +                    protected ClassLoader getClassLoader(URL[] urls) {
   15.76 +                        return new URLClassLoader(urls, T7021650.class.getClassLoader());
   15.77 +                    }
   15.78 +                };
   15.79 +            }
   15.80 +        });
   15.81 +
   15.82 +        Demo.preRegister(context, demoCounter);
   15.83 +        MyAttr.preRegister(context, myAttrCounter);
   15.84 +
   15.85 +        String[] args = {
   15.86 +            "-d", ".",
   15.87 +            "-processor", T7021650.class.getName(),
   15.88 +            "-XprintRounds",
   15.89 +            new File(testSrc, T7021650.class.getName() + ".java").getPath()
   15.90 +        };
   15.91 +
   15.92 +        compile(context, args);
   15.93 +
   15.94 +        // Expect to create Demo for initial round, then MAX_ROUNDS in which
   15.95 +        // GenX files are generated, then standard final round of processing.
   15.96 +        checkEqual("demoCounter", demoCounter.count, MAX_ROUNDS + 2);
   15.97 +
   15.98 +        // Expect to create MyAttr for same processing rounds as for Demo,
   15.99 +        // plus additional context for final compilation.
  15.100 +        checkEqual("myAttrCounter", myAttrCounter.count, MAX_ROUNDS + 3);
  15.101 +    }
  15.102 +
  15.103 +    void compile(Context context, String... args) throws Exception {
  15.104 +        StringWriter sw = new StringWriter();
  15.105 +        PrintWriter pw = new PrintWriter(sw);
  15.106 +        Main m = new Main("javac", pw);
  15.107 +        int rc = m.compile(args, context);
  15.108 +        pw.close();
  15.109 +        String out = sw.toString();
  15.110 +        if (!out.isEmpty())
  15.111 +            System.err.println(out);
  15.112 +        if (rc != 0)
  15.113 +            throw new Exception("compilation failed unexpectedly: rc=" + rc);
  15.114 +    }
  15.115 +
  15.116 +    void checkEqual(String label, int found, int expect) throws Exception {
  15.117 +        if (found != expect)
  15.118 +            throw new Exception("unexpected value for " + label
  15.119 +                    + ": expected " + expect
  15.120 +                    + ": found " + found);
  15.121 +    }
  15.122 +
  15.123 +    //---------------
  15.124 +
  15.125 +    /*
  15.126 +     * A custom class unknown to javac but nonetheless registered in the context.
  15.127 +     */
  15.128 +    static class Demo {
  15.129 +        static void preRegister(Context context, final Counter counter) {
  15.130 +            context.put(Demo.class, new Context.Factory<Demo>() {
  15.131 +                public Demo make(Context c) {
  15.132 +                    counter.count++;
  15.133 +                    return new Demo(c);
  15.134 +                }
  15.135 +            });
  15.136 +        }
  15.137 +
  15.138 +        Demo(Context c) {
  15.139 +            c.put(Demo.class, this);
  15.140 +        }
  15.141 +
  15.142 +        static Demo instance(Context context) {
  15.143 +            return context.get(Demo.class);
  15.144 +        }
  15.145 +    }
  15.146 +
  15.147 +    /**
  15.148 +     * A custom version of a standard javac component.
  15.149 +     */
  15.150 +    static class MyAttr extends Attr {
  15.151 +        static void preRegister(Context context, final Counter counter) {
  15.152 +            context.put(attrKey, new Context.Factory<Attr>() {
  15.153 +                public Attr make(Context c) {
  15.154 +                    counter.count++;
  15.155 +                    return new MyAttr(c);
  15.156 +                }
  15.157 +            });
  15.158 +        }
  15.159 +
  15.160 +        MyAttr(Context c) {
  15.161 +            super(c);
  15.162 +        }
  15.163 +    }
  15.164 +
  15.165 +    static class Counter {
  15.166 +        int count;
  15.167 +    }
  15.168 +
  15.169 +    //---------------
  15.170 +
  15.171 +    int round = 0;
  15.172 +
  15.173 +    @Override
  15.174 +    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
  15.175 +        round++;
  15.176 +
  15.177 +        Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
  15.178 +
  15.179 +        // verify items in context as expected
  15.180 +        check("Demo", Demo.instance(context), Demo.class);
  15.181 +        check("Attr", Attr.instance(context), MyAttr.class);
  15.182 +
  15.183 +        // For a few rounds, generate new source files, so that we can check whether
  15.184 +        // values in the context are correctly handled in subsequent processing rounds
  15.185 +        if (round <= MAX_ROUNDS) {
  15.186 +            String pkg = "p";
  15.187 +            String currClass = "Gen" + round;
  15.188 +            String curr = pkg + "." + currClass;
  15.189 +            String next = (pkg + ".Gen" + (round + 1));
  15.190 +            StringBuilder text = new StringBuilder();
  15.191 +            text.append("package ").append(pkg).append(";\n");
  15.192 +            text.append("public class ").append(currClass).append(" {\n");
  15.193 +            if (round < MAX_ROUNDS)
  15.194 +                text.append("    ").append(next).append(" x;\n");
  15.195 +            text.append("}\n");
  15.196 +
  15.197 +            try {
  15.198 +                JavaFileObject fo = filer.createSourceFile(curr);
  15.199 +                Writer out = fo.openWriter();
  15.200 +                try {
  15.201 +                    out.write(text.toString());
  15.202 +                } finally {
  15.203 +                    out.close();
  15.204 +                }
  15.205 +            } catch (IOException e) {
  15.206 +                throw new Error(e);
  15.207 +            }
  15.208 +        }
  15.209 +
  15.210 +        return true;
  15.211 +    }
  15.212 +
  15.213 +    void check(String label, Object o, Class<?> clazz) {
  15.214 +        if (o == null)
  15.215 +            throw new IllegalStateException(label + ": no item found");
  15.216 +        if (!clazz.isAssignableFrom(o.getClass()))
  15.217 +            throw new IllegalStateException(label + ": unexpected class: " + o.getClass());
  15.218 +    }
  15.219 +}

mercurial