001    /*
002     * Copyright 2004-2008 Sun Microsystems, Inc.  All Rights Reserved.
003     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004     *
005     * This code is free software; you can redistribute it and/or modify it
006     * under the terms of the GNU General Public License version 2 only, as
007     * published by the Free Software Foundation.  Sun designates this
008     * particular file as subject to the "Classpath" exception as provided
009     * by Sun in the LICENSE file that accompanied this code.
010     *
011     * This code is distributed in the hope that it will be useful, but WITHOUT
012     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014     * version 2 for more details (a copy is included in the LICENSE file that
015     * accompanied this code).
016     *
017     * You should have received a copy of the GNU General Public License version
018     * 2 along with this work; if not, write to the Free Software Foundation,
019     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020     *
021     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022     * CA 95054 USA or visit www.sun.com if you need additional information or
023     * have any questions.
024     */
025    
026    package com.sun.tools.apt.mirror;
027    
028    
029    import com.sun.tools.apt.mirror.declaration.DeclarationMaker;
030    import com.sun.tools.apt.mirror.type.TypeMaker;
031    import com.sun.tools.javac.code.*;
032    import com.sun.tools.javac.code.Symbol.CompletionFailure;
033    import com.sun.tools.javac.comp.Attr;
034    import com.sun.tools.javac.comp.Enter;
035    import com.sun.tools.javac.util.Context;
036    import com.sun.tools.javac.util.Names;
037    
038    
039    /**
040     * The environment for a run of apt.
041     */
042    
043    public class AptEnv {
044    
045        public Names names;                 // javac's name table
046        public Symtab symtab;               // javac's predefined symbols
047        public Types jctypes;               // javac's type utilities
048        public Enter enter;                 // javac's enter phase
049        public Attr attr;                   // javac's attr phase (to evaluate
050                                            //   constant initializers)
051        public TypeMaker typeMaker;         // apt's internal type utilities
052        public DeclarationMaker declMaker;  // apt's internal declaration utilities
053    
054    
055        private static final Context.Key<AptEnv> aptEnvKey =
056                new Context.Key<AptEnv>();
057    
058        public static AptEnv instance(Context context) {
059            AptEnv instance = context.get(aptEnvKey);
060            if (instance == null) {
061                instance = new AptEnv(context);
062            }
063            return instance;
064        }
065    
066        private AptEnv(Context context) {
067            context.put(aptEnvKey, this);
068    
069            names = Names.instance(context);
070            symtab = Symtab.instance(context);
071            jctypes = Types.instance(context);
072            enter = Enter.instance(context);
073            attr = Attr.instance(context);
074            typeMaker = TypeMaker.instance(context);
075            declMaker = DeclarationMaker.instance(context);
076        }
077    
078    
079        /**
080         * Does a symbol have a given flag?  Forces symbol completion.
081         */
082        public static boolean hasFlag(Symbol sym, long flag) {
083            return (getFlags(sym) & flag) != 0;
084        }
085    
086        /**
087         * Returns a symbol's flags.  Forces completion.
088         */
089        public static long getFlags(Symbol sym) {
090            complete(sym);
091            return sym.flags();
092        }
093    
094        /**
095         * Completes a symbol, ignoring completion failures.
096         */
097        private static void complete(Symbol sym) {
098            while (true) {
099                try {
100                    sym.complete();
101                    return;
102                } catch (CompletionFailure e) {
103                    // Should never see two in a row, but loop just to be sure.
104                }
105            }
106        }
107    }