[ecj] Patch: FYI: merge in generics

Tom Tromey tromey@redhat.com
Fri Jun 23 14:43:00 GMT 2006


I'm checking this in on the gcj-eclipse branch.

This patch merges the classpath generics import to the gcj-eclipse
branch.

In the appended I'm only including the libgcj-specific changes, not
everything in classpath.

Also, the libgcj bits are not really complete.  I didn't make
StringBuffer implement Appendable.  ProcessBuilder is a stub, as is
the new System.getenv.  I'll fix these later.

In order to build this you will need a new version of gcjh (called
"gcjh1" in the build).  The one that is built as part of gcj will not
work properly with 1.5 bytecode.  So, I rewrote gcjh in java, using
the ASM library.  You can get this gcjh, along with ASM and the also
ecj, here:

    http://people.redhat.com/~tromey/gcjh/

I'm hoping to get this gcjh into Classpath sometime soon.
However I think we will continue to make a jar available to make
building simpler.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* java/io/PrintStream.java (PrintStream): Implement Appendable.
	* java/lang/Class.java: Genericized.
	(getEnumConstants): New method.
	(isEnum): Likewise.
	(isSynthetic): Likewise.
	(isAnnotation): Likewise.
	* java/lang/reflect/Constructor.java (getDeclaringClass,
	getTypeParameters, declaringClass): Genericized.
	* java/lang/reflect/Method.java (invoke): Now varargs.
	* java/lang/ref/Reference.java (Reference): Imported genericized
	version from Classpath.
	(get): Now native.
	* java/lang/ref/natReference.cc (get): New method.
	* java/lang/ProcessBuilder.java: New file.
	* java/lang/System.java (environmentMap): New field.
	(clearProperty): New method.
	(getenv): Likewise.
	(EnvironmentCollection): New class.
	(EnvironmentMap): Likewise.
	(EnvironmentSet): Likewise.
	* java/lang/StringBuilder.java (StringBuilder): Implements
	Appendable.
	* gnu/classpath/SystemProperties.java (remove): New method.

Index: gnu/classpath/SystemProperties.java
===================================================================
--- gnu/classpath/SystemProperties.java	(revision 114871)
+++ gnu/classpath/SystemProperties.java	(working copy)
@@ -1,5 +1,5 @@
 /* SystemProperties.java -- Manage the System properties.
-   Copyright (C) 2004, 2005 Free Software Foundation
+   Copyright (C) 2004, 2005, 2006 Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -154,4 +154,18 @@
    * @return true if the system is big-endian.
    */
   private static native boolean isWordsBigEndian();
+
+  /**
+   * Removes the supplied system property and its current value.
+   * If the specified property does not exist, nothing happens.
+   * 
+   * @throws NullPointerException if the property name is null.
+   * @return the value of the removed property, or null if no
+   *         such property exists.
+   */
+  public static String remove(String name)
+  {
+    return (String) properties.remove(name);
+  }
+
 }
Index: java/lang/StringBuilder.java
===================================================================
--- java/lang/StringBuilder.java	(revision 114871)
+++ java/lang/StringBuilder.java	(working copy)
@@ -74,9 +74,8 @@
  *
  * @since 1.5
  */
-// FIX15: Implement Appendable when co-variant methods are available
 public final class StringBuilder
-  implements Serializable, CharSequence
+  implements Serializable, CharSequence, Appendable
 {
   // Implementation note: if you change this class, you usually will
   // want to change StringBuffer as well.
Index: java/lang/System.java
===================================================================
--- java/lang/System.java	(revision 114871)
+++ java/lang/System.java	(working copy)
@@ -48,6 +48,15 @@
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.PrintStream;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.Properties;
 import java.util.PropertyPermission;
 
@@ -103,6 +112,11 @@
     = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err)), true);
 
   /**
+   * A cached copy of the environment variable map.
+   */
+  private static Map<String,String> environmentMap;
+
+  /**
    * This class is uninstantiable.
    */
   private System()
