http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/io/FileVisitResult.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/io/FileVisitResult.java b/src/main/groovy/io/FileVisitResult.java deleted file mode 100644 index 2c73dd1..0000000 --- a/src/main/groovy/io/FileVisitResult.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.io; - -/** - * Represents special return values for the 'preDir', 'postDir' and 'visit'/supplied Closures used with - * {@link org.codehaus.groovy.runtime.DefaultGroovyMethods#traverse(java.io.File, java.util.Map, groovy.lang.Closure)} - * and related methods to control subsequent traversal behavior. - */ -public enum FileVisitResult { - /** Continue processing; the default */ - CONTINUE, - /** Skip processing sibling files/directories within the current directory being processed */ - SKIP_SIBLINGS, - /** Do not process the child files/subdirectories within the current directory being processed */ - SKIP_SUBTREE, - /** Do not process any more files */ - TERMINATE -}
http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/io/GroovyPrintStream.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/io/GroovyPrintStream.java b/src/main/groovy/io/GroovyPrintStream.java deleted file mode 100644 index d77c5aa..0000000 --- a/src/main/groovy/io/GroovyPrintStream.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.io; - -import org.codehaus.groovy.runtime.InvokerHelper; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; - -/** - * A PrintStream that outputs objects in Groovy style. - * That means print(Object) uses InvokerHelper.toString(Object) - * to produce the same results as Writer.print(Object). - * - * @author Jim White - * @since 1.6 - */ -public class GroovyPrintStream extends PrintStream -{ - /** - * Creates a new print stream. This stream will not flush automatically. - * - * @see java.io.PrintStream#PrintStream(java.io.OutputStream) - */ - public GroovyPrintStream(OutputStream out) { - super(out, false); - } - - /** - * Creates a new print stream. - * - * @see java.io.PrintStream#PrintStream(java.io.OutputStream, boolean) - */ - public GroovyPrintStream(OutputStream out, boolean autoFlush) { - super(out, autoFlush); - } - - /** - * Creates a new print stream. - * - * @see java.io.PrintStream#PrintStream(java.io.OutputStream, boolean, String) - */ - public GroovyPrintStream(OutputStream out, boolean autoFlush, String encoding) - throws UnsupportedEncodingException - { - super(out, autoFlush, encoding); - } - - /** - * Creates a new print stream, without automatic line flushing, with the - * specified file name. - * - * @see java.io.PrintStream#PrintStream(String) - */ - public GroovyPrintStream(String fileName) throws FileNotFoundException { - super(fileName); - } - - /** - * Creates a new print stream, without automatic line flushing, with the - * specified file name and charset. - * - * @see java.io.PrintStream#PrintStream(String, String) - */ - public GroovyPrintStream(String fileName, String csn) - throws FileNotFoundException, UnsupportedEncodingException - { - super(fileName, csn); - } - - /** - * Creates a new print stream, without automatic line flushing, with the - * specified file. - * - * @see java.io.PrintStream#PrintStream(File) - */ - public GroovyPrintStream(File file) throws FileNotFoundException { - super(file); - } - - /** - * Creates a new print stream, without automatic line flushing, with the - * specified file and charset. - * - * @see java.io.PrintStream#PrintStream(File, String) - */ - public GroovyPrintStream(File file, String csn) - throws FileNotFoundException, UnsupportedEncodingException - { - super(file, csn); - } - - /** - * Prints an object Groovy style. - * - * @param obj The <code>Object</code> to be printed - */ - public void print(Object obj) { - print(InvokerHelper.toString(obj)); - } - - /** - * Prints an object Groovy style followed by a newline. - * - * @param obj The <code>Object</code> to be printed - */ - public void println(Object obj) { - println(InvokerHelper.toString(obj)); - } - -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/io/GroovyPrintWriter.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/io/GroovyPrintWriter.java b/src/main/groovy/io/GroovyPrintWriter.java deleted file mode 100644 index 0a076b9..0000000 --- a/src/main/groovy/io/GroovyPrintWriter.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.io; - -import org.codehaus.groovy.runtime.InvokerHelper; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.io.Writer; - -/** - * A PrintWriter that outputs objects in Groovy style. - * That means print(Object) uses InvokerHelper.toString(Object) - * to produce the same results as Writer.print(Object). - * - * @author Jim White - * @since 1.6 - */ -public class GroovyPrintWriter extends PrintWriter -{ - public GroovyPrintWriter(File file) throws FileNotFoundException - { - super(file); - } - - public GroovyPrintWriter(File file, String csn) - throws FileNotFoundException, UnsupportedEncodingException - { - super(file, csn); - } - - public GroovyPrintWriter(Writer out) - { - super(out); - } - - public GroovyPrintWriter(Writer out, boolean autoflush) - { - super(out, autoflush); - } - - public GroovyPrintWriter(OutputStream out) - { - super(out); - } - - public GroovyPrintWriter(OutputStream out, boolean autoflush) - { - super(out, autoflush); - } - - public GroovyPrintWriter(String filename) throws FileNotFoundException - { - super(filename); - } - - public GroovyPrintWriter(String filename, String csn) - throws FileNotFoundException, UnsupportedEncodingException - { - super(filename, csn); - } - -// Don't need to do this if Groovy is going to print char[] like a string. -// public void print(char[] x) -// { -// write(InvokerHelper.toString(x)); -// } - - public void print(Object x) - { - write(InvokerHelper.toString(x)); - } - - public void println(Object x) - { - // JDK 1.6 has changed the implementation to do a - // String.valueOf(x) rather than call print(x). - // Probably to improve performance by doing the conversion outside the lock. - // This will do the same thing for us, and we don't have to have access to the lock. - println(InvokerHelper.toString(x)); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/io/LineColumnReader.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/io/LineColumnReader.java b/src/main/groovy/io/LineColumnReader.java deleted file mode 100644 index 49b7c94..0000000 --- a/src/main/groovy/io/LineColumnReader.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.io; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.nio.CharBuffer; - -/** - * The <code>LineColumnReader</code> is an extension to <code>BufferedReader</code> - * that keeps track of the line and column information of where the cursor is. - * - * @author Guillaume Laforge - * @since 1.8.0 - */ -public class LineColumnReader extends BufferedReader { - - /** - * The current line position - */ - private long line = 1; - - /** - * The current column position - */ - private long column = 1; - - /** - * The latest marked line position - */ - private long lineMark = 1; - - /** - * The latest marked line position - */ - private long columnMark = 1; - - private boolean newLineWasRead = false; - - /** - * Constructor wrapping a <code>Reader</code> - * (<code>FileReader</code>, <code>FileReader</code>, <code>InputStreamReader</code>, etc.) - * - * @param reader the reader to wrap - */ - public LineColumnReader(Reader reader) { - super(reader); - } - - /** - * Marks the present position in the stream. Subsequent calls to reset() will attempt to reposition the stream to this point. - * - * @param readAheadLimit Limit on the number of characters that may be read while still preserving the mark. - * An attempt to reset the stream after reading characters up to this limit or beyond may fail. - * A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. - * Therefore large values should be used with care. - */ - @Override - public void mark(int readAheadLimit) throws IOException { - lineMark = line; - columnMark = column; - super.mark(readAheadLimit); - } - - /** - * Resets the stream to the most recent mark. - */ - @Override - public void reset() throws IOException { - line = lineMark; - column = columnMark; - super.reset(); - } - - /** - * Reads a single character. - * - * @return The character read, as an integer in the range 0 to 65535 (0x00-0xffff), - * or -1 if the end of the stream has been reached - */ - @Override - public int read() throws IOException { - if (newLineWasRead) { - line += 1; - column = 1; - newLineWasRead = false; - } - - int charRead = super.read(); - if (charRead > -1) { - char c = (char)charRead; - // found a \r or \n, like on Mac or Unix - // could also be Windows' \r\n - if (c == '\r' || c == '\n') { - newLineWasRead = true; - if (c == '\r') { - mark(1); - c = (char)super.read(); - // check if we have \r\n like on Windows - // if it's not \r\n we reset, otherwise, the \n is just consummed - if (c != '\n') { - reset(); - } - } - } else { - column += 1; - } - } - - return charRead; - } - - /** - * Reads characters into a portion of an array. - * - * @param chars Destination array of char - * @param startOffset Offset at which to start storing characters - * @param length Maximum number of characters to read - * @return an exception if an error occurs - */ - @Override - public int read(char[] chars, int startOffset, int length) throws IOException { - for (int i = startOffset; i <= startOffset + length; i++) { - int readInt = read(); - if (readInt == -1) return i - startOffset; - chars[i] = (char)readInt; - } - return length; - } - - /** - * Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), - * a carriage return ('\r'), or a carriage return followed immediately by a linefeed. - * - * @return A String containing the contents of the line, not including any line-termination characters, - * or null if the end of the stream has been reached - */ - @Override - public String readLine() throws IOException { - StringBuilder result = new StringBuilder(); - for (;;) { - int intRead = read(); - if (intRead == -1) { - return result.length() == 0 ? null : result.toString(); - } - - char c = (char)intRead; - if (c == '\n' || c == '\r') break; - result.append(c); - } - return result.toString(); - } - - /** - * Skips characters. - * - * @param toSkip the number of characters to skip - * @return The number of characters actually skipped - */ - @Override - public long skip(long toSkip) throws IOException { - for (long i = 0; i < toSkip; i++) { - int intRead = read(); - if (intRead == -1) return i; - } - return toSkip; - } - - /** - * Reads characters into an array. - * This method will block until some input is available, an I/O error occurs, - * or the end of the stream is reached. - * - * @param chars Destination buffer - * @return The number of characters read, or -1 if the end of the stream has been reached - */ - @Override - public int read(char[] chars) throws IOException { - return read(chars, 0, chars.length - 1); - } - - /** - * Not implemented. - * - * @param buffer Destination buffer - * @return The number of characters read, or -1 if the end of the stream has been reached - * @throws UnsupportedOperationException as the method is not implemented - */ - @Override - public int read(CharBuffer buffer) { - throw new UnsupportedOperationException("read(CharBuffer) not yet implemented"); - } - - /** - * Closes the stream and releases any system resources associated with it. - * Once the stream has been closed, further read(), ready(), mark(), reset(), or skip() invocations - * will throw an IOException. Closing a previously closed stream has no effect. - */ - @Override - public void close() throws IOException { - super.close(); - } - - public long getColumn() { - return column; - } - - public void setColumn(long column) { - this.column = column; - } - - public long getColumnMark() { - return columnMark; - } - - public void setColumnMark(long columnMark) { - this.columnMark = columnMark; - } - - public long getLine() { - return line; - } - - public void setLine(long line) { - this.line = line; - } - - public long getLineMark() { - return lineMark; - } - - public void setLineMark(long lineMark) { - this.lineMark = lineMark; - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/io/PlatformLineWriter.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/io/PlatformLineWriter.java b/src/main/groovy/io/PlatformLineWriter.java deleted file mode 100644 index 0071e0f..0000000 --- a/src/main/groovy/io/PlatformLineWriter.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.io; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.Writer; - -/** - * A buffered writer that gobbles any \r characters - * and replaces every \n with a platform specific newline. - * In many places Groovy normalises streams to only have \n - * characters but when creating files that must be used - * by other platform-aware tools, you sometimes want the - * newlines to match what the platform expects. - * - * @author Paul King - */ -public class PlatformLineWriter extends Writer { - private final BufferedWriter writer; - - public PlatformLineWriter(Writer out) { - writer = new BufferedWriter(out); - } - - public PlatformLineWriter(Writer out, int sz) { - writer = new BufferedWriter(out, sz); - } - - public void write(char cbuf[], int off, int len) throws IOException { - for (; len > 0; len--) { - char c = cbuf[off++]; - if (c == '\n') { - writer.newLine(); - } else if (c != '\r') { - writer.write(c); - } - } - } - - public void flush() throws IOException { - writer.flush(); - } - - public void close() throws IOException { - writer.close(); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/io/package.html ---------------------------------------------------------------------- diff --git a/src/main/groovy/io/package.html b/src/main/groovy/io/package.html deleted file mode 100644 index fef0d09..0000000 --- a/src/main/groovy/io/package.html +++ /dev/null @@ -1,28 +0,0 @@ -<!-- - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. - ---> -<html> - <head> - <title>package groovy.io.*</title> - </head> - <body> - <p>Classes for Groovier Input/Output.</p> - </body> -</html> http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/lang/AdaptingMetaClass.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/AdaptingMetaClass.java b/src/main/groovy/lang/AdaptingMetaClass.java deleted file mode 100644 index 81afc26..0000000 --- a/src/main/groovy/lang/AdaptingMetaClass.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -/** - * An interface for MetaClass instances that "adapt" other MetaClass instances such as a proxy or - * delegating MetaClass. - * - * @author Graeme Rocher - * @since 1.5 - */ -public interface AdaptingMetaClass extends MetaClass { - - /** - * Returns the MetaClass that this adapter adapts - * - * @return The MetaClass instance - */ - MetaClass getAdaptee(); - - /** - * Sets the MetaClass adapted by this MetaClass - * - * @param metaClass The MetaClass to adapt - */ - void setAdaptee(MetaClass metaClass); -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/lang/BenchmarkInterceptor.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/BenchmarkInterceptor.java b/src/main/groovy/lang/BenchmarkInterceptor.java deleted file mode 100644 index 77bcb64..0000000 --- a/src/main/groovy/lang/BenchmarkInterceptor.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * Interceptor that registers the timestamp of each method call - * before and after invocation. The timestamps are stored internally - * and can be retrieved through the with the <pre>getCalls()</pre> - * and <pre>statistic()</pre> API. - * <p> - * Example usage: - * <pre> - * def proxy = ProxyMetaClass.getInstance(ArrayList.class) - * proxy.interceptor = new BenchmarkInterceptor() - * proxy.use { - * def list = (0..10000).collect{ it } - * 4.times { list.size() } - * 4000.times { list.set(it, it+1) } - * } - * proxy.interceptor.statistic() - * </pre> - * Which produces the following output: - * <pre> - * [[size, 4, 0], [set, 4000, 21]] - * </pre> - */ -public class BenchmarkInterceptor implements Interceptor { - - protected Map calls = new LinkedHashMap(); // keys to list of invocation times and before and after - - /** - * Returns the raw data associated with the current benchmark run. - */ - public Map getCalls() { - return calls; - } - - /** - * Resets all the benchmark data on this object. - */ - public void reset() { - calls = new HashMap(); - } - /** - * This code is executed before the method is called. - * @param object receiver object for the method call - * @param methodName name of the method to call - * @param arguments arguments to the method call - * @return null - * relays this result. - */ - public Object beforeInvoke(Object object, String methodName, Object[] arguments) { - if (!calls.containsKey(methodName)) calls.put(methodName, new LinkedList()); - ((List) calls.get(methodName)).add(Long.valueOf(System.currentTimeMillis())); - - return null; - } - /** - * This code is executed after the method is called. - * @param object receiver object for the called method - * @param methodName name of the called method - * @param arguments arguments to the called method - * @param result result of the executed method call or result of beforeInvoke if method was not called - * @return result - */ - public Object afterInvoke(Object object, String methodName, Object[] arguments, Object result) { - ((List) calls.get(methodName)).add(Long.valueOf(System.currentTimeMillis())); - return result; - } - - /** - * The call should be invoked separately - * @return true - */ - public boolean doInvoke() { - return true; - } - - /** - * Returns benchmark statistics as a List<Object[]>. - * AccumulateTime is measured in milliseconds and is as accurate as - * System.currentTimeMillis() allows it to be. - * @return a list of lines, each item is [methodname, numberOfCalls, accumulatedTime] - */ - public List statistic() { - List result = new LinkedList(); - for (Iterator iter = calls.keySet().iterator(); iter.hasNext();) { - Object[] line = new Object[3]; - result.add(line); - line[0] = iter.next(); - List times = (List) calls.get(line[0]); - line[1] = Integer.valueOf(times.size() / 2); - int accTime = 0; - for (Iterator it = times.iterator(); it.hasNext();) { - Long start = (Long) it.next(); - Long end = (Long) it.next(); - accTime += end.longValue() - start.longValue(); - } - line[2] = Long.valueOf(accTime); - } - return result; - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/lang/Binding.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/Binding.java b/src/main/groovy/lang/Binding.java deleted file mode 100644 index 6505ea5..0000000 --- a/src/main/groovy/lang/Binding.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Represents the variable bindings of a script which can be altered - * from outside the script object or created outside of a script and passed - * into it. - * <p> Binding instances are not supposed to be used in a multi-threaded context. - * - * @author <a href="mailto:[email protected]">James Strachan</a> - */ -public class Binding extends GroovyObjectSupport { - private Map variables; - - public Binding() { - } - - public Binding(Map variables) { - this.variables = variables; - } - - /** - * A helper constructor used in main(String[]) method calls - * - * @param args are the command line arguments from a main() - */ - public Binding(String[] args) { - this(); - setVariable("args", args); - } - - /** - * @param name the name of the variable to lookup - * @return the variable value - */ - public Object getVariable(String name) { - if (variables == null) - throw new MissingPropertyException(name, this.getClass()); - - Object result = variables.get(name); - - if (result == null && !variables.containsKey(name)) { - throw new MissingPropertyException(name, this.getClass()); - } - - return result; - } - - /** - * Sets the value of the given variable - * - * @param name the name of the variable to set - * @param value the new value for the given variable - */ - public void setVariable(String name, Object value) { - if (variables == null) - variables = new LinkedHashMap(); - variables.put(name, value); - } - - /** - * Simple check for whether the binding contains a particular variable or not. - * - * @param name the name of the variable to check for - */ - public boolean hasVariable(String name) { - return variables != null && variables.containsKey(name); - } - - public Map getVariables() { - if (variables == null) - variables = new LinkedHashMap(); - return variables; - } - - /** - * Overloaded to make variables appear as bean properties or via the subscript operator - */ - public Object getProperty(String property) { - /** @todo we should check if we have the property with the metaClass instead of try/catch */ - try { - return super.getProperty(property); - } - catch (MissingPropertyException e) { - return getVariable(property); - } - } - - /** - * Overloaded to make variables appear as bean properties or via the subscript operator - */ - public void setProperty(String property, Object newValue) { - /** @todo we should check if we have the property with the metaClass instead of try/catch */ - try { - super.setProperty(property, newValue); - } - catch (MissingPropertyException e) { - setVariable(property, newValue); - } - } - -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/lang/Buildable.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/Buildable.java b/src/main/groovy/lang/Buildable.java deleted file mode 100644 index af22958..0000000 --- a/src/main/groovy/lang/Buildable.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - - -public interface Buildable { - void build(GroovyObject builder); -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/lang/Category.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/Category.java b/src/main/groovy/lang/Category.java deleted file mode 100644 index f880828..0000000 --- a/src/main/groovy/lang/Category.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import org.codehaus.groovy.transform.GroovyASTTransformationClass; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Transforms an instance-style Groovy class or interface to become a static-style - * conventional Groovy category. - * <p> - * Groovy categories are the original mechanism used - * by Groovy when augmenting classes with new methods. Writing categories required - * using a class writing style where all methods were static and an additional - * self parameter was defined. The self parameter and static nature of the methods - * disappeared once applied by Groovy's metaclass framework but some regarded - * the writing style as a little noisy. This transformation allows you to write - * your categories without the "apparent noise" but adds it back in during - * compilation so that the classes appear as normal categories. - * <p> - * It might seem strange writing your class/object enhancements using a succinct - * notation, then having "noise" added, then having the noise removed during - * category application. If this worries you, then you may also like to consider - * using Groovy's {@code ExpandoMetaClass} mechanism which avoids - * the category definition altogether. If you already have an investment in - * categories or like some of the other features which categories currently give you, - * then read on. - * <p> - * The mechanics: during compilation, all methods are transformed to static ones with an additional - * self parameter of the type you supply as the annotation parameter (the default type - * for the self parameters is {@code Object} which might be more broad reaching than - * you like so it is usually wise to specify a type). - * Properties invoked using 'this' references are transformed so that - * they are instead invoked on the additional self parameter and not on - * the Category instance. (Remember that once the category is applied, the reverse - * will occur and we will be back to conceptually having methods on the {@code this} - * references again!) - * <p> - * Classes conforming to the conventional Groovy category conventions can be used - * within {@code use} statements or mixed in at runtime with the {@code mixin} method on classes. - * <p> - * An example showing a {@code use} statement (allowing fine-grained application of - * the category methods): - * <pre class="groovyTestCase"> - * {@code @Category}(Integer) - * class IntegerOps { - * def triple() { - * this * 3 - * } - * } - * - * use (IntegerOps) { - * assert 25.triple() == 75 - * } - * </pre> - * Or, "mixing in" your methods at runtime: - * <pre class="groovyTestCase"> - * {@code @Category}(List) - * class Shuffler { - * def shuffle() { - * def result = new ArrayList(this) - * Collections.shuffle(result) - * result - * } - * } - * - * class Sentence extends ArrayList { - * Sentence(Collection initial) { super(initial) } - * } - * Sentence.mixin Shuffler - * - * def words = ["The", "quick", "brown", "fox"] - * println new Sentence(words).shuffle() - * // => [quick, fox, The, brown] (order will vary) - * </pre> - * - * @author Alex Tkachman - */ [email protected] -@Retention(RetentionPolicy.SOURCE) -@Target(ElementType.TYPE) -@GroovyASTTransformationClass("org.codehaus.groovy.transform.CategoryASTTransformation") -public @interface Category { - Class value () default Object.class; -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/lang/Closure.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/Closure.java b/src/main/groovy/lang/Closure.java deleted file mode 100644 index 99d2ea9..0000000 --- a/src/main/groovy/lang/Closure.java +++ /dev/null @@ -1,1054 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -import org.apache.groovy.internal.util.UncheckedThrow; -import org.codehaus.groovy.reflection.ReflectionCache; -import org.codehaus.groovy.reflection.stdclasses.CachedClosureClass; -import org.codehaus.groovy.runtime.ComposedClosure; -import org.codehaus.groovy.runtime.CurriedClosure; -import org.codehaus.groovy.runtime.InvokerHelper; -import org.codehaus.groovy.runtime.InvokerInvocationException; -import org.codehaus.groovy.runtime.callsite.BooleanClosureWrapper; -import org.codehaus.groovy.runtime.memoize.LRUCache; -import org.codehaus.groovy.runtime.memoize.Memoize; -import org.codehaus.groovy.runtime.memoize.UnlimitedConcurrentCache; - -import java.io.IOException; -import java.io.Serializable; -import java.io.StringWriter; -import java.io.Writer; - -/** - * Represents any closure object in Groovy. - * <p> - * Groovy allows instances of Closures to be called in a - * short form. For example: - * <pre class="groovyTestCase"> - * def a = 1 - * def c = { a } - * assert c() == 1 - * </pre> - * To be able to use a Closure in this way with your own - * subclass, you need to provide a doCall method with any - * signature you want to. This ensures that - * {@link #getMaximumNumberOfParameters()} and - * {@link #getParameterTypes()} will work too without any - * additional code. If no doCall method is provided a - * closure must be used in its long form like - * <pre class="groovyTestCase"> - * def a = 1 - * def c = {a} - * assert c.call() == 1 - * </pre> - * - * @author <a href="mailto:[email protected]">James Strachan</a> - * @author <a href="mailto:[email protected]">John Wilson</a> - * @author <a href="mailto:[email protected]">Jochen Theodorou</a> - * @author Graeme Rocher - * @author Paul King - */ -public abstract class Closure<V> extends GroovyObjectSupport implements Cloneable, Runnable, GroovyCallable<V>, Serializable { - - /** - * With this resolveStrategy set the closure will attempt to resolve property references and methods to the - * owner first, then the delegate (<b>this is the default strategy</b>). - * - * For example the following code: - * <pre> - * class Test { - * def x = 30 - * def y = 40 - * - * def run() { - * def data = [ x: 10, y: 20 ] - * def cl = { y = x + y } - * cl.delegate = data - * cl() - * assert x == 30 - * assert y == 70 - * assert data == [x:10, y:20] - * } - * } - * - * new Test().run() - * </pre> - * Will succeed, because the x and y fields declared in the Test class shadow the variables in the delegate.<p> - * <i>Note that local variables are always looked up first, independently of the resolution strategy.</i> - */ - public static final int OWNER_FIRST = 0; - - /** - * With this resolveStrategy set the closure will attempt to resolve property references and methods to the - * delegate first then the owner. - * - * For example the following code: - * <pre class="groovyTestCase"> - * class Test { - * def x = 30 - * def y = 40 - * - * def run() { - * def data = [ x: 10, y: 20 ] - * def cl = { y = x + y } - * cl.delegate = data - * cl.resolveStrategy = Closure.DELEGATE_FIRST - * cl() - * assert x == 30 - * assert y == 40 - * assert data == [x:10, y:30] - * } - * } - * - * new Test().run() - * </pre> - * This will succeed, because the x and y variables declared in the delegate shadow the fields in the owner class.<p> - * <i>Note that local variables are always looked up first, independently of the resolution strategy.</i> - */ - public static final int DELEGATE_FIRST = 1; - - /** - * With this resolveStrategy set the closure will resolve property references and methods to the owner only - * and not call the delegate at all. For example the following code : - * - * <pre> - * class Test { - * def x = 30 - * def y = 40 - * - * def run() { - * def data = [ x: 10, y: 20, z: 30 ] - * def cl = { y = x + y + z } - * cl.delegate = data - * cl.resolveStrategy = Closure.OWNER_ONLY - * cl() - * println x - * println y - * println data - * } - * } - * - * new Test().run() - * </pre> - * - * will throw "No such property: z" error because even if the z variable is declared in the delegate, no - * lookup is made.<p> - * <i>Note that local variables are always looked up first, independently of the resolution strategy.</i> - */ - public static final int OWNER_ONLY = 2; - - /** - * With this resolveStrategy set the closure will resolve property references and methods to the delegate - * only and entirely bypass the owner. For example the following code : - * - * <pre> - * class Test { - * def x = 30 - * def y = 40 - * def z = 50 - * - * def run() { - * def data = [ x: 10, y: 20 ] - * def cl = { y = x + y + z } - * cl.delegate = data - * cl.resolveStrategy = Closure.DELEGATE_ONLY - * cl() - * println x - * println y - * println data - * } - * } - * - * new Test().run() - * </pre> - * - * will throw an error because even if the owner declares a "z" field, the resolution strategy will bypass - * lookup in the owner.<p> - * <i>Note that local variables are always looked up first, independently of the resolution strategy.</i> - */ - public static final int DELEGATE_ONLY = 3; - - /** - * With this resolveStrategy set the closure will resolve property references to itself and go - * through the usual MetaClass look-up process. This means that properties and methods are neither resolved - * from the owner nor the delegate, but only on the closure object itself. This allows the developer to - * override getProperty using ExpandoMetaClass of the closure itself.<p> - * <i>Note that local variables are always looked up first, independently of the resolution strategy.</i> - */ - public static final int TO_SELF = 4; - - public static final int DONE = 1, SKIP = 2; - private static final Object[] EMPTY_OBJECT_ARRAY = {}; - public static final Closure IDENTITY = new Closure<Object>(null) { - public Object doCall(Object args) { - return args; - } - }; - - private Object delegate; - private Object owner; - private Object thisObject; - private int resolveStrategy = OWNER_FIRST; - private int directive; - protected Class[] parameterTypes; - protected int maximumNumberOfParameters; - private static final long serialVersionUID = 4368710879820278874L; - private BooleanClosureWrapper bcw; - - public Closure(Object owner, Object thisObject) { - this.owner = owner; - this.delegate = owner; - this.thisObject = thisObject; - - final CachedClosureClass cachedClass = (CachedClosureClass) ReflectionCache.getCachedClass(getClass()); - parameterTypes = cachedClass.getParameterTypes(); - maximumNumberOfParameters = cachedClass.getMaximumNumberOfParameters(); - } - - /** - * Constructor used when the "this" object for the Closure is null. - * This is rarely the case in normal Groovy usage. - * - * @param owner the Closure owner - */ - public Closure(Object owner) { - this(owner, null); - } - - /** - * Sets the strategy which the closure uses to resolve property references and methods. - * The default is Closure.OWNER_FIRST - * - * @param resolveStrategy The resolve strategy to set - * - * @see groovy.lang.Closure#DELEGATE_FIRST - * @see groovy.lang.Closure#DELEGATE_ONLY - * @see groovy.lang.Closure#OWNER_FIRST - * @see groovy.lang.Closure#OWNER_ONLY - * @see groovy.lang.Closure#TO_SELF - */ - public void setResolveStrategy(int resolveStrategy) { - this.resolveStrategy = resolveStrategy; - } - - /** - * Gets the strategy which the closure uses to resolve methods and properties - * - * @return The resolve strategy - * - * @see groovy.lang.Closure#DELEGATE_FIRST - * @see groovy.lang.Closure#DELEGATE_ONLY - * @see groovy.lang.Closure#OWNER_FIRST - * @see groovy.lang.Closure#OWNER_ONLY - * @see groovy.lang.Closure#TO_SELF - */ - public int getResolveStrategy() { - return resolveStrategy; - } - - public Object getThisObject(){ - return thisObject; - } - - public Object getProperty(final String property) { - if ("delegate".equals(property)) { - return getDelegate(); - } else if ("owner".equals(property)) { - return getOwner(); - } else if ("maximumNumberOfParameters".equals(property)) { - return getMaximumNumberOfParameters(); - } else if ("parameterTypes".equals(property)) { - return getParameterTypes(); - } else if ("metaClass".equals(property)) { - return getMetaClass(); - } else if ("class".equals(property)) { - return getClass(); - } else if ("directive".equals(property)) { - return getDirective(); - } else if ("resolveStrategy".equals(property)) { - return getResolveStrategy(); - } else if ("thisObject".equals(property)) { - return getThisObject(); - } else { - switch(resolveStrategy) { - case DELEGATE_FIRST: - return getPropertyDelegateFirst(property); - case DELEGATE_ONLY: - return InvokerHelper.getProperty(this.delegate, property); - case OWNER_ONLY: - return InvokerHelper.getProperty(this.owner, property); - case TO_SELF: - return super.getProperty(property); - default: - return getPropertyOwnerFirst(property); - } - } - } - - private Object getPropertyDelegateFirst(String property) { - if (delegate == null) return getPropertyOwnerFirst(property); - return getPropertyTryThese(property, this.delegate, this.owner); - } - - private Object getPropertyOwnerFirst(String property) { - return getPropertyTryThese(property, this.owner, this.delegate); - } - - private Object getPropertyTryThese(String property, Object firstTry, Object secondTry) { - try { - // let's try getting the property on the first object - return InvokerHelper.getProperty(firstTry, property); - - } catch (MissingPropertyException e1) { - if (secondTry != null && firstTry != this && firstTry != secondTry) { - try { - // let's try getting the property on the second object - return InvokerHelper.getProperty(secondTry, property); - } catch (GroovyRuntimeException e2) { - // ignore, we'll throw e1 - } - } - throw e1; - - } catch (MissingFieldException e2) { // see GROOVY-5875 - if (secondTry != null && firstTry != this && firstTry != secondTry) { - try { - // let's try getting the property on the second object - return InvokerHelper.getProperty(secondTry, property); - } catch (GroovyRuntimeException e3) { - // ignore, we'll throw e2 - } - } - throw e2; - } - } - - public void setProperty(String property, Object newValue) { - if ("delegate".equals(property)) { - setDelegate(newValue); - } else if ("metaClass".equals(property)) { - setMetaClass((MetaClass) newValue); - } else if ("resolveStrategy".equals(property)) { - setResolveStrategy(((Number) newValue).intValue()); - } else if ("directive".equals(property)) { - setDirective(((Number) newValue).intValue()); - } else { - switch(resolveStrategy) { - case DELEGATE_FIRST: - setPropertyDelegateFirst(property, newValue); - break; - case DELEGATE_ONLY: - InvokerHelper.setProperty(this.delegate, property, newValue); - break; - case OWNER_ONLY: - InvokerHelper.setProperty(this.owner, property, newValue); - break; - case TO_SELF: - super.setProperty(property, newValue); - break; - default: - setPropertyOwnerFirst(property, newValue); - } - } - } - - private void setPropertyDelegateFirst(String property, Object newValue) { - if (delegate == null) setPropertyOwnerFirst(property, newValue); - else setPropertyTryThese(property, newValue, this.delegate, this.owner); - } - - private void setPropertyOwnerFirst(String property, Object newValue) { - setPropertyTryThese(property, newValue, this.owner, this.delegate); - } - - private void setPropertyTryThese(String property, Object newValue, Object firstTry, Object secondTry) { - try { - // let's try setting the property on the first object - InvokerHelper.setProperty(firstTry, property, newValue); - } catch (GroovyRuntimeException e1) { - if (firstTry != null && firstTry != this && firstTry != secondTry) { - try { - // let's try setting the property on the second object - InvokerHelper.setProperty(secondTry, property, newValue); - return; - } catch (GroovyRuntimeException e2) { - // ignore, we'll throw e1 - } - } - throw e1; - } - } - - public boolean isCase(Object candidate){ - if (bcw==null) { - bcw = new BooleanClosureWrapper(this); - } - return bcw.call(candidate); - } - - /** - * Invokes the closure without any parameters, returning any value if applicable. - * - * @return the value if applicable or null if there is no return statement in the closure - */ - public V call() { - final Object[] NOARGS = EMPTY_OBJECT_ARRAY; - return call(NOARGS); - } - - @SuppressWarnings("unchecked") - public V call(Object... args) { - try { - return (V) getMetaClass().invokeMethod(this,"doCall",args); - } catch (InvokerInvocationException e) { - UncheckedThrow.rethrow(e.getCause()); - return null; // unreachable statement - } catch (Exception e) { - return (V) throwRuntimeException(e); - } - } - - /** - * Invokes the closure, returning any value if applicable. - * - * @param arguments could be a single value or a List of values - * @return the value if applicable or null if there is no return statement in the closure - */ - public V call(final Object arguments) { - return call(new Object[]{arguments}); - } - - protected static Object throwRuntimeException(Throwable throwable) { - if (throwable instanceof RuntimeException) { - throw (RuntimeException) throwable; - } else { - throw new GroovyRuntimeException(throwable.getMessage(), throwable); - } - } - - /** - * @return the owner Object to which method calls will go which is - * typically the outer class when the closure is constructed - */ - public Object getOwner() { - return this.owner; - } - - /** - * @return the delegate Object to which method calls will go which is - * typically the outer class when the closure is constructed - */ - public Object getDelegate() { - return this.delegate; - } - - /** - * Allows the delegate to be changed such as when performing markup building - * - * @param delegate the new delegate - */ - public void setDelegate(Object delegate) { - this.delegate = delegate; - } - - /** - * @return the parameter types of the longest doCall method - * of this closure - */ - public Class[] getParameterTypes() { - return parameterTypes; - } - - /** - * @return the maximum number of parameters a doCall method - * of this closure can take - */ - public int getMaximumNumberOfParameters() { - return maximumNumberOfParameters; - } - - /** - * @return a version of this closure which implements Writable. Note that - * the returned Writable also overrides {@link #toString()} in order - * to allow rendering the result directly to a String. - */ - public Closure asWritable() { - return new WritableClosure(); - } - - /* (non-Javadoc) - * @see java.lang.Runnable#run() - */ - public void run() { - call(); - } - - /** - * Support for Closure currying. - * <p> - * Typical usage: - * <pre class="groovyTestCase"> - * def multiply = { a, b -> a * b } - * def doubler = multiply.curry(2) - * assert doubler(4) == 8 - * </pre> - * Note: special treatment is given to Closure vararg-style capability. - * If you curry a vararg parameter, you don't consume the entire vararg array - * but instead the first parameter of the vararg array as the following example shows: - * <pre class="groovyTestCase"> - * def a = { one, two, Object[] others -> one + two + others.sum() } - * assert a.parameterTypes.name == ['java.lang.Object', 'java.lang.Object', '[Ljava.lang.Object;'] - * assert a(1,2,3,4) == 10 - * def b = a.curry(1) - * assert b.parameterTypes.name == ['java.lang.Object', '[Ljava.lang.Object;'] - * assert b(2,3,4) == 10 - * def c = b.curry(2) - * assert c.parameterTypes.name == ['[Ljava.lang.Object;'] - * assert c(3,4) == 10 - * def d = c.curry(3) - * assert d.parameterTypes.name == ['[Ljava.lang.Object;'] - * assert d(4) == 10 - * def e = d.curry(4) - * assert e.parameterTypes.name == ['[Ljava.lang.Object;'] - * assert e() == 10 - * assert e(5) == 15 - * </pre> - * - * - * @param arguments the arguments to bind - * @return the new closure with its arguments bound - */ - public Closure<V> curry(final Object... arguments) { - return new CurriedClosure<V>(this, arguments); - } - - /** - * Support for Closure currying. - * - * @param argument the argument to bind - * @return the new closure with the argument bound - * @see #curry(Object...) - */ - public Closure<V> curry(final Object argument) { - return curry(new Object[]{argument}); - } - - /** - * Support for Closure "right" currying. - * Parameters are supplied on the right rather than left as per the normal curry() method. - * Typical usage: - * <pre class="groovyTestCase"> - * def divide = { a, b -> a / b } - * def halver = divide.rcurry(2) - * assert halver(8) == 4 - * </pre> - * - * The position of the curried parameters will be calculated lazily, for example, - * if two overloaded doCall methods are available, the supplied arguments plus the - * curried arguments will be concatenated and the result used for method selection. - * - * @param arguments the arguments to bind - * @return the new closure with its arguments bound - * @see #curry(Object...) - */ - public Closure<V> rcurry(final Object... arguments) { - return new CurriedClosure<V>(-arguments.length, this, arguments); - } - - /** - * Support for Closure "right" currying. - * - * @param argument the argument to bind - * @return the new closure with the argument bound - * @see #rcurry(Object...) - */ - public Closure<V> rcurry(final Object argument) { - return rcurry(new Object[]{argument}); - } - - /** - * Support for Closure currying at a given index. - * Parameters are supplied from index position "n". - * Typical usage: - * <pre> - * def caseInsensitive = { a, b -> a.toLowerCase() <=> b.toLowerCase() } as Comparator - * def caseSensitive = { a, b -> a <=> b } as Comparator - * def animals1 = ['ant', 'dog', 'BEE'] - * def animals2 = animals1 + ['Cat'] - * // curry middle param of this utility method: - * // Collections#binarySearch(List list, Object key, Comparator c) - * def catSearcher = Collections.&binarySearch.ncurry(1, "cat") - * [[animals1, animals2], [caseInsensitive, caseSensitive]].combinations().each{ a, c -> - * def idx = catSearcher(a.sort(c), c) - * print a.sort(c).toString().padRight(22) - * if (idx < 0) println "Not found but would belong in position ${-idx - 1}" - * else println "Found at index $idx" - * } - * // => - * // [ant, BEE, dog] Not found but would belong in position 2 - * // [ant, BEE, Cat, dog] Found at index 2 - * // [BEE, ant, dog] Not found but would belong in position 2 - * // [BEE, Cat, ant, dog] Not found but would belong in position 3 - * </pre> - * - * The position of the curried parameters will be calculated eagerly - * and implies all arguments prior to the specified n index are supplied. - * Default parameter values prior to the n index will not be available. - * - * @param n the index from which to bind parameters (may be -ve in which case it will be normalized) - * @param arguments the arguments to bind - * @return the new closure with its arguments bound - * @see #curry(Object...) - */ - public Closure<V> ncurry(int n, final Object... arguments) { - return new CurriedClosure<V>(n, this, arguments); - } - - /** - * Support for Closure currying at a given index. - * - * @param argument the argument to bind - * @return the new closure with the argument bound - * @see #ncurry(int, Object...) - */ - public Closure<V> ncurry(int n, final Object argument) { - return ncurry(n, new Object[]{argument}); - } - - /** - * Support for Closure forward composition. - * <p> - * Typical usage: - * <pre class="groovyTestCase"> - * def times2 = { a -> a * 2 } - * def add3 = { a -> a + 3 } - * def timesThenAdd = times2 >> add3 - * // equivalent: timesThenAdd = { a -> add3(times2(a)) } - * assert timesThenAdd(3) == 9 - * </pre> - * - * @param other the Closure to compose with the current Closure - * @return the new composed Closure - */ - public <W> Closure<W> rightShift(final Closure<W> other) { - return new ComposedClosure<W>(this, other); - } - - /** - * Support for Closure reverse composition. - * <p> - * Typical usage: - * <pre class="groovyTestCase"> - * def times2 = { a -> a * 2 } - * def add3 = { a -> a + 3 } - * def addThenTimes = times2 << add3 - * // equivalent: addThenTimes = { a -> times2(add3(a)) } - * assert addThenTimes(3) == 12 - * </pre> - * - * @param other the Closure to compose with the current Closure - * @return the new composed Closure - */ - public Closure<V> leftShift(final Closure other) { - return new ComposedClosure<V>(other, this); - } - - /* * - * Alias for calling a Closure for non-closure arguments. - * <p> - * Typical usage: - * <pre class="groovyTestCase"> - * def times2 = { a -> a * 2 } - * def add3 = { a -> a * 3 } - * assert add3 << times2 << 3 == 9 - * </pre> - * - * @param arg the argument to call the closure with - * @return the result of calling the Closure - */ - public V leftShift(final Object arg) { - return call(arg); - } - - /** - * Creates a caching variant of the closure. - * Whenever the closure is called, the mapping between the parameters and the return value is preserved in cache - * making subsequent calls with the same arguments fast. - * This variant will keep all cached values forever, i.e. till the closure gets garbage-collected. - * The returned function can be safely used concurrently from multiple threads, however, the implementation - * values high average-scenario performance and so concurrent calls on the memoized function with identical argument values - * may not necessarily be able to benefit from each other's cached return value. With this having been mentioned, - * the performance trade-off still makes concurrent use of memoized functions safe and highly recommended. - * - * The cache gets garbage-collected together with the memoized closure. - * - * @return A new closure forwarding to the original one while caching the results - */ - public Closure<V> memoize() { - return Memoize.buildMemoizeFunction(new UnlimitedConcurrentCache(), this); - } - - /** - * Creates a caching variant of the closure with upper limit on the cache size. - * Whenever the closure is called, the mapping between the parameters and the return value is preserved in cache - * making subsequent calls with the same arguments fast. - * This variant will keep all values until the upper size limit is reached. Then the values in the cache start rotating - * using the LRU (Last Recently Used) strategy. - * The returned function can be safely used concurrently from multiple threads, however, the implementation - * values high average-scenario performance and so concurrent calls on the memoized function with identical argument values - * may not necessarily be able to benefit from each other's cached return value. With this having been mentioned, - * the performance trade-off still makes concurrent use of memoized functions safe and highly recommended. - * - * The cache gets garbage-collected together with the memoized closure. - * - * @param maxCacheSize The maximum size the cache can grow to - * @return A new function forwarding to the original one while caching the results - */ - public Closure<V> memoizeAtMost(final int maxCacheSize) { - if (maxCacheSize < 0) throw new IllegalArgumentException("A non-negative number is required as the maxCacheSize parameter for memoizeAtMost."); - - return Memoize.buildMemoizeFunction(new LRUCache(maxCacheSize), this); - } - - /** - * Creates a caching variant of the closure with automatic cache size adjustment and lower limit - * on the cache size. - * Whenever the closure is called, the mapping between the parameters and the return value is preserved in cache - * making subsequent calls with the same arguments fast. - * This variant allows the garbage collector to release entries from the cache and at the same time allows - * the user to specify how many entries should be protected from the eventual gc-initiated eviction. - * Cached entries exceeding the specified preservation threshold are made available for eviction based on - * the LRU (Last Recently Used) strategy. - * Given the non-deterministic nature of garbage collector, the actual cache size may grow well beyond the limits - * set by the user if memory is plentiful. - * The returned function can be safely used concurrently from multiple threads, however, the implementation - * values high average-scenario performance and so concurrent calls on the memoized function with identical argument values - * may not necessarily be able to benefit from each other's cached return value. Also the protectedCacheSize parameter - * might not be respected accurately in such scenarios for some periods of time. With this having been mentioned, - * the performance trade-off still makes concurrent use of memoized functions safe and highly recommended. - * - * The cache gets garbage-collected together with the memoized closure. - * @param protectedCacheSize Number of cached return values to protect from garbage collection - * @return A new function forwarding to the original one while caching the results - */ - public Closure<V> memoizeAtLeast(final int protectedCacheSize) { - if (protectedCacheSize < 0) throw new IllegalArgumentException("A non-negative number is required as the protectedCacheSize parameter for memoizeAtLeast."); - - return Memoize.buildSoftReferenceMemoizeFunction(protectedCacheSize, new UnlimitedConcurrentCache(), this); - } - - /** - * Creates a caching variant of the closure with automatic cache size adjustment and lower and upper limits - * on the cache size. - * Whenever the closure is called, the mapping between the parameters and the return value is preserved in cache - * making subsequent calls with the same arguments fast. - * This variant allows the garbage collector to release entries from the cache and at the same time allows - * the user to specify how many entries should be protected from the eventual gc-initiated eviction. - * Cached entries exceeding the specified preservation threshold are made available for eviction based on - * the LRU (Last Recently Used) strategy. - * Given the non-deterministic nature of garbage collector, the actual cache size may grow well beyond the protected - * size limits set by the user, if memory is plentiful. - * Also, this variant will never exceed in size the upper size limit. Once the upper size limit has been reached, - * the values in the cache start rotating using the LRU (Last Recently Used) strategy. - * The returned function can be safely used concurrently from multiple threads, however, the implementation - * values high average-scenario performance and so concurrent calls on the memoized function with identical argument values - * may not necessarily be able to benefit from each other's cached return value. Also the protectedCacheSize parameter - * might not be respected accurately in such scenarios for some periods of time. With this having been mentioned, - * the performance trade-off still makes concurrent use of memoized functions safe and highly recommended. - * - * The cache gets garbage-collected together with the memoized closure. - * @param protectedCacheSize Number of cached return values to protect from garbage collection - * @param maxCacheSize The maximum size the cache can grow to - * @return A new function forwarding to the original one while caching the results - */ - public Closure<V> memoizeBetween(final int protectedCacheSize, final int maxCacheSize) { - if (protectedCacheSize < 0) throw new IllegalArgumentException("A non-negative number is required as the protectedCacheSize parameter for memoizeBetween."); - if (maxCacheSize < 0) throw new IllegalArgumentException("A non-negative number is required as the maxCacheSize parameter for memoizeBetween."); - if (protectedCacheSize > maxCacheSize) throw new IllegalArgumentException("The maxCacheSize parameter to memoizeBetween is required to be greater or equal to the protectedCacheSize parameter."); - - return Memoize.buildSoftReferenceMemoizeFunction(protectedCacheSize, new LRUCache(maxCacheSize), this); - } - - /** - * Builds a trampolined variant of the current closure. - * To prevent stack overflow due to deep recursion, functions can instead leverage the trampoline mechanism - * and avoid recursive calls altogether. Under trampoline, the function is supposed to perform one step of - * the calculation and, instead of a recursive call to itself or another function, it return back a new closure, - * which will be executed by the trampoline as the next step. - * Once a non-closure value is returned, the trampoline stops and returns the value as the final result. - * Here is an example: - * <pre> - * def fact - * fact = { n, total -> - * n == 0 ? total : fact.trampoline(n - 1, n * total) - * }.trampoline() - * def factorial = { n -> fact(n, 1G)} - * println factorial(20) // => 2432902008176640000 - * </pre> - * - * @param args Parameters to the closure, so as the trampoline mechanism can call it - * @return A closure, which will execute the original closure on a trampoline. - */ - public Closure<V> trampoline(final Object... args) { - return new TrampolineClosure<V>(this.curry(args)); - } - - /** - * Builds a trampolined variant of the current closure. - * To prevent stack overflow due to deep recursion, functions can instead leverage the trampoline mechanism - * and avoid recursive calls altogether. Under trampoline, the function is supposed to perform one step of - * the calculation and, instead of a recursive call to itself or another function, it return back a new closure, - * which will be executed by the trampoline as the next step. - * Once a non-closure value is returned, the trampoline stops and returns the value as the final result. - * @return A closure, which will execute the original closure on a trampoline. - * @see #trampoline(Object...) - */ - public Closure<V> trampoline() { - return new TrampolineClosure<V>(this); - } - - /* (non-Javadoc) - * @see java.lang.Object#clone() - */ - public Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException e) { - return null; - } - } - - /* - * Implementation note: - * This has to be an inner class! - * - * Reason: - * Closure.this.call will call the outer call method, but - * with the inner class as executing object. This means any - * invokeMethod or getProperty call will be called on this - * inner class instead of the outer! - */ - private class WritableClosure extends Closure implements Writable { - public WritableClosure() { - super(Closure.this); - } - - /* (non-Javadoc) - * @see groovy.lang.Writable#writeTo(java.io.Writer) - */ - public Writer writeTo(Writer out) throws IOException { - Closure.this.call(new Object[]{out}); - - return out; - } - - /* (non-Javadoc) - * @see groovy.lang.GroovyObject#invokeMethod(java.lang.String, java.lang.Object) - */ - public Object invokeMethod(String method, Object arguments) { - if ("clone".equals(method)) { - return clone(); - } else if ("curry".equals(method)) { - return curry((Object[]) arguments); - } else if ("asWritable".equals(method)) { - return asWritable(); - } else { - return Closure.this.invokeMethod(method, arguments); - } - } - - /* (non-Javadoc) - * @see groovy.lang.GroovyObject#getProperty(java.lang.String) - */ - public Object getProperty(String property) { - return Closure.this.getProperty(property); - } - - /* (non-Javadoc) - * @see groovy.lang.GroovyObject#setProperty(java.lang.String, java.lang.Object) - */ - public void setProperty(String property, Object newValue) { - Closure.this.setProperty(property, newValue); - } - - /* (non-Javadoc) - * @see groovy.lang.Closure#call() - */ - public Object call() { - return ((Closure) getOwner()).call(); - } - - /* (non-Javadoc) - * @see groovy.lang.Closure#call(java.lang.Object) - */ - public Object call(Object arguments) { - return ((Closure) getOwner()).call(arguments); - } - - public Object call(Object... args) { - return ((Closure) getOwner()).call(args); - } - - public Object doCall(Object... args) { - return call(args); - } - - /* (non-Javadoc) - * @see groovy.lang.Closure#getDelegate() - */ - public Object getDelegate() { - return Closure.this.getDelegate(); - } - - /* (non-Javadoc) - * @see groovy.lang.Closure#setDelegate(java.lang.Object) - */ - public void setDelegate(Object delegate) { - Closure.this.setDelegate(delegate); - } - - /* (non-Javadoc) - * @see groovy.lang.Closure#getParameterTypes() - */ - public Class[] getParameterTypes() { - return Closure.this.getParameterTypes(); - } - - /* (non-Javadoc) - * @see groovy.lang.Closure#getParameterTypes() - */ - public int getMaximumNumberOfParameters() { - return Closure.this.getMaximumNumberOfParameters(); - } - - /* (non-Javadoc) - * @see groovy.lang.Closure#asWritable() - */ - public Closure asWritable() { - return this; - } - - /* (non-Javadoc) - * @see java.lang.Runnable#run() - */ - public void run() { - Closure.this.run(); - } - - /* (non-Javadoc) - * @see java.lang.Object#clone() - */ - public Object clone() { - return ((Closure) Closure.this.clone()).asWritable(); - } - - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return Closure.this.hashCode(); - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object arg0) { - return Closure.this.equals(arg0); - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - final StringWriter writer = new StringWriter(); - - try { - writeTo(writer); - } catch (IOException e) { - return null; - } - - return writer.toString(); - } - - public Closure curry(final Object... arguments) { - return (new CurriedClosure(this, arguments)).asWritable(); - } - - public void setResolveStrategy(int resolveStrategy) { - Closure.this.setResolveStrategy(resolveStrategy); - } - - public int getResolveStrategy() { - return Closure.this.getResolveStrategy(); - } - } - - /** - * @return Returns the directive. - */ - public int getDirective() { - return directive; - } - - /** - * @param directive The directive to set. - */ - public void setDirective(int directive) { - this.directive = directive; - } - - /** - * Returns a copy of this closure where the "owner", "delegate" and "thisObject" - * fields are null, allowing proper serialization when one of them is not serializable. - * - * @return a serializable closure. - * - * @since 1.8.5 - */ - @SuppressWarnings("unchecked") - public Closure<V> dehydrate() { - Closure<V> result = (Closure<V>) this.clone(); - result.delegate = null; - result.owner = null; - result.thisObject = null; - return result; - } - - /** - * Returns a copy of this closure for which the delegate, owner and thisObject are - * replaced with the supplied parameters. Use this when you want to rehydrate a - * closure which has been made serializable thanks to the {@link #dehydrate()} - * method. - * @param delegate the closure delegate - * @param owner the closure owner - * @param thisObject the closure "this" object - * @return a copy of this closure where owner, delegate and thisObject are replaced - * - * @since 1.8.5 - */ - @SuppressWarnings("unchecked") - public Closure<V> rehydrate(Object delegate, Object owner, Object thisObject) { - Closure<V> result = (Closure<V>) this.clone(); - result.delegate = delegate; - result.owner = owner; - result.thisObject = thisObject; - return result; - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/lang/ClosureException.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/ClosureException.java b/src/main/groovy/lang/ClosureException.java deleted file mode 100644 index 12986ad..0000000 --- a/src/main/groovy/lang/ClosureException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -/** - * An exception thrown by a closure invocation - * - * @author <a href="mailto:[email protected]">James Strachan</a> - */ -public class ClosureException extends RuntimeException { - - private final Closure closure; - - public ClosureException(Closure closure, Throwable cause) { - super("Exception thrown by call to closure: " + closure + " reason: " + cause, cause); - this.closure = closure; - } - - public Closure getClosure() { - return closure; - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/d638ca43/src/main/groovy/lang/ClosureInvokingMethod.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/ClosureInvokingMethod.java b/src/main/groovy/lang/ClosureInvokingMethod.java deleted file mode 100644 index 3e54278..0000000 --- a/src/main/groovy/lang/ClosureInvokingMethod.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package groovy.lang; - -/** - * An interface for MetaMethods that invoke closures to implements. Used by ExpandoMetaClass - * - * @see groovy.lang.ExpandoMetaClass - * - * @author Graeme Rocher - * @since 1.5 - */ -public interface ClosureInvokingMethod { - - /** - * Returns the original closure that this method invokes - * @return The closure - */ - Closure getClosure(); - - /** - * Is it a static method? - * @return True if it is - */ - boolean isStatic(); - - /** - * The method name - * @return The method name - */ - String getName(); -}
