This commit is contained in:
Xiaobin Lu 2009-10-28 10:37:17 -07:00
commit 5e86d923f2
68 changed files with 2788 additions and 241 deletions

View File

@ -48,3 +48,4 @@ bca2225b66d78c4bf4d9801f54cac7715a598650 jdk7-b68
c5d39b6be65cba0effb5f466ea48fe43764d0e0c jdk7-b71
df4bcd06e1d0ab306efa5a44f24a409dc0c0c742 jdk7-b72
ce74bd35ce948d629a356e168797f44b593b1578 jdk7-b73
4e7661eaa211e186674f6cbefec4aef1144ac2a0 jdk7-b74

View File

@ -48,3 +48,4 @@ e1b972ff53cd58f825791f8ed9b2deffd16e768c jdk7-b68
4c36e9853dda27bdac5ef4839a610509fbe31d34 jdk7-b71
0d7e03b426df27c21dcc44ffb9178eacd1b04f10 jdk7-b72
3ac6dcf7823205546fbbc3d4ea59f37358d0b0d4 jdk7-b73
2c88089b6e1c053597418099a14232182c387edc jdk7-b74

View File

@ -48,3 +48,4 @@ a12ea7c7b497b4ba7830550095ef633bd6f43971 jdk7-b67
3f1ef7f899ea2aec189c4fb67e5c8fa374437c50 jdk7-b71
c793a31209263fbb867c23c752599d85c21abb73 jdk7-b72
b751c528c55560cf2adeaeef24b39ca1f4d1cbf7 jdk7-b73
5d0cf59a3203b9f57aceebc33ae656b884987955 jdk7-b74

View File

@ -48,3 +48,4 @@ d07e68298d4e17ebf93d8299e43fcc3ded26472a jdk7-b68
50a95aa4a247f0cbbf66df285a8b1d78ffb153d9 jdk7-b71
a94714c550658fd6741793ef036cb9625dc2ab1a jdk7-b72
faf94d94786b621f8e13cbcc941ca69c6d967c3f jdk7-b73
f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 jdk7-b74

View File

@ -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

View File

@ -48,3 +48,4 @@ c83f0106b78a85c7e614d27a328675460b2081cf jdk7-b70
ff94d8ce0daded647bb326630e643d010357afce jdk7-b71
37c805b6156fd492c12301688b54a6bcca39e729 jdk7-b72
feb05980f9f2964e6bc2b3a8532f9b3054c2289b jdk7-b73
ea7b88c676dd8b269bc858a4a17c14dc96c8aed1 jdk7-b74

View File

@ -48,3 +48,4 @@ dd3c5f3ec28d5d5e5c0dc3229fdd52d85d04274d jdk7-b70
03314cf56a7212bbb6c186dbc9f15aca988a48ec jdk7-b71
4c990aa99bc037fd81dd1b1b269690e9bea8a0b4 jdk7-b72
558985e26fe16f5a6ebb2edb9180a42e1c8e8202 jdk7-b73
f4466e1b608088c90e11beaa4b600f102608c6a1 jdk7-b74

View File

@ -48,3 +48,4 @@ b23d905cb5d3b382295240d28ab0bfb266b4503c jdk7-b68
b3f3240135f0c10b9f2481c174b81b7fcf0daa60 jdk7-b71
460639b036f327282832a4fe52b7aa45688afd50 jdk7-b72
f708138c9aca4b389872838fe6773872fce3609e jdk7-b73
eacb36e30327e7ae33baa068e82ddccbd91eaae2 jdk7-b74

View File

@ -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)

View File

@ -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 \

View File

@ -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) \

View File

@ -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.

View File

@ -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;
}

View File

@ -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">&sect;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>>

View File

@ -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

View File

@ -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}.

View 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;
}
}

View File

@ -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) {

View File

@ -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 ){

View File

@ -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));

View File

@ -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();

View File

@ -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();

View File

@ -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");

View File

@ -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;
}

View File

@ -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");

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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

View File

@ -235,7 +235,8 @@ class UnixDirectoryStream
@Override
public void remove() {
if (isClosed) {
throw new ClosedDirectoryStreamException();
throwAsConcurrentModificationException(new
ClosedDirectoryStreamException());
}
Path entry;
synchronized (this) {

View File

@ -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) {

View 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();
}
}
}

View 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\"");
}
}

View File

@ -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.");
}

View File

@ -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());
}
}

View 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);
}
}

View File

@ -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 {

View File

@ -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.*;

View 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;

View File

@ -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());
}

View File

@ -22,7 +22,7 @@
*/
/* @test
* @bug 4313887 6838333
* @bug 4313887 6838333 6891404
* @summary Unit test for java.nio.file.attribute.AclFileAttribueView
* @library ../..
*/

View 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;
}
}

View File

@ -48,3 +48,4 @@ ce9bcdcb7859bb7ef10afd078ad59ba7847f208d jdk7-b69
33c8c38e1757006c17d80499fb3347102501fae5 jdk7-b71
261c54b2312ed26d6ec45c675831375460250519 jdk7-b72
9596dff460935f09684c11d156ce591f92584f0d jdk7-b73
1a66b08deed0459054b5b1bea3dfbead30d258fa jdk7-b74

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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()));
}

View File

@ -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;
}
}

View File

@ -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() + "]";
}
/**

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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() {

View File

@ -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);
}

View File

@ -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 == '_') {

View File

@ -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=\

View File

@ -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));

View File

@ -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) {

View File

@ -77,9 +77,25 @@ public interface Elements {
* Returns the text of the documentation (&quot;Javadoc&quot;)
* comment of an element.
*
* <p> A documentation comment of an element is a comment that
* begins with "{@code /**}" , ends with a separate
* "<code>*&#47</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>*&#47</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);

View 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;
}

View File

@ -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 {

View 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>();
}

View 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;
}

View 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

View 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> { }
}
}
}

View 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][][];
}
}
}