@@ -399,6 +413,29 @@
   }
 
   /**
+   * Remove a single system property by name. A security check may be
+   * performed, <code>checkPropertyAccess(key, "write")</code>.
+   *
+   * @param key the name of the system property to remove
+   * @return the previous value, or null
+   * @throws SecurityException if permission is denied
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if key is ""
+   * @since 1.5
+   */
+  public static String clearProperty(String key)
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPermission(new PropertyPermission(key, "write"));
+    // This handles both the null pointer exception and the illegal
+    // argument exception.
+    if (key.length() == 0)
+      throw new IllegalArgumentException("key can't be empty");
+    return SystemProperties.remove(key);
+  }
+
+  /**
    * Gets the value of an environment variable.
    *
    * @param name the name of the environment variable
@@ -421,6 +458,59 @@
   }
 
   /**
+   * <p>
+   * Returns an unmodifiable view of the system environment variables.
+   * If the underlying system does not support environment variables,
+   * an empty map is returned.
+   * </p>
+   * <p>
+   * The returned map is read-only and does not accept queries using
+   * null keys or values, or those of a type other than <code>String</code>.
+   * Attempts to modify the map will throw an
+   * <code>UnsupportedOperationException</code>, while attempts
+   * to pass in a null value will throw a
+   * <code>NullPointerException</code>.  Types other than <code>String</code>
+   * throw a <code>ClassCastException</code>.
+   * </p>
+   * <p>
+   * As the returned map is generated using data from the underlying
+   * platform, it may not comply with the <code>equals()</code>
+   * and <code>hashCode()</code> contracts.  It is also likely that
+   * the keys of this map will be case-sensitive.
+   * </p>
+   * <p>
+   * Use of this method may require a security check for the
+   * RuntimePermission "getenv.*".
+   * </p>
+   *
+   * @return a map of the system environment variables.
+   * @throws SecurityException if the checkPermission method of
+   *         an installed security manager prevents access to
+   *         the system environment variables.
+   * @since 1.5
+   */
+  public static Map<String, String> getenv()
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe.
+    if (sm != null)
+      sm.checkPermission(new RuntimePermission("getenv.*"));
+    if (environmentMap == null)
+      {
+	// List<String> environ = (List<String>)VMSystem.environ();
+	// FIXME
+	List<String> environ = new ArrayList<String>();
+	Map<String,String> variables = new EnvironmentMap();
+	for (String pair : environ)
+	  {
+	    String[] parts = pair.split("=");
+	    variables.put(parts[0], parts[1]);
+	  }
+	environmentMap = Collections.unmodifiableMap(variables);
+      }
+    return environmentMap;
+  }
+
+  /**
    * Terminate the Virtual Machine. This just calls
    * <code>Runtime.getRuntime().exit(status)</code>, and never returns.
    * Obviously, a security check is in order, <code>checkExit</code>.
@@ -562,4 +652,382 @@
    * @see #getenv(String)
    */
   static native String getenv0(String name);
