1 /*
   2  * Copyright (c) 2017, 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  * @modules jdk.incubator.vector
  27  * @run testng MethodOverideTest
  28  *
  29  */
  30 
  31 import jdk.incubator.vector.ByteVector;
  32 import jdk.incubator.vector.DoubleVector;
  33 import jdk.incubator.vector.FloatVector;
  34 import jdk.incubator.vector.IntVector;
  35 import jdk.incubator.vector.Vector.Shape;
  36 import jdk.incubator.vector.ShortVector;
  37 import jdk.incubator.vector.Vector;
  38 import org.testng.Assert;
  39 import org.testng.annotations.DataProvider;
  40 import org.testng.annotations.Test;
  41 
  42 import java.lang.reflect.Field;
  43 import java.lang.reflect.Method;
  44 import java.lang.reflect.Modifier;
  45 import java.util.ArrayList;
  46 import java.util.List;
  47 import java.util.stream.Collectors;
  48 import java.util.stream.Stream;
  49 
  50 public class MethodOverideTest {
  51 
  52     @DataProvider
  53     public static Object[][] vectorClassesProvider() {
  54         return Stream.of(
  55                 ByteVector.class,
  56                 ShortVector.class,
  57                 IntVector.class,
  58                 FloatVector.class,
  59                 DoubleVector.class).
  60                 map(c -> new Object[]{c}).
  61                 toArray(Object[][]::new);
  62     }
  63 
  64     static List<Object> getConcreteSpeciesInstances(Class<?> primitiveVectorClass) {
  65         try {
  66             List<Object> csis = new ArrayList<>();
  67             for (Field sf : primitiveVectorClass.getFields()) {
  68                 if (Vector.Species.class.isAssignableFrom(sf.getType())) {
  69                     csis.add(sf.get(null));
  70                 }
  71             }
  72             return csis;
  73         }
  74         catch (ReflectiveOperationException e) {
  75             throw new InternalError(e);
  76         }
  77     }
  78 
  79     static List<Class<?>> getConcreteVectorClasses(Class<?> primitiveVectorClass) {
  80         try {
  81             List<Class<?>> cvcs = new ArrayList<>();
  82             for (Object speciesInstance : getConcreteSpeciesInstances(primitiveVectorClass)) {
  83                     Method zero = primitiveVectorClass.getMethod("zero", Vector.Species.class);
  84                     Object vectorInstance = zero.invoke(null, speciesInstance);
  85 
  86                     cvcs.add(vectorInstance.getClass());
  87             }
  88             return cvcs;
  89         }
  90         catch (ReflectiveOperationException e) {
  91             throw new InternalError(e);
  92         }
  93     }
  94 
  95     static List<Method> getDeclaredPublicAndNonAbstractMethods(Class<?> c) {
  96         return Stream.of(c.getDeclaredMethods()).
  97                 filter(cc -> Modifier.isPublic(cc.getModifiers())).
  98                 filter(cc -> !Modifier.isAbstract(cc.getModifiers())).
  99                 filter(cc -> !Modifier.isFinal(cc.getModifiers())).
 100                 filter(cc -> !cc.isSynthetic()).
 101                 collect(Collectors.toList());
 102     }
 103 
 104     static int checkMethods(Class<?> primitiveClass, List<Class<?>> concreteClasses) {
 105         List<Method> publicNonAbstractMethods = getDeclaredPublicAndNonAbstractMethods(primitiveClass);
 106 
 107         int notOverriddenMethodsCount = 0;
 108         for (Class<?> cc : concreteClasses) {
 109             List<Method> overriddenMethods = new ArrayList<>();
 110             List<Method> notOverriddenMethods = new ArrayList<>();
 111 
 112             for (Method m : publicNonAbstractMethods) {
 113                 try {
 114                     Method ccm = cc.getDeclaredMethod(m.getName(), m.getParameterTypes());
 115                     // Method overridden by concrete vector
 116                     // This method can be made abstract
 117                     overriddenMethods.add(m);
 118                 }
 119                 catch (NoSuchMethodException e) {
 120                     // Method implemented on primitive vector but not concrete vector
 121                     // Method is not intrinsic
 122                     notOverriddenMethods.add(m);
 123                 }
 124             }
 125 
 126             System.out.println(cc.getName() + " <- " + primitiveClass.getName());
 127             System.out.println("--Methods overridden that can be abstract");
 128             overriddenMethods.stream().forEach(m -> System.out.println("    " + m));
 129 
 130             System.out.println("--Methods not overridden that may need to be so and use intrinsics");
 131             notOverriddenMethods.stream().forEach(m -> System.out.println("    " + m));
 132             notOverriddenMethodsCount += notOverriddenMethods.size();
 133         }
 134 
 135         return notOverriddenMethodsCount;
 136     }
 137 
 138     @Test(dataProvider = "vectorClassesProvider")
 139     public void checkMethodsOnPrimitiveVector(Class<?> primitiveVector) {
 140         int nonIntrinsicMethods = checkMethods(primitiveVector, getConcreteVectorClasses(primitiveVector));
 141 
 142 //        Assert.assertEquals(nonIntrinsicMethods, 0);
 143     }
 144 }