mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-24 23:00:02 +00:00
Merge
This commit is contained in:
commit
5e86d923f2
1
.hgtags
1
.hgtags
@ -48,3 +48,4 @@ bca2225b66d78c4bf4d9801f54cac7715a598650 jdk7-b68
|
||||
c5d39b6be65cba0effb5f466ea48fe43764d0e0c jdk7-b71
|
||||
df4bcd06e1d0ab306efa5a44f24a409dc0c0c742 jdk7-b72
|
||||
ce74bd35ce948d629a356e168797f44b593b1578 jdk7-b73
|
||||
4e7661eaa211e186674f6cbefec4aef1144ac2a0 jdk7-b74
|
||||
|
||||
@ -48,3 +48,4 @@ e1b972ff53cd58f825791f8ed9b2deffd16e768c jdk7-b68
|
||||
4c36e9853dda27bdac5ef4839a610509fbe31d34 jdk7-b71
|
||||
0d7e03b426df27c21dcc44ffb9178eacd1b04f10 jdk7-b72
|
||||
3ac6dcf7823205546fbbc3d4ea59f37358d0b0d4 jdk7-b73
|
||||
2c88089b6e1c053597418099a14232182c387edc jdk7-b74
|
||||
|
||||
@ -48,3 +48,4 @@ a12ea7c7b497b4ba7830550095ef633bd6f43971 jdk7-b67
|
||||
3f1ef7f899ea2aec189c4fb67e5c8fa374437c50 jdk7-b71
|
||||
c793a31209263fbb867c23c752599d85c21abb73 jdk7-b72
|
||||
b751c528c55560cf2adeaeef24b39ca1f4d1cbf7 jdk7-b73
|
||||
5d0cf59a3203b9f57aceebc33ae656b884987955 jdk7-b74
|
||||
|
||||
@ -48,3 +48,4 @@ d07e68298d4e17ebf93d8299e43fcc3ded26472a jdk7-b68
|
||||
50a95aa4a247f0cbbf66df285a8b1d78ffb153d9 jdk7-b71
|
||||
a94714c550658fd6741793ef036cb9625dc2ab1a jdk7-b72
|
||||
faf94d94786b621f8e13cbcc941ca69c6d967c3f jdk7-b73
|
||||
f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 jdk7-b74
|
||||
|
||||
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2009
|
||||
|
||||
HS_MAJOR_VER=17
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=03
|
||||
HS_BUILD_NUMBER=04
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=7
|
||||
|
||||
@ -48,3 +48,4 @@ c83f0106b78a85c7e614d27a328675460b2081cf jdk7-b70
|
||||
ff94d8ce0daded647bb326630e643d010357afce jdk7-b71
|
||||
37c805b6156fd492c12301688b54a6bcca39e729 jdk7-b72
|
||||
feb05980f9f2964e6bc2b3a8532f9b3054c2289b jdk7-b73
|
||||
ea7b88c676dd8b269bc858a4a17c14dc96c8aed1 jdk7-b74
|
||||
|
||||
@ -48,3 +48,4 @@ dd3c5f3ec28d5d5e5c0dc3229fdd52d85d04274d jdk7-b70
|
||||
03314cf56a7212bbb6c186dbc9f15aca988a48ec jdk7-b71
|
||||
4c990aa99bc037fd81dd1b1b269690e9bea8a0b4 jdk7-b72
|
||||
558985e26fe16f5a6ebb2edb9180a42e1c8e8202 jdk7-b73
|
||||
f4466e1b608088c90e11beaa4b600f102608c6a1 jdk7-b74
|
||||
|
||||
@ -48,3 +48,4 @@ b23d905cb5d3b382295240d28ab0bfb266b4503c jdk7-b68
|
||||
b3f3240135f0c10b9f2481c174b81b7fcf0daa60 jdk7-b71
|
||||
460639b036f327282832a4fe52b7aa45688afd50 jdk7-b72
|
||||
f708138c9aca4b389872838fe6773872fce3609e jdk7-b73
|
||||
eacb36e30327e7ae33baa068e82ddccbd91eaae2 jdk7-b74
|
||||
|
||||
@ -165,11 +165,6 @@ else
|
||||
JAVADOC_CMD = $(JAVA_TOOLS_DIR)/javadoc $(JAVA_TOOLS_FLAGS:%=-J%)
|
||||
endif
|
||||
|
||||
#always use the bootstrap javah until bug-ID 6889255 is fixed. These
|
||||
#five lines should be removed as part of that fix:
|
||||
JAVAH_CMD = $(JAVA_TOOLS_DIR)/javah \
|
||||
$(JAVAHFLAGS)
|
||||
|
||||
# Override of what javac to use (see deploy workspace)
|
||||
ifdef JAVAC
|
||||
JAVAC_CMD = $(JAVAC)
|
||||
|
||||
@ -258,6 +258,7 @@ JAVA_JAVA_java = \
|
||||
java/util/ServiceConfigurationError.java \
|
||||
java/util/Timer.java \
|
||||
java/util/TimerTask.java \
|
||||
java/util/Objects.java \
|
||||
java/util/UUID.java \
|
||||
java/util/concurrent/AbstractExecutorService.java \
|
||||
java/util/concurrent/ArrayBlockingQueue.java \
|
||||
|
||||
@ -211,7 +211,7 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVM_NAM
|
||||
$(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVM_NAME): $(HOTSPOT_KERNEL_PATH)/$(JVM_NAME)
|
||||
$(install-file)
|
||||
|
||||
$(LIB_LOCATION)/$(LIBJSIG_NAME): $(HOTSPOT_SERVER_PATH)/$(LIBJSIG_NAME)
|
||||
$(LIB_LOCATION)/$(LIBJSIG_NAME): $(HOTSPOT_IMPORT_PATH)/$(ARCH_VM_SUBDIR)/$(LIBJSIG_NAME)
|
||||
$(install-import-file)
|
||||
|
||||
$(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_NAME) \
|
||||
|
||||
@ -25,11 +25,12 @@
|
||||
|
||||
package com.sun.naming.internal;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
@ -112,6 +113,52 @@ public final class ResourceManager {
|
||||
private static final WeakHashMap urlFactoryCache = new WeakHashMap(11);
|
||||
private static final WeakReference NO_FACTORY = new WeakReference(null);
|
||||
|
||||
/**
|
||||
* A class to allow JNDI properties be specified as applet parameters
|
||||
* without creating a static dependency on java.applet.
|
||||
*/
|
||||
private static class AppletParameter {
|
||||
private static final Class<?> clazz = getClass("java.applet.Applet");
|
||||
private static final Method getMethod =
|
||||
getMethod(clazz, "getParameter", String.class);
|
||||
private static Class<?> getClass(String name) {
|
||||
try {
|
||||
return Class.forName(name, true, null);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private static Method getMethod(Class<?> clazz,
|
||||
String name,
|
||||
Class<?>... paramTypes)
|
||||
{
|
||||
if (clazz != null) {
|
||||
try {
|
||||
return clazz.getMethod(name, paramTypes);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the applet's named parameter.
|
||||
*/
|
||||
static Object get(Object applet, String name) {
|
||||
// if clazz is null then applet cannot be an Applet.
|
||||
if (clazz == null || !clazz.isInstance(applet))
|
||||
throw new ClassCastException(applet.getClass().getName());
|
||||
try {
|
||||
return getMethod.invoke(applet, name);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (IllegalAccessException iae) {
|
||||
throw new AssertionError(iae);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There should be no instances of this class.
|
||||
private ResourceManager() {
|
||||
@ -143,7 +190,7 @@ public final class ResourceManager {
|
||||
if (env == null) {
|
||||
env = new Hashtable(11);
|
||||
}
|
||||
Applet applet = (Applet)env.get(Context.APPLET);
|
||||
Object applet = env.get(Context.APPLET);
|
||||
|
||||
// Merge property values from env param, applet params, and system
|
||||
// properties. The first value wins: there's no concatenation of
|
||||
@ -157,7 +204,7 @@ public final class ResourceManager {
|
||||
Object val = env.get(props[i]);
|
||||
if (val == null) {
|
||||
if (applet != null) {
|
||||
val = applet.getParameter(props[i]);
|
||||
val = AppletParameter.get(applet, props[i]);
|
||||
}
|
||||
if (val == null) {
|
||||
// Read system property.
|
||||
|
||||
@ -209,7 +209,17 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
cpath = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
try {
|
||||
return sun.security.provider.PolicyFile.canonPath(cpath);
|
||||
String path = cpath;
|
||||
if (cpath.endsWith("*")) {
|
||||
// call getCanonicalPath with a path with wildcard character
|
||||
// replaced to avoid calling it with paths that are
|
||||
// intended to match all entries in a directory
|
||||
path = path.substring(0, path.length()-1) + "-";
|
||||
path = new File(path).getCanonicalPath();
|
||||
return path.substring(0, path.length()-1) + "*";
|
||||
} else {
|
||||
return new File(path).getCanonicalPath();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
return cpath;
|
||||
}
|
||||
|
||||
@ -40,10 +40,17 @@ import java.io.ObjectStreamException;
|
||||
* Edition</i>, <a
|
||||
* href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9">§8.9</a>.
|
||||
*
|
||||
* <p> Note that when using an enumeration type as the type of a set
|
||||
* or as the type of the keys in a map, specialized and efficient
|
||||
* {@linkplain java.util.EnumSet set} and {@linkplain
|
||||
* java.util.EnumMap map} implementations are available.
|
||||
*
|
||||
* @param <E> The enum type subclass
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Class#getEnumConstants()
|
||||
* @see java.util.EnumSet
|
||||
* @see java.util.EnumMap
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class Enum<E extends Enum<E>>
|
||||
|
||||
@ -44,6 +44,8 @@ import java.lang.annotation.Annotation;
|
||||
* as Java Object Serialization or other persistence mechanisms, to
|
||||
* manipulate objects in a manner that would normally be prohibited.
|
||||
*
|
||||
* <p>By default, a reflected object is <em>not</em> accessible.
|
||||
*
|
||||
* @see Field
|
||||
* @see Method
|
||||
* @see Constructor
|
||||
|
||||
@ -412,7 +412,7 @@ public abstract class Path
|
||||
* dependent if {@code "a/b/../x"} would locate the same file as {@code "/a/x"}.
|
||||
*
|
||||
* @param other
|
||||
* the resulting path
|
||||
* the path to relativize against this path
|
||||
*
|
||||
* @return the resulting relative path, or {@code null} if both paths are
|
||||
* equal
|
||||
@ -1615,23 +1615,23 @@ public abstract class Path
|
||||
* Tests if the file referenced by this object is the same file referenced
|
||||
* by another object.
|
||||
*
|
||||
* <p> If this {@code FileRef} and the given {@code FileRef} are {@link
|
||||
* <p> If this {@code Path} and the given {@code Path} are {@link
|
||||
* #equals(Object) equal} then this method returns {@code true} without checking
|
||||
* if the file exists. If the {@code FileRef} and the given {@code FileRef}
|
||||
* are associated with different providers, or the given {@code FileRef} is
|
||||
* if the file exists. If the {@code Path} and the given {@code Path}
|
||||
* are associated with different providers, or the given {@code Path} is
|
||||
* {@code null} then this method returns {@code false}. Otherwise, this method
|
||||
* checks if both {@code FileRefs} locate the same file, and depending on the
|
||||
* checks if both {@code Paths} locate the same file, and depending on the
|
||||
* implementation, may require to open or access both files.
|
||||
*
|
||||
* <p> If the file system and files remain static, then this method implements
|
||||
* an equivalence relation for non-null {@code FileRefs}.
|
||||
* an equivalence relation for non-null {@code Paths}.
|
||||
* <ul>
|
||||
* <li>It is <i>reflexive</i>: for a non-null {@code FileRef} {@code f},
|
||||
* <li>It is <i>reflexive</i>: for a non-null {@code Path} {@code f},
|
||||
* {@code f.isSameFile(f)} should return {@code true}.
|
||||
* <li>It is <i>symmetric</i>: for two non-null {@code FileRefs}
|
||||
* <li>It is <i>symmetric</i>: for two non-null {@code Path}
|
||||
* {@code f} and {@code g}, {@code f.isSameFile(g)} will equal
|
||||
* {@code g.isSameFile(f)}.
|
||||
* <li>It is <i>transitive</i>: for three {@code FileRefs}
|
||||
* <li>It is <i>transitive</i>: for three {@code Paths}
|
||||
* {@code f}, {@code g}, and {@code h}, if {@code f.isSameFile(g)} returns
|
||||
* {@code true} and {@code g.isSameFile(h)} returns {@code true}, then
|
||||
* {@code f.isSameFile(h)} will return return {@code true}.
|
||||
|
||||
156
jdk/src/share/classes/java/util/Objects.java
Normal file
156
jdk/src/share/classes/java/util/Objects.java
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This class consists of {@code static} utility methods for operating
|
||||
* on objects. These utilities include {@code null}-safe or {@code
|
||||
* null}-tolerant methods for computing the hash code of an object,
|
||||
* returning a string for an object, and comparing two objects.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public class Objects {
|
||||
private Objects() {
|
||||
throw new AssertionError("No java.util.Objects instances for you!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the arguments are equal to each other
|
||||
* and {@code false} otherwise.
|
||||
* Consequently, if both arguments are {@code null}, {@code true}
|
||||
* is returned and if exactly one argument is {@code null}, {@code
|
||||
* false} is returned. Otherwise, equality is determined by using
|
||||
* the {@link Object#equals equals} method of the first
|
||||
* argument.
|
||||
*
|
||||
* @param a an object
|
||||
* @param b an object to be compared with {@code a} for equality
|
||||
* @return {@code true} if the arguments are equal to each other
|
||||
* and {@code false} otherwise
|
||||
* @see Object#equals(Object)
|
||||
*/
|
||||
public static boolean equals(Object a, Object b) {
|
||||
return (a == b) || (a != null && a.equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code of a non-{@code null} argument and 0 for
|
||||
* a {@code null} argument.
|
||||
*
|
||||
* @param o an object
|
||||
* @return the hash code of a non-{@code null} argument and 0 for
|
||||
* a {@code null} argument
|
||||
* @see Object#hashCode
|
||||
*/
|
||||
public static int hashCode(Object o) {
|
||||
return o != null ? o.hashCode() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of calling {@code toString} for a non-{@code
|
||||
* null} argument and {@code "null"} for a {@code null} argument.
|
||||
*
|
||||
* @param o an object
|
||||
* @return the result of calling {@code toString} for a non-{@code
|
||||
* null} argument and {@code "null"} for a {@code null} argument
|
||||
* @see Object#toString
|
||||
* @see String#valueOf(Object)
|
||||
*/
|
||||
public static String toString(Object o) {
|
||||
return String.valueOf(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 0 if the arguments are identical and {@code
|
||||
* c.compare(a, b)} otherwise.
|
||||
* Consequently, if both arguments are {@code null} 0
|
||||
* is returned.
|
||||
*
|
||||
* <p>Note that if one of the arguments is {@code null}, a {@code
|
||||
* NullPointerException} may or may not be thrown depending on
|
||||
* what ordering policy, if any, the {@link Comparator Comparator}
|
||||
* chooses to have for {@code null} values.
|
||||
*
|
||||
* @param <T> the type of the objects being compared
|
||||
* @param a an object
|
||||
* @param b an object to be compared with {@code a}
|
||||
* @param c the {@code Comparator} to compare the first two arguments
|
||||
* @return 0 if the arguments are identical and {@code
|
||||
* c.compare(a, b)} otherwise.
|
||||
* @see Comparable
|
||||
* @see Comparator
|
||||
*/
|
||||
public static <T> int compare(T a, T b, Comparator<? super T> c) {
|
||||
return (a == b) ? 0 : c.compare(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified object reference is not {@code null}. This
|
||||
* method is designed primarily for doing parameter validation in methods
|
||||
* and constructors, as demonstrated below:
|
||||
* <blockquote><pre>
|
||||
* public Foo(Bar bar) {
|
||||
* this.bar = Objects.nonNull(bar);
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* @param obj the object reference to check for nullity
|
||||
* @param <T> the type of the reference
|
||||
* @return {@code obj} if not {@code null}
|
||||
* @throws NullPointerException if {@code obj} is {@code null}
|
||||
*/
|
||||
public static <T> T nonNull(T obj) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException();
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified object reference is not {@code null} and
|
||||
* throws a customized {@link NullPointerException} if it is. This method
|
||||
* is designed primarily for doing parameter validation in methods and
|
||||
* constructors with multiple parameters, as demonstrated below:
|
||||
* <blockquote><pre>
|
||||
* public Foo(Bar bar, Baz baz) {
|
||||
* this.bar = Objects.nonNull(bar, "bar must not be null");
|
||||
* this.baz = Objects.nonNull(baz, "baz must not be null");
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* @param obj the object reference to check for nullity
|
||||
* @param message detail message to be used in the event that a {@code
|
||||
* NullPointerException} is thrown
|
||||
* @param <T> the type of the reference
|
||||
* @return {@code obj} if not {@code null}
|
||||
* @throws NullPointerException if {@code obj} is {@code null}
|
||||
*/
|
||||
public static <T> T nonNull(T obj, String message) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(message);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@ -293,10 +293,8 @@ class JarVerifier {
|
||||
}
|
||||
sfv.process(sigFileSigners);
|
||||
|
||||
} catch (sun.security.pkcs.ParsingException pe) {
|
||||
if (debug != null) debug.println("processEntry caught: "+pe);
|
||||
// ignore and treat as unsigned
|
||||
} catch (IOException ioe) {
|
||||
// e.g. sun.security.pkcs.ParsingException
|
||||
if (debug != null) debug.println("processEntry caught: "+ioe);
|
||||
// ignore and treat as unsigned
|
||||
} catch (SignatureException se) {
|
||||
|
||||
@ -730,7 +730,7 @@ public class FloatingDecimal{
|
||||
* Thus we will need more than one digit if we're using
|
||||
* E-form
|
||||
*/
|
||||
if ( decExp <= -3 || decExp >= 8 ){
|
||||
if ( decExp < -3 || decExp >= 8 ){
|
||||
high = low = false;
|
||||
}
|
||||
while( ! low && ! high ){
|
||||
@ -783,7 +783,7 @@ public class FloatingDecimal{
|
||||
* Thus we will need more than one digit if we're using
|
||||
* E-form
|
||||
*/
|
||||
if ( decExp <= -3 || decExp >= 8 ){
|
||||
if ( decExp < -3 || decExp >= 8 ){
|
||||
high = low = false;
|
||||
}
|
||||
while( ! low && ! high ){
|
||||
@ -847,7 +847,7 @@ public class FloatingDecimal{
|
||||
* Thus we will need more than one digit if we're using
|
||||
* E-form
|
||||
*/
|
||||
if ( decExp <= -3 || decExp >= 8 ){
|
||||
if ( decExp < -3 || decExp >= 8 ){
|
||||
high = low = false;
|
||||
}
|
||||
while( ! low && ! high ){
|
||||
|
||||
@ -31,6 +31,7 @@ import java.nio.channels.*;
|
||||
import java.net.*;
|
||||
import javax.net.ssl.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
import java.text.*;
|
||||
import sun.net.www.MessageHeader;
|
||||
import com.sun.net.httpserver.*;
|
||||
@ -204,6 +205,21 @@ class ExchangeImpl {
|
||||
tmpout.write (bytes(statusLine, 0), 0, statusLine.length());
|
||||
boolean noContentToSend = false; // assume there is content
|
||||
rspHdrs.set ("Date", df.format (new Date()));
|
||||
|
||||
/* check for response type that is not allowed to send a body */
|
||||
|
||||
if ((rCode>=100 && rCode <200) /* informational */
|
||||
||(rCode == 204) /* no content */
|
||||
||(rCode == 304)) /* not modified */
|
||||
{
|
||||
if (contentLen != -1) {
|
||||
Logger logger = server.getLogger();
|
||||
String msg = "sendResponseHeaders: rCode = "+ rCode
|
||||
+ ": forcing contentLen = -1";
|
||||
logger.warning (msg);
|
||||
}
|
||||
contentLen = -1;
|
||||
}
|
||||
if (contentLen == 0) {
|
||||
if (http10) {
|
||||
o.setWrappedStream (new UndefLengthOutputStream (this, ros));
|
||||
|
||||
@ -1180,6 +1180,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
inputStream = http.getInputStream();
|
||||
|
||||
respCode = getResponseCode();
|
||||
if (respCode == -1) {
|
||||
disconnectInternal();
|
||||
throw new IOException ("Invalid Http response");
|
||||
}
|
||||
if (respCode == HTTP_PROXY_AUTH) {
|
||||
if (streaming()) {
|
||||
disconnectInternal();
|
||||
|
||||
@ -1832,8 +1832,9 @@ public class PolicyFile extends java.security.Policy {
|
||||
return canonCs;
|
||||
}
|
||||
|
||||
// public for java.io.FilePermission
|
||||
public static String canonPath(String path) throws IOException {
|
||||
// Wrapper to return a canonical path that avoids calling getCanonicalPath()
|
||||
// with paths that are intended to match all entries in the directory
|
||||
private static String canonPath(String path) throws IOException {
|
||||
if (path.endsWith("*")) {
|
||||
path = path.substring(0, path.length()-1) + "-";
|
||||
path = new File(path).getCanonicalPath();
|
||||
|
||||
@ -210,7 +210,7 @@ final class SunEntries {
|
||||
* CertStores
|
||||
*/
|
||||
map.put("CertStore.LDAP",
|
||||
"sun.security.provider.certpath.LDAPCertStore");
|
||||
"sun.security.provider.certpath.ldap.LDAPCertStore");
|
||||
map.put("CertStore.LDAP LDAPSchema", "RFC2587");
|
||||
map.put("CertStore.Collection",
|
||||
"sun.security.provider.certpath.CollectionCertStore");
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package sun.security.provider.certpath;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.cert.CertStore;
|
||||
import java.security.cert.X509CertSelector;
|
||||
import java.security.cert.X509CRLSelector;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Helper used by URICertStore when delegating to another CertStore to
|
||||
* fetch certs and CRLs.
|
||||
*/
|
||||
|
||||
public interface CertStoreHelper {
|
||||
|
||||
/**
|
||||
* Returns a CertStore using the given URI as parameters.
|
||||
*/
|
||||
CertStore getCertStore(URI uri)
|
||||
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Wraps an existing X509CertSelector when needing to avoid DN matching
|
||||
* issues.
|
||||
*/
|
||||
X509CertSelector wrap(X509CertSelector selector,
|
||||
X500Principal certSubject,
|
||||
String dn)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Wraps an existing X509CRLSelector when needing to avoid DN matching
|
||||
* issues.
|
||||
*/
|
||||
X509CRLSelector wrap(X509CRLSelector selector,
|
||||
Collection<X500Principal> certIssuers,
|
||||
String dn)
|
||||
throws IOException;
|
||||
}
|
||||
@ -64,6 +64,8 @@ public final class OCSP {
|
||||
|
||||
private static final Debug debug = Debug.getInstance("certpath");
|
||||
|
||||
private static final int CONNECT_TIMEOUT = 15000; // 15 seconds
|
||||
|
||||
private OCSP() {}
|
||||
|
||||
/**
|
||||
@ -176,6 +178,8 @@ public final class OCSP {
|
||||
debug.println("connecting to OCSP service at: " + url);
|
||||
}
|
||||
HttpURLConnection con = (HttpURLConnection)url.openConnection();
|
||||
con.setConnectTimeout(CONNECT_TIMEOUT);
|
||||
con.setReadTimeout(CONNECT_TIMEOUT);
|
||||
con.setDoOutput(true);
|
||||
con.setDoInput(true);
|
||||
con.setRequestMethod("POST");
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
|
||||
package sun.security.provider.certpath;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
import java.security.AccessController;
|
||||
@ -335,10 +334,11 @@ class OCSPChecker extends PKIXCertPathChecker {
|
||||
(issuerCert, currCertImpl.getSerialNumberObject());
|
||||
response = OCSP.check(Collections.singletonList(certId), uri,
|
||||
responderCert, pkixParams.getDate());
|
||||
} catch (IOException ioe) {
|
||||
// should allow this to pass if network failures are acceptable
|
||||
} catch (Exception e) {
|
||||
// Wrap all exceptions in CertPathValidatorException so that
|
||||
// we can fallback to CRLs, if enabled.
|
||||
throw new CertPathValidatorException
|
||||
("Unable to send OCSP request", ioe);
|
||||
("Unable to send OCSP request", e);
|
||||
}
|
||||
|
||||
RevocationStatus rs = (RevocationStatus) response.getSingleResponse(certId);
|
||||
|
||||
@ -30,6 +30,8 @@ import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URLConnection;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
@ -120,6 +122,32 @@ class URICertStore extends CertStoreSpi {
|
||||
private CertStore ldapCertStore;
|
||||
private String ldapPath;
|
||||
|
||||
/**
|
||||
* Holder class to lazily load LDAPCertStoreHelper if present.
|
||||
*/
|
||||
private static class LDAP {
|
||||
private static final String CERT_STORE_HELPER =
|
||||
"sun.security.provider.certpath.ldap.LDAPCertStoreHelper";
|
||||
private static final CertStoreHelper helper =
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<CertStoreHelper>() {
|
||||
public CertStoreHelper run() {
|
||||
try {
|
||||
Class<?> c = Class.forName(CERT_STORE_HELPER, true, null);
|
||||
return (CertStoreHelper)c.newInstance();
|
||||
} catch (ClassNotFoundException cnf) {
|
||||
return null;
|
||||
} catch (InstantiationException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}});
|
||||
static CertStoreHelper helper() {
|
||||
return helper;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a URICertStore.
|
||||
*
|
||||
@ -135,9 +163,10 @@ class URICertStore extends CertStoreSpi {
|
||||
this.uri = ((URICertStoreParameters) params).uri;
|
||||
// if ldap URI, use an LDAPCertStore to fetch certs and CRLs
|
||||
if (uri.getScheme().toLowerCase().equals("ldap")) {
|
||||
if (LDAP.helper() == null)
|
||||
throw new NoSuchAlgorithmException("LDAP not present");
|
||||
ldap = true;
|
||||
ldapCertStore =
|
||||
LDAPCertStore.getInstance(LDAPCertStore.getParameters(uri));
|
||||
ldapCertStore = LDAP.helper().getCertStore(uri);
|
||||
ldapPath = uri.getPath();
|
||||
// strip off leading '/'
|
||||
if (ldapPath.charAt(0) == '/') {
|
||||
@ -219,8 +248,7 @@ class URICertStore extends CertStoreSpi {
|
||||
if (ldap) {
|
||||
X509CertSelector xsel = (X509CertSelector) selector;
|
||||
try {
|
||||
xsel = new LDAPCertStore.LDAPCertSelector
|
||||
(xsel, xsel.getSubject(), ldapPath);
|
||||
xsel = LDAP.helper().wrap(xsel, xsel.getSubject(), ldapPath);
|
||||
} catch (IOException ioe) {
|
||||
throw new CertStoreException(ioe);
|
||||
}
|
||||
@ -340,7 +368,7 @@ class URICertStore extends CertStoreSpi {
|
||||
if (ldap) {
|
||||
X509CRLSelector xsel = (X509CRLSelector) selector;
|
||||
try {
|
||||
xsel = new LDAPCertStore.LDAPCRLSelector(xsel, null, ldapPath);
|
||||
xsel = LDAP.helper().wrap(xsel, null, ldapPath);
|
||||
} catch (IOException ioe) {
|
||||
throw new CertStoreException(ioe);
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package sun.security.provider.certpath;
|
||||
package sun.security.provider.certpath.ldap;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@ -46,6 +46,7 @@ import java.security.cert.*;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.misc.HexDumpEncoder;
|
||||
import sun.security.provider.certpath.X509CertificatePair;
|
||||
import sun.security.util.Cache;
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.x509.X500Name;
|
||||
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package sun.security.provider.certpath.ldap;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.cert.CertStore;
|
||||
import java.security.cert.X509CertSelector;
|
||||
import java.security.cert.X509CRLSelector;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.security.provider.certpath.CertStoreHelper;
|
||||
|
||||
/**
|
||||
* LDAP implementation of CertStoreHelper.
|
||||
*/
|
||||
|
||||
public class LDAPCertStoreHelper
|
||||
implements CertStoreHelper
|
||||
{
|
||||
public LDAPCertStoreHelper() { }
|
||||
|
||||
@Override
|
||||
public CertStore getCertStore(URI uri)
|
||||
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
|
||||
{
|
||||
return LDAPCertStore.getInstance(LDAPCertStore.getParameters(uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509CertSelector wrap(X509CertSelector selector,
|
||||
X500Principal certSubject,
|
||||
String ldapDN)
|
||||
throws IOException
|
||||
{
|
||||
return new LDAPCertStore.LDAPCertSelector(selector, certSubject, ldapDN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509CRLSelector wrap(X509CRLSelector selector,
|
||||
Collection<X500Principal> certIssuers,
|
||||
String ldapDN)
|
||||
throws IOException
|
||||
{
|
||||
return new LDAPCertStore.LDAPCRLSelector(selector, certIssuers, ldapDN);
|
||||
}
|
||||
}
|
||||
@ -104,11 +104,11 @@ class SolarisAclFileAttributeView
|
||||
int uid;
|
||||
if (user.isSpecial()) {
|
||||
uid = -1;
|
||||
if (who.getName().equals(UnixUserPrincipals.SPECIAL_OWNER.getName()))
|
||||
if (who == UnixUserPrincipals.SPECIAL_OWNER)
|
||||
flags |= ACE_OWNER;
|
||||
else if (who.getName().equals(UnixUserPrincipals.SPECIAL_GROUP.getName()))
|
||||
flags |= ACE_GROUP;
|
||||
else if (who.getName().equals(UnixUserPrincipals.SPECIAL_EVERYONE.getName()))
|
||||
else if (who == UnixUserPrincipals.SPECIAL_GROUP)
|
||||
flags |= (ACE_GROUP | ACE_IDENTIFIER_GROUP);
|
||||
else if (who == UnixUserPrincipals.SPECIAL_EVERYONE)
|
||||
flags |= ACE_EVERYONE;
|
||||
else
|
||||
throw new AssertionError("Unable to map special identifier");
|
||||
@ -281,7 +281,7 @@ class SolarisAclFileAttributeView
|
||||
aceFlags.add(AclEntryFlag.DIRECTORY_INHERIT);
|
||||
if ((flags & ACE_NO_PROPAGATE_INHERIT_ACE) > 0)
|
||||
aceFlags.add(AclEntryFlag.NO_PROPAGATE_INHERIT);
|
||||
if ((flags & ACE_INHERIT_ONLY_ACE ) > 0)
|
||||
if ((flags & ACE_INHERIT_ONLY_ACE) > 0)
|
||||
aceFlags.add(AclEntryFlag.INHERIT_ONLY);
|
||||
|
||||
// build the ACL entry and add it to the list
|
||||
|
||||
@ -235,7 +235,8 @@ class UnixDirectoryStream
|
||||
@Override
|
||||
public void remove() {
|
||||
if (isClosed) {
|
||||
throw new ClosedDirectoryStreamException();
|
||||
throwAsConcurrentModificationException(new
|
||||
ClosedDirectoryStreamException());
|
||||
}
|
||||
Path entry;
|
||||
synchronized (this) {
|
||||
|
||||
@ -179,7 +179,7 @@ class WindowsDirectoryStream
|
||||
synchronized (closeLock) {
|
||||
if (!isOpen)
|
||||
throwAsConcurrentModificationException(new
|
||||
IllegalStateException("Directory stream is closed"));
|
||||
ClosedDirectoryStreamException());
|
||||
try {
|
||||
name = FindNextFile(handle, findDataBuffer.address());
|
||||
if (name == null) {
|
||||
@ -236,7 +236,8 @@ class WindowsDirectoryStream
|
||||
@Override
|
||||
public void remove() {
|
||||
if (!isOpen) {
|
||||
throw new IllegalStateException("Directory stream is closed");
|
||||
throwAsConcurrentModificationException(new
|
||||
ClosedDirectoryStreamException());
|
||||
}
|
||||
Path entry;
|
||||
synchronized (this) {
|
||||
|
||||
93
jdk/test/com/sun/net/httpserver/bugs/B6886436.java
Normal file
93
jdk/test/com/sun/net/httpserver/bugs/B6886436.java
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6886436
|
||||
* @summary
|
||||
*/
|
||||
|
||||
import com.sun.net.httpserver.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.logging.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
public class B6886436 {
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Logger logger = Logger.getLogger ("com.sun.net.httpserver");
|
||||
ConsoleHandler c = new ConsoleHandler();
|
||||
c.setLevel (Level.WARNING);
|
||||
logger.addHandler (c);
|
||||
logger.setLevel (Level.WARNING);
|
||||
Handler handler = new Handler();
|
||||
InetSocketAddress addr = new InetSocketAddress (0);
|
||||
HttpServer server = HttpServer.create (addr, 0);
|
||||
HttpContext ctx = server.createContext ("/test", handler);
|
||||
ExecutorService executor = Executors.newCachedThreadPool();
|
||||
server.setExecutor (executor);
|
||||
server.start ();
|
||||
|
||||
URL url = new URL ("http://localhost:"+server.getAddress().getPort()+"/test/foo.html");
|
||||
HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
|
||||
try {
|
||||
InputStream is = urlc.getInputStream();
|
||||
while (is.read()!= -1) ;
|
||||
is.close ();
|
||||
urlc = (HttpURLConnection)url.openConnection ();
|
||||
urlc.setReadTimeout (3000);
|
||||
is = urlc.getInputStream();
|
||||
while (is.read()!= -1);
|
||||
is.close ();
|
||||
|
||||
} catch (IOException e) {
|
||||
server.stop(2);
|
||||
executor.shutdown();
|
||||
throw new RuntimeException ("Test failed");
|
||||
}
|
||||
server.stop(2);
|
||||
executor.shutdown();
|
||||
System.out.println ("OK");
|
||||
}
|
||||
|
||||
public static boolean error = false;
|
||||
|
||||
static class Handler implements HttpHandler {
|
||||
int invocation = 1;
|
||||
public void handle (HttpExchange t)
|
||||
throws IOException
|
||||
{
|
||||
InputStream is = t.getRequestBody();
|
||||
Headers map = t.getRequestHeaders();
|
||||
Headers rmap = t.getResponseHeaders();
|
||||
while (is.read () != -1) ;
|
||||
is.close();
|
||||
// send a 204 response with an empty chunked body
|
||||
t.sendResponseHeaders (204, 0);
|
||||
t.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
39
jdk/test/java/lang/Double/ToString.java
Normal file
39
jdk/test/java/lang/Double/ToString.java
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4428022
|
||||
* @summary Tests for Double.toString
|
||||
* @author Andrew Haley <aph@redhat.com>
|
||||
*/
|
||||
|
||||
public class ToString {
|
||||
|
||||
public static void main(String args[]) {
|
||||
if (!Double.toString(0.001).equals("0.001"))
|
||||
throw new RuntimeException("Double.toString(0.001) is not \"0.001\"");
|
||||
if (!Double.toString(0.002).equals("0.002"))
|
||||
throw new RuntimeException("Double.toString(0.001) is not \"0.002\"");
|
||||
}
|
||||
}
|
||||
@ -49,6 +49,21 @@ public class GetSystemProperties {
|
||||
private static final String VALUE4 = "test.property.value4";
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
// Save a copy of the original system properties
|
||||
Properties props = System.getProperties();
|
||||
|
||||
try {
|
||||
// replace the system Properties object for any modification
|
||||
// in case jtreg caches a copy
|
||||
System.setProperties(new Properties(props));
|
||||
runTest();
|
||||
} finally {
|
||||
// restore original system properties
|
||||
System.setProperties(props);
|
||||
}
|
||||
}
|
||||
|
||||
private static void runTest() throws Exception {
|
||||
RuntimeMXBean mbean = ManagementFactory.getRuntimeMXBean();
|
||||
|
||||
// Print all system properties
|
||||
@ -88,7 +103,10 @@ public class GetSystemProperties {
|
||||
Map<String,String> props2 = mbean.getSystemProperties();
|
||||
// expect the system properties returned should be
|
||||
// same as the one before adding KEY3 and KEY4
|
||||
props1.equals(props2);
|
||||
if (!props1.equals(props2)) {
|
||||
throw new RuntimeException("Two copies of system properties " +
|
||||
"are expected to be equal");
|
||||
}
|
||||
|
||||
System.out.println("Test passed.");
|
||||
}
|
||||
|
||||
@ -40,8 +40,21 @@ import java.lang.management.RuntimeMXBean;
|
||||
public class PropertiesTest {
|
||||
private static int NUM_MYPROPS = 3;
|
||||
public static void main(String[] argv) throws Exception {
|
||||
Properties sysProps = System.getProperties();
|
||||
// Save a copy of the original system properties
|
||||
Properties props = System.getProperties();
|
||||
|
||||
try {
|
||||
// replace the system Properties object for any modification
|
||||
// in case jtreg caches a copy
|
||||
System.setProperties(new Properties(props));
|
||||
runTest(props.size());
|
||||
} finally {
|
||||
// restore original system properties
|
||||
System.setProperties(props);
|
||||
}
|
||||
}
|
||||
|
||||
private static void runTest(int sysPropsCount) throws Exception {
|
||||
// Create a new system properties using the old one
|
||||
// as the defaults
|
||||
Properties myProps = new Properties( System.getProperties() );
|
||||
@ -65,10 +78,10 @@ public class PropertiesTest {
|
||||
System.out.println(i++ + ": " + key + " : " + value);
|
||||
}
|
||||
|
||||
if (props.size() != NUM_MYPROPS + sysProps.size()) {
|
||||
if (props.size() != NUM_MYPROPS + sysPropsCount) {
|
||||
throw new RuntimeException("Test Failed: " +
|
||||
"Expected number of properties = " +
|
||||
NUM_MYPROPS + sysProps.size() +
|
||||
NUM_MYPROPS + sysPropsCount +
|
||||
" but found = " + props.size());
|
||||
}
|
||||
}
|
||||
|
||||
69
jdk/test/java/lang/reflect/DefaultAccessibility.java
Normal file
69
jdk/test/java/lang/reflect/DefaultAccessibility.java
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6648344
|
||||
* @summary Test that default accessibility is false
|
||||
* @author Joseph D. Darcy
|
||||
*/
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
public class DefaultAccessibility {
|
||||
private DefaultAccessibility() {
|
||||
super();
|
||||
}
|
||||
|
||||
private static int f = 42;
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
Class<?> daClass = (new DefaultAccessibility()).getClass();
|
||||
|
||||
int elementCount = 0;
|
||||
for(Constructor<?> ctor : daClass.getDeclaredConstructors()) {
|
||||
elementCount++;
|
||||
if (ctor.isAccessible())
|
||||
throw new RuntimeException("Unexpected accessibility for constructor " +
|
||||
ctor);
|
||||
}
|
||||
|
||||
for(Method method : daClass.getDeclaredMethods()) {
|
||||
elementCount++;
|
||||
if (method.isAccessible())
|
||||
throw new RuntimeException("Unexpected accessibility for method " +
|
||||
method);
|
||||
}
|
||||
|
||||
for(Field field : daClass.getDeclaredFields()) {
|
||||
elementCount++;
|
||||
if (field.isAccessible())
|
||||
throw new RuntimeException("Unexpected accessibility for field " +
|
||||
field);
|
||||
}
|
||||
|
||||
if (elementCount < 3)
|
||||
throw new RuntimeException("Expected at least three members; only found " +
|
||||
elementCount);
|
||||
}
|
||||
}
|
||||
@ -154,8 +154,10 @@ public class Basic {
|
||||
stream.close();
|
||||
|
||||
// test IllegalStateException
|
||||
dir.resolve(foo).createFile();
|
||||
stream = dir.newDirectoryStream();
|
||||
i = stream.iterator();
|
||||
i.next();
|
||||
try {
|
||||
stream.iterator();
|
||||
throw new RuntimeException("IllegalStateException not thrown as expected");
|
||||
@ -172,17 +174,26 @@ public class Basic {
|
||||
throw new RuntimeException("ConcurrentModificationException not thrown as expected");
|
||||
} catch (ConcurrentModificationException x) {
|
||||
Throwable t = x.getCause();
|
||||
if (!(t instanceof IllegalStateException))
|
||||
throw new RuntimeException("Cause is not IllegalStateException as expected");
|
||||
if (!(t instanceof ClosedDirectoryStreamException))
|
||||
throw new RuntimeException("Cause is not ClosedDirectoryStreamException as expected");
|
||||
}
|
||||
try {
|
||||
i.next();
|
||||
throw new RuntimeException("IllegalStateException not thrown as expected");
|
||||
throw new RuntimeException("ConcurrentModificationException not thrown as expected");
|
||||
} catch (ConcurrentModificationException x) {
|
||||
Throwable t = x.getCause();
|
||||
if (!(t instanceof IllegalStateException))
|
||||
throw new RuntimeException("Cause is not IllegalStateException as expected");
|
||||
if (!(t instanceof ClosedDirectoryStreamException))
|
||||
throw new RuntimeException("Cause is not ClosedDirectoryStreamException as expected");
|
||||
}
|
||||
try {
|
||||
i.remove();
|
||||
throw new RuntimeException("ConcurrentModificationException not thrown as expected");
|
||||
} catch (ConcurrentModificationException x) {
|
||||
Throwable t = x.getCause();
|
||||
if (!(t instanceof ClosedDirectoryStreamException))
|
||||
throw new RuntimeException("Cause is not ClosedDirectoryStreamException as expected");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
* @summary Unit test for probeContentType method
|
||||
* @library ..
|
||||
* @build ContentType SimpleFileTypeDetector
|
||||
* @run main ContentType
|
||||
* @run main/othervm ContentType
|
||||
*/
|
||||
|
||||
import java.nio.file.*;
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
* @bug 6866804
|
||||
* @summary Unit test for java.nio.file.Path
|
||||
* @library ..
|
||||
* @build CheckPermissions
|
||||
* @run main/othervm CheckPermissions
|
||||
*/
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@ -92,7 +92,6 @@ public class CopyAndMove {
|
||||
{
|
||||
assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());
|
||||
assertTrue(attrs1.isHidden() == attrs2.isHidden());
|
||||
assertTrue(attrs1.isArchive() == attrs2.isArchive());
|
||||
assertTrue(attrs1.isSystem() == attrs2.isSystem());
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4313887 6838333
|
||||
* @bug 4313887 6838333 6891404
|
||||
* @summary Unit test for java.nio.file.attribute.AclFileAttribueView
|
||||
* @library ../..
|
||||
*/
|
||||
|
||||
155
jdk/test/java/util/Objects/BasicObjectsTest.java
Normal file
155
jdk/test/java/util/Objects/BasicObjectsTest.java
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6797535
|
||||
* @summary Basic tests for methods in java.util.Objects
|
||||
* @author Joseph D. Darcy
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BasicObjectsTest {
|
||||
public static void main(String... args) {
|
||||
int errors = 0;
|
||||
errors += testEquals();
|
||||
errors += testHashCode();
|
||||
errors += testToString();
|
||||
errors += testCompare();
|
||||
errors += testNonNull();
|
||||
if (errors > 0 )
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
private static int testEquals() {
|
||||
int errors = 0;
|
||||
Object[] values = {null, "42", 42};
|
||||
for(int i = 0; i < values.length; i++)
|
||||
for(int j = 0; j < values.length; j++) {
|
||||
boolean expected = (i == j);
|
||||
Object a = values[i];
|
||||
Object b = values[j];
|
||||
boolean result = Objects.equals(a, b);
|
||||
if (result != expected) {
|
||||
errors++;
|
||||
System.err.printf("When equating %s to %s, got %b instead of %b%n.",
|
||||
a, b, result, expected);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testHashCode() {
|
||||
int errors = 0;
|
||||
errors += (Objects.hashCode(null) == 0 ) ? 0 : 1;
|
||||
String s = "42";
|
||||
errors += (Objects.hashCode(s) == s.hashCode() ) ? 0 : 1;
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testToString() {
|
||||
int errors = 0;
|
||||
errors += ("null".equals(Objects.toString(null)) ) ? 0 : 1;
|
||||
String s = "Some string";
|
||||
errors += (s.equals(Objects.toString(s)) ) ? 0 : 1;
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testCompare() {
|
||||
int errors = 0;
|
||||
String[] values = {"e. e. cummings", "zzz"};
|
||||
String[] VALUES = {"E. E. Cummings", "ZZZ"};
|
||||
errors += compareTest(null, null, 0);
|
||||
for(int i = 0; i < values.length; i++) {
|
||||
String a = values[i];
|
||||
errors += compareTest(a, a, 0);
|
||||
for(int j = 0; j < VALUES.length; j++) {
|
||||
int expected = Integer.compare(i, j);
|
||||
String b = VALUES[j];
|
||||
errors += compareTest(a, b, expected);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int compareTest(String a, String b, int expected) {
|
||||
int errors = 0;
|
||||
int result = Objects.compare(a, b, String.CASE_INSENSITIVE_ORDER);
|
||||
if (Integer.signum(result) != Integer.signum(expected)) {
|
||||
errors++;
|
||||
System.err.printf("When comparing %s to %s, got %d instead of %d%n.",
|
||||
a, b, result, expected);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testNonNull() {
|
||||
int errors = 0;
|
||||
String s;
|
||||
|
||||
// Test 1-arg variant
|
||||
try {
|
||||
s = Objects.nonNull("pants");
|
||||
if (s != "pants") {
|
||||
System.err.printf("1-arg non-null failed to return its arg");
|
||||
errors++;
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
System.err.printf("1-arg nonNull threw unexpected NPE");
|
||||
errors++;
|
||||
}
|
||||
|
||||
try {
|
||||
s = Objects.nonNull(null);
|
||||
System.err.printf("1-arg nonNull failed to throw NPE");
|
||||
errors++;
|
||||
} catch (NullPointerException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
// Test 2-arg variant
|
||||
try {
|
||||
s = Objects.nonNull("pants", "trousers");
|
||||
if (s != "pants") {
|
||||
System.err.printf("2-arg nonNull failed to return its arg");
|
||||
errors++;
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
System.err.printf("2-arg nonNull threw unexpected NPE");
|
||||
errors++;
|
||||
}
|
||||
|
||||
try {
|
||||
s = Objects.nonNull(null, "pantaloons");
|
||||
System.err.printf("2-arg nonNull failed to throw NPE");
|
||||
errors++;
|
||||
} catch (NullPointerException e) {
|
||||
if (e.getMessage() != "pantaloons") {
|
||||
System.err.printf("2-arg nonNull threw NPE w/ bad detail msg");
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
@ -48,3 +48,4 @@ ce9bcdcb7859bb7ef10afd078ad59ba7847f208d jdk7-b69
|
||||
33c8c38e1757006c17d80499fb3347102501fae5 jdk7-b71
|
||||
261c54b2312ed26d6ec45c675831375460250519 jdk7-b72
|
||||
9596dff460935f09684c11d156ce591f92584f0d jdk7-b73
|
||||
1a66b08deed0459054b5b1bea3dfbead30d258fa jdk7-b74
|
||||
|
||||
@ -369,14 +369,33 @@ public class ConstantPool {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw value of the class referenced by this constant pool entry.
|
||||
* This will either be the name of the class, in internal form, or a
|
||||
* descriptor for an array class.
|
||||
* @return the raw value of the class
|
||||
*/
|
||||
public String getName() throws ConstantPoolException {
|
||||
return cp.getUTF8Value(name_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* If this constant pool entry identifies either a class or interface type,
|
||||
* or a possibly multi-dimensional array of a class of interface type,
|
||||
* return the name of the class or interface in internal form. Otherwise,
|
||||
* (i.e. if this is a possibly multi-dimensional array of a primitive type),
|
||||
* return null.
|
||||
* @return the base class or interface name
|
||||
*/
|
||||
public String getBaseName() throws ConstantPoolException {
|
||||
String name = getName();
|
||||
int index = name.indexOf("[L") + 1;
|
||||
return name.substring(index);
|
||||
if (name.startsWith("[")) {
|
||||
int index = name.indexOf("[L");
|
||||
if (index == -1)
|
||||
return null;
|
||||
return name.substring(index + 2, name.length() - 1);
|
||||
} else
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getDimensionCount() throws ConstantPoolException {
|
||||
|
||||
@ -27,6 +27,7 @@ package com.sun.tools.classfile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.sun.tools.classfile.Type.*;
|
||||
|
||||
/**
|
||||
* See JVMS3 4.4.4.
|
||||
@ -50,19 +51,19 @@ public class Signature extends Descriptor {
|
||||
|
||||
@Override
|
||||
public int getParameterCount(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
Type.MethodType m = (Type.MethodType) getType(constant_pool);
|
||||
return m.argTypes.size();
|
||||
MethodType m = (MethodType) getType(constant_pool);
|
||||
return m.paramTypes.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameterTypes(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
Type.MethodType m = (Type.MethodType) getType(constant_pool);
|
||||
MethodType m = (MethodType) getType(constant_pool);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
String sep = "";
|
||||
for (Type argType: m.argTypes) {
|
||||
for (Type paramType: m.paramTypes) {
|
||||
sb.append(sep);
|
||||
sb.append(argType);
|
||||
sb.append(paramType);
|
||||
sep = ", ";
|
||||
}
|
||||
sb.append(")");
|
||||
@ -71,7 +72,7 @@ public class Signature extends Descriptor {
|
||||
|
||||
@Override
|
||||
public String getReturnType(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
Type.MethodType m = (Type.MethodType) getType(constant_pool);
|
||||
MethodType m = (MethodType) getType(constant_pool);
|
||||
return m.returnType.toString();
|
||||
}
|
||||
|
||||
@ -84,12 +85,12 @@ public class Signature extends Descriptor {
|
||||
this.sig = sig;
|
||||
sigp = 0;
|
||||
|
||||
List<Type> typeArgTypes = null;
|
||||
List<TypeParamType> typeParamTypes = null;
|
||||
if (sig.charAt(sigp) == '<')
|
||||
typeArgTypes = parseTypeArgTypes();
|
||||
typeParamTypes = parseTypeParamTypes();
|
||||
|
||||
if (sig.charAt(sigp) == '(') {
|
||||
List<Type> argTypes = parseTypeSignatures(')');
|
||||
List<Type> paramTypes = parseTypeSignatures(')');
|
||||
Type returnType = parseTypeSignature();
|
||||
List<Type> throwsTypes = null;
|
||||
while (sigp < sig.length() && sig.charAt(sigp) == '^') {
|
||||
@ -98,16 +99,19 @@ public class Signature extends Descriptor {
|
||||
throwsTypes = new ArrayList<Type>();
|
||||
throwsTypes.add(parseTypeSignature());
|
||||
}
|
||||
return new Type.MethodType(typeArgTypes, argTypes, returnType, throwsTypes);
|
||||
return new MethodType(typeParamTypes, paramTypes, returnType, throwsTypes);
|
||||
} else {
|
||||
Type t = parseTypeSignature();
|
||||
if (typeArgTypes == null && sigp == sig.length())
|
||||
if (typeParamTypes == null && sigp == sig.length())
|
||||
return t;
|
||||
Type superclass = t;
|
||||
List<Type> superinterfaces = new ArrayList<Type>();
|
||||
while (sigp < sig.length())
|
||||
List<Type> superinterfaces = null;
|
||||
while (sigp < sig.length()) {
|
||||
if (superinterfaces == null)
|
||||
superinterfaces = new ArrayList<Type>();
|
||||
superinterfaces.add(parseTypeSignature());
|
||||
return new Type.ClassSigType(typeArgTypes, superclass, superinterfaces);
|
||||
}
|
||||
return new ClassSigType(typeParamTypes, superclass, superinterfaces);
|
||||
|
||||
}
|
||||
}
|
||||
@ -116,61 +120,61 @@ public class Signature extends Descriptor {
|
||||
switch (sig.charAt(sigp)) {
|
||||
case 'B':
|
||||
sigp++;
|
||||
return new Type.SimpleType("byte");
|
||||
return new SimpleType("byte");
|
||||
|
||||
case 'C':
|
||||
sigp++;
|
||||
return new Type.SimpleType("char");
|
||||
return new SimpleType("char");
|
||||
|
||||
case 'D':
|
||||
sigp++;
|
||||
return new Type.SimpleType("double");
|
||||
return new SimpleType("double");
|
||||
|
||||
case 'F':
|
||||
sigp++;
|
||||
return new Type.SimpleType("float");
|
||||
return new SimpleType("float");
|
||||
|
||||
case 'I':
|
||||
sigp++;
|
||||
return new Type.SimpleType("int");
|
||||
return new SimpleType("int");
|
||||
|
||||
case 'J':
|
||||
sigp++;
|
||||
return new Type.SimpleType("long");
|
||||
return new SimpleType("long");
|
||||
|
||||
case 'L':
|
||||
return parseClassTypeSignature();
|
||||
|
||||
case 'S':
|
||||
sigp++;
|
||||
return new Type.SimpleType("short");
|
||||
return new SimpleType("short");
|
||||
|
||||
case 'T':
|
||||
return parseTypeVariableSignature();
|
||||
|
||||
case 'V':
|
||||
sigp++;
|
||||
return new Type.SimpleType("void");
|
||||
return new SimpleType("void");
|
||||
|
||||
case 'Z':
|
||||
sigp++;
|
||||
return new Type.SimpleType("boolean");
|
||||
return new SimpleType("boolean");
|
||||
|
||||
case '[':
|
||||
sigp++;
|
||||
return new Type.ArrayType(parseTypeSignature());
|
||||
return new ArrayType(parseTypeSignature());
|
||||
|
||||
case '*':
|
||||
sigp++;
|
||||
return new Type.WildcardType();
|
||||
return new WildcardType();
|
||||
|
||||
case '+':
|
||||
sigp++;
|
||||
return new Type.WildcardType("extends", parseTypeSignature());
|
||||
return new WildcardType(WildcardType.Kind.EXTENDS, parseTypeSignature());
|
||||
|
||||
case '-':
|
||||
sigp++;
|
||||
return new Type.WildcardType("super", parseTypeSignature());
|
||||
return new WildcardType(WildcardType.Kind.SUPER, parseTypeSignature());
|
||||
|
||||
default:
|
||||
throw new IllegalStateException(debugInfo());
|
||||
@ -194,30 +198,22 @@ public class Signature extends Descriptor {
|
||||
|
||||
private Type parseClassTypeSignatureRest() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Type t = null;
|
||||
char sigch;
|
||||
while (true) {
|
||||
List<Type> argTypes = null;
|
||||
ClassType t = null;
|
||||
char sigch ;
|
||||
|
||||
do {
|
||||
switch (sigch = sig.charAt(sigp)) {
|
||||
case '/':
|
||||
sigp++;
|
||||
sb.append(".");
|
||||
case '<':
|
||||
argTypes = parseTypeSignatures('>');
|
||||
break;
|
||||
|
||||
case '.':
|
||||
sigp++;
|
||||
if (t == null)
|
||||
t = new Type.SimpleType(sb.toString());
|
||||
return new Type.InnerClassType(t, parseClassTypeSignatureRest());
|
||||
|
||||
case ';':
|
||||
sigp++;
|
||||
if (t == null)
|
||||
t = new Type.SimpleType(sb.toString());
|
||||
return t;
|
||||
|
||||
case '<':
|
||||
List<Type> argTypes = parseTypeSignatures('>');
|
||||
t = new Type.ClassType(sb.toString(), argTypes);
|
||||
t = new ClassType(t, sb.toString(), argTypes);
|
||||
sb.setLength(0);
|
||||
argTypes = null;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -225,21 +221,22 @@ public class Signature extends Descriptor {
|
||||
sb.append(sigch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (sigch != ';');
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
private List<Type> parseTypeArgTypes() {
|
||||
private List<TypeParamType> parseTypeParamTypes() {
|
||||
assert sig.charAt(sigp) == '<';
|
||||
sigp++;
|
||||
List<Type> types = null;
|
||||
types = new ArrayList<Type>();
|
||||
List<TypeParamType> types = new ArrayList<TypeParamType>();
|
||||
while (sig.charAt(sigp) != '>')
|
||||
types.add(parseTypeArgType());
|
||||
types.add(parseTypeParamType());
|
||||
sigp++;
|
||||
return types;
|
||||
}
|
||||
|
||||
private Type parseTypeArgType() {
|
||||
private TypeParamType parseTypeParamType() {
|
||||
int sep = sig.indexOf(":", sigp);
|
||||
String name = sig.substring(sigp, sep);
|
||||
Type classBound = null;
|
||||
@ -253,13 +250,13 @@ public class Signature extends Descriptor {
|
||||
interfaceBounds = new ArrayList<Type>();
|
||||
interfaceBounds.add(parseTypeSignature());
|
||||
}
|
||||
return new Type.TypeArgType(name, classBound, interfaceBounds);
|
||||
return new TypeParamType(name, classBound, interfaceBounds);
|
||||
}
|
||||
|
||||
private Type parseTypeVariableSignature() {
|
||||
sigp++;
|
||||
int sep = sig.indexOf(';', sigp);
|
||||
Type t = new Type.SimpleType(sig.substring(sigp, sep));
|
||||
Type t = new SimpleType(sig.substring(sigp, sep));
|
||||
sigp = sep + 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -31,6 +31,9 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
* Family of classes used to represent the parsed form of a {@link Descriptor}
|
||||
* or {@link Signature}.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
@ -62,11 +65,26 @@ public abstract class Type {
|
||||
R visitMethodType(MethodType type, P p);
|
||||
R visitClassSigType(ClassSigType type, P p);
|
||||
R visitClassType(ClassType type, P p);
|
||||
R visitInnerClassType(InnerClassType type, P p);
|
||||
R visitTypeArgType(TypeArgType type, P p);
|
||||
R visitTypeParamType(TypeParamType type, P p);
|
||||
R visitWildcardType(WildcardType type, P p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a type signature with a simple name. The name may be that of a
|
||||
* primitive type, such "{@code int}, {@code float}, etc
|
||||
* or that of a type argument, such as {@code T}, {@code K}, {@code V}, etc.
|
||||
*
|
||||
* See:
|
||||
* JVMS 4.3.2
|
||||
* BaseType:
|
||||
* {@code B}, {@code C}, {@code D}, {@code F}, {@code I},
|
||||
* {@code J}, {@code S}, {@code Z};
|
||||
* VoidDescriptor:
|
||||
* {@code V};
|
||||
* JVMS 4.3.4
|
||||
* TypeVariableSignature:
|
||||
* {@code T} Identifier {@code ;}
|
||||
*/
|
||||
public static class SimpleType extends Type {
|
||||
public SimpleType(String name) {
|
||||
this.name = name;
|
||||
@ -91,6 +109,14 @@ public abstract class Type {
|
||||
public final String name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an array type signature.
|
||||
*
|
||||
* See:
|
||||
* JVMS 4.3.4
|
||||
* ArrayTypeSignature:
|
||||
* {@code [} TypeSignature {@code ]}
|
||||
*/
|
||||
public static class ArrayType extends Type {
|
||||
public ArrayType(Type elemType) {
|
||||
this.elemType = elemType;
|
||||
@ -108,17 +134,26 @@ public abstract class Type {
|
||||
public final Type elemType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a method type signature.
|
||||
*
|
||||
* See;
|
||||
* JVMS 4.3.4
|
||||
* MethodTypeSignature:
|
||||
* FormalTypeParameters_opt {@code (} TypeSignature* {@code)} ReturnType
|
||||
* ThrowsSignature*
|
||||
*/
|
||||
public static class MethodType extends Type {
|
||||
public MethodType(List<? extends Type> argTypes, Type resultType) {
|
||||
this(null, argTypes, resultType, null);
|
||||
public MethodType(List<? extends Type> paramTypes, Type resultType) {
|
||||
this(null, paramTypes, resultType, null);
|
||||
}
|
||||
|
||||
public MethodType(List<? extends Type> typeArgTypes,
|
||||
List<? extends Type> argTypes,
|
||||
public MethodType(List<? extends TypeParamType> typeParamTypes,
|
||||
List<? extends Type> paramTypes,
|
||||
Type returnType,
|
||||
List<? extends Type> throwsTypes) {
|
||||
this.typeArgTypes = typeArgTypes;
|
||||
this.argTypes = argTypes;
|
||||
this.typeParamTypes = typeParamTypes;
|
||||
this.paramTypes = paramTypes;
|
||||
this.returnType = returnType;
|
||||
this.throwsTypes = throwsTypes;
|
||||
}
|
||||
@ -130,22 +165,32 @@ public abstract class Type {
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendIfNotEmpty(sb, "<", typeArgTypes, "> ");
|
||||
appendIfNotEmpty(sb, "<", typeParamTypes, "> ");
|
||||
sb.append(returnType);
|
||||
append(sb, " (", argTypes, ")");
|
||||
append(sb, " (", paramTypes, ")");
|
||||
appendIfNotEmpty(sb, " throws ", throwsTypes, "");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public final List<? extends Type> typeArgTypes;
|
||||
public final List<? extends Type> argTypes;
|
||||
public final List<? extends TypeParamType> typeParamTypes;
|
||||
public final List<? extends Type> paramTypes;
|
||||
public final Type returnType;
|
||||
public final List<? extends Type> throwsTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a class signature. These describe the signature of
|
||||
* a class that has type arguments.
|
||||
*
|
||||
* See:
|
||||
* JVMS 4.3.4
|
||||
* ClassSignature:
|
||||
* FormalTypeParameters_opt SuperclassSignature SuperinterfaceSignature*
|
||||
*/
|
||||
public static class ClassSigType extends Type {
|
||||
public ClassSigType(List<Type> typeArgTypes, Type superclassType, List<Type> superinterfaceTypes) {
|
||||
this.typeArgTypes = typeArgTypes;
|
||||
public ClassSigType(List<TypeParamType> typeParamTypes, Type superclassType,
|
||||
List<Type> superinterfaceTypes) {
|
||||
this.typeParamTypes = typeParamTypes;
|
||||
this.superclassType = superclassType;
|
||||
this.superinterfaceTypes = superinterfaceTypes;
|
||||
}
|
||||
@ -157,7 +202,7 @@ public abstract class Type {
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendIfNotEmpty(sb, "<", typeArgTypes, ">");
|
||||
appendIfNotEmpty(sb, "<", typeParamTypes, ">");
|
||||
if (superclassType != null) {
|
||||
sb.append(" extends ");
|
||||
sb.append(superclassType);
|
||||
@ -166,13 +211,30 @@ public abstract class Type {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public final List<Type> typeArgTypes;
|
||||
public final List<TypeParamType> typeParamTypes;
|
||||
public final Type superclassType;
|
||||
public final List<Type> superinterfaceTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a class type signature. This is used to represent a
|
||||
* reference to a class, such as in a field, parameter, return type, etc.
|
||||
*
|
||||
* See:
|
||||
* JVMS 4.3.4
|
||||
* ClassTypeSignature:
|
||||
* {@code L} PackageSpecifier_opt SimpleClassTypeSignature
|
||||
* ClassTypeSignatureSuffix* {@code ;}
|
||||
* PackageSpecifier:
|
||||
* Identifier {@code /} PackageSpecifier*
|
||||
* SimpleClassTypeSignature:
|
||||
* Identifier TypeArguments_opt }
|
||||
* ClassTypeSignatureSuffix:
|
||||
* {@code .} SimpleClassTypeSignature
|
||||
*/
|
||||
public static class ClassType extends Type {
|
||||
public ClassType(String name, List<Type> typeArgs) {
|
||||
public ClassType(ClassType outerType, String name, List<Type> typeArgs) {
|
||||
this.outerType = outerType;
|
||||
this.name = name;
|
||||
this.typeArgs = typeArgs;
|
||||
}
|
||||
@ -181,47 +243,54 @@ public abstract class Type {
|
||||
return visitor.visitClassType(this, data);
|
||||
}
|
||||
|
||||
public String getBinaryName() {
|
||||
if (outerType == null)
|
||||
return name;
|
||||
else
|
||||
return (outerType.getBinaryName() + "$" + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (outerType != null) {
|
||||
sb.append(outerType);
|
||||
sb.append(".");
|
||||
}
|
||||
sb.append(name);
|
||||
appendIfNotEmpty(sb, "<", typeArgs, ">");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public final ClassType outerType;
|
||||
public final String name;
|
||||
public final List<Type> typeArgs;
|
||||
}
|
||||
|
||||
|
||||
public static class InnerClassType extends Type {
|
||||
public InnerClassType(Type outerType, Type innerType) {
|
||||
this.outerType = outerType;
|
||||
this.innerType = innerType;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitInnerClassType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return outerType + "." + innerType;
|
||||
}
|
||||
|
||||
public final Type outerType;
|
||||
public final Type innerType;
|
||||
}
|
||||
|
||||
public static class TypeArgType extends Type {
|
||||
public TypeArgType(String name, Type classBound, List<Type> interfaceBounds) {
|
||||
/**
|
||||
* Represents a FormalTypeParameter. These are used to declare the type
|
||||
* parameters for generic classes and methods.
|
||||
*
|
||||
* See:
|
||||
* JVMS 4.3.4
|
||||
* FormalTypeParameters:
|
||||
* {@code <} FormalTypeParameter+ {@code >}
|
||||
* FormalTypeParameter:
|
||||
* Identifier ClassBound InterfaceBound*
|
||||
* ClassBound:
|
||||
* {@code :} FieldTypeSignature_opt
|
||||
* InterfaceBound:
|
||||
* {@code :} FieldTypeSignature
|
||||
*/
|
||||
public static class TypeParamType extends Type {
|
||||
public TypeParamType(String name, Type classBound, List<Type> interfaceBounds) {
|
||||
this.name = name;
|
||||
this.classBound = classBound;
|
||||
this.interfaceBounds = interfaceBounds;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitTypeArgType(this, data);
|
||||
return visitor.visitTypeParamType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -249,12 +318,25 @@ public abstract class Type {
|
||||
public final List<Type> interfaceBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a wildcard type argument. A type argument that is not a
|
||||
* wildcard type argument will be represented by a ClassType, ArrayType, etc.
|
||||
*
|
||||
* See:
|
||||
* JVMS 4.3.4
|
||||
* TypeArgument:
|
||||
* WildcardIndicator_opt FieldTypeSignature
|
||||
* {@code *}
|
||||
* WildcardIndicator:
|
||||
* {@code +}
|
||||
* {@code -}
|
||||
*/
|
||||
public static class WildcardType extends Type {
|
||||
public enum Kind { UNBOUNDED, EXTENDS, SUPER };
|
||||
public WildcardType() {
|
||||
this(null, null);
|
||||
this(Kind.UNBOUNDED, null);
|
||||
}
|
||||
|
||||
public WildcardType(String kind, Type boundType) {
|
||||
public WildcardType(Kind kind, Type boundType) {
|
||||
this.kind = kind;
|
||||
this.boundType = boundType;
|
||||
}
|
||||
@ -265,13 +347,19 @@ public abstract class Type {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (kind == null)
|
||||
return "?";
|
||||
else
|
||||
return "? " + kind + " " + boundType;
|
||||
switch (kind) {
|
||||
case UNBOUNDED:
|
||||
return "?";
|
||||
case EXTENDS:
|
||||
return "? extends " + boundType;
|
||||
case SUPER:
|
||||
return "? super " + boundType;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
public final String kind;
|
||||
public final Kind kind;
|
||||
public final Type boundType;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1212,25 +1212,58 @@ public abstract class Symbol implements Element {
|
||||
public List<VarSymbol> params() {
|
||||
owner.complete();
|
||||
if (params == null) {
|
||||
List<Name> names = savedParameterNames;
|
||||
// If ClassReader.saveParameterNames has been set true, then
|
||||
// savedParameterNames will be set to a list of names that
|
||||
// matches the types in type.getParameterTypes(). If any names
|
||||
// were not found in the class file, those names in the list will
|
||||
// be set to the empty name.
|
||||
// If ClassReader.saveParameterNames has been set false, then
|
||||
// savedParameterNames will be null.
|
||||
List<Name> paramNames = savedParameterNames;
|
||||
savedParameterNames = null;
|
||||
if (names == null) {
|
||||
names = List.nil();
|
||||
int i = 0;
|
||||
for (Type t : type.getParameterTypes())
|
||||
names = names.prepend(name.table.fromString("arg" + i++));
|
||||
names = names.reverse();
|
||||
}
|
||||
// discard the provided names if the list of names is the wrong size.
|
||||
if (paramNames == null || paramNames.size() != type.getParameterTypes().size())
|
||||
paramNames = List.nil();
|
||||
ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
|
||||
List<Name> remaining = paramNames;
|
||||
// assert: remaining and paramNames are both empty or both
|
||||
// have same cardinality as type.getParameterTypes()
|
||||
int i = 0;
|
||||
for (Type t : type.getParameterTypes()) {
|
||||
buf.append(new VarSymbol(PARAMETER, names.head, t, this));
|
||||
names = names.tail;
|
||||
Name paramName;
|
||||
if (remaining.isEmpty()) {
|
||||
// no names for any parameters available
|
||||
paramName = createArgName(i, paramNames);
|
||||
} else {
|
||||
paramName = remaining.head;
|
||||
remaining = remaining.tail;
|
||||
if (paramName.isEmpty()) {
|
||||
// no name for this specific parameter
|
||||
paramName = createArgName(i, paramNames);
|
||||
}
|
||||
}
|
||||
buf.append(new VarSymbol(PARAMETER, paramName, t, this));
|
||||
i++;
|
||||
}
|
||||
params = buf.toList();
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
// Create a name for the argument at position 'index' that is not in
|
||||
// the exclude list. In normal use, either no names will have been
|
||||
// provided, in which case the exclude list is empty, or all the names
|
||||
// will have been provided, in which case this method will not be called.
|
||||
private Name createArgName(int index, List<Name> exclude) {
|
||||
String prefix = "arg";
|
||||
while (true) {
|
||||
Name argName = name.table.fromString(prefix + index);
|
||||
if (!exclude.contains(argName))
|
||||
return argName;
|
||||
prefix += "$";
|
||||
}
|
||||
}
|
||||
|
||||
public Symbol asMemberOf(Type site, Types types) {
|
||||
return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
|
||||
}
|
||||
|
||||
@ -120,6 +120,14 @@ public abstract class BaseFileObject implements JavaFileObject {
|
||||
|
||||
}
|
||||
|
||||
// force subtypes to define equals
|
||||
@Override
|
||||
public abstract boolean equals(Object other);
|
||||
|
||||
// force subtypes to define hashCode
|
||||
@Override
|
||||
public abstract int hashCode();
|
||||
|
||||
/** The file manager that created this JavaFileObject. */
|
||||
protected final JavacFileManager fileManager;
|
||||
}
|
||||
|
||||
@ -968,7 +968,7 @@ public class JavacFileManager implements StandardJavaFileManager {
|
||||
} else {
|
||||
File siblingDir = null;
|
||||
if (sibling != null && sibling instanceof RegularFileObject) {
|
||||
siblingDir = ((RegularFileObject)sibling).f.getParentFile();
|
||||
siblingDir = ((RegularFileObject)sibling).file.getParentFile();
|
||||
}
|
||||
return new RegularFileObject(this, new File(siblingDir, fileName.basename()));
|
||||
}
|
||||
|
||||
@ -33,6 +33,8 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
@ -53,7 +55,8 @@ class RegularFileObject extends BaseFileObject {
|
||||
*/
|
||||
private boolean hasParents = false;
|
||||
private String name;
|
||||
final File f;
|
||||
final File file;
|
||||
private Reference<File> absFileRef;
|
||||
|
||||
public RegularFileObject(JavacFileManager fileManager, File f) {
|
||||
this(fileManager, f.getName(), f);
|
||||
@ -65,17 +68,17 @@ class RegularFileObject extends BaseFileObject {
|
||||
throw new IllegalArgumentException("directories not supported");
|
||||
}
|
||||
this.name = name;
|
||||
this.f = f;
|
||||
this.file = f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI toUri() {
|
||||
return f.toURI().normalize();
|
||||
return file.toURI().normalize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return f.getPath();
|
||||
return file.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -90,20 +93,20 @@ class RegularFileObject extends BaseFileObject {
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream() throws IOException {
|
||||
return new FileInputStream(f);
|
||||
return new FileInputStream(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
ensureParentDirectoriesExist();
|
||||
return new FileOutputStream(f);
|
||||
return new FileOutputStream(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
|
||||
CharBuffer cb = fileManager.getCachedContent(this);
|
||||
if (cb == null) {
|
||||
InputStream in = new FileInputStream(f);
|
||||
InputStream in = new FileInputStream(file);
|
||||
try {
|
||||
ByteBuffer bb = fileManager.makeByteBuffer(in);
|
||||
JavaFileObject prev = fileManager.log.useSource(this);
|
||||
@ -126,17 +129,17 @@ class RegularFileObject extends BaseFileObject {
|
||||
@Override
|
||||
public Writer openWriter() throws IOException {
|
||||
ensureParentDirectoriesExist();
|
||||
return new OutputStreamWriter(new FileOutputStream(f), fileManager.getEncodingName());
|
||||
return new OutputStreamWriter(new FileOutputStream(file), fileManager.getEncodingName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified() {
|
||||
return f.lastModified();
|
||||
return file.lastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete() {
|
||||
return f.delete();
|
||||
return file.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -146,7 +149,7 @@ class RegularFileObject extends BaseFileObject {
|
||||
|
||||
@Override
|
||||
protected String inferBinaryName(Iterable<? extends File> path) {
|
||||
String fPath = f.getPath();
|
||||
String fPath = file.getPath();
|
||||
//System.err.println("RegularFileObject " + file + " " +r.getPath());
|
||||
for (File dir: path) {
|
||||
//System.err.println("dir: " + dir);
|
||||
@ -178,7 +181,7 @@ class RegularFileObject extends BaseFileObject {
|
||||
if (name.equalsIgnoreCase(n)) {
|
||||
try {
|
||||
// allow for Windows
|
||||
return f.getCanonicalFile().getName().equals(n);
|
||||
return file.getCanonicalFile().getName().equals(n);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
@ -187,7 +190,7 @@ class RegularFileObject extends BaseFileObject {
|
||||
|
||||
private void ensureParentDirectoriesExist() throws IOException {
|
||||
if (!hasParents) {
|
||||
File parent = f.getParentFile();
|
||||
File parent = file.getParentFile();
|
||||
if (parent != null && !parent.exists()) {
|
||||
if (!parent.mkdirs()) {
|
||||
if (!parent.exists() || !parent.isDirectory()) {
|
||||
@ -199,21 +202,34 @@ class RegularFileObject extends BaseFileObject {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two file objects are equal.
|
||||
* Two RegularFileObjects are equal if the absolute paths of the underlying
|
||||
* files are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof RegularFileObject)) {
|
||||
if (this == other)
|
||||
return true;
|
||||
|
||||
if (!(other instanceof RegularFileObject))
|
||||
return false;
|
||||
}
|
||||
|
||||
RegularFileObject o = (RegularFileObject) other;
|
||||
try {
|
||||
return f.equals(o.f) || f.getCanonicalFile().equals(o.f.getCanonicalFile());
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
return getAbsoluteFile().equals(o.getAbsoluteFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return f.hashCode();
|
||||
return getAbsoluteFile().hashCode();
|
||||
}
|
||||
|
||||
private File getAbsoluteFile() {
|
||||
File absFile = (absFileRef == null ? null : absFileRef.get());
|
||||
if (absFile == null) {
|
||||
absFile = file.getAbsoluteFile();
|
||||
absFileRef = new SoftReference<File>(absFile);
|
||||
}
|
||||
return absFile;
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,13 +76,13 @@ public class SymbolArchive extends ZipArchive {
|
||||
@Override
|
||||
public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
|
||||
RelativeDirectory prefix_subdir = new RelativeDirectory(prefix, subdirectory.path);
|
||||
ZipEntry ze = new RelativeFile(prefix_subdir, file).getZipEntry(zdir);
|
||||
ZipEntry ze = new RelativeFile(prefix_subdir, file).getZipEntry(zfile);
|
||||
return new SymbolFileObject(this, file, ze);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SymbolArchive[" + zdir.getName() + "]";
|
||||
return "SymbolArchive[" + zfile.getName() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -47,6 +47,8 @@ import com.sun.tools.javac.file.JavacFileManager.Archive;
|
||||
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
|
||||
import com.sun.tools.javac.file.RelativePath.RelativeFile;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems.
|
||||
@ -56,20 +58,20 @@ import com.sun.tools.javac.util.List;
|
||||
*/
|
||||
public class ZipArchive implements Archive {
|
||||
|
||||
public ZipArchive(JavacFileManager fm, ZipFile zdir) throws IOException {
|
||||
this(fm, zdir, true);
|
||||
public ZipArchive(JavacFileManager fm, ZipFile zfile) throws IOException {
|
||||
this(fm, zfile, true);
|
||||
}
|
||||
|
||||
protected ZipArchive(JavacFileManager fm, ZipFile zdir, boolean initMap) throws IOException {
|
||||
protected ZipArchive(JavacFileManager fm, ZipFile zfile, boolean initMap) throws IOException {
|
||||
this.fileManager = fm;
|
||||
this.zdir = zdir;
|
||||
this.zfile = zfile;
|
||||
this.map = new HashMap<RelativeDirectory,List<String>>();
|
||||
if (initMap)
|
||||
initMap();
|
||||
}
|
||||
|
||||
protected void initMap() throws IOException {
|
||||
for (Enumeration<? extends ZipEntry> e = zdir.entries(); e.hasMoreElements(); ) {
|
||||
for (Enumeration<? extends ZipEntry> e = zfile.entries(); e.hasMoreElements(); ) {
|
||||
ZipEntry entry;
|
||||
try {
|
||||
entry = e.nextElement();
|
||||
@ -110,7 +112,7 @@ public class ZipArchive implements Archive {
|
||||
}
|
||||
|
||||
public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
|
||||
ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zdir);
|
||||
ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zfile);
|
||||
return new ZipFileObject(this, file, ze);
|
||||
}
|
||||
|
||||
@ -119,17 +121,39 @@ public class ZipArchive implements Archive {
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
zdir.close();
|
||||
zfile.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ZipArchive[" + zdir.getName() + "]";
|
||||
return "ZipArchive[" + zfile.getName() + "]";
|
||||
}
|
||||
|
||||
private File getAbsoluteFile() {
|
||||
File absFile = (absFileRef == null ? null : absFileRef.get());
|
||||
if (absFile == null) {
|
||||
absFile = new File(zfile.getName()).getAbsoluteFile();
|
||||
absFileRef = new SoftReference<File>(absFile);
|
||||
}
|
||||
return absFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* The file manager that created this archive.
|
||||
*/
|
||||
protected JavacFileManager fileManager;
|
||||
/**
|
||||
* The index for the contents of this archive.
|
||||
*/
|
||||
protected final Map<RelativeDirectory,List<String>> map;
|
||||
protected final ZipFile zdir;
|
||||
/**
|
||||
* The zip file for the archive.
|
||||
*/
|
||||
protected final ZipFile zfile;
|
||||
/**
|
||||
* A reference to the absolute filename for the zip file for the archive.
|
||||
*/
|
||||
protected Reference<File> absFileRef;
|
||||
|
||||
/**
|
||||
* A subclass of JavaFileObject representing zip entries.
|
||||
@ -148,18 +172,18 @@ public class ZipArchive implements Archive {
|
||||
}
|
||||
|
||||
public URI toUri() {
|
||||
File zipFile = new File(zarch.zdir.getName());
|
||||
File zipFile = new File(zarch.zfile.getName());
|
||||
return createJarUri(zipFile, entry.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return zarch.zdir.getName() + "(" + entry.getName() + ")";
|
||||
return zarch.zfile.getName() + "(" + entry.getName() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortName() {
|
||||
return new File(zarch.zdir.getName()).getName() + "(" + entry + ")";
|
||||
return new File(zarch.zfile.getName()).getName() + "(" + entry + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -169,7 +193,7 @@ public class ZipArchive implements Archive {
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream() throws IOException {
|
||||
return zarch.zdir.getInputStream(entry);
|
||||
return zarch.zfile.getInputStream(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -181,7 +205,7 @@ public class ZipArchive implements Archive {
|
||||
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
|
||||
CharBuffer cb = fileManager.getCachedContent(this);
|
||||
if (cb == null) {
|
||||
InputStream in = zarch.zdir.getInputStream(entry);
|
||||
InputStream in = zarch.zfile.getInputStream(entry);
|
||||
try {
|
||||
ByteBuffer bb = fileManager.makeByteBuffer(in);
|
||||
JavaFileObject prev = fileManager.log.useSource(this);
|
||||
@ -237,18 +261,27 @@ public class ZipArchive implements Archive {
|
||||
return name.equals(cn + k.extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two file objects are equal.
|
||||
* Two ZipFileObjects are equal if the absolute paths of the underlying
|
||||
* zip files are equal and if the paths within those zip files are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof ZipFileObject)) {
|
||||
if (this == other)
|
||||
return true;
|
||||
|
||||
if (!(other instanceof ZipFileObject))
|
||||
return false;
|
||||
}
|
||||
|
||||
ZipFileObject o = (ZipFileObject) other;
|
||||
return zarch.zdir.equals(o.zarch.zdir) || name.equals(o.name);
|
||||
return zarch.getAbsoluteFile().equals(o.zarch.getAbsoluteFile())
|
||||
&& name.equals(o.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return zarch.zdir.hashCode() + name.hashCode();
|
||||
return zarch.getAbsoluteFile().hashCode() + name.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -89,6 +90,7 @@ public class ZipFileIndex {
|
||||
|
||||
// ZipFileIndex data entries
|
||||
private File zipFile;
|
||||
private Reference<File> absFileRef;
|
||||
private long zipFileLastModified = NOT_MODIFIED;
|
||||
private RandomAccessFile zipRandomFile;
|
||||
private Entry[] entries;
|
||||
@ -1215,6 +1217,15 @@ public class ZipFileIndex {
|
||||
return zipFile;
|
||||
}
|
||||
|
||||
File getAbsoluteFile() {
|
||||
File absFile = (absFileRef == null ? null : absFileRef.get());
|
||||
if (absFile == null) {
|
||||
absFile = zipFile.getAbsoluteFile();
|
||||
absFileRef = new SoftReference<File>(absFile);
|
||||
}
|
||||
return absFile;
|
||||
}
|
||||
|
||||
private RelativeDirectory getRelativeDirectory(String path) {
|
||||
RelativeDirectory rd;
|
||||
SoftReference<RelativeDirectory> ref = relativeDirectoryCache.get(path);
|
||||
|
||||
@ -219,17 +219,27 @@ public class ZipFileIndexArchive implements Archive {
|
||||
return name.equals(cn + k.extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two file objects are equal.
|
||||
* Two ZipFileIndexFileObjects are equal if the absolute paths of the underlying
|
||||
* zip files are equal and if the paths within those zip files are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other)
|
||||
return true;
|
||||
|
||||
if (!(other instanceof ZipFileIndexFileObject))
|
||||
return false;
|
||||
|
||||
ZipFileIndexFileObject o = (ZipFileIndexFileObject) other;
|
||||
return entry.equals(o.entry);
|
||||
return zfIndex.getAbsoluteFile().equals(o.zfIndex.getAbsoluteFile())
|
||||
&& name.equals(o.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return zipName.hashCode() + (name.hashCode() << 10);
|
||||
return zfIndex.getAbsoluteFile().hashCode() + name.hashCode();
|
||||
}
|
||||
|
||||
private String getPrefixedEntryName() {
|
||||
|
||||
@ -29,6 +29,7 @@ import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -191,6 +192,16 @@ public class ClassReader implements Completer {
|
||||
*/
|
||||
boolean debugJSR308;
|
||||
|
||||
/** A table to hold the constant pool indices for method parameter
|
||||
* names, as given in LocalVariableTable attributes.
|
||||
*/
|
||||
int[] parameterNameIndices;
|
||||
|
||||
/**
|
||||
* Whether or not any parameter names have been found.
|
||||
*/
|
||||
boolean haveParameterNameIndices;
|
||||
|
||||
/** Get the ClassReader instance for this invocation. */
|
||||
public static ClassReader instance(Context context) {
|
||||
ClassReader instance = context.get(classReaderKey);
|
||||
@ -922,32 +933,33 @@ public class ClassReader implements Completer {
|
||||
void read(Symbol sym, int attrLen) {
|
||||
int newbp = bp + attrLen;
|
||||
if (saveParameterNames) {
|
||||
// pick up parameter names from the variable table
|
||||
List<Name> parameterNames = List.nil();
|
||||
int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
|
||||
int endParam = firstParam + Code.width(sym.type.getParameterTypes());
|
||||
// Pick up parameter names from the variable table.
|
||||
// Parameter names are not explicitly identified as such,
|
||||
// but all parameter name entries in the LocalVariableTable
|
||||
// have a start_pc of 0. Therefore, we record the name
|
||||
// indicies of all slots with a start_pc of zero in the
|
||||
// parameterNameIndicies array.
|
||||
// Note that this implicitly honors the JVMS spec that
|
||||
// there may be more than one LocalVariableTable, and that
|
||||
// there is no specified ordering for the entries.
|
||||
int numEntries = nextChar();
|
||||
for (int i=0; i<numEntries; i++) {
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
int start_pc = nextChar();
|
||||
int length = nextChar();
|
||||
int nameIndex = nextChar();
|
||||
int sigIndex = nextChar();
|
||||
int register = nextChar();
|
||||
if (start_pc == 0 &&
|
||||
firstParam <= register &&
|
||||
register < endParam) {
|
||||
int index = firstParam;
|
||||
for (Type t : sym.type.getParameterTypes()) {
|
||||
if (index == register) {
|
||||
parameterNames = parameterNames.prepend(readName(nameIndex));
|
||||
break;
|
||||
}
|
||||
index += Code.width(t);
|
||||
if (start_pc == 0) {
|
||||
// ensure array large enough
|
||||
if (register >= parameterNameIndices.length) {
|
||||
int newSize = Math.max(register, parameterNameIndices.length + 8);
|
||||
parameterNameIndices =
|
||||
Arrays.copyOf(parameterNameIndices, newSize);
|
||||
}
|
||||
parameterNameIndices[register] = nameIndex;
|
||||
haveParameterNameIndices = true;
|
||||
}
|
||||
}
|
||||
parameterNames = parameterNames.reverse();
|
||||
((MethodSymbol)sym).savedParameterNames = parameterNames;
|
||||
}
|
||||
bp = newbp;
|
||||
}
|
||||
@ -1839,6 +1851,8 @@ public class ClassReader implements Completer {
|
||||
syms.methodClass);
|
||||
}
|
||||
MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);
|
||||
if (saveParameterNames)
|
||||
initParameterNames(m);
|
||||
Symbol prevOwner = currentOwner;
|
||||
currentOwner = m;
|
||||
try {
|
||||
@ -1846,9 +1860,90 @@ public class ClassReader implements Completer {
|
||||
} finally {
|
||||
currentOwner = prevOwner;
|
||||
}
|
||||
if (saveParameterNames)
|
||||
setParameterNames(m, type);
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the parameter names array.
|
||||
* Parameter names are currently inferred from the names in the
|
||||
* LocalVariableTable attributes of a Code attribute.
|
||||
* (Note: this means parameter names are currently not available for
|
||||
* methods without a Code attribute.)
|
||||
* This method initializes an array in which to store the name indexes
|
||||
* of parameter names found in LocalVariableTable attributes. It is
|
||||
* slightly supersized to allow for additional slots with a start_pc of 0.
|
||||
*/
|
||||
void initParameterNames(MethodSymbol sym) {
|
||||
// make allowance for synthetic parameters.
|
||||
final int excessSlots = 4;
|
||||
int expectedParameterSlots =
|
||||
Code.width(sym.type.getParameterTypes()) + excessSlots;
|
||||
if (parameterNameIndices == null
|
||||
|| parameterNameIndices.length < expectedParameterSlots) {
|
||||
parameterNameIndices = new int[expectedParameterSlots];
|
||||
} else
|
||||
Arrays.fill(parameterNameIndices, 0);
|
||||
haveParameterNameIndices = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parameter names for a symbol from the name index in the
|
||||
* parameterNameIndicies array. The type of the symbol may have changed
|
||||
* while reading the method attributes (see the Signature attribute).
|
||||
* This may be because of generic information or because anonymous
|
||||
* synthetic parameters were added. The original type (as read from
|
||||
* the method descriptor) is used to help guess the existence of
|
||||
* anonymous synthetic parameters.
|
||||
* On completion, sym.savedParameter names will either be null (if
|
||||
* no parameter names were found in the class file) or will be set to a
|
||||
* list of names, one per entry in sym.type.getParameterTypes, with
|
||||
* any missing names represented by the empty name.
|
||||
*/
|
||||
void setParameterNames(MethodSymbol sym, Type jvmType) {
|
||||
// if no names were found in the class file, there's nothing more to do
|
||||
if (!haveParameterNameIndices)
|
||||
return;
|
||||
|
||||
int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
|
||||
// the code in readMethod may have skipped the first parameter when
|
||||
// setting up the MethodType. If so, we make a corresponding allowance
|
||||
// here for the position of the first parameter. Note that this
|
||||
// assumes the skipped parameter has a width of 1 -- i.e. it is not
|
||||
// a double width type (long or double.)
|
||||
if (sym.name == names.init && currentOwner.hasOuterInstance()) {
|
||||
// Sometimes anonymous classes don't have an outer
|
||||
// instance, however, there is no reliable way to tell so
|
||||
// we never strip this$n
|
||||
if (!currentOwner.name.isEmpty())
|
||||
firstParam += 1;
|
||||
}
|
||||
|
||||
if (sym.type != jvmType) {
|
||||
// reading the method attributes has caused the symbol's type to
|
||||
// be changed. (i.e. the Signature attribute.) This may happen if
|
||||
// there are hidden (synthetic) parameters in the descriptor, but
|
||||
// not in the Signature. The position of these hidden parameters
|
||||
// is unspecified; for now, assume they are at the beginning, and
|
||||
// so skip over them. The primary case for this is two hidden
|
||||
// parameters passed into Enum constructors.
|
||||
int skip = Code.width(jvmType.getParameterTypes())
|
||||
- Code.width(sym.type.getParameterTypes());
|
||||
firstParam += skip;
|
||||
}
|
||||
List<Name> paramNames = List.nil();
|
||||
int index = firstParam;
|
||||
for (Type t: sym.type.getParameterTypes()) {
|
||||
int nameIdx = (index < parameterNameIndices.length
|
||||
? parameterNameIndices[index] : 0);
|
||||
Name name = nameIdx == 0 ? names.empty : readName(nameIdx);
|
||||
paramNames = paramNames.prepend(name);
|
||||
index += Code.width(t);
|
||||
}
|
||||
sym.savedParameterNames = paramNames.reverse();
|
||||
}
|
||||
|
||||
/** Skip a field or method
|
||||
*/
|
||||
void skipMember() {
|
||||
@ -2632,10 +2727,20 @@ public class ClassReader implements Completer {
|
||||
return true; // fail-safe mode
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two file objects are equal.
|
||||
* SourceFileObjects are just placeholder objects for the value of a
|
||||
* SourceFile attribute, and do not directly represent specific files.
|
||||
* Two SourceFileObjects are equal if their names are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other)
|
||||
return true;
|
||||
|
||||
if (!(other instanceof SourceFileObject))
|
||||
return false;
|
||||
|
||||
SourceFileObject o = (SourceFileObject) other;
|
||||
return name.equals(o.name);
|
||||
}
|
||||
|
||||
@ -876,7 +876,11 @@ public class Scanner implements Lexer {
|
||||
}
|
||||
scanChar();
|
||||
skipIllegalUnderscores();
|
||||
scanNumber(2);
|
||||
if (digit(2) < 0) {
|
||||
lexError("invalid.binary.number");
|
||||
} else {
|
||||
scanNumber(2);
|
||||
}
|
||||
} else {
|
||||
putChar('0');
|
||||
if (ch == '_') {
|
||||
|
||||
@ -252,6 +252,8 @@ compiler.err.intf.meth.cant.have.body=\
|
||||
interface methods cannot have body
|
||||
compiler.err.invalid.annotation.member.type=\
|
||||
invalid type for annotation member
|
||||
compiler.err.invalid.binary.number=\
|
||||
binary numbers must contain at least one binary digit
|
||||
compiler.err.invalid.hex.number=\
|
||||
hexadecimal numbers must contain at least one hexadecimal digit
|
||||
compiler.err.invalid.meth.decl.ret.type.req=\
|
||||
|
||||
@ -179,10 +179,10 @@ public class ClassWriter extends BasicWriter {
|
||||
// The signature parser cannot disambiguate between a
|
||||
// FieldType and a ClassSignatureType that only contains a superclass type.
|
||||
if (t instanceof Type.ClassSigType)
|
||||
print(t);
|
||||
print(getJavaName(t.toString()));
|
||||
else {
|
||||
print(" extends ");
|
||||
print(t);
|
||||
print(getJavaName(t.toString()));
|
||||
}
|
||||
} catch (ConstantPoolException e) {
|
||||
print(report(e));
|
||||
@ -310,7 +310,7 @@ public class ClassWriter extends BasicWriter {
|
||||
|
||||
writeModifiers(flags.getMethodModifiers());
|
||||
if (methodType != null) {
|
||||
writeListIfNotEmpty("<", methodType.typeArgTypes, "> ");
|
||||
writeListIfNotEmpty("<", methodType.typeParamTypes, "> ");
|
||||
}
|
||||
if (getName(m).equals("<init>")) {
|
||||
print(getJavaName(classFile));
|
||||
|
||||
@ -125,7 +125,7 @@ public class LocalVariableTypeTableWriter extends InstructionDetailWriter {
|
||||
print(" // ");
|
||||
Descriptor d = new Signature(entry.signature_index);
|
||||
try {
|
||||
print(d.getFieldType(constant_pool));
|
||||
print(d.getFieldType(constant_pool).toString().replace("/", "."));
|
||||
} catch (InvalidDescriptor e) {
|
||||
print(report(e));
|
||||
} catch (ConstantPoolException e) {
|
||||
|
||||
@ -77,9 +77,25 @@ public interface Elements {
|
||||
* Returns the text of the documentation ("Javadoc")
|
||||
* comment of an element.
|
||||
*
|
||||
* <p> A documentation comment of an element is a comment that
|
||||
* begins with "{@code /**}" , ends with a separate
|
||||
* "<code>*/</code>", and immediately precedes the element,
|
||||
* ignoring white space. Therefore, a documentation comment
|
||||
* contains at least three"{@code *}" characters. The text
|
||||
* returned for the documentation comment is a processed form of
|
||||
* the comment as it appears in source code. The leading "{@code
|
||||
* /**}" and trailing "<code>*/</code>" are removed. For lines
|
||||
* of the comment starting after the initial "{@code /**}",
|
||||
* leading white space characters are discarded as are any
|
||||
* consecutive "{@code *}" characters appearing after the white
|
||||
* space or starting the line. The processed lines are then
|
||||
* concatenated together (including line terminators) and
|
||||
* returned.
|
||||
*
|
||||
* @param e the element being examined
|
||||
* @return the documentation comment of the element, or {@code null}
|
||||
* if there is none
|
||||
* @jls3 3.6 White Space
|
||||
*/
|
||||
String getDocComment(Element e);
|
||||
|
||||
|
||||
485
langtools/test/tools/javac/6889255/T6889255.java
Normal file
485
langtools/test/tools/javac/6889255/T6889255.java
Normal file
@ -0,0 +1,485 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6889255
|
||||
* @summary ClassReader does not read parameter names correctly
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.tools.StandardLocation;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
import com.sun.tools.javac.code.Scope;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Type.ClassType;
|
||||
import com.sun.tools.javac.code.TypeTags;
|
||||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.jvm.ClassReader;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.Names;
|
||||
|
||||
public class T6889255 {
|
||||
boolean testInterfaces = true;
|
||||
boolean testSyntheticMethods = true;
|
||||
|
||||
// The following enums control the generation of the test methods to be compiled.
|
||||
enum GenericKind {
|
||||
NOT_GENERIC,
|
||||
GENERIC
|
||||
};
|
||||
|
||||
enum ClassKind {
|
||||
CLASS("Clss"),
|
||||
INTERFACE("Intf"),
|
||||
ENUM("Enum");
|
||||
final String base;
|
||||
ClassKind(String base) { this.base = base; }
|
||||
};
|
||||
|
||||
enum NestedKind {
|
||||
/** Declare methods inside the outermost container. */
|
||||
NONE,
|
||||
/** Declare methods inside a container with a 'static' modifier. */
|
||||
NESTED,
|
||||
/** Declare methods inside a container without a 'static' modifier. */
|
||||
INNER,
|
||||
/** Declare methods inside a local class in an initializer. */
|
||||
INIT_LOCAL,
|
||||
/** Declare methods inside an anonymous class in an initializer. */
|
||||
INIT_ANON,
|
||||
/** Declare methods inside a local class in a method. */
|
||||
METHOD_LOCAL,
|
||||
/** Declare methods inside an anonymous class in a method. */
|
||||
METHOD_ANON
|
||||
};
|
||||
|
||||
enum MethodKind {
|
||||
ABSTRACT,
|
||||
CONSTRUCTOR,
|
||||
METHOD,
|
||||
STATIC_METHOD,
|
||||
BRIDGE_METHOD
|
||||
};
|
||||
|
||||
enum FinalKind {
|
||||
/** Method body does not reference external final variables. */
|
||||
NO_FINAL,
|
||||
/** Method body references external final variables. */
|
||||
USE_FINAL
|
||||
};
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new T6889255().run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
genTest();
|
||||
|
||||
test("no-args", false);
|
||||
test("g", true, "-g");
|
||||
|
||||
if (errors > 0)
|
||||
throw new Exception(errors + " errors found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a file containing lots of method definitions to be tested.
|
||||
* There are 3 sets of nested loops that generate the methods.
|
||||
* 1. The outermost set declares [generic] (class | interface | enum)
|
||||
* 2. The middle set declares [(nested | inner | anon | local)] class
|
||||
* 3. The innermost set declares
|
||||
* [generic] (constructor|method|static-method|bridge-method) [using final variables in outer scope]
|
||||
* Invalid combinations are filtered out.
|
||||
*/
|
||||
void genTest() throws Exception {
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter("Test.java"));
|
||||
|
||||
// This interface is used to force bridge methods to be generated, by
|
||||
// implementing its methods with subtypes of Object
|
||||
out.write("interface Base {\n");
|
||||
out.write(" Object base_m1(int i1);\n");
|
||||
out.write(" Object base_m2(int i1);\n");
|
||||
out.write("}\n");
|
||||
|
||||
int outerNum = 0;
|
||||
// Outermost set of loops, to generate a top level container
|
||||
for (GenericKind outerGenericKind: GenericKind.values()) {
|
||||
for (ClassKind outerClassKind: ClassKind.values()) {
|
||||
if (outerGenericKind == GenericKind.GENERIC && outerClassKind == ClassKind.ENUM)
|
||||
continue;
|
||||
String outerClassName = outerClassKind.base + (outerNum++);
|
||||
String outerTypeArg = outerClassKind.toString().charAt(0) + "T";
|
||||
if (outerClassKind == ClassKind.CLASS)
|
||||
out.write("abstract ");
|
||||
out.write(outerClassKind.toString().toLowerCase() + " " + outerClassName);
|
||||
if (outerGenericKind == GenericKind.GENERIC)
|
||||
out.write("<" + outerTypeArg + ">");
|
||||
if (outerClassKind == ClassKind.INTERFACE)
|
||||
out.write(" extends Base");
|
||||
else
|
||||
out.write(" implements Base");
|
||||
out.write(" {\n");
|
||||
if (outerClassKind == ClassKind.ENUM) {
|
||||
out.write(" E1(0,0,0), E2(0,0,0), E3(0,0,0);\n");
|
||||
out.write(" " + outerClassName + "(int i1, int i2, int i3) { }\n");
|
||||
}
|
||||
// Middle set of loops, to generate an optional nested container
|
||||
int nestedNum = 0;
|
||||
int methodNum = 0;
|
||||
for (GenericKind nestedGenericKind: GenericKind.values()) {
|
||||
nextNestedKind:
|
||||
for (NestedKind nestedKind: NestedKind.values()) {
|
||||
// if the nested kind is none, there is no point iterating over all
|
||||
// nested generic kinds, so arbitarily limit it to just one kind
|
||||
if (nestedKind == NestedKind.NONE && nestedGenericKind != GenericKind.NOT_GENERIC)
|
||||
continue;
|
||||
if ((nestedKind == NestedKind.METHOD_ANON || nestedKind == NestedKind.INIT_ANON)
|
||||
&& nestedGenericKind == GenericKind.GENERIC)
|
||||
continue;
|
||||
String indent = " ";
|
||||
boolean haveFinal = false;
|
||||
switch (nestedKind) {
|
||||
case METHOD_ANON: case METHOD_LOCAL:
|
||||
if (outerClassKind == ClassKind.INTERFACE)
|
||||
continue nextNestedKind;
|
||||
out.write(indent + "void m" + + (nestedNum++) + "() {\n");
|
||||
indent += " ";
|
||||
out.write(indent + "final int fi1 = 0;\n");
|
||||
haveFinal = true;
|
||||
break;
|
||||
case INIT_ANON: case INIT_LOCAL:
|
||||
if (outerClassKind == ClassKind.INTERFACE)
|
||||
continue nextNestedKind;
|
||||
out.write(indent + "{\n");
|
||||
indent += " ";
|
||||
break;
|
||||
}
|
||||
for (ClassKind nestedClassKind: ClassKind.values()) {
|
||||
if ((nestedGenericKind == GenericKind.GENERIC)
|
||||
&& (nestedClassKind == ClassKind.ENUM))
|
||||
continue;
|
||||
if ((nestedKind == NestedKind.METHOD_ANON || nestedKind == NestedKind.METHOD_LOCAL
|
||||
|| nestedKind == NestedKind.INIT_ANON || nestedKind == NestedKind.INIT_LOCAL)
|
||||
&& nestedClassKind != ClassKind.CLASS)
|
||||
continue;
|
||||
// if the nested kind is none, there is no point iterating over all
|
||||
// nested class kinds, so arbitarily limit it to just one kind
|
||||
if (nestedKind == NestedKind.NONE && nestedClassKind != ClassKind.CLASS)
|
||||
continue;
|
||||
|
||||
ClassKind methodClassKind;
|
||||
String methodClassName;
|
||||
boolean allowAbstractMethods;
|
||||
boolean allowStaticMethods;
|
||||
switch (nestedKind) {
|
||||
case NONE:
|
||||
methodClassKind = outerClassKind;
|
||||
methodClassName = outerClassName;
|
||||
allowAbstractMethods = (outerClassKind == ClassKind.CLASS);
|
||||
allowStaticMethods = (outerClassKind != ClassKind.INTERFACE);
|
||||
break;
|
||||
case METHOD_ANON:
|
||||
case INIT_ANON:
|
||||
out.write(indent + "new Base() {\n");
|
||||
indent += " ";
|
||||
methodClassKind = ClassKind.CLASS;
|
||||
methodClassName = null;
|
||||
allowAbstractMethods = false;
|
||||
allowStaticMethods = false;
|
||||
break;
|
||||
default: { // INNER, NESTED, LOCAL
|
||||
String nestedClassName = "N" + nestedClassKind.base + (nestedNum++);
|
||||
String nestedTypeArg = nestedClassKind.toString().charAt(0) + "T";
|
||||
out.write(indent);
|
||||
if (nestedKind == NestedKind.NESTED)
|
||||
out.write("static ");
|
||||
if (nestedClassKind == ClassKind.CLASS)
|
||||
out.write("abstract ");
|
||||
out.write(nestedClassKind.toString().toLowerCase() + " " + nestedClassName);
|
||||
if (nestedGenericKind == GenericKind.GENERIC)
|
||||
out.write("<" + nestedTypeArg + ">");
|
||||
if (nestedClassKind == ClassKind.INTERFACE)
|
||||
out.write(" extends Base ");
|
||||
else
|
||||
out.write(" implements Base ");
|
||||
out.write(" {\n");
|
||||
indent += " ";
|
||||
if (nestedClassKind == ClassKind.ENUM) {
|
||||
out.write(indent + "E1(0,0,0), E2(0,0,0), E3(0,0,0);\n");
|
||||
out.write(indent + nestedClassName + "(int i1, int i2, int i3) { }\n");
|
||||
}
|
||||
methodClassKind = nestedClassKind;
|
||||
methodClassName = nestedClassName;
|
||||
allowAbstractMethods = (nestedClassKind == ClassKind.CLASS);
|
||||
allowStaticMethods = (nestedKind == NestedKind.NESTED && nestedClassKind != ClassKind.INTERFACE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Innermost loops, to generate methods
|
||||
for (GenericKind methodGenericKind: GenericKind.values()) {
|
||||
for (FinalKind finalKind: FinalKind.values()) {
|
||||
for (MethodKind methodKind: MethodKind.values()) {
|
||||
// out.write("// " + outerGenericKind
|
||||
// + " " + outerClassKind
|
||||
// + " " + nestedKind
|
||||
// + " " + nestedGenericKind
|
||||
// + " " + nestedClassKind
|
||||
// + " " + methodGenericKind
|
||||
// + " " + finalKind
|
||||
// + " " + methodKind
|
||||
// + "\n");
|
||||
switch (methodKind) {
|
||||
case CONSTRUCTOR:
|
||||
if (nestedKind == NestedKind.METHOD_ANON || nestedKind == NestedKind.INIT_ANON)
|
||||
break;
|
||||
if (methodClassKind != ClassKind.CLASS)
|
||||
break;
|
||||
if (finalKind == FinalKind.USE_FINAL && !haveFinal)
|
||||
break;
|
||||
out.write(indent);
|
||||
if (methodGenericKind == GenericKind.GENERIC) {
|
||||
out.write("<CT> " + methodClassName + "(CT c1, CT c2");
|
||||
} else {
|
||||
out.write(methodClassName + "(boolean b1, char c2");
|
||||
}
|
||||
if (finalKind == FinalKind.USE_FINAL) {
|
||||
// add a dummy parameter to avoid duplicate declaration
|
||||
out.write(", int i3) { int i = fi1; }\n");
|
||||
} else
|
||||
out.write(") { }\n");
|
||||
break;
|
||||
case ABSTRACT:
|
||||
if (!allowAbstractMethods)
|
||||
continue;
|
||||
// fallthrough
|
||||
case METHOD:
|
||||
if (finalKind == FinalKind.USE_FINAL && !haveFinal)
|
||||
break;
|
||||
out.write(indent);
|
||||
if (methodKind == MethodKind.ABSTRACT)
|
||||
out.write("abstract ");
|
||||
if (methodGenericKind == GenericKind.GENERIC)
|
||||
out.write("<MT> ");
|
||||
out.write("void m" + (methodNum++) + "(int i1, long l2, float f3)");
|
||||
if (methodKind == MethodKind.ABSTRACT || methodClassKind == ClassKind.INTERFACE)
|
||||
out.write(";\n");
|
||||
else {
|
||||
out.write(" {");
|
||||
if (finalKind == FinalKind.USE_FINAL)
|
||||
out.write(" int i = fi1;");
|
||||
out.write(" }\n");
|
||||
}
|
||||
break;
|
||||
case BRIDGE_METHOD:
|
||||
if (methodGenericKind == GenericKind.GENERIC)
|
||||
break;
|
||||
out.write(indent);
|
||||
// methods Base.base_m1 and Base.base_m2 are declared for the
|
||||
// benefit of bridge methods. They need to be implemented
|
||||
// whether or not a final variable is used.
|
||||
String methodName = (finalKind == FinalKind.NO_FINAL ? "base_m1" : "base_m2");
|
||||
out.write("public String " + methodName + "(int i1)");
|
||||
if (methodClassKind == ClassKind.INTERFACE)
|
||||
out.write(";\n");
|
||||
else {
|
||||
out.write(" {");
|
||||
if (finalKind == FinalKind.USE_FINAL && haveFinal)
|
||||
out.write(" int i = fi1;");
|
||||
out.write(" return null; }\n");
|
||||
}
|
||||
break;
|
||||
case STATIC_METHOD:
|
||||
if (!allowStaticMethods)
|
||||
break;
|
||||
if (finalKind == FinalKind.USE_FINAL && !haveFinal)
|
||||
break;
|
||||
out.write(indent + "static ");
|
||||
if (methodGenericKind == GenericKind.GENERIC)
|
||||
out.write("<MT> ");
|
||||
out.write("void m" + (methodNum++) + "(int i1, long l2, float f3) {");
|
||||
if (finalKind == FinalKind.USE_FINAL)
|
||||
out.write(" int i = fi1;");
|
||||
out.write(" }\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nestedKind != NestedKind.NONE) {
|
||||
indent = indent.substring(0, indent.length() - 4);
|
||||
out.write(indent + "};\n");
|
||||
}
|
||||
}
|
||||
switch (nestedKind) {
|
||||
case METHOD_ANON: case METHOD_LOCAL:
|
||||
case INIT_ANON: case INIT_LOCAL:
|
||||
indent = indent.substring(0, indent.length() - 4);
|
||||
out.write(indent + "}\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
out.write("}\n\n");
|
||||
}
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
|
||||
|
||||
void test(String testName, boolean expectNames, String... opts) throws Exception {
|
||||
System.err.println("Test " + testName
|
||||
+ ": expectNames:" + expectNames
|
||||
+ " javacOpts:" + Arrays.asList(opts));
|
||||
|
||||
File outDir = new File(testName);
|
||||
outDir.mkdirs();
|
||||
compile(outDir, opts);
|
||||
|
||||
Context ctx = new Context();
|
||||
JavacFileManager fm = new JavacFileManager(ctx, true, null);
|
||||
fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(outDir));
|
||||
ClassReader cr = ClassReader.instance(ctx);
|
||||
cr.saveParameterNames = true;
|
||||
Names names = Names.instance(ctx);
|
||||
|
||||
Set<String> classes = getTopLevelClasses(outDir);
|
||||
Deque<String> work = new LinkedList<String>(classes);
|
||||
String classname;
|
||||
while ((classname = work.poll()) != null) {
|
||||
System.err.println("Checking class " + classname);
|
||||
ClassSymbol sym = cr.enterClass(names.table.fromString(classname));
|
||||
sym.complete();
|
||||
|
||||
if ((sym.flags() & Flags.INTERFACE) != 0 && !testInterfaces)
|
||||
continue;
|
||||
|
||||
for (Scope.Entry e = sym.members_field.elems; e != null; e = e.sibling) {
|
||||
System.err.println("Checking member " + e.sym);
|
||||
switch (e.sym.kind) {
|
||||
case Kinds.TYP: {
|
||||
String name = e.sym.flatName().toString();
|
||||
if (!classes.contains(name)) {
|
||||
classes.add(name);
|
||||
work.add(name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Kinds.MTH:
|
||||
verify((MethodSymbol) e.sym, expectNames);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void verify(MethodSymbol m, boolean expectNames) {
|
||||
if ((m.flags() & Flags.SYNTHETIC) != 0 && !testSyntheticMethods)
|
||||
return;
|
||||
|
||||
//System.err.println("verify: " + m.params());
|
||||
int i = 1;
|
||||
for (VarSymbol v: m.params()) {
|
||||
String expectName;
|
||||
if (expectNames)
|
||||
expectName = getExpectedName(v, i);
|
||||
else
|
||||
expectName = "arg" + (i - 1);
|
||||
checkEqual(expectName, v.name.toString());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
String getExpectedName(VarSymbol v, int i) {
|
||||
// special cases:
|
||||
// synthetic method
|
||||
if (((v.owner.owner.flags() & Flags.ENUM) != 0)
|
||||
&& v.owner.name.toString().equals("valueOf"))
|
||||
return "name";
|
||||
// interfaces don't have saved names
|
||||
// -- no Code attribute for the LocalVariableTable attribute
|
||||
if ((v.owner.owner.flags() & Flags.INTERFACE) != 0)
|
||||
return "arg" + (i - 1);
|
||||
// abstract methods don't have saved names
|
||||
// -- no Code attribute for the LocalVariableTable attribute
|
||||
if ((v.owner.flags() & Flags.ABSTRACT) != 0)
|
||||
return "arg" + (i - 1);
|
||||
// bridge methods use xN
|
||||
if ((v.owner.flags() & Flags.BRIDGE) != 0)
|
||||
return "x" + (i - 1);
|
||||
|
||||
// The rest of this method assumes the local conventions in the test program
|
||||
Type t = v.type;
|
||||
String s;
|
||||
if (t.tag == TypeTags.CLASS)
|
||||
s = ((ClassType) t).tsym.name.toString();
|
||||
else
|
||||
s = t.toString();
|
||||
return String.valueOf(Character.toLowerCase(s.charAt(0))) + i;
|
||||
}
|
||||
|
||||
void compile(File outDir, String... opts) throws Exception {
|
||||
//File testSrc = new File(System.getProperty("test.src"), ".");
|
||||
List<String> args = new ArrayList<String>();
|
||||
args.add("-d");
|
||||
args.add(outDir.getPath());
|
||||
args.addAll(Arrays.asList(opts));
|
||||
//args.add(new File(testSrc, "Test.java").getPath());
|
||||
args.add("Test.java");
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
|
||||
pw.close();
|
||||
if (rc != 0) {
|
||||
System.err.println(sw.toString());
|
||||
throw new Exception("compilation failed unexpectedly");
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> getTopLevelClasses(File outDir) {
|
||||
Set<String> classes = new HashSet<String>();
|
||||
for (String f: outDir.list()) {
|
||||
if (f.endsWith(".class") && !f.contains("$"))
|
||||
classes.add(f.replace(".class", ""));
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
void checkEqual(String expect, String found) {
|
||||
if (!expect.equals(found))
|
||||
error("mismatch: expected:" + expect + " found:" + found);
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
int errors;
|
||||
}
|
||||
@ -59,9 +59,9 @@ public class T6440528 extends ToolTester {
|
||||
}
|
||||
|
||||
private File getUnderlyingFile(Object o) throws Exception {
|
||||
Field f = o.getClass().getDeclaredField("f");
|
||||
f.setAccessible(true);
|
||||
return (File)f.get(o);
|
||||
Field file = o.getClass().getDeclaredField("file");
|
||||
file.setAccessible(true);
|
||||
return (File)file.get(o);
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
|
||||
249
langtools/test/tools/javac/api/T6838467.java
Normal file
249
langtools/test/tools/javac/api/T6838467.java
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6838467
|
||||
* @summary JSR199 FileObjects don't obey general contract of equals.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
import javax.tools.*;
|
||||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
|
||||
public class T6838467 {
|
||||
boolean fileSystemIsCaseSignificant = !new File("a").equals(new File("A"));
|
||||
|
||||
enum FileKind {
|
||||
DIR("dir"),
|
||||
ZIP("zip"),
|
||||
ZIPFILEINDEX("zip");
|
||||
FileKind(String path) {
|
||||
file = new File(path);
|
||||
}
|
||||
final File file;
|
||||
};
|
||||
|
||||
enum CompareKind {
|
||||
SAME {
|
||||
File other(File f) { return f; }
|
||||
},
|
||||
ABSOLUTE {
|
||||
File other(File f) { return f.getAbsoluteFile(); }
|
||||
},
|
||||
DIFFERENT {
|
||||
File other(File f) { return new File("not_" + f.getPath()); }
|
||||
},
|
||||
CASEEQUIV {
|
||||
File other(File f) { return new File(f.getPath().toUpperCase()); }
|
||||
};
|
||||
abstract File other(File f);
|
||||
};
|
||||
|
||||
String[] paths = { "p/A.java", "p/B.java", "p/C.java" };
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new T6838467().run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
// on Windows, verify file system is not case significant
|
||||
if (System.getProperty("os.name").toLowerCase().startsWith("windows")
|
||||
&& fileSystemIsCaseSignificant) {
|
||||
error("fileSystemIsCaseSignificant is set on Windows.");
|
||||
}
|
||||
|
||||
// create a set of directories and zip files to compare
|
||||
createTestDir(new File("dir"), paths);
|
||||
createTestDir(new File("not_dir"), paths);
|
||||
createTestZip(new File("zip"), paths);
|
||||
createTestZip(new File("not_zip"), paths);
|
||||
if (fileSystemIsCaseSignificant) {
|
||||
createTestDir(new File("DIR"), paths);
|
||||
createTestZip(new File("ZIP"), paths);
|
||||
}
|
||||
|
||||
// test the various sorts of file objects that can be obtained from
|
||||
// the file manager, and for various values that may or may not match.
|
||||
for (FileKind fk: FileKind.values()) {
|
||||
for (CompareKind ck: CompareKind.values()) {
|
||||
test(fk, ck);
|
||||
}
|
||||
}
|
||||
|
||||
// verify that the various different types of file object were all
|
||||
// tested
|
||||
Set<String> expectClasses = new HashSet<String>(Arrays.asList(
|
||||
"RegularFileObject", "ZipFileObject", "ZipFileIndexFileObject" ));
|
||||
if (!foundClasses.equals(expectClasses)) {
|
||||
error("expected fileobject classes not found\n"
|
||||
+ "expected: " + expectClasses + "\n"
|
||||
+ "found: " + foundClasses);
|
||||
}
|
||||
|
||||
if (errors > 0)
|
||||
throw new Exception(errors + " errors");
|
||||
}
|
||||
|
||||
void test(FileKind fk, CompareKind ck) throws IOException {
|
||||
File f1 = fk.file;
|
||||
JavaFileManager fm1 = createFileManager(fk, f1);
|
||||
|
||||
File f2 = ck.other(fk.file);
|
||||
JavaFileManager fm2 = createFileManager(fk, f2);
|
||||
|
||||
try {
|
||||
// If the directories or zip files match, we expect "n" matches in
|
||||
// the "n-squared" comparisons to come, where "n" is the number of
|
||||
// entries in the the directories or zip files.
|
||||
// If the directories or zip files don't themselves match,
|
||||
// we obviously don't expect any of their contents to match either.
|
||||
int expect = (f1.getAbsoluteFile().equals(f2.getAbsoluteFile()) ? paths.length : 0);
|
||||
|
||||
System.err.println("test " + (++count) + " " + fk + " " + ck + " " + f1 + " " + f2);
|
||||
test(fm1, fm2, expect);
|
||||
|
||||
} finally {
|
||||
fm1.close();
|
||||
fm2.close();
|
||||
}
|
||||
}
|
||||
|
||||
// For a pair of file managers that may or may not have similar entries
|
||||
// on the classpath, compare all files returned from one against all files
|
||||
// returned from the other. For each pair of files, verify that if they
|
||||
// are equal, the hashcode is equal as well, and finally verify that the
|
||||
// expected number of matches was found.
|
||||
void test(JavaFileManager fm1, JavaFileManager fm2, int expectEqualCount) throws IOException {
|
||||
boolean foundFiles1 = false;
|
||||
boolean foundFiles2 = false;
|
||||
int foundEqualCount = 0;
|
||||
Set<JavaFileObject.Kind> kinds = EnumSet.allOf(JavaFileObject.Kind.class);
|
||||
for (FileObject fo1: fm1.list(StandardLocation.CLASS_PATH, "p", kinds, false)) {
|
||||
foundFiles1 = true;
|
||||
foundClasses.add(fo1.getClass().getSimpleName());
|
||||
for (FileObject fo2: fm2.list(StandardLocation.CLASS_PATH, "p", kinds, false)) {
|
||||
foundFiles2 = true;
|
||||
foundClasses.add(fo1.getClass().getSimpleName());
|
||||
System.err.println("compare " + fo1 + " " + fo2);
|
||||
if (fo1.equals(fo2)) {
|
||||
foundEqualCount++;
|
||||
int hash1 = fo1.hashCode();
|
||||
int hash2 = fo2.hashCode();
|
||||
if (hash1 != hash2)
|
||||
error("hashCode error: " + fo1 + " [" + hash1 + "] "
|
||||
+ fo2 + " [" + hash2 + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundFiles1)
|
||||
error("no files found for file manager 1");
|
||||
if (!foundFiles2)
|
||||
error("no files found for file manager 2");
|
||||
// verify the expected number of matches were found
|
||||
if (foundEqualCount != expectEqualCount)
|
||||
error("expected matches not found: expected " + expectEqualCount + ", found " + foundEqualCount);
|
||||
}
|
||||
|
||||
// create a file manager to test a FileKind, with a given directory
|
||||
// or zip file placed on the classpath
|
||||
JavaFileManager createFileManager(FileKind fk, File classpath) throws IOException {
|
||||
StandardJavaFileManager fm = createFileManager(fk == FileKind.ZIP);
|
||||
fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(classpath));
|
||||
return fm;
|
||||
}
|
||||
|
||||
JavacFileManager createFileManager(boolean useJavaUtilZip) {
|
||||
// javac should really not be using system properties like this
|
||||
// -- it should really be using (hidden) options -- but until then
|
||||
// take care to leave system properties as we find them, so as not
|
||||
// to adversely affect other tests that might follow.
|
||||
String prev = System.getProperty("useJavaUtilZip");
|
||||
boolean resetProperties = false;
|
||||
try {
|
||||
if (useJavaUtilZip) {
|
||||
System.setProperty("useJavaUtilZip", "true");
|
||||
resetProperties = true;
|
||||
} else if (System.getProperty("useJavaUtilZip") != null) {
|
||||
System.getProperties().remove("useJavaUtilZip");
|
||||
resetProperties = true;
|
||||
}
|
||||
|
||||
Context c = new Context();
|
||||
return new JavacFileManager(c, false, null);
|
||||
} finally {
|
||||
if (resetProperties) {
|
||||
if (prev == null) {
|
||||
System.getProperties().remove("useJavaUtilZip");
|
||||
} else {
|
||||
System.setProperty("useJavaUtilZip", prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create a directory containing a given set of paths
|
||||
void createTestDir(File dir, String[] paths) throws IOException {
|
||||
for (String p: paths) {
|
||||
File file = new File(dir, p);
|
||||
file.getParentFile().mkdirs();
|
||||
FileWriter out = new FileWriter(file);
|
||||
try {
|
||||
out.write(p);
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create a sip file containing a given set of entries
|
||||
void createTestZip(File zip, String[] paths) throws IOException {
|
||||
if (zip.getParentFile() != null)
|
||||
zip.getParentFile().mkdirs();
|
||||
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip));
|
||||
try {
|
||||
for (String p: paths) {
|
||||
ZipEntry ze = new ZipEntry(p);
|
||||
zos.putNextEntry(ze);
|
||||
byte[] bytes = p.getBytes();
|
||||
zos.write(bytes, 0, bytes.length);
|
||||
zos.closeEntry();
|
||||
}
|
||||
} finally {
|
||||
zos.close();
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println("Error: " + msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int count;
|
||||
int errors;
|
||||
Set<String> foundClasses = new HashSet<String>();
|
||||
}
|
||||
|
||||
12
langtools/test/tools/javac/literals/T6891079.java
Normal file
12
langtools/test/tools/javac/literals/T6891079.java
Normal file
@ -0,0 +1,12 @@
|
||||
/* @test /nodynamiccopyright/
|
||||
* @bug 6891079
|
||||
* @summary Compiler allows invalid binary literals 0b and oBL
|
||||
* @compile/fail/ref=T6891079.out -XDrawDiagnostics T6891079.java
|
||||
*/
|
||||
|
||||
class Test {
|
||||
int bi = 0B;
|
||||
long bl = 0BL;
|
||||
int xi = 0X;
|
||||
long xl = 0XL;
|
||||
}
|
||||
7
langtools/test/tools/javac/literals/T6891079.out
Normal file
7
langtools/test/tools/javac/literals/T6891079.out
Normal file
@ -0,0 +1,7 @@
|
||||
T6891079.java:8:14: compiler.err.invalid.binary.number
|
||||
T6891079.java:9:15: compiler.err.invalid.binary.number
|
||||
T6891079.java:9:18: compiler.err.expected: token.identifier
|
||||
T6891079.java:10:14: compiler.err.invalid.hex.number
|
||||
T6891079.java:11:15: compiler.err.invalid.hex.number
|
||||
T6891079.java:11:18: compiler.err.expected: token.identifier
|
||||
6 errors
|
||||
511
langtools/test/tools/javap/classfile/6888367/T6888367.java
Normal file
511
langtools/test/tools/javap/classfile/6888367/T6888367.java
Normal file
@ -0,0 +1,511 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import com.sun.tools.classfile.Type.ArrayType;
|
||||
import com.sun.tools.classfile.Type.ClassSigType;
|
||||
import com.sun.tools.classfile.Type.ClassType;
|
||||
import com.sun.tools.classfile.Type.MethodType;
|
||||
import com.sun.tools.classfile.Type.SimpleType;
|
||||
import com.sun.tools.classfile.Type.TypeParamType;
|
||||
import com.sun.tools.classfile.Type.WildcardType;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6888367
|
||||
* @summary classfile library parses signature attributes incorrectly
|
||||
*/
|
||||
|
||||
/*
|
||||
* This test is a pretty detailed test both of javac signature generation and classfile
|
||||
* signature parsing. The first part of the test tests all the examples given in the
|
||||
* second part of the test. Each example comes with one or two annotations, @Desc, @Sig,
|
||||
* for the descriptor and signature of the annotated declaration. Annotations are
|
||||
* provided whenever the annotated item is expected to have a corresponding value.
|
||||
* Each annotation has two argument values. The first arg is the expected value of the
|
||||
* descriptor/signature as found in the class file. This value is mostly for documentation
|
||||
* purposes in reading the test. The second value is the rendering of the descriptor or
|
||||
* signature using a custom Type visitor that explicitly includes an indication of the
|
||||
* Type classes being used to represent the descriptor/signature. Thus we test
|
||||
* that the descriptor/signature is being parsed into the expected type tree structure.
|
||||
*/
|
||||
public class T6888367 {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new T6888367().run();
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
ClassFile cf = getClassFile("Test");
|
||||
|
||||
testFields(cf);
|
||||
testMethods(cf);
|
||||
testInnerClasses(cf); // recursive
|
||||
|
||||
if (errors > 0)
|
||||
throw new Exception(errors + " errors found");
|
||||
}
|
||||
|
||||
void testFields(ClassFile cf) throws Exception {
|
||||
String cn = cf.getName();
|
||||
ConstantPool cp = cf.constant_pool;
|
||||
for (Field f: cf.fields) {
|
||||
test("field " + cn + "." + f.getName(cp), f.descriptor, f.attributes, cp);
|
||||
}
|
||||
}
|
||||
|
||||
void testMethods(ClassFile cf) throws Exception {
|
||||
String cn = cf.getName();
|
||||
ConstantPool cp = cf.constant_pool;
|
||||
for (Method m: cf.methods) {
|
||||
test("method " + cn + "." + m.getName(cp), m.descriptor, m.attributes, cp);
|
||||
}
|
||||
}
|
||||
|
||||
void testInnerClasses(ClassFile cf) throws Exception {
|
||||
ConstantPool cp = cf.constant_pool;
|
||||
InnerClasses_attribute ic =
|
||||
(InnerClasses_attribute) cf.attributes.get(Attribute.InnerClasses);
|
||||
for (InnerClasses_attribute.Info info: ic.classes) {
|
||||
String outerClassName = cp.getClassInfo(info.outer_class_info_index).getName();
|
||||
if (!outerClassName.equals(cf.getName())) {
|
||||
continue;
|
||||
}
|
||||
String innerClassName = cp.getClassInfo(info.inner_class_info_index).getName();
|
||||
ClassFile icf = getClassFile(innerClassName);
|
||||
test("class " + innerClassName, null, icf.attributes, icf.constant_pool);
|
||||
testInnerClasses(icf);
|
||||
}
|
||||
}
|
||||
|
||||
void test(String name, Descriptor desc, Attributes attrs, ConstantPool cp)
|
||||
throws Exception {
|
||||
AnnotValues d = getDescValue(attrs, cp);
|
||||
AnnotValues s = getSigValue(attrs, cp);
|
||||
if (d == null && s == null) // not a test field or method if no @Desc or @Sig given
|
||||
return;
|
||||
|
||||
System.err.println(name);
|
||||
|
||||
if (desc != null) {
|
||||
System.err.println(" descriptor: " + desc.getValue(cp));
|
||||
checkEqual(d.raw, desc.getValue(cp));
|
||||
Type dt = new Signature(desc.index).getType(cp);
|
||||
checkEqual(d.type, tp.print(dt));
|
||||
}
|
||||
|
||||
Signature_attribute sa = (Signature_attribute) attrs.get(Attribute.Signature);
|
||||
if (sa != null)
|
||||
System.err.println(" signature: " + sa.getSignature(cp));
|
||||
|
||||
if (s != null || sa != null) {
|
||||
if (s != null && sa != null) {
|
||||
checkEqual(s.raw, sa.getSignature(cp));
|
||||
Type st = new Signature(sa.signature_index).getType(cp);
|
||||
checkEqual(s.type, tp.print(st));
|
||||
} else if (s != null)
|
||||
error("@Sig annotation found but not Signature attribute");
|
||||
else
|
||||
error("Signature attribute found but no @Sig annotation");
|
||||
}
|
||||
|
||||
System.err.println();
|
||||
}
|
||||
|
||||
|
||||
ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
|
||||
URL url = getClass().getResource(name + ".class");
|
||||
InputStream in = url.openStream();
|
||||
try {
|
||||
return ClassFile.read(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
AnnotValues getDescValue(Attributes attrs, ConstantPool cp) throws Exception {
|
||||
return getAnnotValues(Desc.class.getName(), attrs, cp);
|
||||
}
|
||||
|
||||
AnnotValues getSigValue(Attributes attrs, ConstantPool cp) throws Exception {
|
||||
return getAnnotValues(Sig.class.getName(), attrs, cp);
|
||||
}
|
||||
|
||||
static class AnnotValues {
|
||||
AnnotValues(String raw, String type) {
|
||||
this.raw = raw;
|
||||
this.type = type;
|
||||
}
|
||||
final String raw;
|
||||
final String type;
|
||||
}
|
||||
|
||||
AnnotValues getAnnotValues(String annotName, Attributes attrs, ConstantPool cp)
|
||||
throws Exception {
|
||||
RuntimeInvisibleAnnotations_attribute annots =
|
||||
(RuntimeInvisibleAnnotations_attribute)attrs.get(Attribute.RuntimeInvisibleAnnotations);
|
||||
if (annots != null) {
|
||||
for (Annotation a: annots.annotations) {
|
||||
if (cp.getUTF8Value(a.type_index).equals("L" + annotName + ";")) {
|
||||
Annotation.Primitive_element_value pv0 =
|
||||
(Annotation.Primitive_element_value) a.element_value_pairs[0].value;
|
||||
Annotation.Primitive_element_value pv1 =
|
||||
(Annotation.Primitive_element_value) a.element_value_pairs[1].value;
|
||||
return new AnnotValues(
|
||||
cp.getUTF8Value(pv0.const_value_index),
|
||||
cp.getUTF8Value(pv1.const_value_index));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
void checkEqual(String expect, String found) {
|
||||
if (!(expect == null ? found == null : expect.equals(found))) {
|
||||
System.err.println("expected: " + expect);
|
||||
System.err.println(" found: " + found);
|
||||
error("unexpected values found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println("error: " + msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
|
||||
TypePrinter tp = new TypePrinter();
|
||||
|
||||
class TypePrinter implements Type.Visitor<String,Void> {
|
||||
String print(Type t) {
|
||||
return t == null ? null : t.accept(this, null);
|
||||
}
|
||||
String print(String pre, List<? extends Type> ts, String post) {
|
||||
if (ts == null)
|
||||
return null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(pre);
|
||||
String sep = "";
|
||||
for (Type t: ts) {
|
||||
sb.append(sep);
|
||||
sb.append(print(t));
|
||||
sep = ",";
|
||||
}
|
||||
sb.append(post);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitSimpleType(SimpleType type, Void p) {
|
||||
return "S{" + type.name + "}";
|
||||
}
|
||||
|
||||
public String visitArrayType(ArrayType type, Void p) {
|
||||
return "A{" + print(type.elemType) + "}";
|
||||
}
|
||||
|
||||
public String visitMethodType(MethodType type, Void p) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("M{");
|
||||
if (type.typeParamTypes != null)
|
||||
sb.append(print("<", type.typeParamTypes, ">"));
|
||||
sb.append(print(type.returnType));
|
||||
sb.append(print("(", type.paramTypes, ")"));
|
||||
if (type.throwsTypes != null)
|
||||
sb.append(print("", type.throwsTypes, ""));
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitClassSigType(ClassSigType type, Void p) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("CS{");
|
||||
if (type.typeParamTypes != null)
|
||||
sb.append(print("<", type.typeParamTypes, ">"));
|
||||
sb.append(print(type.superclassType));
|
||||
if (type.superinterfaceTypes != null)
|
||||
sb.append(print("i(", type.superinterfaceTypes, ")"));
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitClassType(ClassType type, Void p) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("C{");
|
||||
if (type.outerType != null) {
|
||||
sb.append(print(type.outerType));
|
||||
sb.append(".");
|
||||
}
|
||||
sb.append(type.name);
|
||||
if (type.typeArgs != null)
|
||||
sb.append(print("<", type.typeArgs, ">"));
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitTypeParamType(TypeParamType type, Void p) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("TA{");
|
||||
sb.append(type.name);
|
||||
if (type.classBound != null) {
|
||||
sb.append(":c");
|
||||
sb.append(print(type.classBound));
|
||||
}
|
||||
if (type.interfaceBounds != null)
|
||||
sb.append(print(":i", type.interfaceBounds, ""));
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitWildcardType(WildcardType type, Void p) {
|
||||
switch (type.kind) {
|
||||
case UNBOUNDED:
|
||||
return "W{?}";
|
||||
case EXTENDS:
|
||||
return "W{e," + print(type.boundType) + "}";
|
||||
case SUPER:
|
||||
return "W{s," + print(type.boundType) + "}";
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@interface Desc {
|
||||
String d();
|
||||
String t();
|
||||
}
|
||||
|
||||
@interface Sig {
|
||||
String s();
|
||||
String t();
|
||||
}
|
||||
|
||||
class Clss { }
|
||||
interface Intf { }
|
||||
class GenClss<T> { }
|
||||
|
||||
class Test {
|
||||
// fields
|
||||
|
||||
@Desc(d="Z", t="S{boolean}")
|
||||
boolean z;
|
||||
|
||||
@Desc(d="B", t="S{byte}")
|
||||
byte b;
|
||||
|
||||
@Desc(d="C", t="S{char}")
|
||||
char c;
|
||||
|
||||
@Desc(d="D", t="S{double}")
|
||||
double d;
|
||||
|
||||
@Desc(d="F", t="S{float}")
|
||||
float f;
|
||||
|
||||
@Desc(d="I", t="S{int}")
|
||||
int i;
|
||||
|
||||
@Desc(d="J", t="S{long}")
|
||||
long l;
|
||||
|
||||
@Desc(d="S", t="S{short}")
|
||||
short s;
|
||||
|
||||
@Desc(d="LClss;", t="C{Clss}")
|
||||
Clss clss;
|
||||
|
||||
@Desc(d="LIntf;", t="C{Intf}")
|
||||
Intf intf;
|
||||
|
||||
@Desc(d="[I", t="A{S{int}}")
|
||||
int[] ai;
|
||||
|
||||
@Desc(d="[LClss;", t="A{C{Clss}}")
|
||||
Clss[] aClss;
|
||||
|
||||
@Desc(d="LGenClss;", t="C{GenClss}")
|
||||
@Sig(s="LGenClss<LClss;>;", t="C{GenClss<C{Clss}>}")
|
||||
GenClss<Clss> genClass;
|
||||
|
||||
// methods, return types
|
||||
|
||||
@Desc(d="()V", t="M{S{void}()}")
|
||||
void mv0() { }
|
||||
|
||||
@Desc(d="()I", t="M{S{int}()}")
|
||||
int mi0() { return 0; }
|
||||
|
||||
@Desc(d="()LClss;", t="M{C{Clss}()}")
|
||||
Clss mclss0() { return null; }
|
||||
|
||||
@Desc(d="()[I", t="M{A{S{int}}()}")
|
||||
int[] mai0() { return null; }
|
||||
|
||||
@Desc(d="()[LClss;", t="M{A{C{Clss}}()}")
|
||||
Clss[] maClss0() { return null; }
|
||||
|
||||
@Desc(d="()LGenClss;", t="M{C{GenClss}()}")
|
||||
@Sig(s="()LGenClss<LClss;>;", t="M{C{GenClss<C{Clss}>}()}")
|
||||
GenClss<Clss> mgenClss0() { return null; }
|
||||
|
||||
@Desc(d="()LGenClss;", t="M{C{GenClss}()}")
|
||||
@Sig(s="()LGenClss<*>;", t="M{C{GenClss<W{?}>}()}")
|
||||
GenClss<?> mgenClssW0() { return null; }
|
||||
|
||||
@Desc(d="()LGenClss;", t="M{C{GenClss}()}")
|
||||
@Sig(s="()LGenClss<+LClss;>;", t="M{C{GenClss<W{e,C{Clss}}>}()}")
|
||||
GenClss<? extends Clss> mgenClssWExtClss0() { return null; }
|
||||
|
||||
@Desc(d="()LGenClss;", t="M{C{GenClss}()}")
|
||||
@Sig(s="()LGenClss<-LClss;>;", t="M{C{GenClss<W{s,C{Clss}}>}()}")
|
||||
GenClss<? super Clss> mgenClssWSupClss0() { return null; }
|
||||
|
||||
@Desc(d="()Ljava/lang/Object;", t="M{C{java/lang/Object}()}")
|
||||
@Sig(s="<T:Ljava/lang/Object;>()TT;", t="M{<TA{T:cC{java/lang/Object}}>S{T}()}")
|
||||
<T> T mt0() { return null; }
|
||||
|
||||
@Desc(d="()LGenClss;", t="M{C{GenClss}()}")
|
||||
@Sig(s="<T:Ljava/lang/Object;>()LGenClss<+TT;>;",
|
||||
t="M{<TA{T:cC{java/lang/Object}}>C{GenClss<W{e,S{T}}>}()}")
|
||||
<T> GenClss<? extends T> mgenClssWExtT0() { return null; }
|
||||
|
||||
@Desc(d="()LGenClss;", t="M{C{GenClss}()}")
|
||||
@Sig(s="<T:Ljava/lang/Object;>()LGenClss<-TT;>;", t="M{<TA{T:cC{java/lang/Object}}>C{GenClss<W{s,S{T}}>}()}")
|
||||
<T> GenClss<? super T> mgenClssWSupT0() { return null; }
|
||||
|
||||
// methods, arg types
|
||||
|
||||
@Desc(d="(I)V", t="M{S{void}(S{int})}")
|
||||
void mi1(int arg) { }
|
||||
|
||||
@Desc(d="(LClss;)V", t="M{S{void}(C{Clss})}")
|
||||
void mclss1(Clss arg) { }
|
||||
|
||||
@Desc(d="([I)V", t="M{S{void}(A{S{int}})}")
|
||||
void mai1(int[] arg) { }
|
||||
|
||||
@Desc(d="([LClss;)V", t="M{S{void}(A{C{Clss}})}")
|
||||
void maClss1(Clss[] arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<LClss;>;)V", t="M{S{void}(C{GenClss<C{Clss}>})}")
|
||||
void mgenClss1(GenClss<Clss> arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<*>;)V", t="M{S{void}(C{GenClss<W{?}>})}")
|
||||
void mgenClssW1(GenClss<?> arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<+LClss;>;)V", t="M{S{void}(C{GenClss<W{e,C{Clss}}>})}")
|
||||
void mgenClssWExtClss1(GenClss<? extends Clss> arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<-LClss;>;)V", t="M{S{void}(C{GenClss<W{s,C{Clss}}>})}")
|
||||
void mgenClssWSupClss1(GenClss<? super Clss> arg) { }
|
||||
|
||||
@Desc(d="(Ljava/lang/Object;)V", t="M{S{void}(C{java/lang/Object})}")
|
||||
@Sig(s="<T:Ljava/lang/Object;>(TT;)V",
|
||||
t="M{<TA{T:cC{java/lang/Object}}>S{void}(S{T})}")
|
||||
<T> void mt1(T arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="<T:Ljava/lang/Object;>(LGenClss<+TT;>;)V",
|
||||
t="M{<TA{T:cC{java/lang/Object}}>S{void}(C{GenClss<W{e,S{T}}>})}")
|
||||
<T> void mgenClssWExtT1(GenClss<? extends T> arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="<T:Ljava/lang/Object;>(LGenClss<-TT;>;)V",
|
||||
t="M{<TA{T:cC{java/lang/Object}}>S{void}(C{GenClss<W{s,S{T}}>})}")
|
||||
<T> void mgenClssWSupT1(GenClss<? super T> arg) { }
|
||||
|
||||
// methods, throws
|
||||
|
||||
@Desc(d="()V", t="M{S{void}()}")
|
||||
void m_E() throws Exception { }
|
||||
|
||||
@Desc(d="()V", t="M{S{void}()}")
|
||||
@Sig(s="<T:Ljava/lang/Throwable;>()V^TT;",
|
||||
t="M{<TA{T:cC{java/lang/Throwable}}>S{void}()S{T}}")
|
||||
<T extends Throwable> void m_T() throws T { }
|
||||
|
||||
// inner classes
|
||||
|
||||
static class X {
|
||||
// no sig
|
||||
class P { }
|
||||
|
||||
@Sig(s="<TQ:Ljava/lang/Object;>LTest$X$P;",
|
||||
t="CS{<TA{TQ:cC{java/lang/Object}}>C{Test$X$P}}")
|
||||
class Q<TQ> extends P { }
|
||||
|
||||
@Sig(s="<TR:Ljava/lang/Object;>LTest$X$Q<TTR;>;",
|
||||
t="CS{<TA{TR:cC{java/lang/Object}}>C{Test$X$Q<S{TR}>}}")
|
||||
class R<TR> extends Q<TR> { }
|
||||
}
|
||||
|
||||
@Sig(s="<TY:Ljava/lang/Object;>Ljava/lang/Object;",
|
||||
t="CS{<TA{TY:cC{java/lang/Object}}>C{java/lang/Object}}")
|
||||
static class Y<TY> {
|
||||
// no sig
|
||||
class P { }
|
||||
|
||||
@Sig(s="<TQ:Ljava/lang/Object;>LTest$Y<TTY;>.P;",
|
||||
t="CS{<TA{TQ:cC{java/lang/Object}}>C{C{Test$Y<S{TY}>}.P}}")
|
||||
class Q<TQ> extends P { }
|
||||
|
||||
@Sig(s="<TR:Ljava/lang/Object;>LTest$Y<TTY;>.Q<TTR;>;",
|
||||
t="CS{<TA{TR:cC{java/lang/Object}}>C{C{Test$Y<S{TY}>}.Q<S{TR}>}}")
|
||||
class R<TR> extends Q<TR> {
|
||||
// no sig
|
||||
class R1 { }
|
||||
|
||||
@Sig(s="<TR2:Ljava/lang/Object;>LTest$Y<TTY;>.R<TTR;>.R1;",
|
||||
t="CS{<TA{TR2:cC{java/lang/Object}}>C{C{C{Test$Y<S{TY}>}.R<S{TR}>}.R1}}")
|
||||
class R2<TR2> extends R1 { }
|
||||
}
|
||||
|
||||
@Sig(s="LTest$Y<TTY;>.Q<TTY;>;", t="C{C{Test$Y<S{TY}>}.Q<S{TY}>}")
|
||||
class S extends Q<TY> {
|
||||
// no sig
|
||||
class S1 { }
|
||||
|
||||
@Sig(s="<TS2:Ljava/lang/Object;>LTest$Y<TTY;>.S.S1;",
|
||||
t="CS{<TA{TS2:cC{java/lang/Object}}>C{C{C{Test$Y<S{TY}>}.S}.S1}}")
|
||||
class S2<TS2> extends S1 { }
|
||||
|
||||
@Sig(s="LTest$Y<TTY;>.S.S2<TTY;>;",
|
||||
t="C{C{C{Test$Y<S{TY}>}.S}.S2<S{TY}>}")
|
||||
class S3 extends S2<TY> { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
121
langtools/test/tools/javap/classfile/T6887895.java
Normal file
121
langtools/test/tools/javap/classfile/T6887895.java
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6887895
|
||||
* @summary CONSTANT_Class_info getBaseName does not handle arrays of primitives correctly
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import com.sun.tools.classfile.ConstantPool.*;
|
||||
|
||||
public class T6887895 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T6887895().run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
Set<String> found = new TreeSet<String>();
|
||||
|
||||
ClassFile cf = getClassFile("T6887895$Test.class");
|
||||
for (CPInfo cpInfo: cf.constant_pool.entries()) {
|
||||
if (cpInfo instanceof CONSTANT_Class_info) {
|
||||
CONSTANT_Class_info info = (CONSTANT_Class_info) cpInfo;
|
||||
String name = info.getName();
|
||||
String baseName = info.getBaseName();
|
||||
System.out.println("found: " + name + " " + baseName);
|
||||
if (baseName != null)
|
||||
found.add(baseName);
|
||||
}
|
||||
}
|
||||
|
||||
String[] expectNames = {
|
||||
"java/lang/Object",
|
||||
"java/lang/String",
|
||||
"T6887895",
|
||||
"T6887895$Test"
|
||||
};
|
||||
|
||||
Set<String> expect = new TreeSet<String>(Arrays.asList(expectNames));
|
||||
if (!found.equals(expect)) {
|
||||
System.err.println("found: " + found);
|
||||
System.err.println("expect: " + expect);
|
||||
throw new Exception("unexpected values found");
|
||||
}
|
||||
}
|
||||
|
||||
ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
|
||||
URL url = getClass().getResource(name);
|
||||
InputStream in = url.openStream();
|
||||
try {
|
||||
return ClassFile.read(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
void m() {
|
||||
boolean[] az = new boolean[0];
|
||||
boolean[][] aaz = new boolean[0][];
|
||||
boolean[][][] aaaz = new boolean[0][][];
|
||||
|
||||
byte[] ab = new byte[0];
|
||||
byte[][] aab = new byte[0][];
|
||||
byte[][][] aaab = new byte[0][][];
|
||||
|
||||
char[] ac = new char[0];
|
||||
char[][] aac = new char[0][];
|
||||
char[][][] aaac = new char[0][][];
|
||||
|
||||
double[] ad = new double[0];
|
||||
double[][] aad = new double[0][];
|
||||
double[][][] aaad = new double[0][][];
|
||||
|
||||
float[] af = new float[0];
|
||||
float[][] aaf = new float[0][];
|
||||
float[][][] aaaf = new float[0][][];
|
||||
|
||||
int[] ai = new int[0];
|
||||
int[][] aai = new int[0][];
|
||||
int[][][] aaai = new int[0][][];
|
||||
|
||||
long[] al = new long[0];
|
||||
long[][] aal = new long[0][];
|
||||
long[][][] aaal = new long[0][][];
|
||||
|
||||
short[] as = new short[0];
|
||||
short[][] aas = new short[0][];
|
||||
short[][][] aaas = new short[0][][];
|
||||
|
||||
String[] aS = new String[0];
|
||||
String[][] aaS = new String[0][];
|
||||
String[][][] aaaS = new String[0][][];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user