+
+
+  /**
+   * This is a specialised <code>Collection</code>, providing
+   * the necessary provisions for the collections used by the
+   * environment variable map.  Namely, it prevents
+   * querying anything but <code>String</code>s.
+   *
+   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+   */
+  private static class EnvironmentCollection
+    extends AbstractCollection<String>
+  {
+
+    /**
+     * The wrapped collection.
+     */
+    protected Collection<String> c;
+
+    /**
+     * Constructs a new environment collection, which
+     * wraps the elements of the supplied collection.
+     *
+     * @param coll the collection to use as a base for
+     *             this collection.
+     */
+    public EnvironmentCollection(Collection<String> coll)
+    {
+      c = coll;
+    }
+        
+    /**
+     * Blocks queries containing a null object or an object which
+     * isn't of type <code>String</code>.  All other queries
+     * are forwarded to the underlying collection.
+     *
+     * @param obj the object to look for.
+     * @return true if the object exists in the collection.
+     * @throws NullPointerException if the specified object is null.
+     * @throws ClassCastException if the specified object is not a String.
+     */
+    public boolean contains(Object obj)
+    {
+      if (obj == null)
+	  throw new
+	    NullPointerException("This collection does not support " +
+				 "null values.");
+      if (!(obj instanceof String))
+	  throw new
+	    ClassCastException("This collection only supports Strings.");
+      return c.contains(obj);
+    }
+    
+    /**
+     * Blocks queries where the collection contains a null object or
+     * an object which isn't of type <code>String</code>.  All other
+     * queries are forwarded to the underlying collection.
+     *
+     * @param coll the collection of objects to look for.
+     * @return true if the collection contains all elements in the collection.
+     * @throws NullPointerException if the collection is null.
+     * @throws NullPointerException if any collection entry is null.
+     * @throws ClassCastException if any collection entry is not a String.
+     */
+    public boolean containsAll(Collection<?> coll)
+    {
+      for (Object o: coll)
+	{
+	  if (o == null)
+	      throw new
+		NullPointerException("This collection does not support " +
+				     "null values.");
+	  if (!(o instanceof String))
+	      throw new
+		ClassCastException("This collection only supports Strings.");
+	}
+      return c.containsAll(coll);
+    }
+
+    /**
+     * This returns an iterator over the map elements, with the
+     * same provisions as for the collection and underlying map.
+     *
+     * @return an iterator over the map elements.
+     */
+    public Iterator<String> iterator()
+    {
+      return c.iterator();
+    }
+    
+    /**
+     * Blocks the removal of elements from the collection.
+     *
+     * @return true if the removal was sucessful.
+     * @throws NullPointerException if the collection is null.
+     * @throws NullPointerException if any collection entry is null.
+     * @throws ClassCastException if any collection entry is not a String.
+     */
+    public boolean remove(Object key)
+    {
+      if (key == null)
+	  throw new
+	    NullPointerException("This collection does not support " +
+				 "null values.");
+      if (!(key instanceof String))
+	  throw new
+	    ClassCastException("This collection only supports Strings.");
+      return c.contains(key);
+    }	
+        
+    /**
+     * Blocks the removal of all elements in the specified
+     * collection from the collection.
+     *
+     * @param coll the collection of elements to remove.
+     * @return true if the elements were removed.
+     * @throws NullPointerException if the collection is null.
+     * @throws NullPointerException if any collection entry is null.
+     * @throws ClassCastException if any collection entry is not a String.
+     */
+    public boolean removeAll(Collection<?> coll)
+    {
+      for (Object o: coll)
+	{
+	  if (o == null)
+	      throw new
+		NullPointerException("This collection does not support " +
+				     "null values.");
+	  if (!(o instanceof String))
+	    throw new
+	      ClassCastException("This collection only supports Strings.");
+	}
+      return c.removeAll(coll);
+    }
+    
+    /**
+     * Blocks the retention of all elements in the specified
+     * collection from the collection.
+     *
+     * @param c the collection of elements to retain.
+     * @return true if the other elements were removed.
+     * @throws NullPointerException if the collection is null.
+     * @throws NullPointerException if any collection entry is null.
+     * @throws ClassCastException if any collection entry is not a String.
+     */
+    public boolean retainAll(Collection<?> coll)
+    {
+      for (Object o: coll)
+	{
+	  if (o == null)
+	      throw new
+		NullPointerException("This collection does not support " +
+				     "null values.");
+	  if (!(o instanceof String))
+	    throw new
+	      ClassCastException("This collection only supports Strings.");
+	}
+      return c.containsAll(coll);
+    }
+
+    /**
+     * This simply calls the same method on the wrapped
+     * collection.
+     *
+     * @return the size of the underlying collection.
+     */
+    public int size()
+    {
+      return c.size();
+    }
+
+  } // class EnvironmentCollection<String>
+
+  /**
+   * This is a specialised <code>HashMap</code>, which
+   * prevents the addition or querying of anything other than
+   * <code>String</code> objects. 
+   *
+   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+   */
+  private static class EnvironmentMap
+    extends HashMap<String,String>
+  {
+    
+    /**
+     * Cache the entry set.
+     */
+    private transient Set<Map.Entry<String,String>> entries;
+
+    /**
+     * Cache the key set.
+     */
+    private transient Set<String> keys;
+
+    /**
+     * Cache the value collection.
+     */
+    private transient Collection<String> values;
+
+    /**
+     * Constructs a new empty <code>EnvironmentMap</code>.
+     */
+    EnvironmentMap()
+    {
+      super();
+    }
+    
+    /**
+     * Blocks queries containing a null key or one which is not
+     * of type <code>String</code>.  All other queries
+     * are forwarded to the superclass.
+     *
+     * @param key the key to look for in the map.
+     * @return true if the key exists in the map.
+     * @throws NullPointerException if the specified key is null.
+     */
+    public boolean containsKey(Object key)
+    {
+      if (key == null)
+	throw new
+	  NullPointerException("This map does not support null keys.");
+      if (!(key instanceof String))
+	throw new
+	  ClassCastException("This map only allows queries using Strings.");
+      return super.containsKey(key);
+    }
+    
+    /**
+     * Blocks queries using a null or non-<code>String</code> value.
+     * All other queries are forwarded to the superclass.
+     *
+     * @param value the value to look for in the map.
+     * @return true if the value exists in the map.
+     * @throws NullPointerException if the specified value is null.
+     */
+    public boolean containsValue(Object value)
+    {
+      if (value == null)
+	  throw new
+	    NullPointerException("This map does not support null values.");
+      if (!(value instanceof String))
+	throw new
+	  ClassCastException("This map only allows queries using Strings.");
+      return super.containsValue(value);
+    }
+
+    /**
+     * Returns a set view of the map entries, with the same
+     * provisions as for the underlying map.
+     *
+     * @return a set containing the map entries.
+     */
+    public Set<Map.Entry<String,String>> entrySet()
+    {
+      if (entries == null)
+        entries = super.entrySet();
+      return entries;
+    }
+
+    /**
+     * Blocks queries containing a null or non-<code>String</code> key.
+     * All other queries are passed on to the superclass.
+     *
+     * @param key the key to retrieve the value for.
+     * @return the value associated with the given key.
+     * @throws NullPointerException if the specified key is null.
+     * @throws ClassCastException if the specified key is not a String.
+     */
+    public String get(Object key)
+    {
+      if (key == null)
+	throw new
+	  NullPointerException("This map does not support null keys.");
+      if (!(key instanceof String))
+	throw new
+	  ClassCastException("This map only allows queries using Strings.");
+      return super.get(key);
+    }
+    
+    /**
+     * Returns a set view of the keys, with the same
+     * provisions as for the underlying map.
+     *
+     * @return a set containing the keys.
+     */
+    public Set<String> keySet()
+    {
+      if (keys == null)
+        keys = new EnvironmentSet(super.keySet());
+      return keys;
+    }
+    
+    /**
+     * Removes a key-value pair from the map.  The queried key may not
+     * be null or of a type other than a <code>String</code>.
+     *
+     * @param key the key of the entry to remove.
+     * @return the removed value.
+     * @throws NullPointerException if the specified key is null.
+     * @throws ClassCastException if the specified key is not a String.
+     */
+    public String remove(Object key)
+    {
+      if (key == null)
+	throw new
+	  NullPointerException("This map does not support null keys.");
+      if (!(key instanceof String))
+	throw new
+	  ClassCastException("This map only allows queries using Strings.");
+      return super.remove(key);
+    }
+    
+    /**
+     * Returns a collection view of the values, with the same
+     * provisions as for the underlying map.
+     *
+     * @return a collection containing the values.
+     */
+    public Collection<String> values()
+    {
+      if (values == null)
+        values = new EnvironmentCollection(super.values());
+      return values;
+    }
+    
+  }
+
+  /**
+   * This is a specialised <code>Set</code>, providing
+   * the necessary provisions for the collections used by the
+   * environment variable map.  Namely, it prevents
+   * modifications and the use of queries with null
+   * or non-<code>String</code> values.
+   *
+   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+   */
+  private static class EnvironmentSet
+    extends EnvironmentCollection
+    implements Set<String>
+  {
+
+    /**
+     * Constructs a new environment set, which
+     * wraps the elements of the supplied set.
+     *
+     * @param set the set to use as a base for
+     *             this set.
+     */
+    public EnvironmentSet(Set<String> set)
+    {
+      super(set);
+    }
+
+    /**
+     * This simply calls the same method on the wrapped
+     * collection.
+     *
+     * @param obj the object to compare with.
+     * @return true if the two objects are equal.
+     */
+    public boolean equals(Object obj)
+    {
+      return c.equals(obj);
+    }
+
+    /**
+     * This simply calls the same method on the wrapped
+     * collection.
+     *
+     * @return the hashcode of the collection.
+     */
+    public int hashCode()
+    {
+      return c.hashCode();
+    }
+
+  } // class EnvironmentSet<String>
+
 } // class System
