EMMA Coverage Report (generated Thu Dec 06 15:52:10 GMT 2007)
[all classes][com.sun.tools.javac.comp]

COVERAGE SUMMARY FOR SOURCE FILE [Annotate.java]

nameclass, %method, %block, %line, %
Annotate.java100% (1/1)60%  (6/10)16%  (108/656)27%  (29.4/110)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Annotate100% (1/1)60%  (6/10)16%  (108/656)27%  (29.4/110)
earlier (Annotate$Annotator): void 0%   (0/1)0%   (0/6)0%   (0/2)
enterAnnotation (JCTree$JCAnnotation, Type, Env): Attribute$Compound 0%   (0/1)0%   (0/226)0%   (0/31)
enterAttributeValue (Type, JCTree$JCExpression, Env): Attribute 0%   (0/1)0%   (0/295)0%   (0/44)
later (Annotate$Annotator): void 0%   (0/1)0%   (0/6)0%   (0/2)
flush (): void 100% (1/1)59%  (22/37)78%  (5.4/7)
<static initializer> 100% (1/1)100% (5/5)100% (1/1)
Annotate (Context): void 100% (1/1)100% (51/51)100% (14/14)
enterDone (): void 100% (1/1)100% (9/9)100% (3/3)
enterStart (): void 100% (1/1)100% (7/7)100% (2/2)
instance (Context): Annotate 100% (1/1)100% (14/14)100% (4/4)

