1 /*
   2  * Copyright (c) 2003, 2015, 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 4642611
  27  *  @summary Test that method.allLineLocations() should
  28  *           throw AbsentInformationException exception
  29  *
  30  *  @author Serguei Spitsyn
  31  *
  32  *  @modules jdk.jdi
  33  *  @run build TestScaffold VMConnection TargetListener TargetAdapter
  34  *  @run compile -g:none NoLocInfoTest.java
  35  *  @run driver NoLocInfoTest
  36  */
  37 import com.sun.jdi.*;
  38 import com.sun.jdi.event.*;
  39 import com.sun.jdi.request.*;
  40 
  41 import java.util.*;
  42 
  43     /********** target program **********/
  44 
  45 interface InterfaceNoLocInfoTarg {
  46     int instanceMeth();
  47     int instanceMeth1();
  48 }
  49 
  50 abstract class AbstractNoLocInfoTarg implements InterfaceNoLocInfoTarg {
  51     protected int fld;
  52 
  53     // Constructor
  54     AbstractNoLocInfoTarg() {
  55         fld = 1000;
  56     }
  57 
  58     public abstract int instanceMeth();
  59 
  60     public int instanceMeth1() {
  61         fld = 999;
  62         fld = instanceMeth();
  63         return 0;
  64     }
  65 }
  66 
  67 class NoLocInfoTarg extends AbstractNoLocInfoTarg {
  68 
  69     // Class has a default constructor
  70 
  71     public static void main(String[] args){
  72         System.out.println("A number is: " + new NoLocInfoTarg().instanceMeth());
  73     }
  74 
  75     public static int staticMeth() {
  76         int i = 2;
  77         return i;
  78     }
  79 
  80     public int instanceMeth() {
  81         int i = 0;
  82         i++;
  83         return i + staticMeth();
  84     }
  85 
  86     private void voidInstanceMeth() {}
  87     static native int staticNativeMeth();
  88     native boolean instanceNativeMeth();
  89 }
  90 
  91     /********** test program **********/
  92 
  93 public class NoLocInfoTest extends TestScaffold {
  94     final String[] args;
  95 
  96     NoLocInfoTest (String args[]) {
  97         super(args);
  98         this.args = args;
  99     }
 100 
 101     public static void main(String[] args)      throws Exception {
 102         new NoLocInfoTest(args).startTests();
 103     }
 104 
 105     /********** test assist **********/
 106 
 107     Method getMethod(String className, String methodName) {
 108         List refs = vm().classesByName(className);
 109         if (refs.size() != 1) {
 110             failure("Failure: " + refs.size() +
 111                     " ReferenceTypes named: " + className);
 112             return null;
 113         }
 114         ReferenceType refType = (ReferenceType)refs.get(0);
 115         List meths = refType.methodsByName(methodName);
 116         if (meths.size() != 1) {
 117             failure("Failure: " + meths.size() +
 118                     " methods named: " + methodName);
 119             return null;
 120         }
 121         return (Method)meths.get(0);
 122     }
 123 
 124     void checkLineNumberTable(String className, String methodName) {
 125         println("GetLineNumberTable for method: " + className + "." + methodName);
 126         Method method = getMethod(className, methodName);
 127 
 128         try {
 129             List locations = method.allLineLocations();
 130             failure("Failure: com.sun.jdi.AbsentInformationException was expected; " +
 131                     "LineNumberTable.size() = " + locations.size());
 132         }
 133         catch (com.sun.jdi.AbsentInformationException ex) {
 134             println("Success: com.sun.jdi.AbsentInformationException thrown as expected");
 135         }
 136         println("");
 137     }
 138 
 139     void checkEmptyLineNumberTable(String className, String methodName) {
 140         println("GetLineNumberTable for abstract/native method: " +
 141                  className + "." + methodName);
 142         Method method = getMethod(className, methodName);
 143 
 144         try {
 145             int size = method.allLineLocations().size();
 146             if (size == 0) {
 147                println("Succes: LineNumberTable.size() == " + size + " as expected");
 148             } else {
 149                failure("Failure: LineNumberTable.size()==" + size + ", but ZERO was expected");
 150             }
 151         }
 152         catch (com.sun.jdi.AbsentInformationException ex) {
 153             failure("Failure: com.sun.jdi.AbsentInformationException was not expected; ");
 154         }
 155         println("");
 156     }
 157 
 158     /********** test core **********/
 159 
 160     protected void runTests() throws Exception {
 161 
 162         /*
 163          * Get to the top of main() to get everything loaded
 164          */
 165         startToMain("NoLocInfoTarg");
 166 
 167         println("\n Abstract Methods:");
 168         // For abtsract methods allLineLocations() always returns empty List
 169         checkEmptyLineNumberTable("InterfaceNoLocInfoTarg", "instanceMeth");
 170         checkEmptyLineNumberTable("InterfaceNoLocInfoTarg", "instanceMeth1");
 171         checkEmptyLineNumberTable("AbstractNoLocInfoTarg",  "instanceMeth");
 172 
 173         println("\n Native Methods:");
 174         // For native methods allLineLocations() always returns empty List
 175         checkEmptyLineNumberTable("NoLocInfoTarg", "staticNativeMeth");
 176         checkEmptyLineNumberTable("NoLocInfoTarg", "instanceNativeMeth");
 177 
 178         println("\n Non-Abstract Methods of Abstract class:");
 179         checkLineNumberTable("AbstractNoLocInfoTarg", "<init>");
 180         checkLineNumberTable("AbstractNoLocInfoTarg", "instanceMeth1");
 181 
 182         println("\n Methods of Non-Abstract class:");
 183         checkLineNumberTable("NoLocInfoTarg", "<init>"); // default constructor
 184         checkLineNumberTable("NoLocInfoTarg", "main");
 185         checkLineNumberTable("NoLocInfoTarg", "instanceMeth");
 186         checkLineNumberTable("NoLocInfoTarg", "instanceMeth1"); // inherited
 187         checkLineNumberTable("NoLocInfoTarg", "voidInstanceMeth");
 188 
 189         /*
 190          * resume until the end
 191          */
 192         listenUntilVMDisconnect();
 193 
 194         /*
 195          * deal with results of test
 196          * if anything has called failure("foo") testFailed will be true
 197          */
 198         if (!testFailed) {
 199             println("NoLocInfoTest: passed");
 200         } else {
 201             throw new Exception("NoLocInfoTest: failed");
 202         }
 203     }
 204 }