Index: java/lang/ProcessBuilder.java
===================================================================
--- java/lang/ProcessBuilder.java	(revision 0)
+++ java/lang/ProcessBuilder.java	(revision 0)
@@ -0,0 +1,118 @@
+/* ProcessBuilder.java - Represent spawned system process
+   Copyright (C) 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public final class ProcessBuilder
+{
+  private File directory = new File(System.getProperty("user.dir"));
+  private List<String> command;
+  // FIXME: make a copy.
+  private Map<String, String> environment = System.getenv();
+  private boolean redirect = false;
+
+  public ProcessBuilder(List<String> command)
+  {
+    this.command = command;
+  }
+
+  public ProcessBuilder(String... command)
+  {
+    this.command = Arrays.asList(command);
+  }
+
+  public List<String> command()
+  {
+    return command;
+  }
+
+  public ProcessBuilder command(List<String> command)
+  {
+    this.command = command;
+    return this;
+  }
+
+  public ProcessBuilder command(String... command)
+  {
+    this.command = Arrays.asList(command);
+    return this;
+  }
+
+  public File directory()
+  {
+    return directory;
+  }
+
+  public ProcessBuilder directory(File directory)
+  {
+    this.directory = directory;
+    return this;
+  }
+
+  public Map<String, String> environment()
+  {
+    return environment;
+  }
+
+  public boolean redirectErrorStream()
+  {
+    return redirect;
+  }
+
+  public ProcessBuilder redirectErrorStream(boolean redirect)
+  {
+    this.redirect = redirect;
+    return this;
+  }
+
+  public Process start() throws IOException
+  {
+    SecurityManager sm = SecurityManager.current; // Be thread-safe!
+    if (sm != null)
+      sm.checkExec(command.get(0));
+    //    return VMProcess.exec(command, environment, directory, redirect);
+    // FIXME
+    return null;
+  }
+}
Index: java/lang/ref/natReference.cc
===================================================================
--- java/lang/ref/natReference.cc	(revision 114871)
+++ java/lang/ref/natReference.cc	(working copy)
@@ -1,6 +1,6 @@
 // natReference.cc - Native code for References
 
-/* Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation
+/* Copyright (C) 2001, 2002, 2003, 2005, 2006  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -368,3 +368,10 @@
       add_to_hash (this);
     }
 }
+
+::java::lang::Object *
+::java::lang::ref::Reference::get()
+{
+  JvSynchronize sync (lock);
+  return referent;
+}
Index: java/lang/ref/Reference.java
===================================================================
--- java/lang/ref/Reference.java	(revision 114871)
+++ java/lang/ref/Reference.java	(working copy)
@@ -1,5 +1,5 @@
 /* java.lang.ref.Reference
-   Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2002, 2003, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -70,7 +70,7 @@
  * @author Jochen Hoenicke
  * @see java.util.WeakHashtable
  */
