You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2017/12/20 00:56:30 UTC
[33/49] groovy git commit: Move source files to proper packages
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/SpreadListEvaluatingException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/SpreadListEvaluatingException.java b/src/main/groovy/groovy/lang/SpreadListEvaluatingException.java
new file mode 100644
index 0000000..b6de965
--- /dev/null
+++ b/src/main/groovy/groovy/lang/SpreadListEvaluatingException.java
@@ -0,0 +1,25 @@
+/*
+ * 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 class SpreadListEvaluatingException extends GroovyRuntimeException {
+ public SpreadListEvaluatingException(String message) {
+ super(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/SpreadMap.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/SpreadMap.java b/src/main/groovy/groovy/lang/SpreadMap.java
new file mode 100644
index 0000000..7ba9e4f
--- /dev/null
+++ b/src/main/groovy/groovy/lang/SpreadMap.java
@@ -0,0 +1,120 @@
+/*
+ * 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.runtime.typehandling.DefaultTypeTransformation;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper to turn a list with an even number of elements into a Map.
+ *
+ * @author Pilho Kim
+ * @author Tim Tiemens
+ */
+public class SpreadMap extends HashMap {
+ private int hashCode;
+
+ public SpreadMap(Object[] values) {
+ int i = 0;
+ while (i < values.length) {
+ super.put(values[i++], values[i++]);
+ }
+ }
+
+ public SpreadMap(Map map) {
+ super(map);
+ }
+
+ /**
+ * @since 1.8.0
+ * @param list the list to make spreadable
+ */
+ public SpreadMap(List list) {
+ this(list.toArray());
+ }
+
+ public Object put(Object key, Object value) {
+ throw new RuntimeException("SpreadMap: " + this + " is an immutable map, and so ("
+ + key + ": " + value + ") cannot be added.");
+ }
+
+ public Object remove(Object key) {
+ throw new RuntimeException("SpreadMap: " + this + " is an immutable map, and so the key ("
+ + key + ") cannot be deleted.");
+ }
+
+ public void putAll(Map t) {
+ throw new RuntimeException("SpreadMap: " + this + " is an immutable map, and so the map ("
+ + t + ") cannot be put in this spreadMap.");
+ }
+
+ public boolean equals(Object that) {
+ if (that instanceof SpreadMap) {
+ return equals((SpreadMap) that);
+ }
+ return false;
+ }
+
+ public boolean equals(SpreadMap that) {
+ if (that == null) return false;
+
+ if (size() == that.size()) {
+ for (Object key : keySet()) {
+ if (!DefaultTypeTransformation.compareEqual(get(key), that.get(key))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ if (hashCode == 0) {
+ for (Object key : keySet()) {
+ int hash = (key != null) ? key.hashCode() : 0xbabe;
+ hashCode ^= hash;
+ }
+ }
+ return hashCode;
+ }
+
+ /**
+ * @return the string expression of <code>this</code>
+ */
+ public String toString() {
+ if (isEmpty()) {
+ return "*:[:]";
+ }
+ StringBuilder sb = new StringBuilder("*:[");
+ Iterator iter = keySet().iterator();
+ while (iter.hasNext()) {
+ Object key = iter.next();
+ sb.append(key).append(":").append(get(key));
+ if (iter.hasNext())
+ sb.append(", ");
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/SpreadMapEvaluatingException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/SpreadMapEvaluatingException.java b/src/main/groovy/groovy/lang/SpreadMapEvaluatingException.java
new file mode 100644
index 0000000..408a223
--- /dev/null
+++ b/src/main/groovy/groovy/lang/SpreadMapEvaluatingException.java
@@ -0,0 +1,25 @@
+/*
+ * 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 class SpreadMapEvaluatingException extends GroovyRuntimeException {
+ public SpreadMapEvaluatingException(String message) {
+ super(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/StringWriterIOException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/StringWriterIOException.java b/src/main/groovy/groovy/lang/StringWriterIOException.java
new file mode 100644
index 0000000..0372399
--- /dev/null
+++ b/src/main/groovy/groovy/lang/StringWriterIOException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.io.IOException;
+
+/**
+ * An IO exception occurred trying to append to a StringWriter which should never happen.
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class StringWriterIOException extends RuntimeException {
+
+ public StringWriterIOException(IOException e) {
+ super(e);
+ }
+
+ public IOException getIOException() {
+ return (IOException) getCause();
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/TracingInterceptor.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/TracingInterceptor.java b/src/main/groovy/groovy/lang/TracingInterceptor.java
new file mode 100644
index 0000000..f67de11
--- /dev/null
+++ b/src/main/groovy/groovy/lang/TracingInterceptor.java
@@ -0,0 +1,120 @@
+/*
+ * 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.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+/*
+ * This {@link Interceptor} traces method calls on the proxied object to a log.
+ * By default, the log is simply <pre>System.out</pre>; however, that can be
+ * changed with the <pre>setWriter(Writer)</pre> method.
+ * <p>
+ * A message will be written to output before a method is invoked and after a method
+ * is invoked. If methods are nested, and invoke one another, then indentation
+ * of two spaces is written.
+ * <p>
+ * Here is an example usage on the ArrayList object: <br>
+ * <pre class="groovyTestCase">
+ * def proxy = ProxyMetaClass.getInstance(ArrayList.class)
+ * proxy.interceptor = new TracingInterceptor()
+ * proxy.use {
+ * def list = [1, 2, 3]
+ * assert 3 == list.size()
+ * assert list.contains(1)
+ * }
+ * </pre>
+ * Running this code produces this output:
+ * <pre>
+ * before java.util.ArrayList.size()
+ * after java.util.ArrayList.size()
+ * before java.util.ArrayList.contains(java.lang.Integer)
+ * after java.util.ArrayList.contains(java.lang.Integer)
+ * </pre>
+ */
+public class TracingInterceptor implements Interceptor {
+
+ protected Writer writer = new PrintWriter(System.out);
+ private int indent = 0;
+
+ /**
+ * Returns the writer associated with this interceptor.
+ */
+ public Writer getWriter() {
+ return writer;
+ }
+
+ /**
+ * Changes the writer associated with this interceptor.
+ */
+ public void setWriter(Writer writer) {
+ this.writer = writer;
+ }
+
+ public Object beforeInvoke(Object object, String methodName, Object[] arguments) {
+ write(object, methodName, arguments, "before");
+ indent++ ;
+ return null;
+ }
+
+ public Object afterInvoke(Object object, String methodName, Object[] arguments, Object result) {
+ indent--;
+ write(object, methodName, arguments, "after ");
+ return result;
+ }
+
+ public boolean doInvoke() {
+ return true;
+ }
+ private String indent(){
+ StringBuilder result = new StringBuilder();
+ for (int i=0; i<indent;i++){
+ result.append(" ");
+ }
+ return result.toString();
+ }
+
+ protected void write(Object object, String methodName, Object[] arguments, final String origin) {
+ try {
+ writer.write(indent());
+ writer.write(origin);
+ writer.write(" ");
+ Class theClass = object instanceof Class ? (Class) object: object.getClass();
+ writeInfo(theClass, methodName, arguments);
+ writer.write("\n");
+ writer.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void writeInfo(final Class aClass, String methodName, Object[] arguments) throws IOException {
+ writer.write(aClass.getName());
+ writer.write(".");
+ writer.write(methodName);
+ writer.write("(");
+ for (int i = 0; i < arguments.length; i++) {
+ if (i > 0) writer.write(", ");
+ Object argument = arguments[i];
+ writer.write(argument.getClass().getName());
+ }
+ writer.write(")");
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/TrampolineClosure.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/TrampolineClosure.java b/src/main/groovy/groovy/lang/TrampolineClosure.java
new file mode 100644
index 0000000..ed68f00
--- /dev/null
+++ b/src/main/groovy/groovy/lang/TrampolineClosure.java
@@ -0,0 +1,111 @@
+/*
+ * 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;
+
+/**
+ * A TrampolineClosure wraps a closure that needs to be executed on a functional trampoline.
+ * Upon calling, a TrampolineClosure will call the original closure waiting for its result.
+ * If the outcome of the call is another instance of a TrampolineClosure, created perhaps as a result to a call to the TrampolineClosure.trampoline()
+ * method, the TrampolineClosure will again be invoked. This repetitive invocation of returned TrampolineClosure instances will continue
+ * until a value other than TrampolineClosure is returned.
+ * That value will become the final result of the trampoline.
+ *
+ * @author Vaclav Pech
+ */
+final class TrampolineClosure<V> extends Closure<V> {
+
+ private final Closure<V> original;
+
+ TrampolineClosure(final Closure<V> original) {
+ super(original.getOwner(), original.getDelegate());
+ this.original = original;
+ }
+
+ /**
+ * Delegates to the wrapped closure
+ */
+ @Override
+ public int getMaximumNumberOfParameters() {
+ return original.maximumNumberOfParameters;
+ }
+
+ /**
+ * Delegates to the wrapped closure
+ */
+ @Override
+ public Class[] getParameterTypes() {
+ return original.parameterTypes;
+ }
+
+ /**
+ * Starts the trampoline loop and calls the wrapped closure as the first step.
+ * @return The final result of the trampoline
+ */
+ @Override
+ public V call() {
+ return loop(original.call());
+ }
+
+ /**
+ * Starts the trampoline loop and calls the wrapped closure as the first step.
+ * @return The final result of the trampoline
+ */
+ @Override
+ public V call(final Object arguments) {
+ return loop(original.call(arguments));
+ }
+
+ /**
+ * Starts the trampoline loop and calls the wrapped closure as the first step.
+ * @return The final result of the trampoline
+ */
+ @Override
+ public V call(final Object... args) {
+ return loop(original.call(args));
+ }
+
+ private V loop(final Object lastResult) {
+ Object result = lastResult;
+
+ for (;;) {
+ if (result instanceof TrampolineClosure) {
+ result = ((TrampolineClosure)result).original.call();
+ } else return (V) result;
+ }
+ }
+
+ /**
+ * Builds a trampolined variant of the current closure.
+ * @param args Parameters to curry to the underlying closure.
+ * @return An instance of TrampolineClosure wrapping the original closure after currying.
+ */
+ @Override
+ public Closure<V> trampoline(final Object... args) {
+ return new TrampolineClosure<V>(original.curry(args));
+ }
+
+ /**
+ * Returns itself, since it is a good enough trampolined variant of the current closure.
+ * @return An instance of TrampolineClosure wrapping the original closure.
+ */
+ @Override
+ public Closure<V> trampoline() {
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple.java b/src/main/groovy/groovy/lang/Tuple.java
new file mode 100644
index 0000000..036d13e
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple.java
@@ -0,0 +1,85 @@
+/*
+ * 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.runtime.typehandling.DefaultTypeTransformation;
+
+import java.io.Serializable;
+import java.util.AbstractList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Represents a list of Objects.
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class Tuple<E> extends AbstractList<E> implements Serializable {
+ private static final long serialVersionUID = -6707770506387821031L;
+ private final E[] contents;
+
+ public Tuple(E... contents) {
+ if (contents == null) throw new NullPointerException();
+ this.contents = contents;
+ }
+
+ @Override
+ public E get(int index) {
+ return contents[index];
+ }
+
+ @Override
+ public int size() {
+ return contents.length;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<E> subList(int fromIndex, int toIndex) {
+ int size = toIndex - fromIndex;
+ E[] newContent = (E[]) new Object[size];
+ System.arraycopy(contents, fromIndex, newContent, 0, size);
+ return new Tuple<>(newContent);
+ }
+
+ public Tuple<E> subTuple(int fromIndex, int toIndex) {
+ return (Tuple<E>) subList(fromIndex, toIndex);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || !(o instanceof Tuple)) return false;
+
+ Tuple that = (Tuple) o;
+ int size = size();
+ if (size != that.size()) return false;
+ for (int i = 0; i < size; i++) {
+ if (!DefaultTypeTransformation.compareEqual(get(i), that.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(contents);
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple1.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple1.java b/src/main/groovy/groovy/lang/Tuple1.java
new file mode 100644
index 0000000..9b8d6bd
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple1.java
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+/**
+ * Represents a list of 1 typed Object.
+ *
+ * @since 2.5.0
+ */
+public class Tuple1<T1> extends Tuple {
+ private static final long serialVersionUID = -4647790147461409603L;
+ private final T1 first;
+
+ public Tuple1(T1 first) {
+ super(first);
+
+ this.first = first;
+ }
+
+ @Override
+ public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ default:
+ throw new IndexOutOfBoundsException("index: " + index);
+ }
+ }
+
+ @Override
+ public int size() {
+ return 1;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple2.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple2.java b/src/main/groovy/groovy/lang/Tuple2.java
new file mode 100644
index 0000000..b096aee
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple2.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+/**
+ * Represents a list of 2 typed Objects.
+ */
+public class Tuple2<T1, T2> extends Tuple {
+ private static final long serialVersionUID = 9006144674906325597L;
+ private final T1 first;
+ private final T2 second;
+
+ public Tuple2(T1 first, T2 second) {
+ super(first, second);
+
+ this.first = first;
+ this.second = second;
+ }
+
+ @Override
+ public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ default:
+ throw new IndexOutOfBoundsException("index: " + index);
+ }
+ }
+
+ @Override
+ public int size() {
+ return 2;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+
+ public T2 getSecond() {
+ return second;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple3.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple3.java b/src/main/groovy/groovy/lang/Tuple3.java
new file mode 100644
index 0000000..b5fe7d9
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple3.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+/**
+ * Represents a list of 3 typed Objects.
+ *
+ * @since 2.5.0
+ */
+public class Tuple3<T1, T2, T3> extends Tuple {
+ private static final long serialVersionUID = 8469774237154310687L;
+ private final T1 first;
+ private final T2 second;
+ private final T3 third;
+
+ public Tuple3(T1 first, T2 second, T3 third) {
+ super(first, second, third);
+
+ this.first = first;
+ this.second = second;
+ this.third = third;
+ }
+
+ @Override
+ public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ case 2:
+ return third;
+ default:
+ throw new IndexOutOfBoundsException("index: " + index);
+ }
+ }
+
+ @Override
+ public int size() {
+ return 3;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+
+ public T2 getSecond() {
+ return second;
+ }
+
+ public T3 getThird() {
+ return third;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple4.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple4.java b/src/main/groovy/groovy/lang/Tuple4.java
new file mode 100644
index 0000000..04f414e
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple4.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+/**
+ * Represents a list of 4 typed Objects.
+ *
+ * @since 2.5.0
+ */
+public class Tuple4<T1, T2, T3, T4> extends Tuple {
+ private static final long serialVersionUID = -7788878731471377207L;
+ private final T1 first;
+ private final T2 second;
+ private final T3 third;
+ private final T4 fourth;
+
+ public Tuple4(T1 first, T2 second, T3 third, T4 fourth) {
+ super(first, second, third, fourth);
+
+ this.first = first;
+ this.second = second;
+ this.third = third;
+ this.fourth = fourth;
+ }
+
+ @Override
+ public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ case 2:
+ return third;
+ case 3:
+ return fourth;
+ default:
+ throw new IndexOutOfBoundsException("index: " + index);
+ }
+ }
+
+ @Override
+ public int size() {
+ return 4;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+
+ public T2 getSecond() {
+ return second;
+ }
+
+ public T3 getThird() {
+ return third;
+ }
+
+ public T4 getFourth() {
+ return fourth;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple5.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple5.java b/src/main/groovy/groovy/lang/Tuple5.java
new file mode 100644
index 0000000..ee9c802
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple5.java
@@ -0,0 +1,87 @@
+/*
+ * 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;
+
+/**
+ * Represents a list of 5 typed Objects.
+ *
+ * @since 2.5.0
+ */
+public class Tuple5<T1, T2, T3, T4, T5> extends Tuple {
+ private static final long serialVersionUID = 6722094358774027115L;
+ private final T1 first;
+ private final T2 second;
+ private final T3 third;
+ private final T4 fourth;
+ private final T5 fifth;
+
+ public Tuple5(T1 first, T2 second, T3 third, T4 fourth, T5 fifth) {
+ super(first, second, third, fourth, fifth);
+
+ this.first = first;
+ this.second = second;
+ this.third = third;
+ this.fourth = fourth;
+ this.fifth = fifth;
+ }
+
+ @Override
+ public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ case 2:
+ return third;
+ case 3:
+ return fourth;
+ case 4:
+ return fifth;
+ default:
+ throw new IndexOutOfBoundsException("index: " + index);
+ }
+ }
+
+ @Override
+ public int size() {
+ return 5;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+
+ public T2 getSecond() {
+ return second;
+ }
+
+ public T3 getThird() {
+ return third;
+ }
+
+ public T4 getFourth() {
+ return fourth;
+ }
+
+ public T5 getFifth() {
+ return fifth;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple6.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple6.java b/src/main/groovy/groovy/lang/Tuple6.java
new file mode 100644
index 0000000..76d12ca
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple6.java
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+/**
+ * Represents a list of 6 typed Objects.
+ *
+ * @since 2.5.0
+ */
+public class Tuple6<T1, T2, T3, T4, T5, T6> extends Tuple {
+ private static final long serialVersionUID = -7848588473093102288L;
+ private final T1 first;
+ private final T2 second;
+ private final T3 third;
+ private final T4 fourth;
+ private final T5 fifth;
+ private final T6 sixth;
+
+ public Tuple6(T1 first, T2 second, T3 third, T4 fourth, T5 fifth, T6 sixth) {
+ super(first, second, third, fourth, fifth, sixth);
+
+ this.first = first;
+ this.second = second;
+ this.third = third;
+ this.fourth = fourth;
+ this.fifth = fifth;
+ this.sixth = sixth;
+ }
+
+ @Override
+ public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ case 2:
+ return third;
+ case 3:
+ return fourth;
+ case 4:
+ return fifth;
+ case 5:
+ return sixth;
+ default:
+ throw new IndexOutOfBoundsException("index: " + index);
+ }
+ }
+
+ @Override
+ public int size() {
+ return 6;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+
+ public T2 getSecond() {
+ return second;
+ }
+
+ public T3 getThird() {
+ return third;
+ }
+
+ public T4 getFourth() {
+ return fourth;
+ }
+
+ public T5 getFifth() {
+ return fifth;
+ }
+
+ public T6 getSixth() {
+ return sixth;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple7.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple7.java b/src/main/groovy/groovy/lang/Tuple7.java
new file mode 100644
index 0000000..05046e7
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple7.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+/**
+ * Represents a list of 7 typed Objects.
+ *
+ * @since 2.5.0
+ */
+public class Tuple7<T1, T2, T3, T4, T5, T6, T7> extends Tuple {
+ private static final long serialVersionUID = 4226144828786865766L;
+ private final T1 first;
+ private final T2 second;
+ private final T3 third;
+ private final T4 fourth;
+ private final T5 fifth;
+ private final T6 sixth;
+ private final T7 seventh;
+
+ public Tuple7(T1 first, T2 second, T3 third, T4 fourth, T5 fifth, T6 sixth, T7 seventh) {
+ super(first, second, third, fourth, fifth, sixth, seventh);
+
+ this.first = first;
+ this.second = second;
+ this.third = third;
+ this.fourth = fourth;
+ this.fifth = fifth;
+ this.sixth = sixth;
+ this.seventh = seventh;
+ }
+
+ @Override
+ public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ case 2:
+ return third;
+ case 3:
+ return fourth;
+ case 4:
+ return fifth;
+ case 5:
+ return sixth;
+ case 6:
+ return seventh;
+ default:
+ throw new IndexOutOfBoundsException("index: " + index);
+ }
+ }
+
+ @Override
+ public int size() {
+ return 7;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+
+ public T2 getSecond() {
+ return second;
+ }
+
+ public T3 getThird() {
+ return third;
+ }
+
+ public T4 getFourth() {
+ return fourth;
+ }
+
+ public T5 getFifth() {
+ return fifth;
+ }
+
+ public T6 getSixth() {
+ return sixth;
+ }
+
+ public T7 getSeventh() {
+ return seventh;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple8.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple8.java b/src/main/groovy/groovy/lang/Tuple8.java
new file mode 100644
index 0000000..1f38ca9
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple8.java
@@ -0,0 +1,111 @@
+/*
+ * 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;
+
+/**
+ * Represents a list of 8 typed Objects.
+ *
+ * @since 2.5.0
+ */
+public class Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> extends Tuple {
+ private static final long serialVersionUID = -8895822084644138566L;
+ private final T1 first;
+ private final T2 second;
+ private final T3 third;
+ private final T4 fourth;
+ private final T5 fifth;
+ private final T6 sixth;
+ private final T7 seventh;
+ private final T8 eighth;
+
+ public Tuple8(T1 first, T2 second, T3 third, T4 fourth, T5 fifth, T6 sixth, T7 seventh, T8 eighth) {
+ super(first, second, third, fourth, fifth, sixth, seventh, eighth);
+
+ this.first = first;
+ this.second = second;
+ this.third = third;
+ this.fourth = fourth;
+ this.fifth = fifth;
+ this.sixth = sixth;
+ this.seventh = seventh;
+ this.eighth = eighth;
+ }
+
+ @Override
+ public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ case 2:
+ return third;
+ case 3:
+ return fourth;
+ case 4:
+ return fifth;
+ case 5:
+ return sixth;
+ case 6:
+ return seventh;
+ case 7:
+ return eighth;
+ default:
+ throw new IndexOutOfBoundsException("index: " + index);
+ }
+ }
+
+ @Override
+ public int size() {
+ return 8;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+
+ public T2 getSecond() {
+ return second;
+ }
+
+ public T3 getThird() {
+ return third;
+ }
+
+ public T4 getFourth() {
+ return fourth;
+ }
+
+ public T5 getFifth() {
+ return fifth;
+ }
+
+ public T6 getSixth() {
+ return sixth;
+ }
+
+ public T7 getSeventh() {
+ return seventh;
+ }
+
+ public T8 getEighth() {
+ return eighth;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Tuple9.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple9.java b/src/main/groovy/groovy/lang/Tuple9.java
new file mode 100644
index 0000000..3189c10
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple9.java
@@ -0,0 +1,120 @@
+/*
+ * 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;
+
+/**
+ * Represents a list of 9 typed Objects.
+ *
+ * @since 2.5.0
+ */
+public class Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> extends Tuple {
+ private static final long serialVersionUID = -5181196675351911769L;
+ private final T1 first;
+ private final T2 second;
+ private final T3 third;
+ private final T4 fourth;
+ private final T5 fifth;
+ private final T6 sixth;
+ private final T7 seventh;
+ private final T8 eighth;
+ private final T9 ninth;
+
+ public Tuple9(T1 first, T2 second, T3 third, T4 fourth, T5 fifth, T6 sixth, T7 seventh, T8 eighth, T9 ninth) {
+ super(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth);
+
+ this.first = first;
+ this.second = second;
+ this.third = third;
+ this.fourth = fourth;
+ this.fifth = fifth;
+ this.sixth = sixth;
+ this.seventh = seventh;
+ this.eighth = eighth;
+ this.ninth = ninth;
+ }
+
+ @Override
+ public Object get(int index) {
+ switch (index) {
+ case 0:
+ return first;
+ case 1:
+ return second;
+ case 2:
+ return third;
+ case 3:
+ return fourth;
+ case 4:
+ return fifth;
+ case 5:
+ return sixth;
+ case 6:
+ return seventh;
+ case 7:
+ return eighth;
+ case 8:
+ return ninth;
+ default:
+ throw new IndexOutOfBoundsException("index: " + index);
+ }
+ }
+
+ @Override
+ public int size() {
+ return 9;
+ }
+
+ public T1 getFirst() {
+ return first;
+ }
+
+ public T2 getSecond() {
+ return second;
+ }
+
+ public T3 getThird() {
+ return third;
+ }
+
+ public T4 getFourth() {
+ return fourth;
+ }
+
+ public T5 getFifth() {
+ return fifth;
+ }
+
+ public T6 getSixth() {
+ return sixth;
+ }
+
+ public T7 getSeventh() {
+ return seventh;
+ }
+
+ public T8 getEighth() {
+ return eighth;
+ }
+
+ public T9 getNinth() {
+ return ninth;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Writable.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Writable.java b/src/main/groovy/groovy/lang/Writable.java
new file mode 100644
index 0000000..ec135cd
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Writable.java
@@ -0,0 +1,56 @@
+/*
+ * 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.io.IOException;
+import java.io.Writer;
+
+
+/**
+ * Represents an object which is capable of writing itself to a text stream
+ * in a more efficient format than just creating a toString() representation
+ * of itself. This mechanism is particularly useful for templates and such like.
+ * <p>
+ * It is worth noting that writable implementations often override their
+ * toString() implementation as well to allow rendering the same result
+ * directly to a String; however this is not required.
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public interface Writable {
+
+ /**
+ * Writes this object to the given writer.
+ * <p>
+ * This is used to defer content creation until the point when it is
+ * streamed to the output destination. Oftentimes, content will be defined
+ * but not necessarily created (as is may be the case with a Closure
+ * definition.) In that case, the output is then 'deferred' to the point
+ * when it is serialized to the writer. This class may be used whenever an
+ * object should be responsible for creating its own textual representation,
+ * but creating the entire output as a single String would be inefficient
+ * (such as outputting a multi-gigabyte XML document.)
+ *
+ * @param out the Writer to which this Writable should output its data.
+ * @return the Writer that was passed
+ * @throws IOException if an error occurred while outputting data to the writer
+ */
+ Writer writeTo(Writer out) throws IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/groovydoc/Groovydoc.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/groovydoc/Groovydoc.java b/src/main/groovy/groovy/lang/groovydoc/Groovydoc.java
new file mode 100644
index 0000000..d7d4204
--- /dev/null
+++ b/src/main/groovy/groovy/lang/groovydoc/Groovydoc.java
@@ -0,0 +1,96 @@
+/*
+ * 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.groovydoc;
+
+import java.lang.reflect.AnnotatedElement;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Represents groovydoc
+ */
+public class Groovydoc {
+ private final String content;
+ private List<GroovydocTag> tagList;
+ private final GroovydocHolder holder;
+
+ public Groovydoc(String content, GroovydocHolder groovydocHolder) {
+ this.content = content;
+ this.holder = groovydocHolder;
+ }
+
+ public Groovydoc(final String content, final AnnotatedElement annotatedElement) {
+ this.content = content;
+ this.holder = new GroovydocHolder<AnnotatedElement>() {
+ @Override
+ public Groovydoc getGroovydoc() {
+ return Groovydoc.this;
+ }
+
+ @Override
+ public AnnotatedElement getInstance() {
+ return annotatedElement;
+ }
+ };
+ }
+
+ /**
+ * Get the content of groovydoc
+ * @return the text content
+ */
+ public String getContent() {
+ return content;
+ }
+
+ /**
+ * TODO Get list of groovydoc tags
+ * @return a list of tags
+ */
+ public List<GroovydocTag> getTagList() {
+ throw new UnsupportedOperationException("[TODO]parsing tags will be a new features of the next releases");
+// return tagList;
+ }
+
+ /**
+ * Get the holder of the groovydoc
+ * @return the groovydoc holder
+ */
+ public GroovydocHolder getHolder() {
+ return holder;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Groovydoc groovydoc = (Groovydoc) o;
+ return Objects.equals(content, groovydoc.content) &&
+ Objects.equals(holder, groovydoc.holder);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(content, holder);
+ }
+
+ @Override
+ public String toString() {
+ return this.content;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/groovydoc/GroovydocHolder.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/groovydoc/GroovydocHolder.java b/src/main/groovy/groovy/lang/groovydoc/GroovydocHolder.java
new file mode 100644
index 0000000..eb41df4
--- /dev/null
+++ b/src/main/groovy/groovy/lang/groovydoc/GroovydocHolder.java
@@ -0,0 +1,37 @@
+/*
+ * 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.groovydoc;
+
+/**
+ * Represents Groovydoc Holder
+ */
+public interface GroovydocHolder<T> {
+ String DOC_COMMENT = "_DOC_COMMENT"; // keys for meta data
+ /**
+ * Get the groovydoc
+ * @return the groovydoc
+ */
+ Groovydoc getGroovydoc();
+
+ /**
+ * Get GroovydocHolder instance
+ * @return GroovydocHolder instance
+ */
+ T getInstance();
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/groovydoc/GroovydocTag.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/groovydoc/GroovydocTag.java b/src/main/groovy/groovy/lang/groovydoc/GroovydocTag.java
new file mode 100644
index 0000000..14e5aaa
--- /dev/null
+++ b/src/main/groovy/groovy/lang/groovydoc/GroovydocTag.java
@@ -0,0 +1,68 @@
+/*
+ * 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.groovydoc;
+
+import java.util.Objects;
+
+/**
+ * TODO parse groovydoc to get tag content
+ */
+public class GroovydocTag {
+ private String name;
+ private String content;
+ private Groovydoc groovydoc;
+
+ public GroovydocTag(String name, String content, Groovydoc groovydoc) {
+ this.name = name;
+ this.content = content;
+ this.groovydoc = groovydoc;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public Groovydoc getGroovydoc() {
+ return groovydoc;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ GroovydocTag that = (GroovydocTag) o;
+ return Objects.equals(name, that.name) &&
+ Objects.equals(content, that.content) &&
+ Objects.equals(groovydoc, that.groovydoc);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, content, groovydoc);
+ }
+
+ @Override
+ public String toString() {
+ return content;
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/package.html
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/package.html b/src/main/groovy/groovy/lang/package.html
new file mode 100644
index 0000000..1ea84fc
--- /dev/null
+++ b/src/main/groovy/groovy/lang/package.html
@@ -0,0 +1,28 @@
+<!--
+
+ 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.lang.*</title>
+ </head>
+ <body>
+ <p>Core Groovy language classes for implementing data structures, closures, metadata and so forth.</p>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/org/codehaus/groovy/transform/ASTTestTransformation.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/org/codehaus/groovy/transform/ASTTestTransformation.groovy b/src/main/groovy/groovy/org/codehaus/groovy/transform/ASTTestTransformation.groovy
new file mode 100644
index 0000000..dcfe314
--- /dev/null
+++ b/src/main/groovy/groovy/org/codehaus/groovy/transform/ASTTestTransformation.groovy
@@ -0,0 +1,233 @@
+/*
+ * 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 org.codehaus.groovy.transform
+
+import groovy.transform.CompilationUnitAware
+import org.codehaus.groovy.ast.ASTNode
+import org.codehaus.groovy.ast.AnnotationNode
+import org.codehaus.groovy.ast.ClassCodeVisitorSupport
+import org.codehaus.groovy.ast.ClassHelper
+import org.codehaus.groovy.ast.ClassNode
+import org.codehaus.groovy.ast.MethodNode
+import org.codehaus.groovy.ast.expr.ClosureExpression
+import org.codehaus.groovy.ast.expr.PropertyExpression
+import org.codehaus.groovy.ast.expr.VariableExpression
+import org.codehaus.groovy.ast.stmt.Statement
+import org.codehaus.groovy.control.CompilationUnit
+import org.codehaus.groovy.control.CompilePhase
+import org.codehaus.groovy.control.CompilerConfiguration
+import org.codehaus.groovy.control.ErrorCollector
+import org.codehaus.groovy.control.Janitor
+import org.codehaus.groovy.control.ProcessingUnit
+import org.codehaus.groovy.control.SourceUnit
+import org.codehaus.groovy.control.customizers.ImportCustomizer
+import org.codehaus.groovy.control.io.ReaderSource
+import org.codehaus.groovy.runtime.MethodClosure
+import org.codehaus.groovy.syntax.SyntaxException
+import org.codehaus.groovy.tools.Utilities
+
+import static org.codehaus.groovy.ast.tools.GeneralUtils.classX
+import static org.codehaus.groovy.ast.tools.GeneralUtils.propX
+
+@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
+class ASTTestTransformation extends AbstractASTTransformation implements CompilationUnitAware {
+ private CompilationUnit compilationUnit
+
+ void visit(final ASTNode[] nodes, final SourceUnit source) {
+ AnnotationNode annotationNode = nodes[0]
+ def member = annotationNode.getMember('phase')
+ def phase = null
+ if (member) {
+ if (member instanceof VariableExpression) {
+ phase = CompilePhase.valueOf(member.text)
+ } else if (member instanceof PropertyExpression) {
+ phase = CompilePhase.valueOf(member.propertyAsString)
+ }
+ annotationNode.setMember('phase', propX(classX(ClassHelper.make(CompilePhase)), phase.toString()))
+ }
+ member = annotationNode.getMember('value')
+ if (member && !(member instanceof ClosureExpression)) {
+ throw new SyntaxException("ASTTest value must be a closure", member.getLineNumber(), member.getColumnNumber())
+ }
+ if (!member && !annotationNode.getNodeMetaData(ASTTestTransformation)) {
+ throw new SyntaxException("Missing test expression", annotationNode.getLineNumber(), annotationNode.getColumnNumber())
+ }
+ // convert value into node metadata so that the expression doesn't mix up with other AST xforms like type checking
+ annotationNode.putNodeMetaData(ASTTestTransformation, member)
+ annotationNode.getMembers().remove('value')
+
+ def pcallback = compilationUnit.progressCallback
+ def callback = new CompilationUnit.ProgressCallback() {
+ Binding binding = new Binding([:].withDefault {null})
+
+ @Override
+ void call(final ProcessingUnit context, final int phaseRef) {
+ if (phase==null || phaseRef == phase.phaseNumber) {
+ ClosureExpression testClosure = nodes[0].getNodeMetaData(ASTTestTransformation)
+ StringBuilder sb = new StringBuilder()
+ for (int i = testClosure.lineNumber; i <= testClosure.lastLineNumber; i++) {
+ sb.append(source.source.getLine(i, new Janitor())).append('\n')
+ }
+ def testSource = sb.substring(testClosure.columnNumber + 1, sb.length())
+ testSource = testSource.substring(0, testSource.lastIndexOf('}'))
+ CompilerConfiguration config = new CompilerConfiguration()
+ def customizer = new ImportCustomizer()
+ config.addCompilationCustomizers(customizer)
+ binding['sourceUnit'] = source
+ binding['node'] = nodes[1]
+ binding['lookup'] = new MethodClosure(LabelFinder, "lookup").curry(nodes[1])
+ binding['compilationUnit'] = compilationUnit
+ binding['compilePhase'] = CompilePhase.fromPhaseNumber(phaseRef)
+
+ GroovyShell shell = new GroovyShell(binding, config)
+
+ source.AST.imports.each {
+ customizer.addImport(it.alias, it.type.name)
+ }
+ source.AST.starImports.each {
+ customizer.addStarImports(it.packageName)
+ }
+ source.AST.staticImports.each {
+ customizer.addStaticImport(it.value.alias, it.value.type.name, it.value.fieldName)
+ }
+ source.AST.staticStarImports.each {
+ customizer.addStaticStars(it.value.className)
+ }
+ shell.evaluate(testSource)
+ }
+ }
+ }
+
+ if (pcallback!=null) {
+ if (pcallback instanceof ProgressCallbackChain) {
+ pcallback.addCallback(callback)
+ } else {
+ pcallback = new ProgressCallbackChain(pcallback, callback)
+ }
+ callback = pcallback
+ }
+
+ compilationUnit.setProgressCallback(callback)
+
+ }
+
+ void setCompilationUnit(final CompilationUnit unit) {
+ this.compilationUnit = unit
+ }
+
+ private static class AssertionSourceDelegatingSourceUnit extends SourceUnit {
+ private final ReaderSource delegate
+
+ AssertionSourceDelegatingSourceUnit(final String name, final ReaderSource source, final CompilerConfiguration flags, final GroovyClassLoader loader, final ErrorCollector er) {
+ super(name, '', flags, loader, er)
+ delegate = source
+ }
+
+ @Override
+ String getSample(final int line, final int column, final Janitor janitor) {
+ String sample = null;
+ String text = delegate.getLine(line, janitor);
+
+ if (text != null) {
+ if (column > 0) {
+ String marker = Utilities.repeatString(" ", column - 1) + "^";
+
+ if (column > 40) {
+ int start = column - 30 - 1;
+ int end = (column + 10 > text.length() ? text.length() : column + 10 - 1);
+ sample = " " + text.substring(start, end) + Utilities.eol() + " " +
+ marker.substring(start, marker.length());
+ } else {
+ sample = " " + text + Utilities.eol() + " " + marker;
+ }
+ } else {
+ sample = text;
+ }
+ }
+
+ return sample;
+
+ }
+
+ }
+
+ private static class ProgressCallbackChain extends CompilationUnit.ProgressCallback {
+
+ private final List<CompilationUnit.ProgressCallback> chain = new LinkedList<CompilationUnit.ProgressCallback>()
+
+ ProgressCallbackChain(CompilationUnit.ProgressCallback... callbacks) {
+ if (callbacks!=null) {
+ callbacks.each { addCallback(it) }
+ }
+ }
+
+ public void addCallback(CompilationUnit.ProgressCallback callback) {
+ chain << callback
+ }
+
+ @Override
+ void call(final ProcessingUnit context, final int phase) {
+ chain*.call(context, phase)
+ }
+ }
+
+ public static class LabelFinder extends ClassCodeVisitorSupport {
+
+ public static List<Statement> lookup(MethodNode node, String label) {
+ LabelFinder finder = new LabelFinder(label, null)
+ node.code.visit(finder)
+
+ finder.targets
+ }
+
+ public static List<Statement> lookup(ClassNode node, String label) {
+ LabelFinder finder = new LabelFinder(label, null)
+ node.methods*.code*.visit(finder)
+ node.declaredConstructors*.code*.visit(finder)
+
+ finder.targets
+ }
+
+ private final String label
+ private final SourceUnit unit
+
+ private final List<Statement> targets = new LinkedList<Statement>();
+
+ LabelFinder(final String label, final SourceUnit unit) {
+ this.label = label
+ this.unit = unit;
+ }
+
+ @Override
+ protected SourceUnit getSourceUnit() {
+ unit
+ }
+
+ @Override
+ protected void visitStatement(final Statement statement) {
+ super.visitStatement(statement)
+ if (statement.statementLabel==label) targets << statement
+ }
+
+ List<Statement> getTargets() {
+ return Collections.unmodifiableList(targets)
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/org/codehaus/groovy/transform/ConditionalInterruptibleASTTransformation.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/org/codehaus/groovy/transform/ConditionalInterruptibleASTTransformation.groovy b/src/main/groovy/groovy/org/codehaus/groovy/transform/ConditionalInterruptibleASTTransformation.groovy
new file mode 100644
index 0000000..2cda121
--- /dev/null
+++ b/src/main/groovy/groovy/org/codehaus/groovy/transform/ConditionalInterruptibleASTTransformation.groovy
@@ -0,0 +1,145 @@
+/*
+ * 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 org.codehaus.groovy.transform
+
+import groovy.transform.ConditionalInterrupt
+import org.codehaus.groovy.ast.AnnotatedNode
+import org.codehaus.groovy.ast.AnnotationNode
+import org.codehaus.groovy.ast.ClassHelper
+import org.codehaus.groovy.ast.ClassNode
+import org.codehaus.groovy.ast.FieldNode
+import org.codehaus.groovy.ast.MethodNode
+import org.codehaus.groovy.ast.Parameter
+import org.codehaus.groovy.ast.PropertyNode
+import org.codehaus.groovy.ast.expr.ArgumentListExpression
+import org.codehaus.groovy.ast.expr.ClosureExpression
+import org.codehaus.groovy.ast.expr.Expression
+import org.codehaus.groovy.ast.expr.MethodCallExpression
+import org.codehaus.groovy.ast.expr.VariableExpression
+import org.codehaus.groovy.ast.tools.ClosureUtils
+import org.codehaus.groovy.control.CompilePhase
+
+/**
+ * Allows "interrupt-safe" executions of scripts by adding a custom conditional
+ * check on loops (for, while, do) and first statement of closures. By default, also adds an interrupt check
+ * statement on the beginning of method calls.
+ *
+ * @see groovy.transform.ConditionalInterrupt
+ * @author Cedric Champeau
+ * @author Hamlet D'Arcy
+ * @author Paul King
+ * @since 1.8.0
+ */
+@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
+public class ConditionalInterruptibleASTTransformation extends AbstractInterruptibleASTTransformation {
+
+ private static final ClassNode MY_TYPE = ClassHelper.make(ConditionalInterrupt)
+
+ private ClosureExpression conditionNode
+ private String conditionMethod
+ private MethodCallExpression conditionCallExpression
+ private ClassNode currentClass
+
+ protected ClassNode type() {
+ return MY_TYPE
+ }
+
+ protected void setupTransform(AnnotationNode node) {
+ super.setupTransform(node)
+ def member = node.getMember("value")
+ if (!member || !(member instanceof ClosureExpression)) internalError("Expected closure value for annotation parameter 'value'. Found $member")
+ conditionNode = member;
+ conditionMethod = 'conditionalTransform' + node.hashCode() + '$condition'
+ conditionCallExpression = new MethodCallExpression(new VariableExpression('this'), conditionMethod, new ArgumentListExpression())
+ }
+
+ protected String getErrorMessage() {
+ 'Execution interrupted. The following condition failed: ' + convertClosureToSource(conditionNode)
+ }
+
+ void visitClass(ClassNode type) {
+ currentClass = type
+ def method = type.addMethod(conditionMethod, ACC_PRIVATE | ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, conditionNode.code)
+ method.synthetic = true
+ if (applyToAllMembers) {
+ super.visitClass(type)
+ }
+ }
+
+ protected Expression createCondition() {
+ conditionCallExpression
+ }
+
+ @Override
+ void visitAnnotations(AnnotatedNode node) {
+ // this transformation does not apply on annotation nodes
+ // visiting could lead to stack overflows
+ }
+
+ @Override
+ void visitField(FieldNode node) {
+ if (!node.isStatic() && !node.isSynthetic()) {
+ super.visitField node
+ }
+ }
+
+ @Override
+ void visitProperty(PropertyNode node) {
+ if (!node.isStatic() && !node.isSynthetic()) {
+ super.visitProperty node
+ }
+ }
+
+ @Override
+ void visitClosureExpression(ClosureExpression closureExpr) {
+ if (closureExpr == conditionNode) return // do not visit the closure from the annotation itself
+ def code = closureExpr.code
+ closureExpr.code = wrapBlock(code)
+ super.visitClosureExpression closureExpr
+ }
+
+ @Override
+ void visitMethod(MethodNode node) {
+ if (node.name == conditionMethod && !node.isSynthetic()) return // do not visit the generated method
+ if (node.name == 'run' && currentClass.isScript() && node.parameters.length == 0) {
+ // the run() method should not have the statement added, otherwise the script binding won't be set before
+ // the condition is actually tested
+ super.visitMethod(node)
+ } else {
+ if (checkOnMethodStart && !node.isSynthetic() && !node.isStatic() && !node.isAbstract()) {
+ def code = node.code
+ node.code = wrapBlock(code);
+ }
+ if (!node.isSynthetic() && !node.isStatic()) super.visitMethod(node)
+ }
+ }
+
+ /**
+ * Converts a ClosureExpression into the String source.
+ * @param expression a closure
+ * @return the source the closure was created from
+ */
+ private String convertClosureToSource(ClosureExpression expression) {
+ try {
+ return ClosureUtils.convertClosureToSource(this.source.source, expression);
+ } catch(Exception e) {
+ return e.message
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/org/codehaus/groovy/transform/ThreadInterruptibleASTTransformation.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/org/codehaus/groovy/transform/ThreadInterruptibleASTTransformation.groovy b/src/main/groovy/groovy/org/codehaus/groovy/transform/ThreadInterruptibleASTTransformation.groovy
new file mode 100644
index 0000000..a4fb4c3
--- /dev/null
+++ b/src/main/groovy/groovy/org/codehaus/groovy/transform/ThreadInterruptibleASTTransformation.groovy
@@ -0,0 +1,98 @@
+/*
+ * 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 org.codehaus.groovy.transform
+
+import groovy.transform.CompileStatic
+import groovy.transform.ThreadInterrupt
+import org.codehaus.groovy.ast.ClassHelper
+import org.codehaus.groovy.ast.ClassNode
+import org.codehaus.groovy.ast.MethodNode
+import org.codehaus.groovy.ast.Parameter
+import org.codehaus.groovy.ast.expr.ArgumentListExpression
+import org.codehaus.groovy.ast.expr.ClassExpression
+import org.codehaus.groovy.ast.expr.ClosureExpression
+import org.codehaus.groovy.ast.expr.Expression
+import org.codehaus.groovy.ast.expr.MethodCallExpression
+import org.codehaus.groovy.control.CompilePhase
+
+/**
+ * Allows "interrupt-safe" executions of scripts by adding Thread.currentThread().isInterrupted()
+ * checks on loops (for, while, do) and first statement of closures. By default, also adds an interrupt check
+ * statement on the beginning of method calls.
+ *
+ * @see groovy.transform.ThreadInterrupt
+ *
+ * @author Cedric Champeau
+ * @author Hamlet D'Arcy
+ *
+ * @since 1.8.0
+ */
+@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
+@CompileStatic
+public class ThreadInterruptibleASTTransformation extends AbstractInterruptibleASTTransformation {
+
+ private static final ClassNode MY_TYPE = ClassHelper.make(ThreadInterrupt)
+ private static final ClassNode THREAD_TYPE = ClassHelper.make(Thread)
+ private static final MethodNode CURRENTTHREAD_METHOD
+ private static final MethodNode ISINTERRUPTED_METHOD
+
+ static {
+ CURRENTTHREAD_METHOD = THREAD_TYPE.getMethod('currentThread', Parameter.EMPTY_ARRAY)
+ ISINTERRUPTED_METHOD = THREAD_TYPE.getMethod('isInterrupted', Parameter.EMPTY_ARRAY)
+ }
+
+ protected ClassNode type() {
+ return MY_TYPE;
+ }
+
+ protected String getErrorMessage() {
+ 'Execution interrupted. The current thread has been interrupted.'
+ }
+
+ protected Expression createCondition() {
+ def currentThread = new MethodCallExpression(new ClassExpression(THREAD_TYPE),
+ 'currentThread',
+ ArgumentListExpression.EMPTY_ARGUMENTS)
+ currentThread.methodTarget = CURRENTTHREAD_METHOD
+ def isInterrupted = new MethodCallExpression(
+ currentThread,
+ 'isInterrupted', ArgumentListExpression.EMPTY_ARGUMENTS)
+ isInterrupted.methodTarget = ISINTERRUPTED_METHOD
+ [currentThread, isInterrupted]*.implicitThis = false
+
+ isInterrupted
+ }
+
+
+ @Override
+ public void visitClosureExpression(ClosureExpression closureExpr) {
+ def code = closureExpr.code
+ closureExpr.code = wrapBlock(code)
+ super.visitClosureExpression closureExpr
+ }
+
+ @Override
+ public void visitMethod(MethodNode node) {
+ if (checkOnMethodStart && !node.isSynthetic() && !node.isAbstract()) {
+ def code = node.code
+ node.code = wrapBlock(code);
+ }
+ super.visitMethod(node)
+ }
+}