src/share/classes/com/sun/tools/javac/jvm/Target.java
author jjg
Wed May 20 13:36:23 2009 -0700 (8 months ago)
changeset 285 79eb8795a1de
parent 266e2722bd43f3a
permissions -rw-r--r--
6827026: Change javac source and target default to 7
Reviewed-by: darcy, ohair
        1 /*
        2  * Copyright 2002-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 
       26 package com.sun.tools.javac.jvm;
       27 
       28 import java.util.*;
       29 
       30 import com.sun.tools.javac.code.Flags;
       31 import com.sun.tools.javac.code.Symbol;
       32 import com.sun.tools.javac.util.*;
       33 
       34 /** The classfile version target.
       35  *
       36  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
       37  *  you write code that depends on this, you do so at your own risk.
       38  *  This code and its internal interfaces are subject to change or
       39  *  deletion without notice.</b>
       40  */
       41 public enum Target {
       42     JDK1_1("1.1", 45, 3),
       43     JDK1_2("1.2", 46, 0),
       44     JDK1_3("1.3", 47, 0),
       45 
       46     /** J2SE1.4 = Merlin. */
       47     JDK1_4("1.4", 48, 0),
       48 
       49     /** Support for the JSR14 prototype compiler (targeting 1.4 VMs
       50      *  augmented with a few support classes).  This is a transitional
       51      *  option that will not be supported in the product.  */
       52     JSR14("jsr14", 48, 0),
       53 
       54     /** The following are undocumented transitional targets that we
       55      *  had used to test VM fixes in update releases.  We do not
       56      *  promise to retain support for them.  */
       57     JDK1_4_1("1.4.1", 48, 0),
       58     JDK1_4_2("1.4.2", 48, 0),
       59 
       60     /** Tiger. */
       61     JDK1_5("1.5", 49, 0),
       62 
       63     /** JDK 6. */
       64     JDK1_6("1.6", 50, 0),
       65 
       66     /** JDK 7. */
       67     JDK1_7("1.7", 51, 0);
       68 
       69     private static final Context.Key<Target> targetKey =
       70         new Context.Key<Target>();
       71 
       72     public static Target instance(Context context) {
       73         Target instance = context.get(targetKey);
       74         if (instance == null) {
       75             Options options = Options.instance(context);
       76             String targetString = options.get("-target");
       77             if (targetString != null) instance = lookup(targetString);
       78             if (instance == null) instance = DEFAULT;
       79             context.put(targetKey, instance);
       80         }
       81         return instance;
       82     }
       83 
       84     private static Target MIN;
       85     public static Target MIN() { return MIN; }
       86 
       87     private static Target MAX;
       88     public static Target MAX() { return MAX; }
       89 
       90     private static Map<String,Target> tab = new HashMap<String,Target>();
       91     static {
       92         for (Target t : values()) {
       93             if (MIN == null) MIN = t;
       94             MAX = t;
       95             tab.put(t.name, t);
       96         }
       97         tab.put("5", JDK1_5);
       98         tab.put("6", JDK1_6);
       99         tab.put("7", JDK1_7);
      100     }
      101 
      102     public final String name;
      103     public final int majorVersion;
      104     public final int minorVersion;
      105     private Target(String name, int majorVersion, int minorVersion) {
      106         this.name = name;
      107         this.majorVersion = majorVersion;
      108         this.minorVersion = minorVersion;
      109     }
      110 
      111     public static final Target DEFAULT = JDK1_7;
      112 
      113     public static Target lookup(String name) {
      114         return tab.get(name);
      115     }
      116 
      117     /** In -target 1.1 and earlier, the compiler is required to emit
      118      *  synthetic method definitions in abstract classes for interface
      119      *  methods that are not overridden.  We call them "Miranda" methods.
      120      */
      121     public boolean requiresIproxy() {
      122         return compareTo(JDK1_1) <= 0;
      123     }
      124 
      125     /** Beginning in 1.4, we take advantage of the possibility of emitting
      126      *  code to initialize fields before calling the superclass constructor.
      127      *  This is allowed by the VM spec, but the verifier refused to allow
      128      *  it until 1.4.  This is necesary to translate some code involving
      129      *  inner classes.  See, for example, 4030374.
      130      */
      131     public boolean initializeFieldsBeforeSuper() {
      132         return compareTo(JDK1_4) >= 0;
      133     }
      134 
      135     /** Beginning with -target 1.2 we obey the JLS rules for binary
      136      *  compatibility, emitting as the qualifying type of a reference
      137      *  to a method or field the type of the qualifier.  In earlier
      138      *  targets we use as the qualifying type the class in which the
      139      *  member was found.  The following methods named
      140      *  *binaryCompatibility() indicate places where we vary from this
      141      *  general rule. */
      142     public boolean obeyBinaryCompatibility() {
      143         return compareTo(JDK1_2) >= 0;
      144     }
      145 
      146     /** Starting in 1.5, the compiler uses an array type as
      147      *  the qualifier for method calls (such as clone) where required by
      148      *  the language and VM spec.  Earlier versions of the compiler
      149      *  qualified them by Object.
      150      */
      151     public boolean arrayBinaryCompatibility() {
      152         return compareTo(JDK1_5) >= 0;
      153     }
      154 
      155     /** Beginning after 1.2, we follow the binary compatibility rules for
      156      *  interface fields.  The 1.2 VMs had bugs handling interface fields
      157      *  when compiled using binary compatibility (see 4400598), so this is
      158      *  an accommodation to them.
      159      */
      160     public boolean interfaceFieldsBinaryCompatibility() {
      161         return compareTo(JDK1_2) > 0;
      162     }
      163 
      164     /** Beginning in -target 1.5, we follow the binary compatibility
      165      *  rules for interface methods that redefine Object methods.
      166      *  Earlier VMs had bugs handling such methods compiled using binary
      167      *  compatibility (see 4392595, 4398791, 4392595, 4400415).
      168      *  The VMs were fixed during or soon after 1.4.  See 4392595.
      169      */
      170     public boolean interfaceObjectOverridesBinaryCompatibility() {
      171         return compareTo(JDK1_5) >= 0;
      172     }
      173 
      174     /** Beginning in -target 1.4.2, we make synthetic variables
      175      *  package-private instead of private.  This is to prevent the
      176      *  necessity of access methods, which effectively relax the
      177      *  protection of the field but bloat the class files and affect
      178      *  execution.
      179      */
      180     public boolean usePrivateSyntheticFields() {
      181         return compareTo(JDK1_4_2) < 0;
      182     }
      183 
      184     /** Sometimes we need to create a field to cache a value like a
      185      *  class literal of the assertions flag.  In -target 1.4.2 and
      186      *  later we create a new synthetic class for this instead of
      187      *  using the outermost class.  See 4401576.
      188      */
      189     public boolean useInnerCacheClass() {
      190         return compareTo(JDK1_4_2) >= 0;
      191     }
      192 
      193     /** Return true if cldc-style stack maps need to be generated. */
      194     public boolean generateCLDCStackmap() {
      195         return false;
      196     }
      197 
      198     /** Beginning in -target 6, we generate stackmap attribute in
      199      *  compact format. */
      200     public boolean generateStackMapTable() {
      201         return compareTo(JDK1_6) >= 0;
      202     }
      203 
      204     /** Beginning in -target 6, package-info classes are marked synthetic.
      205      */
      206     public boolean isPackageInfoSynthetic() {
      207         return compareTo(JDK1_6) >= 0;
      208     }
      209 
      210     /** Do we generate "empty" stackmap slots after double and long?
      211      */
      212     public boolean generateEmptyAfterBig() {
      213         return false;
      214     }
      215 
      216     /** Beginning in 1.5, we have an unsynchronized version of
      217      *  StringBuffer called StringBuilder that can be used by the
      218      *  compiler for string concatenation.
      219      */
      220     public boolean useStringBuilder() {
      221         return compareTo(JDK1_5) >= 0;
      222     }
      223 
      224     /** Beginning in 1.5, we have flag bits we can use instead of
      225      *  marker attributes.
      226      */
      227     public boolean useSyntheticFlag() {
      228         return compareTo(JDK1_5) >= 0;
      229     }
      230     public boolean useEnumFlag() {
      231         return compareTo(JDK1_5) >= 0;
      232     }
      233     public boolean useAnnotationFlag() {
      234         return compareTo(JDK1_5) >= 0;
      235     }
      236     public boolean useVarargsFlag() {
      237         return compareTo(JDK1_5) >= 0;
      238     }
      239     public boolean useBridgeFlag() {
      240         return compareTo(JDK1_5) >= 0;
      241     }
      242 
      243     /** Return the character to be used in constructing synthetic
      244      *  identifiers, where not specified by the JLS.
      245      */
      246     public char syntheticNameChar() {
      247         return '$';
      248     }
      249 
      250     /** Does the VM have direct support for class literals?
      251      */
      252     public boolean hasClassLiterals() {
      253         return compareTo(JDK1_5) >= 0;
      254     }
      255 
      256     /** Does the VM support an invokedynamic instruction?
      257      */
      258     public boolean hasInvokedynamic() {
      259         return compareTo(JDK1_7) >= 0;
      260     }
      261 
      262     /** Although we may not have support for class literals, should we
      263      *  avoid initializing the class that the literal refers to?
      264      *  See 4468823
      265      */
      266     public boolean classLiteralsNoInit() {
      267         return compareTo(JDK1_4_2) >= 0;
      268     }
      269 
      270     /** Although we may not have support for class literals, when we
      271      *  throw a NoClassDefFoundError, should we initialize its cause?
      272      */
      273     public boolean hasInitCause() {
      274         return compareTo(JDK1_4) >= 0;
      275     }
      276 
      277     /** For bootstrapping, we use J2SE1.4's wrapper class constructors
      278      *  to implement boxing.
      279      */
      280     public boolean boxWithConstructors() {
      281         return compareTo(JDK1_5) < 0;
      282     }
      283 
      284     /** For bootstrapping, we use J2SE1.4's java.util.Collection
      285      *  instead of java.lang.Iterable.
      286      */
      287     public boolean hasIterable() {
      288         return compareTo(JDK1_5) >= 0;
      289     }
      290 
      291     /** For bootstrapping javac only, we do without java.lang.Enum if
      292      *  necessary.
      293      */
      294     public boolean compilerBootstrap(Symbol c) {
      295         return
      296             this == JSR14 &&
      297             (c.flags() & Flags.ENUM) != 0 &&
      298             c.flatName().toString().startsWith("com.sun.tools.")
      299             // && !Target.class.getSuperclass().getName().equals("java.lang.Enum")
      300             ;
      301     }
      302 
      303     /** In J2SE1.5.0, we introduced the "EnclosingMethod" attribute
      304      *  for improved reflection support.
      305      */
      306     public boolean hasEnclosingMethodAttribute() {
      307         return compareTo(JDK1_5) >= 0 || this == JSR14;
      308     }
      309 }