-public abstract class Reference
+public abstract class Reference<T>
 {
   /**
    * The underlying object.  This field is handled in a special way by
@@ -105,7 +105,7 @@
    * The queue this reference is registered on. This is null, if this
    * wasn't registered to any queue or reference was already enqueued.
    */
-  ReferenceQueue queue;
+  ReferenceQueue<? super T> queue;
 
   /**
    * Link to the next entry on the queue.  If this is null, this
@@ -129,7 +129,7 @@
    * class in a different package.  
    * @param referent the object we refer to.
    */
-  Reference(Object ref)
+  Reference(T ref)
   {
     create (ref);
   }
@@ -142,7 +142,7 @@
    * @param q the reference queue to register on.
    * @exception NullPointerException if q is null.
    */
-  Reference(Object ref, ReferenceQueue q)
+  Reference(T ref, ReferenceQueue<? super T> q)
   {
     if (q == null)
       throw new NullPointerException();
@@ -153,20 +153,14 @@
   /**
    * Notifies the VM that a new Reference has been created.
    */
-  private native void create (Object o);
+  private native void create (T o);
 
   /**
    * Returns the object, this reference refers to.
    * @return the object, this reference refers to, or null if the 
    * reference was cleared.
    */
-  public Object get()
-  {
-    synchronized (lock)
-      {
-	return referent;
-      }
-  }
+  public native T get();
 
   /**
    * Clears the reference, so that it doesn't refer to its object
Index: java/lang/reflect/Method.java
===================================================================
--- java/lang/reflect/Method.java	(revision 114871)
+++ java/lang/reflect/Method.java	(working copy)
@@ -309,7 +309,7 @@
    * @throws ExceptionInInitializerError if accessing a static method triggered
    *         class initialization, which then failed
    */
-  public native Object invoke (Object obj, Object[] args)
+  public native Object invoke (Object obj, Object... args)
     throws IllegalAccessException, IllegalArgumentException,
     InvocationTargetException;
 
Index: java/lang/reflect/Constructor.java
===================================================================
--- java/lang/reflect/Constructor.java	(revision 114871)
+++ java/lang/reflect/Constructor.java	(working copy)
@@ -75,7 +75,7 @@
  * @since 1.1
  * @status updated to 1.4
  */
-public final class Constructor extends AccessibleObject
+public final class Constructor<T> extends AccessibleObject
   implements Member, GenericDeclaration
 {
   private static final int CONSTRUCTOR_MODIFIERS
@@ -92,7 +92,7 @@
    * Gets the class that declared this constructor.
    * @return the class that declared this member
    */
-  public Class getDeclaringClass()
+  public Class<T> getDeclaringClass ()
   {
     return declaringClass;
   }
@@ -320,8 +320,7 @@
    *         specification, version 3.
    * @since 1.5
    */
-  /* FIXME[GENERICS]: Add <Constructor<T>> */
-  public TypeVariable[] getTypeParameters()
+  public TypeVariable<Constructor<T>>[] getTypeParameters()
   {
     String sig = getSignature();
     if (sig == null)
@@ -386,7 +385,7 @@
   private native void getType ();
 
   // Declaring class.
-  private Class declaringClass;
+  private Class<T> declaringClass;
 
   // Exception types.
   private Class[] exception_types;
Index: java/lang/Class.java
===================================================================
--- java/lang/Class.java	(revision 114871)
+++ java/lang/Class.java	(working copy)
@@ -43,6 +43,7 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
@@ -82,7 +83,7 @@
  * @since 1.0
  * @see ClassLoader
  */
-public final class Class implements Type, GenericDeclaration, Serializable
+public final class Class<T> implements Type, GenericDeclaration, Serializable
 {
   /**
    * Class is non-instantiable from Java code; only the VM can create
@@ -231,7 +232,7 @@
    * @see #getConstructors()
    * @since 1.1
    */
-  public native Constructor getConstructor(Class[] args)
+  public native Constructor<T> getConstructor(Class... args)
     throws NoSuchMethodException;
 
   /**
@@ -266,7 +267,7 @@
    * @see #getDeclaredConstructors()
    * @since 1.1
    */
-  public native Constructor getDeclaredConstructor(Class[] args)
+  public native Constructor<T> getDeclaredConstructor(Class... args)
     throws NoSuchMethodException;
 
   /**
@@ -368,7 +369,7 @@
    * @see #getDeclaredMethods()
    * @since 1.1
    */
-  public Method getDeclaredMethod(String methodName, Class[] args)
+  public Method getDeclaredMethod(String methodName, Class... args)
     throws NoSuchMethodException
   {
     memberAccessCheck(Member.DECLARED);
@@ -527,7 +528,7 @@
    * @see #getMethods()
    * @since 1.1
    */
-  public Method getMethod(String methodName, Class[] args)
+  public Method getMethod(String methodName, Class... args)
     throws NoSuchMethodException
   {
     memberAccessCheck(Member.PUBLIC);
@@ -929,7 +930,89 @@
       }
   }
 
+
   /**
+   * Returns the enumeration constants of this class, or
+   * null if this class is not an <code>Enum</code>.
+   *
+   * @return an array of <code>Enum</code> constants
+   *         associated with this class, or null if this
+   *         class is not an <code>enum</code>.
+   * @since 1.5
+   */
+  public T[] getEnumConstants()
+  {
+    if (isEnum())
+      {
+	try
+	  {
+	    return (T[]) getMethod("values").invoke(null);
+	  }
+	catch (NoSuchMethodException exception)
+	  {
+	    throw new Error("Enum lacks values() method");
+	  }
+	catch (IllegalAccessException exception)
+	  {
+	    throw new Error("Unable to access Enum class");
+	  }
+	catch (InvocationTargetException exception)
+	  {
+	    throw new
+	      RuntimeException("The values method threw an exception",
+			       exception);
+	  }
+      }
+    else
+      {
+	return null;
+      }
+  }
+
+  /**
+   * Returns true if this class is an <code>Enum</code>.
+   *
+   * @return true if this is an enumeration class.
+   * @since 1.5
+   */
+  public boolean isEnum()
+  {
+    // FIXME
+    int mod = getModifiers ();
+    // FIXME: was 'ENUM'
+    return (mod & 0x4000) != 0;
+  }
+
+  /**
+   * Returns true if this class is a synthetic class, generated by
+   * the compiler.
+   *
+   * @return true if this is a synthetic class.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    // FIXME
+    int mod = getModifiers ();
+    // FIXME: was SYNTHETIC
+    return (mod & 0x1000) != 0;
+  }
+
+  /**
+   * Returns true if this class is an <code>Annotation</code>.
+   *
+   * @return true if this is an annotation class.
+   * @since 1.5
+   */
+  public boolean isAnnotation()
+  {
+    // FIXME
+    int mod = getModifiers ();
+    // FIXME: was ANNOTATION
+    return (mod & 0x2000) != 0;
+  }
+
+  /**
    * Returns the simple name for this class, as used in the source
    * code.  For normal classes, this is the content returned by
    * <code>getName()</code> which follows the last ".".  Anonymous
@@ -956,8 +1039,7 @@
    *         a top-level class.
    * @since 1.5
    */
-   /* FIXME[GENERICS]: Should return Class<?> */
-  public Class getEnclosingClass()
+  public Class<?> getEnclosingClass()
   {
     // FIXME write real implementation
     return null;
@@ -974,8 +1056,7 @@
    *         is returned.
    * @since 1.5
    */
-   /* FIXME[GENERICS]: Should return Constructor<?> */
-  public Constructor getEnclosingConstructor()
+  public Constructor<T> getEnclosingConstructor()
   {
     // FIXME write real implementation
     return null;
@@ -1010,8 +1091,7 @@
    *         specification, version 3.
    * @since 1.5
    */
-   /* FIXME[GENERICS]: Should return TypeVariable<Class<T>> */
-  public TypeVariable[] getTypeParameters()
+  public TypeVariable<Class<T>>[] getTypeParameters()
   {
     // FIXME - provide real implementation.
     return new TypeVariable[0];
Index: java/io/PrintStream.java
===================================================================
--- java/io/PrintStream.java	(revision 114871)
+++ java/io/PrintStream.java	(working copy)
@@ -1,5 +1,5 @@
 /* PrintStream.java -- OutputStream for printing output
-   Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005  Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,6 +38,9 @@
 
 package java.io;
 
+import java.util.Formatter;
+import java.util.Locale;
+
 import gnu.gcj.convert.UnicodeToBytes;
 
 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
@@ -58,7 +61,7 @@
  * @author Aaron M. Renn (arenn@urbanophile.com)
  * @author Tom Tromey (tromey@cygnus.com)
  */
-public class PrintStream extends FilterOutputStream
+public class PrintStream extends FilterOutputStream implements Appendable
 {
   /* Notice the implementation is quite similar to OutputStreamWriter.
    * This leads to some minor duplication, because neither inherits
@@ -558,5 +561,52 @@
         setError ();
       }
   }
+
+  /** @since 1.5 */
+  public PrintStream append(char c)
+  {
+    print(c);
+    return this;
+  }
+
+  /** @since 1.5 */
+  public PrintStream append(CharSequence cs)
+  {
+    print(cs == null ? "null" : cs.toString());
+    return this;
+  }
+
+  /** @since 1.5 */
+  public PrintStream append(CharSequence cs, int start, int end)
+  {
+    print(cs == null ? "null" : cs.subSequence(start, end).toString());
+    return this;
+  }
+
+  /** @since 1.5 */
+  public PrintStream printf(String format, Object... args)
+  {
+    return format(format, args);
+  }
+
+  /** @since 1.5 */
+  public PrintStream printf(Locale locale, String format, Object... args)
+  {
+    return format(locale, format, args);
+  }
+
+  /** @since 1.5 */
+  public PrintStream format(String format, Object... args)
+  {
+    return format(Locale.getDefault(), format, args);
+  }
+
+  /** @since 1.5 */
+  public PrintStream format(Locale locale, String format, Object... args)
+  {
+    Formatter f = new Formatter(this, locale);
+    f.format(format, args);
+    return this;
+  }
 } // class PrintStream
 
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 114871)
+++ Makefile.am	(working copy)
@@ -349,13 +349,13 @@
 	java/lang/reflect/Field.h java/lang/reflect/Method.h \
 	java/lang/reflect/Proxy.h gnu/gcj/runtime/ExtensionClassLoader.h
 
-generic_header_files = $(filter-out $(omitted_headers),$(ordinary_header_files) $(xlib_nat_headers))
+generic_header_files = $(ordinary_header_files) $(xlib_nat_headers)
 
-$(generic_header_files): %.h: classpath/lib/%.class
-	name=`echo $< | sed -e 's/\.class$$//' -e 's,classpath/lib/,,'`; \
-	$(mkinstalldirs) `dirname $$name`; \
-	$(GCJH) -d . -classpath '' -bootclasspath classpath/lib $$name
+MYGCJH = gcjh1
 
+$(generic_header_files):
+	$(MYGCJH) --cni --all classpath/lib --cmdfile=$(srcdir)/headers.txt
+
 inner_nat_headers = java/io/ObjectOutputStream$$PutField.h \
 	java/io/ObjectInputStream$$GetField.h \
 	java/nio/DirectByteBufferImpl$$ReadWrite.h \
@@ -374,137 +374,6 @@
 
 xlib_nat_headers = $(gnu_awt_xlib_header_files) $(gnu_gcj_xlib_header_files)
 
-java/lang/ClassLoader.h: classpath/lib/java/lang/ClassLoader.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-		-prepend 'jclass _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);' \
-		-prepend 'void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, bool is_jar);' \
-		-friend 'jclass (::_Jv_FindClass) (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);' \
-		-friend 'void ::_Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, bool is_jar);' \
-		java/lang/ClassLoader
-
-java/lang/Thread.h: classpath/lib/java/lang/Thread.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-		-prepend 'class _Jv_JNIEnv;' \
-		-prepend '#define _JV_NOT_OWNER 1' \
-		-prepend '#define _JV_INTERRUPTED 2' \
-		-prepend '_Jv_JNIEnv * _Jv_GetCurrentJNIEnv ();' \
-		-prepend 'void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);' \
-		-prepend 'void _Jv_ThreadRun (java::lang::Thread* thread);' \
-		-prepend 'jint _Jv_AttachCurrentThread(java::lang::Thread* thread);' \
-		-prepend 'java::lang::Thread* _Jv_AttachCurrentThread (jstring name, java::lang::ThreadGroup* group);' \
-		-prepend 'java::lang::Thread* _Jv_AttachCurrentThreadAsDaemon (jstring name, java::lang::ThreadGroup* group);' \
-		-prepend 'jint _Jv_DetachCurrentThread ();' \
-		-friend '_Jv_JNIEnv * ::_Jv_GetCurrentJNIEnv ();' \
-		-friend 'void ::_Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);' \
-		-friend 'void ::_Jv_ThreadRun (java::lang::Thread* thread);' \
-		-friend 'jint (::_Jv_AttachCurrentThread) (java::lang::Thread* thread);' \
-		-friend 'java::lang::Thread* ::_Jv_AttachCurrentThread (jstring name, java::lang::ThreadGroup* group);' \
-		-friend 'java::lang::Thread* ::_Jv_AttachCurrentThreadAsDaemon (jstring name, java::lang::ThreadGroup* group);' \
-		-friend 'jint (::_Jv_DetachCurrentThread) ();' \
-		java/lang/Thread
-
-java/lang/String.h: classpath/lib/java/lang/String.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	    -prepend 'jchar* _Jv_GetStringChars (jstring str);' \
-	    -prepend 'jstring* _Jv_StringFindSlot (jchar*, jint, jint);' \
-	    -prepend 'jstring* _Jv_StringGetSlot (jstring);' \
-	    -prepend 'jstring _Jv_NewStringUtf8Const (_Jv_Utf8Const* str);' \
-	    -prepend 'jstring _Jv_NewStringLatin1 (const char*, jsize);' \
-	    -prepend 'jstring _Jv_AllocString (jsize);' \
-	    -friend 'jchar* ::_Jv_GetStringChars (jstring str);' \
-	    -friend 'jstring* ::_Jv_StringFindSlot (jchar*, jint, jint);' \
-	    -friend 'jstring* ::_Jv_StringGetSlot (jstring);' \
-	    -friend 'jstring (::_Jv_NewStringUtf8Const) (_Jv_Utf8Const* str);' \
-	    -friend 'jstring (::_Jv_NewStringLatin1) (const char*, jsize);' \
-	    -friend 'jstring (::_Jv_AllocString) (jsize);' \
-	    java/lang/String
-
-java/lang/reflect/Constructor.h: classpath/lib/java/lang/reflect/Constructor.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	    -prepend 'jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);' \
-	    -prepend 'jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);' \
-	    -friend 'jmethodID (::_Jv_FromReflectedConstructor) (java::lang::reflect::Constructor *);' \
-	    -friend 'jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID, jboolean);' \
-	    -friend 'class java::lang::Class;' \
-	    java/lang/reflect/Constructor
-
-java/lang/reflect/Field.h: classpath/lib/java/lang/reflect/Field.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	    -prepend 'jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);' \
-	    -prepend 'jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv*, jclass, jfieldID, jboolean);' \
-	    -friend 'jfieldID (::_Jv_FromReflectedField) (java::lang::reflect::Field *);' \
-	    -friend 'jobject (::_Jv_JNI_ToReflectedField) (_Jv_JNIEnv*, jclass, jfieldID, jboolean);' \
-	    -friend 'class java::lang::Class;' \
-	    java/lang/reflect/Field
-
-java/lang/reflect/Method.h: classpath/lib/java/lang/reflect/Method.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	    -prepend 'jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);' \
-	    -prepend 'jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);' \
-	    -friend 'jmethodID (::_Jv_FromReflectedMethod) (java::lang::reflect::Method *);' \
-	    -friend 'jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID, jboolean);' \
-	    -friend 'class java::lang::Class;' \
-	    -friend 'class java::io::ObjectInputStream;' \
-	    java/lang/reflect/Method
-
-java/lang/reflect/Proxy.h: classpath/lib/java/lang/reflect/Proxy.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	    java/lang/reflect/Proxy
-
-java/lang/reflect/Proxy$$ProxyData.h: classpath/lib/java/lang/reflect/Proxy.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'java/lang/reflect/Proxy$$ProxyData'
-
-java/lang/reflect/Proxy$$ProxyType.h: classpath/lib/java/lang/reflect/Proxy.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'java/lang/reflect/Proxy$$ProxyType'
-
-gnu/gcj/runtime/ExtensionClassLoader.h: classpath/lib/gnu/gcj/runtime/ExtensionClassLoader.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	    -friend 'class ::java::lang::ClassLoader;' \
-	    gnu/gcj/runtime/ExtensionClassLoader
-
-java/io/ObjectInputStream$$GetField.h: classpath/lib/java/io/ObjectInputStream.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'java/io/ObjectInputStream$$GetField'
-
-java/io/ObjectOutputStream$$PutField.h: classpath/lib/java/io/ObjectOutputStream.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'java/io/ObjectOutputStream$$PutField'
-
-java/nio/DirectByteBufferImpl$$ReadWrite.h: classpath/lib/java/nio/DirectByteBufferImpl.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'java/nio/DirectByteBufferImpl$$ReadWrite'
-
-java/nio/channels/Pipe$$SinkChannel.h: classpath/lib/java/nio/channels/Pipe.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'java/nio/channels/Pipe$$SinkChannel'
-
-java/nio/channels/Pipe$$SourceChannel.h: classpath/lib/java/nio/channels/Pipe.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'java/nio/channels/Pipe$$SourceChannel'
-
-gnu/java/net/PlainSocketImpl$$SocketInputStream.h: classpath/lib/gnu/java/net/PlainSocketImpl.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'gnu/java/net/PlainSocketImpl$$SocketInputStream'
-
-gnu/java/net/PlainSocketImpl$$SocketOutputStream.h: classpath/lib/gnu/java/net/PlainSocketImpl.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'gnu/java/net/PlainSocketImpl$$SocketOutputStream'
-
-gnu/java/nio/PipeImpl$$SinkChannelImpl.h: classpath/lib/gnu/java/nio/PipeImpl.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'gnu/java/nio/PipeImpl$$SinkChannelImpl'
-
-gnu/java/nio/PipeImpl$$SourceChannelImpl.h: classpath/lib/gnu/java/nio/PipeImpl.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'gnu/java/nio/PipeImpl$$SourceChannelImpl'
-
-## Only used by PosixProcess.java
-java/lang/ConcreteProcess$$ProcessManager.h: classpath/lib/java/lang/ConcreteProcess.class
-	$(GCJH) -classpath '' -bootclasspath classpath/lib \
-	'java/lang/ConcreteProcess$$ProcessManager'
-
 ## Headers we maintain by hand and which we want to install.
 extra_headers = java/lang/Object.h java/lang/Class.h
 
Index: headers.txt
===================================================================
--- headers.txt	(revision 0)
+++ headers.txt	(revision 0)
@@ -0,0 +1,63 @@
+class java/lang/ClassLoader
+prepend jclass _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);
+prepend void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, bool is_jar);
+friend jclass (::_Jv_FindClass) (_Jv_Utf8Const *name, java::lang::ClassLoader *loader);
+friend void ::_Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, bool is_jar);
+
+class java/lang/Thread
+prepend class _Jv_JNIEnv;
+prepend #define _JV_NOT_OWNER 1
+prepend #define _JV_INTERRUPTED 2
+prepend _Jv_JNIEnv * _Jv_GetCurrentJNIEnv ();
+prepend void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);
+prepend void _Jv_ThreadRun (java::lang::Thread* thread);
+prepend jint _Jv_AttachCurrentThread(java::lang::Thread* thread);
+prepend java::lang::Thread* _Jv_AttachCurrentThread (jstring name, java::lang::ThreadGroup* group);
+prepend java::lang::Thread* _Jv_AttachCurrentThreadAsDaemon (jstring name, java::lang::ThreadGroup* group);
+prepend jint _Jv_DetachCurrentThread ();
+friend _Jv_JNIEnv * ::_Jv_GetCurrentJNIEnv ();
+friend void ::_Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);
+friend void ::_Jv_ThreadRun (java::lang::Thread* thread);
+friend jint (::_Jv_AttachCurrentThread) (java::lang::Thread* thread);
+friend java::lang::Thread* ::_Jv_AttachCurrentThread (jstring name, java::lang::ThreadGroup* group);
+friend java::lang::Thread* ::_Jv_AttachCurrentThreadAsDaemon (jstring name, java::lang::ThreadGroup* group);
+friend jint (::_Jv_DetachCurrentThread) ();
+
+class java/lang/String
+prepend jchar* _Jv_GetStringChars (jstring str);
+prepend jstring* _Jv_StringFindSlot (jchar*, jint, jint);
+prepend jstring* _Jv_StringGetSlot (jstring);
+prepend jstring _Jv_NewStringUtf8Const (_Jv_Utf8Const* str);
+prepend jstring _Jv_NewStringLatin1 (const char*, jsize);
+prepend jstring _Jv_AllocString (jsize);
+friend jchar* ::_Jv_GetStringChars (jstring str);
+friend jstring* ::_Jv_StringFindSlot (jchar*, jint, jint);
+friend jstring* ::_Jv_StringGetSlot (jstring);
+friend jstring (::_Jv_NewStringUtf8Const) (_Jv_Utf8Const* str);
+friend jstring (::_Jv_NewStringLatin1) (const char*, jsize);
+friend jstring (::_Jv_AllocString) (jsize);
+
+class java/lang/reflect/Constructor
+prepend jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);
+prepend jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+friend jmethodID (::_Jv_FromReflectedConstructor) (java::lang::reflect::Constructor *);
+friend jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+friend class java::lang::Class;
+
+class java/lang/reflect/Field
+prepend jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
+prepend jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv*, jclass, jfieldID, jboolean);
+friend jfieldID (::_Jv_FromReflectedField) (java::lang::reflect::Field *);
+friend jobject (::_Jv_JNI_ToReflectedField) (_Jv_JNIEnv*, jclass, jfieldID, jboolean);
+friend class java::lang::Class;
+
+class java/lang/reflect/Method
+prepend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
+prepend jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+friend jmethodID (::_Jv_FromReflectedMethod) (java::lang::reflect::Method *);
+friend jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+friend class java::lang::Class;
+friend class java::io::ObjectInputStream;
+
+class gnu/gcj/runtime/ExtensionClassLoader
+friend class ::java::lang::ClassLoader;



More information about the Java-patches mailing list