src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java

changeset 1521
71f35e4b93a5
parent 1473
31780dd06ec7
child 1541
4cc73ec94686
     1.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Jan 23 20:57:40 2013 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Jan 23 13:27:24 2013 -0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1999, 2013, 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 @@ -31,12 +31,14 @@
    1.11  import java.util.Set;
    1.12  import java.util.HashSet;
    1.13  
    1.14 +import javax.lang.model.type.TypeKind;
    1.15  import javax.tools.JavaFileManager;
    1.16  import javax.tools.FileObject;
    1.17  import javax.tools.JavaFileObject;
    1.18  
    1.19  import com.sun.tools.javac.code.*;
    1.20  import com.sun.tools.javac.code.Attribute.RetentionPolicy;
    1.21 +import com.sun.tools.javac.code.Attribute.TypeCompound;
    1.22  import com.sun.tools.javac.code.Symbol.*;
    1.23  import com.sun.tools.javac.code.Type.*;
    1.24  import com.sun.tools.javac.code.Types.UniqueType;
    1.25 @@ -47,7 +49,6 @@
    1.26  import com.sun.tools.javac.jvm.Pool.Variable;
    1.27  import com.sun.tools.javac.util.*;
    1.28  
    1.29 -import static com.sun.tools.javac.code.BoundKind.*;
    1.30  import static com.sun.tools.javac.code.Flags.*;
    1.31  import static com.sun.tools.javac.code.Kinds.*;
    1.32  import static com.sun.tools.javac.code.TypeTag.*;
    1.33 @@ -68,19 +69,17 @@
    1.34      protected static final Context.Key<ClassWriter> classWriterKey =
    1.35          new Context.Key<ClassWriter>();
    1.36  
    1.37 -    private final Symtab syms;
    1.38 -
    1.39      private final Options options;
    1.40  
    1.41      /** Switch: verbose output.
    1.42       */
    1.43      private boolean verbose;
    1.44  
    1.45 -    /** Switch: scramble private names.
    1.46 +    /** Switch: scramble private field names.
    1.47       */
    1.48      private boolean scramble;
    1.49  
    1.50 -    /** Switch: scramble private names.
    1.51 +    /** Switch: scramble all field names.
    1.52       */
    1.53      private boolean scrambleAll;
    1.54  
    1.55 @@ -96,7 +95,7 @@
    1.56       */
    1.57      private boolean genCrt;
    1.58  
    1.59 -    /** Switch: describe the generated stackmap
    1.60 +    /** Switch: describe the generated stackmap.
    1.61       */
    1.62      boolean debugstackmap;
    1.63  
    1.64 @@ -114,7 +113,7 @@
    1.65      private Types types;
    1.66  
    1.67      /** The initial sizes of the data and constant pool buffers.
    1.68 -     *  sizes are increased when buffers get full.
    1.69 +     *  Sizes are increased when buffers get full.
    1.70       */
    1.71      static final int DATA_BUF_SIZE = 0x0fff0;
    1.72      static final int POOL_BUF_SIZE = 0x1fff0;
    1.73 @@ -181,7 +180,6 @@
    1.74  
    1.75          log = Log.instance(context);
    1.76          names = Names.instance(context);
    1.77 -        syms = Symtab.instance(context);
    1.78          options = Options.instance(context);
    1.79          target = Target.instance(context);
    1.80          source = Source.instance(context);
    1.81 @@ -279,6 +277,7 @@
    1.82      /** Assemble signature of given type in string buffer.
    1.83       */
    1.84      void assembleSig(Type type) {
    1.85 +        type = type.unannotatedType();
    1.86          switch (type.getTag()) {
    1.87          case BYTE:
    1.88              sigbuf.appendByte('B');
    1.89 @@ -379,6 +378,7 @@
    1.90      }
    1.91  
    1.92      void assembleClassSig(Type type) {
    1.93 +        type = type.unannotatedType();
    1.94          ClassType ct = (ClassType)type;
    1.95          ClassSymbol c = (ClassSymbol)ct.tsym;
    1.96          enterInner(c);
    1.97 @@ -722,6 +722,7 @@
    1.98              acount++;
    1.99          }
   1.100          acount += writeJavaAnnotations(sym.getRawAttributes());
   1.101 +        acount += writeTypeAnnotations(sym.getRawTypeAttributes());
   1.102          return acount;
   1.103      }
   1.104  
   1.105 @@ -838,6 +839,76 @@
   1.106          return attrCount;
   1.107      }
   1.108  
   1.109 +    int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos) {
   1.110 +        if (typeAnnos.isEmpty()) return 0;
   1.111 +
   1.112 +        ListBuffer<Attribute.TypeCompound> visibles = ListBuffer.lb();
   1.113 +        ListBuffer<Attribute.TypeCompound> invisibles = ListBuffer.lb();
   1.114 +
   1.115 +        for (Attribute.TypeCompound tc : typeAnnos) {
   1.116 +            if (tc.position == null || tc.position.type == TargetType.UNKNOWN) {
   1.117 +                boolean found = false;
   1.118 +                // TODO: the position for the container annotation of a
   1.119 +                // repeating type annotation has to be set.
   1.120 +                // This cannot be done when the container is created, because
   1.121 +                // then the position is not determined yet.
   1.122 +                // How can we link these pieces better together?
   1.123 +                if (tc.values.size() == 1) {
   1.124 +                    Pair<MethodSymbol, Attribute> val = tc.values.get(0);
   1.125 +                    if (val.fst.getSimpleName().contentEquals("value") &&
   1.126 +                            val.snd instanceof Attribute.Array) {
   1.127 +                        Attribute.Array arr = (Attribute.Array) val.snd;
   1.128 +                        if (arr.values.length != 0 &&
   1.129 +                                arr.values[0] instanceof Attribute.TypeCompound) {
   1.130 +                            TypeCompound atycomp = (Attribute.TypeCompound) arr.values[0];
   1.131 +                            if (atycomp.position.type != TargetType.UNKNOWN) {
   1.132 +                                tc.position = atycomp.position;
   1.133 +                                found = true;
   1.134 +                            }
   1.135 +                        }
   1.136 +                    }
   1.137 +                }
   1.138 +                if (!found) {
   1.139 +                    // This happens for nested types like @A Outer. @B Inner.
   1.140 +                    // For method parameters we get the annotation twice! Once with
   1.141 +                    // a valid position, once unknown.
   1.142 +                    // TODO: find a cleaner solution.
   1.143 +                    // System.err.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
   1.144 +                    continue;
   1.145 +                }
   1.146 +            }
   1.147 +            if (!tc.position.emitToClassfile())
   1.148 +                continue;
   1.149 +            switch (types.getRetention(tc)) {
   1.150 +            case SOURCE: break;
   1.151 +            case CLASS: invisibles.append(tc); break;
   1.152 +            case RUNTIME: visibles.append(tc); break;
   1.153 +            default: ;// /* fail soft */ throw new AssertionError(vis);
   1.154 +            }
   1.155 +        }
   1.156 +
   1.157 +        int attrCount = 0;
   1.158 +        if (visibles.length() != 0) {
   1.159 +            int attrIndex = writeAttr(names.RuntimeVisibleTypeAnnotations);
   1.160 +            databuf.appendChar(visibles.length());
   1.161 +            for (Attribute.TypeCompound p : visibles)
   1.162 +                writeTypeAnnotation(p);
   1.163 +            endAttr(attrIndex);
   1.164 +            attrCount++;
   1.165 +        }
   1.166 +
   1.167 +        if (invisibles.length() != 0) {
   1.168 +            int attrIndex = writeAttr(names.RuntimeInvisibleTypeAnnotations);
   1.169 +            databuf.appendChar(invisibles.length());
   1.170 +            for (Attribute.TypeCompound p : invisibles)
   1.171 +                writeTypeAnnotation(p);
   1.172 +            endAttr(attrIndex);
   1.173 +            attrCount++;
   1.174 +        }
   1.175 +
   1.176 +        return attrCount;
   1.177 +    }
   1.178 +
   1.179      /** A visitor to write an attribute including its leading
   1.180       *  single-character marker.
   1.181       */
   1.182 @@ -914,6 +985,94 @@
   1.183              p.snd.accept(awriter);
   1.184          }
   1.185      }
   1.186 +
   1.187 +    void writeTypeAnnotation(Attribute.TypeCompound c) {
   1.188 +        writePosition(c.position);
   1.189 +        writeCompoundAttribute(c);
   1.190 +    }
   1.191 +
   1.192 +    void writePosition(TypeAnnotationPosition p) {
   1.193 +        databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte
   1.194 +        switch (p.type) {
   1.195 +        // type cast
   1.196 +        case CAST:
   1.197 +        // instanceof
   1.198 +        case INSTANCEOF:
   1.199 +        // new expression
   1.200 +        case NEW:
   1.201 +            databuf.appendChar(p.offset);
   1.202 +            break;
   1.203 +        // local variable
   1.204 +        case LOCAL_VARIABLE:
   1.205 +        // resource variable
   1.206 +        case RESOURCE_VARIABLE:
   1.207 +            databuf.appendChar(p.lvarOffset.length);  // for table length
   1.208 +            for (int i = 0; i < p.lvarOffset.length; ++i) {
   1.209 +                databuf.appendChar(p.lvarOffset[i]);
   1.210 +                databuf.appendChar(p.lvarLength[i]);
   1.211 +                databuf.appendChar(p.lvarIndex[i]);
   1.212 +            }
   1.213 +            break;
   1.214 +        // exception parameter
   1.215 +        case EXCEPTION_PARAMETER:
   1.216 +            databuf.appendByte(p.exception_index);
   1.217 +            break;
   1.218 +        // method receiver
   1.219 +        case METHOD_RECEIVER:
   1.220 +            // Do nothing
   1.221 +            break;
   1.222 +        // type parameter
   1.223 +        case CLASS_TYPE_PARAMETER:
   1.224 +        case METHOD_TYPE_PARAMETER:
   1.225 +            databuf.appendByte(p.parameter_index);
   1.226 +            break;
   1.227 +        // type parameter bound
   1.228 +        case CLASS_TYPE_PARAMETER_BOUND:
   1.229 +        case METHOD_TYPE_PARAMETER_BOUND:
   1.230 +            databuf.appendByte(p.parameter_index);
   1.231 +            databuf.appendByte(p.bound_index);
   1.232 +            break;
   1.233 +        // class extends or implements clause
   1.234 +        case CLASS_EXTENDS:
   1.235 +            databuf.appendChar(p.type_index);
   1.236 +            break;
   1.237 +        // throws
   1.238 +        case THROWS:
   1.239 +            databuf.appendChar(p.type_index);
   1.240 +            break;
   1.241 +        // method parameter
   1.242 +        case METHOD_FORMAL_PARAMETER:
   1.243 +            databuf.appendByte(p.parameter_index);
   1.244 +            break;
   1.245 +        // method/constructor/reference type argument
   1.246 +        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
   1.247 +        case METHOD_INVOCATION_TYPE_ARGUMENT:
   1.248 +        case METHOD_REFERENCE_TYPE_ARGUMENT:
   1.249 +            databuf.appendChar(p.offset);
   1.250 +            databuf.appendByte(p.type_index);
   1.251 +            break;
   1.252 +        // We don't need to worry about these
   1.253 +        case METHOD_RETURN:
   1.254 +        case FIELD:
   1.255 +            break;
   1.256 +        // lambda formal parameter
   1.257 +        case LAMBDA_FORMAL_PARAMETER:
   1.258 +            databuf.appendByte(p.parameter_index);
   1.259 +            break;
   1.260 +        case UNKNOWN:
   1.261 +            throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!");
   1.262 +        default:
   1.263 +            throw new AssertionError("jvm.ClassWriter: Unknown target type for position: " + p);
   1.264 +        }
   1.265 +
   1.266 +        { // Append location data for generics/arrays.
   1.267 +            databuf.appendByte(p.location.size());
   1.268 +            java.util.List<Integer> loc = TypeAnnotationPosition.getBinaryFromTypePath(p.location);
   1.269 +            for (int i : loc)
   1.270 +                databuf.appendByte((byte)i);
   1.271 +        }
   1.272 +    }
   1.273 +
   1.274  /**********************************************************************
   1.275   * Writing Objects
   1.276   **********************************************************************/
   1.277 @@ -1661,6 +1820,7 @@
   1.278  
   1.279          acount += writeFlagAttrs(c.flags());
   1.280          acount += writeJavaAnnotations(c.getRawAttributes());
   1.281 +        acount += writeTypeAnnotations(c.getRawTypeAttributes());
   1.282          acount += writeEnclosingMethodAttribute(c);
   1.283          acount += writeExtraClassAttributes(c);
   1.284  

mercurial