langtools/test/tools/javac/types/PrimitiveConversionTest.java
changeset 7640 5d199da591db
child 30730 d3ce7619db2c
equal deleted inserted replaced
7639:4e42f74e986f 7640:5d199da591db
       
     1 /*
       
     2  * Copyright (c) 2010, Oracle and/or its affiliates. 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.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @bug 7006109
       
    27  * @summary Add test library to simplify the task of writing automated type-system tests
       
    28  * @author mcimadamore
       
    29  * @library .
       
    30  * @run main PrimitiveConversionTest
       
    31  */
       
    32 
       
    33 import com.sun.tools.javac.code.Type;
       
    34 import com.sun.tools.javac.code.Type.*;
       
    35 import com.sun.tools.javac.code.Symbol.*;
       
    36 import java.lang.reflect.Array;
       
    37 import java.util.EnumSet;
       
    38 
       
    39 /**
       
    40  * Check invariants in assignment/method conversion involving primitive types and arrays
       
    41  */
       
    42 public class PrimitiveConversionTest extends TypeHarness {
       
    43 
       
    44     Type[] types1;
       
    45     Type[] types2;
       
    46     Type[] types3;
       
    47 
       
    48     enum Result {
       
    49         OK_BOTH(true),
       
    50         FAIL_BOTH(false),
       
    51         OK_ASSIGN_ONLY(true);
       
    52 
       
    53         boolean value;
       
    54 
       
    55         Result(boolean value) {
       
    56             this.value = value;
       
    57         }
       
    58     }
       
    59 
       
    60     enum ConversionKind {
       
    61         ASSIGNMENT_CONVERSION(EnumSet.of(Result.OK_BOTH, Result.OK_ASSIGN_ONLY)) {
       
    62             @Override
       
    63             void check(TypeHarness harness, Type from, Type to, Result expected) {
       
    64                 harness.assertAssignable(from, to, resSet.contains(expected));
       
    65             }
       
    66         },
       
    67         METHOD_CONVERSION(EnumSet.of(Result.OK_BOTH)) {
       
    68             @Override
       
    69             void check(TypeHarness harness, Type from, Type to, Result expected) {
       
    70                 harness.assertConvertible(from, to, resSet.contains(expected));
       
    71             }
       
    72         };
       
    73 
       
    74         EnumSet<Result> resSet;
       
    75 
       
    76         private ConversionKind(EnumSet<Result> resSet) {
       
    77             this.resSet = resSet;
       
    78         }
       
    79 
       
    80         abstract void check(TypeHarness harness, Type from, Type to, Result expected);
       
    81     }
       
    82 
       
    83     enum TestKind {
       
    84         SIMPLE {
       
    85             @Override
       
    86             Type[] getFromTypes(PrimitiveConversionTest harness) {
       
    87                 return harness.types1;
       
    88             }
       
    89             @Override
       
    90             Type[] getToTypes(PrimitiveConversionTest harness) {
       
    91                 return harness.types1;
       
    92             }
       
    93             @Override
       
    94             Result[][] getResults(PrimitiveConversionTest harness) {
       
    95                 return harness.results1;
       
    96             }
       
    97         },
       
    98         CONSTANT_TYPES {
       
    99             @Override
       
   100             Type[] getFromTypes(PrimitiveConversionTest harness) {
       
   101                 return harness.types2;
       
   102             }
       
   103             @Override
       
   104             Type[] getToTypes(PrimitiveConversionTest harness) {
       
   105                 return harness.types3;
       
   106             }
       
   107             @Override
       
   108             Result[][] getResults(PrimitiveConversionTest harness) {
       
   109                 return harness.results2;
       
   110             }
       
   111         };
       
   112 
       
   113         abstract Type[] getFromTypes(PrimitiveConversionTest harness);
       
   114         abstract Type[] getToTypes(PrimitiveConversionTest harness);
       
   115         abstract Result[][] getResults(PrimitiveConversionTest harness);
       
   116     }
       
   117 
       
   118     static final Result T = Result.OK_BOTH;
       
   119     static final Result F = Result.FAIL_BOTH;
       
   120     static final Result A = Result.OK_ASSIGN_ONLY;
       
   121 
       
   122     Result[][] results1 = {
       
   123                 //byte, short, int, long, float, double, char, bool, C1, C2, C3, T , byte[], short[], int[], long[], float[], double[], char[], bool[], C1[], C2[], C3[], T[]
       
   124     /*byte*/    { T   , T    , T  , T   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   125     /*short*/   { F   , T    , T  , T   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   126     /*int*/     { F   , F    , T  , T   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   127     /*long*/    { F   , F    , F  , T   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   128     /*float*/   { F   , F    , F  , F   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   129     /*double*/  { F   , F    , F  , F   , F    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   130     /*char*/    { F   , F    , T  , T   , T    , T     , T   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   131     /*bool*/    { F   , F    , F  , F   , F    , F     , F   , T   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   132     /*C1*/      { F   , F    , F  , F   , F    , F     , F   , F   , T , F , T , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   133     /*C2*/      { F   , F    , F  , F   , F    , F     , F   , F   , T , T , T , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   134     /*C3*/      { F   , F    , F  , F   , F    , F     , F   , F   , T , F , T , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   135     /*T*/       { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , T , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   136     /*byte[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , T     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   137     /*short[]*/ { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , T      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   138     /*int[]*/   { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , T    , F     , F      , F       , F     , F     , F   , F   , F   , F },
       
   139     /*long[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , T     , F      , F       , F     , F     , F   , F   , F   , F },
       
   140     /*float[]*/ { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , T      , F       , F     , F     , F   , F   , F   , F },
       
   141     /*double[]*/{ F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , T       , F     , F     , F   , F   , F   , F },
       
   142     /*char[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , T     , F     , F   , F   , F   , F },
       
   143     /*bool[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , T     , F   , F   , F   , F },
       
   144     /*C1[]*/    { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , T   , F   , T   , F },
       
   145     /*C2[]*/    { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , T   , T   , T   , F },
       
   146     /*C3[]*/    { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , T   , F   , T   , F },
       
   147     /*T[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , T }};
       
   148 
       
   149     Result[][] results2 = {
       
   150                 //byte, short, int, long, float, double, char, bool
       
   151     /*byte*/    { T   , T    , T  , T   , T    , T     , F   , F },
       
   152     /*short*/   { F   , T    , T  , T   , T    , T     , F   , F },
       
   153     /*short1*/  { A   , T    , T  , T   , T    , T     , A   , F },
       
   154     /*short2*/  { F   , T    , T  , T   , T    , T     , A   , F },
       
   155     /*int*/     { F   , F    , T  , T   , T    , T     , F   , F },
       
   156     /*int1*/    { A   , A    , T  , T   , T    , T     , A   , F },
       
   157     /*int2*/    { F   , A    , T  , T   , T    , T     , A   , F },
       
   158     /*int4*/    { F   , F    , T  , T   , T    , T     , F   , F },
       
   159     /*long*/    { F   , F    , F  , T   , T    , T     , F   , F },
       
   160     /*long1*/   { F   , F    , F  , T   , T    , T     , F   , F },
       
   161     /*long2*/   { F   , F    , F  , T   , T    , T     , F   , F },
       
   162     /*long4*/   { F   , F    , F  , T   , T    , T     , F   , F },
       
   163     /*long8*/   { F   , F    , F  , T   , T    , T     , F   , F },
       
   164     /*float*/   { F   , F    , F  , F   , T    , T     , F   , F },
       
   165     /*float1*/  { F   , F    , F  , F   , T    , T     , F   , F },
       
   166     /*float2*/  { F   , F    , F  , F   , T    , T     , F   , F },
       
   167     /*float4*/  { F   , F    , F  , F   , T    , T     , F   , F },
       
   168     /*double*/  { F   , F    , F  , F   , F    , T     , F   , F },
       
   169     /*double1*/ { F   , F    , F  , F   , F    , T     , F   , F },
       
   170     /*double2*/ { F   , F    , F  , F   , F    , T     , F   , F },
       
   171     /*double4*/ { F   , F    , F  , F   , F    , T     , F   , F },
       
   172     /*double8*/ { F   , F    , F  , F   , F    , T     , F   , F },
       
   173     /*char*/    { F   , F    , T  , T   , T    , T     , T   , F },
       
   174     /*char1*/   { A   , A    , T  , T   , T    , T     , T   , F },
       
   175     /*char2*/   { F   , A    , T  , T   , T    , T     , T   , F },
       
   176     /*bool*/    { F   , F    , F  , F   , F    , F     , F   , T }};
       
   177 
       
   178     PrimitiveConversionTest() {
       
   179         Type[] primitiveTypes = new Type[] {
       
   180             predef.byteType,
       
   181             predef.shortType,
       
   182             predef.intType,
       
   183             predef.longType,
       
   184             predef.floatType,
       
   185             predef.doubleType,
       
   186             predef.charType,
       
   187             predef.booleanType };
       
   188 
       
   189         ClassType c1 = fac.Class(fac.TypeVariable());
       
   190         ClassType c2 = fac.Class();
       
   191         c2.supertype_field = subst(c1,
       
   192                 Mapping(c1.getTypeArguments().head, predef.stringType));
       
   193         Type c3 = erasure(c1);
       
   194 
       
   195         Type[] referenceTypes = {
       
   196             subst(c1,
       
   197                     Mapping(c1.getTypeArguments().head, predef.stringType)),
       
   198             c2,
       
   199             c3,
       
   200             fac.TypeVariable() };
       
   201 
       
   202         Type[] arrayTypes = new Type[primitiveTypes.length + referenceTypes.length];
       
   203         int idx = 0;
       
   204         for (Type t : join(Type.class, primitiveTypes, referenceTypes)) {
       
   205             arrayTypes[idx++] = fac.Array(t);
       
   206         }
       
   207 
       
   208         types1 = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
       
   209 
       
   210         types2 = new Type[] {
       
   211             predef.byteType,
       
   212             predef.shortType,
       
   213             fac.Constant((short)0x0001),
       
   214             fac.Constant((short)0x0100),
       
   215             predef.intType,
       
   216             fac.Constant((int)0x0000_0001),
       
   217             fac.Constant((int)0x0000_0100),
       
   218             fac.Constant((int)0x0001_0000),
       
   219             predef.longType,
       
   220             fac.Constant((long)0x0000_0000_0000_0001L),
       
   221             fac.Constant((long)0x0000_0000_0000_0100L),
       
   222             fac.Constant((long)0x0000_0000_0001_0000L),
       
   223             fac.Constant((long)0x0001_0000_0000_0000L),
       
   224             predef.floatType,
       
   225             fac.Constant((float)0x0000_0001),
       
   226             fac.Constant((float)0x0000_0100),
       
   227             fac.Constant((float)0x0001_0000),
       
   228             predef.doubleType,
       
   229             fac.Constant((double)0x0000_0000_0000_0001L),
       
   230             fac.Constant((double)0x0000_0000_0000_0100L),
       
   231             fac.Constant((double)0x0000_0000_0001_0000L),
       
   232             fac.Constant((double)0x0001_0000_0000_0000L),
       
   233             predef.charType,
       
   234             fac.Constant((char)0x0001),
       
   235             fac.Constant((char)0x0100),
       
   236             predef.booleanType
       
   237         };
       
   238 
       
   239         types3 = primitiveTypes;
       
   240     }
       
   241 
       
   242     void testConversion(ConversionKind convKind, TestKind testKind) {
       
   243         Type[] rows = testKind.getFromTypes(this);
       
   244         Type[] cols = testKind.getToTypes(this);
       
   245         for (int i = 0; i < rows.length ; i++) {
       
   246             for (int j = 0; j < cols.length ; j++) {
       
   247                 convKind.check(this, rows[i], cols[j], testKind.getResults(this)[i][j]);
       
   248             }
       
   249         }
       
   250     }
       
   251 
       
   252     @SuppressWarnings("unchecked")
       
   253     <T> T[] join(Class<T> type, T[]... args) {
       
   254         int totalLength = 0;
       
   255         for (T[] arr : args) {
       
   256             totalLength += arr.length;
       
   257         }
       
   258         T[] new_arr = (T[])Array.newInstance(type, totalLength);
       
   259         int idx = 0;
       
   260         for (T[] arr : args) {
       
   261             System.arraycopy(arr, 0, new_arr, idx, arr.length);
       
   262             idx += arr.length;
       
   263         }
       
   264         return new_arr;
       
   265     }
       
   266 
       
   267     public static void main(String[] args) {
       
   268         PrimitiveConversionTest harness = new PrimitiveConversionTest();
       
   269         for (ConversionKind convKind : ConversionKind.values()) {
       
   270             for (TestKind testKind : TestKind.values()) {
       
   271                 harness.testConversion(convKind, testKind);
       
   272             }
       
   273         }
       
   274     }
       
   275 }