1/*
2 * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25 
26package com.sun.tools.javac.comp;
27 
28import com.sun.tools.javac.util.*;
29import com.sun.tools.javac.code.*;
30import com.sun.tools.javac.code.Symbol.*;
31import com.sun.tools.javac.tree.*;
32import com.sun.tools.javac.tree.JCTree.*;
33 
34/** Enter annotations on symbols.  Annotations accumulate in a queue,
35 *  which is processed at the top level of any set of recursive calls
36 *  requesting it be processed.
37 *
38 *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
39 *  you write code that depends on this, you do so at your own risk.
40 *  This code and its internal interfaces are subject to change or
41 *  deletion without notice.</b>
42 */
43public class Annotate {
44    protected static final Context.Key<Annotate> annotateKey =
45        new Context.Key<Annotate>();
46 
47    public static Annotate instance(Context context) {
48        Annotate instance = context.get(annotateKey);
49        if (instance == null)
50            instance = new Annotate(context);
51        return instance;
52    }
53 
54    final Attr attr;
55    final TreeMaker make;
56    final Log log;
57    final Symtab syms;
58    final Name.Table names;
59    final Resolve rs;
60    final Types types;
61    final ConstFold cfolder;
62    final Check chk;
63 
64    protected Annotate(Context context) {
65        context.put(annotateKey, this);
66        attr = Attr.instance(context);
67        make = TreeMaker.instance(context);
68        log = Log.instance(context);
69        syms = Symtab.instance(context);
70        names = Name.Table.instance(context);
71        rs = Resolve.instance(context);
72        types = Types.instance(context);
73        cfolder = ConstFold.instance(context);
74        chk = Check.instance(context);
75    }
76 
77/* ********************************************************************
78 * Queue maintenance
79 *********************************************************************/
80 
81    private int enterCount = 0;
82 
83    ListBuffer<Annotator> q = new ListBuffer<Annotator>();
84 
85    public void later(Annotator a) {
86        q.append(a);
87    }
88 
89    public void earlier(Annotator a) {
90        q.prepend(a);
91    }
92 
93    /** Called when the Enter phase starts. */
94    public void enterStart() {
95        enterCount++;
96    }
97 
98    /** Called after the Enter phase completes. */
99    public void enterDone() {
100        enterCount--;
101        flush();
102    }
103 
104    public void flush() {
105        if (enterCount != 0) return;
106        enterCount++;
107        try {
108            while (q.nonEmpty())
109                q.next().enterAnnotation();
110        } finally {
111            enterCount--;
112        }
113    }
114 
115    /** A client that has annotations to add registers an annotator,
116     *  the method it will use to add the annotation.  There are no
117     *  parameters; any needed data should be captured by the
118     *  Annotator.
119     */
120    public interface Annotator {
121        void enterAnnotation();
122        String toString();
123    }
124 
125 
126/* ********************************************************************
127 * Compute an attribute from its annotation.
128 *********************************************************************/
129 
130    /** Process a single compound annotation, returning its
131     *  Attribute. Used from MemberEnter for attaching the attributes
132     *  to the annotated symbol.
133     */
134    Attribute.Compound enterAnnotation(JCAnnotation a,
135                                       Type expected,
136                                       Env<AttrContext> env) {
137        // The annotation might have had its type attributed (but not checked)
138        // by attr.attribAnnotationTypes during MemberEnter, in which case we do not
139        // need to do it again.
140        Type at = (a.annotationType.type != null ? a.annotationType.type
141                  : attr.attribType(a.annotationType, env));
142        a.type = chk.checkType(a.annotationType.pos(), at, expected);
143        if (a.type.isErroneous())
144            return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
145        if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) {
146            log.error(a.annotationType.pos(),
147                      "not.annotation.type", a.type.toString());
148            return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
149        }
150        List<JCExpression> args = a.args;
151        if (args.length() == 1 && args.head.getTag() != JCTree.ASSIGN) {
152            // special case: elided "value=" assumed
153            args.head = make.at(args.head.pos).
154                Assign(make.Ident(names.value), args.head);
155        }
156        ListBuffer<Pair<MethodSymbol,Attribute>> buf =
157            new ListBuffer<Pair<MethodSymbol,Attribute>>();
158        for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
159            JCExpression t = tl.head;
160            if (t.getTag() != JCTree.ASSIGN) {
161                log.error(t.pos(), "annotation.value.must.be.name.value");
162                continue;
163            }
164            JCAssign assign = (JCAssign)t;
165            if (assign.lhs.getTag() != JCTree.IDENT) {
166                log.error(t.pos(), "annotation.value.must.be.name.value");
167                continue;
168            }
169            JCIdent left = (JCIdent)assign.lhs;
170            Symbol method = rs.resolveQualifiedMethod(left.pos(),
171                                                      env,
172                                                      a.type,
173                                                      left.name,
174                                                      List.<Type>nil(),
175                                                      null);
176            left.sym = method;
177            left.type = method.type;
178            if (method.owner != a.type.tsym)
179                log.error(left.pos(), "no.annotation.member", left.name, a.type);
180            Type result = method.type.getReturnType();
181            Attribute value = enterAttributeValue(result, assign.rhs, env);
182            if (!method.type.isErroneous())
183                buf.append(new Pair<MethodSymbol,Attribute>
184                           ((MethodSymbol)method, value));
185        }
186        return new Attribute.Compound(a.type, buf.toList());
187    }
188 
189    Attribute enterAttributeValue(Type expected,
190                                  JCExpression tree,
191                                  Env<AttrContext> env) {
192        if (expected.isPrimitive() || types.isSameType(expected, syms.stringType)) {
193            Type result = attr.attribExpr(tree, env, expected);
194            if (result.isErroneous())
195                return new Attribute.Error(expected);
196            if (result.constValue() == null) {
197                log.error(tree.pos(), "attribute.value.must.be.constant");
198                return new Attribute.Error(expected);
199            }
200            result = cfolder.coerce(result, expected);
201            return new Attribute.Constant(expected, result.constValue());
202        }
203        if (expected.tsym == syms.classType.tsym) {
204            Type result = attr.attribExpr(tree, env, expected);
205            if (result.isErroneous())
206                return new Attribute.Error(expected);
207            if (TreeInfo.name(tree) != names._class) {
208                log.error(tree.pos(), "annotation.value.must.be.class.literal");
209                return new Attribute.Error(expected);
210            }
211            return new Attribute.Class(types,
212                                       (((JCFieldAccess) tree).selected).type);
213        }
214        if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) {
215            if (tree.getTag() != JCTree.ANNOTATION) {
216                log.error(tree.pos(), "annotation.value.must.be.annotation");
217                expected = syms.errorType;
218            }
219            return enterAnnotation((JCAnnotation)tree, expected, env);
220        }
221        if (expected.tag == TypeTags.ARRAY) { // should really be isArray()
222            if (tree.getTag() != JCTree.NEWARRAY) {
223                tree = make.at(tree.pos).
224                    NewArray(null, List.<JCExpression>nil(), List.of(tree));
225            }
226            JCNewArray na = (JCNewArray)tree;
227            if (na.elemtype != null) {
228                log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
229                return new Attribute.Error(expected);
230            }
231            ListBuffer<Attribute> buf = new ListBuffer<Attribute>();
232            for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
233                buf.append(enterAttributeValue(types.elemtype(expected),
234                                               l.head,
235                                               env));
236            }
237            return new Attribute.
238                Array(expected, buf.toArray(new Attribute[buf.length()]));
239        }
240        if (expected.tag == TypeTags.CLASS &&
241            (expected.tsym.flags() & Flags.ENUM) != 0) {
242            attr.attribExpr(tree, env, expected);
243            Symbol sym = TreeInfo.symbol(tree);
244            if (sym == null ||
245                TreeInfo.nonstaticSelect(tree) ||
246                sym.kind != Kinds.VAR ||
247                (sym.flags() & Flags.ENUM) == 0) {
248                log.error(tree.pos(), "enum.annotation.must.be.enum.constant");
249                return new Attribute.Error(expected);
250            }
251            VarSymbol enumerator = (VarSymbol) sym;
252            return new Attribute.Enum(expected, enumerator);
253        }
254        if (!expected.isErroneous())
255            log.error(tree.pos(), "annotation.value.not.allowable.type");
256        return new Attribute.Error(attr.attribExpr(tree, env, expected));
257    }
258}

[all classes][com.sun.tools.javac.comp]
EMMA 2.0.5312 (C) Vladimir Roubtsov