Target.java revision 2841:edf685b5d413
118334Speter/*
290082Sobrien * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
3169699Skan * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
418334Speter *
590082Sobrien * This code is free software; you can redistribute it and/or modify it
618334Speter * under the terms of the GNU General Public License version 2 only, as
790082Sobrien * published by the Free Software Foundation.  Oracle designates this
890082Sobrien * particular file as subject to the "Classpath" exception as provided
990082Sobrien * by Oracle in the LICENSE file that accompanied this code.
1090082Sobrien *
1118334Speter * This code is distributed in the hope that it will be useful, but WITHOUT
1290082Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1390082Sobrien * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1490082Sobrien * version 2 for more details (a copy is included in the LICENSE file that
1590082Sobrien * accompanied this code).
1618334Speter *
1718334Speter * You should have received a copy of the GNU General Public License version
1890082Sobrien * 2 along with this work; if not, write to the Free Software Foundation,
19169699Skan * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20169699Skan *
2118334Speter * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2218334Speter * or visit www.oracle.com if you need additional information or have any
2350449Sobrien * questions.
24132728Skan */
25132728Skan
26132728Skanpackage com.sun.tools.javac.jvm;
2718334Speter
2818334Speterimport java.util.*;
2950449Sobrien
3052299Sobrienimport com.sun.tools.javac.code.Flags;
3152299Sobrienimport com.sun.tools.javac.code.Symbol;
3290082Sobrienimport com.sun.tools.javac.util.*;
33132728Skan
3490082Sobrienimport static com.sun.tools.javac.main.Option.TARGET;
3590082Sobrien
3690082Sobrien/** The classfile version target.
3790082Sobrien *
3890082Sobrien *  <p><b>This is NOT part of any supported API.
3990082Sobrien *  If you write code that depends on this, you do so at your own risk.
4090082Sobrien *  This code and its internal interfaces are subject to change or
41117404Skan *  deletion without notice.</b>
42117404Skan */
43117404Skanpublic enum Target {
44132728Skan    JDK1_1("1.1", 45, 3),
45169699Skan    JDK1_2("1.2", 46, 0),
46169699Skan    JDK1_3("1.3", 47, 0),
47169699Skan
48169699Skan    /** J2SE1.4 = Merlin. */
49169699Skan    JDK1_4("1.4", 48, 0),
50169699Skan
5118334Speter    /** JDK 5, codename Tiger. */
52117404Skan    JDK1_5("1.5", 49, 0),
5390082Sobrien
5490082Sobrien    /** JDK 6. */
5590082Sobrien    JDK1_6("1.6", 50, 0),
5690082Sobrien
5790082Sobrien    /** JDK 7. */
5890082Sobrien    JDK1_7("1.7", 51, 0),
5990082Sobrien
6090082Sobrien    /** JDK 8. */
6190082Sobrien    JDK1_8("1.8", 52, 0),
6250449Sobrien
6350449Sobrien    /** JDK 9, initially an alias for 8. */
64169699Skan    JDK1_9("1.9", 52, 0);
65169699Skan
66169699Skan    private static final Context.Key<Target> targetKey = new Context.Key<>();
67169699Skan
6890082Sobrien    public static Target instance(Context context) {
6990082Sobrien        Target instance = context.get(targetKey);
7050449Sobrien        if (instance == null) {
7190082Sobrien            Options options = Options.instance(context);
72117404Skan            String targetString = options.get(TARGET);
73117404Skan            if (targetString != null) instance = lookup(targetString);
74117404Skan            if (instance == null) instance = DEFAULT;
75117404Skan            context.put(targetKey, instance);
7690082Sobrien        }
7790082Sobrien        return instance;
7850449Sobrien    }
7950449Sobrien
8090082Sobrien    public static final Target MIN = Target.JDK1_6;
8190082Sobrien
8290082Sobrien    private static final Target MAX = values()[values().length - 1];
8318334Speter
8490082Sobrien    private static final Map<String,Target> tab = new HashMap<>();
8590082Sobrien    static {
8690082Sobrien        for (Target t : values()) {
8790082Sobrien            tab.put(t.name, t);
8890082Sobrien        }
8990082Sobrien        tab.put("5", JDK1_5);
9090082Sobrien        tab.put("6", JDK1_6);
9190082Sobrien        tab.put("7", JDK1_7);
9290082Sobrien        tab.put("8", JDK1_8);
9390082Sobrien        tab.put("9", JDK1_9);
9490082Sobrien    }
9590082Sobrien
9690082Sobrien    public final String name;
9790082Sobrien    public final int majorVersion;
9890082Sobrien    public final int minorVersion;
9990082Sobrien    private Target(String name, int majorVersion, int minorVersion) {
10090082Sobrien        this.name = name;
10190082Sobrien        this.majorVersion = majorVersion;
10290082Sobrien        this.minorVersion = minorVersion;
10390082Sobrien    }
10490082Sobrien
10590082Sobrien    public static final Target DEFAULT = JDK1_9;
10690082Sobrien
10790082Sobrien    public static Target lookup(String name) {
10890082Sobrien        return tab.get(name);
10990082Sobrien    }
11090082Sobrien
11190082Sobrien    /** Return the character to be used in constructing synthetic
11290082Sobrien     *  identifiers, where not specified by the JLS.
113132728Skan     */
114132728Skan    public char syntheticNameChar() {
115132728Skan        return '$';
11690082Sobrien    }
11790082Sobrien
11890082Sobrien    /** Does the VM support an invokedynamic instruction?
11990082Sobrien     */
12090082Sobrien    public boolean hasInvokedynamic() {
12190082Sobrien        return compareTo(JDK1_7) >= 0;
12290082Sobrien    }
12390082Sobrien
12490082Sobrien    /** Does the target JDK contains the java.util.Objects class?
12590082Sobrien     */
12690082Sobrien    public boolean hasObjects() {
12790082Sobrien        return compareTo(JDK1_7) >= 0;
12890082Sobrien    }
12990082Sobrien
13090082Sobrien    /** Does the VM support polymorphic method handle invocation?
13190082Sobrien     *  Affects the linkage information output to the classfile.
13290082Sobrien     *  An alias for {@code hasInvokedynamic}, since all the JSR 292 features appear together.
13390082Sobrien     */
134169699Skan    public boolean hasMethodHandles() {
135169699Skan        return hasInvokedynamic();
136169699Skan    }
137169699Skan
13890082Sobrien}
13990082Sobrien