http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/ClosureSignatureHint.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/ClosureSignatureHint.java b/src/main/groovy/transform/stc/ClosureSignatureHint.java deleted file mode 100644 index 9a77d20..0000000 --- a/src/main/groovy/transform/stc/ClosureSignatureHint.java +++ /dev/null @@ -1,144 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassHelper; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.GenericsType; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.ast.Parameter; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -import java.util.List; - -/** - * <p>A closure signature hint class is always used in conjunction with the {@link ClosureParams} annotation. It is - * called at compile time (or may be used by IDEs) to infer the types of the parameters of a {@link groovy.lang.Closure}.</p> - - * <p>A closure hint class is responsible for generating the list of arguments that a closure accepts. Since closures - * may accept several signatures, {@link #getClosureSignatures(org.codehaus.groovy.ast.MethodNode, org.codehaus.groovy.control.SourceUnit, org.codehaus.groovy.control.CompilationUnit, String[], org.codehaus.groovy.ast.ASTNode)} should - * return a list.</p> - * - * <p>Whenever the type checker encounters a method call that targets a method accepting a closure, it will search - * for the {@link ClosureParams} annotation on the {@link groovy.lang.Closure} argument. If it is found, then it - * creates an instance of the hint class and calls the {@link #getClosureSignatures(org.codehaus.groovy.ast.MethodNode, org.codehaus.groovy.control.SourceUnit, org.codehaus.groovy.control.CompilationUnit, String[], org.codehaus.groovy.ast.ASTNode)} - * method, which will in turn return the list of signatures.</p> - * - * <p><i>Note that the signature concept here is used only to describe the parameter types, not the result type, which - * is found in the generic type argument of the {@link groovy.lang.Closure} class.</i></p> - * - * <p>Several predefined hints can be found, which should cover most of the use cases.</p> - * - * @author Cédric Champeau - * @since 2.3.0 - * - */ -public abstract class ClosureSignatureHint { - - /** - * A helper method which will extract the n-th generic type from a class node. - * @param type the class node from which to pick a generic type - * @param gtIndex the index of the generic type to extract - * @return the n-th generic type, or {@link org.codehaus.groovy.ast.ClassHelper#OBJECT_TYPE} if it doesn't exist. - */ - public static ClassNode pickGenericType(ClassNode type, int gtIndex) { - final GenericsType[] genericsTypes = type.getGenericsTypes(); - if (genericsTypes==null || genericsTypes.length<gtIndex) { - return ClassHelper.OBJECT_TYPE; - } - return genericsTypes[gtIndex].getType(); - } - - /** - * A helper method which will extract the n-th generic type from the n-th parameter of a method node. - * @param node the method node from which the generic type should be picked - * @param parameterIndex the index of the parameter in the method parameter list - * @param gtIndex the index of the generic type to extract - * @return the generic type, or {@link org.codehaus.groovy.ast.ClassHelper#OBJECT_TYPE} if it doesn't exist. - */ - public static ClassNode pickGenericType(MethodNode node, int parameterIndex, int gtIndex) { - final Parameter[] parameters = node.getParameters(); - final ClassNode type = parameters[parameterIndex].getOriginType(); - return pickGenericType(type, gtIndex); - } - - /** - * <p>Subclasses should implement this method, which returns the list of accepted closure signatures.</p> - * - * <p>The compiler will call this method each time, in a source file, a method call using a closure - * literal is encountered and that the target method has the corresponding {@link groovy.lang.Closure} parameter - * annotated with {@link groovy.transform.stc.ClosureParams}. So imagine the following code needs to be compiled:</p> - * - * <code>@groovy.transform.TypeChecked - * void doSomething() { - * println ['a','b'].collect { it.toUpperCase() } - * }</code> - * - * <p>The <i>collect</i> method accepts a closure, but normally, the type checker doesn't have enough type information - * in the sole {@link org.codehaus.groovy.runtime.DefaultGroovyMethods#collect(java.util.Collection, groovy.lang.Closure)} method - * signature to infer the type of <i>it</i>. With the annotation, it will now try to find an annotation on the closure parameter. - * If it finds it, then an instance of the hint class is created and the type checker calls it with the following arguments:</p> - * <ul> - * <li>the method node corresponding to the target method (here, the {@link org.codehaus.groovy.runtime.DefaultGroovyMethods#collect(java.util.Collection, groovy.lang.Closure)} method</li> - * <li>the (optional) list of options found in the annotation</li> - * </ul> - * - * <p>Now, the hint instance can return the list of expected parameters. Here, it would have to say that the collect method accepts - * a closure for which the only argument is of the type of the first generic type of the first argument.</p> - * <p>With that type information, the type checker can now infer that the type of <i>it</i> is <i>String</i>, because the first argument (here the receiver of the collect method) - * is a <i>List<String></i></p> - * - * <p></p> - * - * <p>Subclasses are therefore expected to return the signatures according to the available context, which is only the target method and the potential options.</p> - * - * - * @param node the method node for which a {@link groovy.lang.Closure} parameter was annotated with - * {@link ClosureParams} - * @param sourceUnit the source unit of the file being compiled - * @param compilationUnit the compilation unit of the file being compiled - * @param options the options, corresponding to the {@link ClosureParams#options()} found on the annotation @return a non-null list of signature, where a signature corresponds to an array of class nodes, each of them matching a parameter. - * @param usage the AST node, in the compiled file, which triggered a call to this method. Normally only used for logging/error handling - */ - public abstract List<ClassNode[]> getClosureSignatures(MethodNode node, SourceUnit sourceUnit, CompilationUnit compilationUnit, String[] options, ASTNode usage); - - /** - * Finds a class node given a string representing the type. Performs a lookup in the compilation unit to check if it is done in the same source unit. - * @param sourceUnit source unit - * @param compilationUnit compilation unit - * @param className the name of the class we want to get a {@link org.codehaus.groovy.ast.ClassNode} for - * @return a ClassNode representing the type - */ - protected ClassNode findClassNode(final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final String className) { - if (className.endsWith("[]")) { - return findClassNode(sourceUnit, compilationUnit, className.substring(0, className.length() - 2)).makeArray(); - } - ClassNode cn = compilationUnit.getClassNode(className); - if (cn == null) { - try { - cn = ClassHelper.make(Class.forName(className, false, sourceUnit.getClassLoader())); - } catch (ClassNotFoundException e) { - cn = ClassHelper.make(className); - } - } - return cn; - } -}
http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/FirstParam.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/FirstParam.java b/src/main/groovy/transform/stc/FirstParam.java deleted file mode 100644 index 81eb0e7..0000000 --- a/src/main/groovy/transform/stc/FirstParam.java +++ /dev/null @@ -1,93 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -/** - * <p>A hint used to instruct the type checker to pick the first parameter type. For example:</p> - * <code>public <T> def doWith(T src, @ClosureParams(FirstParam.class) Closure c) { c.call(src); }</code> - * - * <p>This class has several inner classes that also helps picking generic argument types instead of the parameter type.</p> - * - * @author Cédric Champeau - * @since 2.3.0 - */ -public class FirstParam extends PickAnyArgumentHint { - public FirstParam() { - super(0,-1); - } - - /** - * <p>A hint used to instruct the type checker to pick the first generic type of the first parameter type. For example:</p> - * <code>void <T> doWithElements(List<T> src, @ClosureParams(FirstParam.FirstGenericType.class) Closure c) { src.each { c.call(it) } }</code> - * - * @author Cédric Champeau - * @since 2.3.0 - */ - public static class FirstGenericType extends PickAnyArgumentHint { - public FirstGenericType() { - super(0,0); - } - } - - /** - * <p>A hint used to instruct the type checker to pick the second generic type of the first parameter type. For example:</p> - * <code>void <T,U> doWithElements(Tuple<T,U> src, @ClosureParams(FirstParam.SecondGenericType.class) Closure c) { src.each { c.call(it) } }</code> - * - * @author Cédric Champeau - * @since 2.3.0 - */ - public static class SecondGenericType extends PickAnyArgumentHint { - public SecondGenericType() { - super(0,1); - } - } - - /** - * <p>A hint used to instruct the type checker to pick the third generic type of the first parameter type. For example:</p> - * <code>void <T,U,V> doWithElements(Triple<T,U,V> src, @ClosureParams(FirstParam.ThirdGenericType.class) Closure c) { src.each { c.call(it) } }</code> - * - * @author Cédric Champeau - * @since 2.3.0 - */ - public static class ThirdGenericType extends PickAnyArgumentHint { - public ThirdGenericType() { - super(0,2); - } - } - - /** - * <p>A hint used to instruct the type checker to pick the type of the component of the first parameter type, which is therefore - * expected to be an array, like in this example:</p> - * <code>void <T> doWithArray(T[] array, @ClosureParams(FirstParam.Component.class) Closure c) { array.each { c.call(it)} }</code> - */ - public static class Component extends FirstParam { - @Override - public ClassNode[] getParameterTypes(final MethodNode node, final String[] options, final SourceUnit sourceUnit, final CompilationUnit unit, final ASTNode usage) { - final ClassNode[] parameterTypes = super.getParameterTypes(node, options, sourceUnit, unit, usage); - parameterTypes[0] = parameterTypes[0].getComponentType(); - return parameterTypes; - } - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/FromAbstractTypeMethods.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/FromAbstractTypeMethods.java b/src/main/groovy/transform/stc/FromAbstractTypeMethods.java deleted file mode 100644 index e5125f1..0000000 --- a/src/main/groovy/transform/stc/FromAbstractTypeMethods.java +++ /dev/null @@ -1,68 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.ast.Parameter; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.transform.trait.Traits; - -import java.util.LinkedList; -import java.util.List; - -/** - * This signature hint uses abstract methods from some type (abstract class or interface) in order - * to infer the expected parameter types. This is especially useful for closure parameter type - * inference when implicit closure coercion is in action. - * - * @author Cédric Champeau - * @since 2.3.0 - */ -public class FromAbstractTypeMethods extends ClosureSignatureHint { - @Override - public List<ClassNode[]> getClosureSignatures(final MethodNode node, final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final String[] options, final ASTNode usage) { - String className = options[0]; - ClassNode cn = findClassNode(sourceUnit, compilationUnit, className); - return extractSignaturesFromMethods(cn); - } - - private static List<ClassNode[]> extractSignaturesFromMethods(final ClassNode cn) { - List<MethodNode> methods = cn.getAllDeclaredMethods(); - List<ClassNode[]> signatures = new LinkedList<ClassNode[]>(); - for (MethodNode method : methods) { - if (!method.isSynthetic() && method.isAbstract()) { - extractParametersFromMethod(signatures, method); - } - } - return signatures; - } - - private static void extractParametersFromMethod(final List<ClassNode[]> signatures, final MethodNode method) { - if (Traits.hasDefaultImplementation(method)) return; - Parameter[] parameters = method.getParameters(); - ClassNode[] typeParams = new ClassNode[parameters.length]; - for (int i = 0; i < parameters.length; i++) { - typeParams[i] = parameters[i].getOriginType(); - } - signatures.add(typeParams); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/FromString.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/FromString.java b/src/main/groovy/transform/stc/FromString.java deleted file mode 100644 index 12f9371..0000000 --- a/src/main/groovy/transform/stc/FromString.java +++ /dev/null @@ -1,80 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.ast.tools.GenericsUtils; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -import java.util.ArrayList; -import java.util.List; - - -/** - * <p>A closure parameter hint class that is convenient if you want to use a String representation - * of the signature. It makes use of the {@link ClosureParams#options() option strings}, where - * each string corresponds to a single signature.</p> - * - * <p>The following example describes a closure as accepting a single signature (List<T> list ->):</p> - * - * <code>public <T> T apply(T src, @ClosureParams(value=FromString.class, options="List<T>" Closure<T> cl)</code> - * - * <p>The next example describes a closure as accepting two signatures (List<T> list ->) and (T t ->):</p> - * - * <code>public <T> T apply(T src, @ClosureParams(value=FromString.class, options={"List<T>","T"} Closure<T> cl)</code> - * - * <p>It is advisable not to use this hint as a replacement for the various {@link FirstParam}, {@link SimpleType}, - * ... hints because it is actually much slower. Using this hint should therefore be limited - * to cases where it's not possible to express the signature using the existing hints.</p> - * - * @author Cédric Champeau - * @since 2.3.0 - */ -public class FromString extends ClosureSignatureHint { - - @Override - public List<ClassNode[]> getClosureSignatures(final MethodNode node, final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final String[] options, final ASTNode usage) { - List<ClassNode[]> list = new ArrayList<ClassNode[]>(options.length); - for (String option : options) { - list.add(parseOption(option, sourceUnit, compilationUnit, node, usage)); - } - return list; - } - - /** - * Parses a string representing a type, that must be aligned with the current context. - * For example, <i>"List<T>"</i> must be converted into the appropriate ClassNode - * for which <i>T</i> matches the appropriate placeholder. - * - * - * @param option a string representing a type - * @param sourceUnit the source unit (of the file being compiled) - * @param compilationUnit the compilation unit (of the file being compiled) - * @param mn the method node - * @param usage - * @return a class node if it could be parsed and resolved, null otherwise - */ - private static ClassNode[] parseOption(final String option, final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final MethodNode mn, final ASTNode usage) { - return GenericsUtils.parseClassNodesFromString(option, sourceUnit, compilationUnit, mn, usage); - } - -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/IncorrectTypeHintException.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/IncorrectTypeHintException.java b/src/main/groovy/transform/stc/IncorrectTypeHintException.java deleted file mode 100644 index aed167a..0000000 --- a/src/main/groovy/transform/stc/IncorrectTypeHintException.java +++ /dev/null @@ -1,32 +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.transform.stc; - -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.syntax.SyntaxException; - -public class IncorrectTypeHintException extends SyntaxException { - public IncorrectTypeHintException(final MethodNode mn, final Throwable e, int line, int column) { - super("Incorrect type hint in @ClosureParams in class "+mn.getDeclaringClass().getName()+" method "+mn.getTypeDescriptor()+" : "+e.getMessage(), e, line, column); - } - - public IncorrectTypeHintException(final MethodNode mn, final String msg, final int line, final int column) { - super("Incorrect type hint in @ClosureParams in class "+mn.getDeclaringClass().getName()+" method "+mn.getTypeDescriptor()+" : "+msg, line, column); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/MapEntryOrKeyValue.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/MapEntryOrKeyValue.java b/src/main/groovy/transform/stc/MapEntryOrKeyValue.java deleted file mode 100644 index 9316ef8..0000000 --- a/src/main/groovy/transform/stc/MapEntryOrKeyValue.java +++ /dev/null @@ -1,119 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassHelper; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.GenericsType; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * <p>A special hint which handles a common use case in the Groovy methods that work on maps. In case of an - * iteration on a list of map entries, you often want the user to be able to work either on a {@link java.util.Map.Entry} map entry - * or on a key,value pair.</p> - * <p>The result is a closure which can have the following forms:</p> - * <ul> - * <li><code>{ key, value -> ...}</code> where key is the key of a map entry, and value the corresponding value</li> - * <li><code>{ entry -> ... }</code> where entry is a {@link java.util.Map.Entry} map entry</li> - * <li><code>{ ...}</code> where <i>it</i> is an implicit {@link java.util.Map.Entry} map entry</li> - * </ul> - * <p>This hint handles all those cases by picking the generics from the first argument of the method (by default).</p> - * <p>The options array is used to modify the behavior of this hint. Each string in the option array consists of - * a key=value pair.</p> - * <ul> - * <li><i>argNum=index</i> of the parameter representing the map (by default, 0)</li> - * <li><i>index=true or false</i>, by default false. If true, then an additional "int" parameter is added, - * for "withIndex" variants</li> - * </ul> - * <code>void doSomething(String str, Map<K,>V map, @ClosureParams(value=MapEntryOrKeyValue.class,options="argNum=1") Closure c) { ... }</code> - */ -public class MapEntryOrKeyValue extends ClosureSignatureHint { - private static final ClassNode MAPENTRY_TYPE = ClassHelper.make(Map.Entry.class); - - public List<ClassNode[]> getClosureSignatures(final MethodNode node, final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final String[] options, final ASTNode usage) { - Options opt; - try { - opt = Options.parse(node, usage, options); - } catch (IncorrectTypeHintException e) { - sourceUnit.addError(e); - return Collections.emptyList(); - } - GenericsType[] genericsTypes = node.getParameters()[opt.parameterIndex].getOriginType().getGenericsTypes(); - if (genericsTypes==null) { - // would happen if you have a raw Map type for example - genericsTypes = new GenericsType[] { - new GenericsType(ClassHelper.OBJECT_TYPE), - new GenericsType(ClassHelper.OBJECT_TYPE) - }; - } - ClassNode[] firstSig; - ClassNode[] secondSig; - ClassNode mapEntry = MAPENTRY_TYPE.getPlainNodeReference(); - mapEntry.setGenericsTypes(genericsTypes); - if (opt.generateIndex) { - firstSig = new ClassNode[] {genericsTypes[0].getType(), genericsTypes[1].getType(), ClassHelper.int_TYPE}; - secondSig = new ClassNode[] {mapEntry, ClassHelper.int_TYPE}; - - } else { - firstSig = new ClassNode[] {genericsTypes[0].getType(), genericsTypes[1].getType()}; - secondSig = new ClassNode[] {mapEntry}; - } - return Arrays.asList(firstSig, secondSig); - } - - private static final class Options { - final int parameterIndex; - final boolean generateIndex; - - private Options(final int parameterIndex, final boolean generateIndex) { - this.parameterIndex = parameterIndex; - this.generateIndex = generateIndex; - } - - static Options parse(MethodNode mn, ASTNode source, String[] options) throws IncorrectTypeHintException { - int pIndex = 0; - boolean generateIndex = false; - for (String option : options) { - String[] keyValue = option.split("="); - if (keyValue.length==2) { - String key = keyValue[0]; - String value = keyValue[1]; - if ("argNum".equals(key)) { - pIndex = Integer.parseInt(value); - } else if ("index".equals(key)) { - generateIndex = Boolean.valueOf(value); - } else { - throw new IncorrectTypeHintException(mn, "Unrecognized option: "+key, source.getLineNumber(), source.getColumnNumber()); - } - } else { - throw new IncorrectTypeHintException(mn, "Incorrect option format. Should be argNum=<num> or index=<boolean> ", source.getLineNumber(), source.getColumnNumber()); - } - } - return new Options(pIndex, generateIndex); - } - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/PickAnyArgumentHint.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/PickAnyArgumentHint.java b/src/main/groovy/transform/stc/PickAnyArgumentHint.java deleted file mode 100644 index 6a5463f..0000000 --- a/src/main/groovy/transform/stc/PickAnyArgumentHint.java +++ /dev/null @@ -1,75 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -/** - * <p>Base class for hints which use the type of a parameter of the annotated method as the signature. - * This can optionally use a generic type of the selected parameter as the hint. For example, imagine the following - * method:</p> - * <code>void foo(A firstArg, B secondArg, Closure c) {...}</code> - * <p>If the <i>c</i> closure should be <code>{ B it -> ...}</code>, then we can see that the parameter type - * should be picked from the second parameter of the foo method, which is what {@link groovy.transform.stc.PickAnyArgumentHint} - * lets you do.</p> - * <p>Alternatively, the method may look like this:</p> - * <code>void <T> foo(A<T> firstArg, B secondArg, Closure c) {...}</code> - * <p>in which case if you want to express the fact that <i>c</i> should accept a <T> then you can use the - * {@link #genericTypeIndex} value.</p> - * <p></p> - * <p>This class is extended by several hint providers that make it easier to use as annotation values.</p> - * - * @author Cédric Champeau - * @since 2.3.0 - */ -public class PickAnyArgumentHint extends SingleSignatureClosureHint { - private final int parameterIndex; - private final int genericTypeIndex; - - /** - * Creates the an argument picker which extracts the type of the first parameter. - */ - public PickAnyArgumentHint() { - this(0,-1); - } - - /** - * Creates a picker which will extract the parameterIndex-th parameter type, or its - * genericTypeIndex-th generic type genericTypeIndex is >=0. - * @param parameterIndex the index of the parameter from which to extract the type - * @param genericTypeIndex if >=0, then returns the corresponding generic type instead of the parameter type. - */ - public PickAnyArgumentHint(final int parameterIndex, final int genericTypeIndex) { - this.parameterIndex = parameterIndex; - this.genericTypeIndex = genericTypeIndex; - } - - @Override - public ClassNode[] getParameterTypes(final MethodNode node, final String[] options, final SourceUnit sourceUnit, final CompilationUnit unit, final ASTNode usage) { - ClassNode type = node.getParameters()[parameterIndex].getOriginType(); - if (genericTypeIndex>=0) { - type = pickGenericType(type, genericTypeIndex); - } - return new ClassNode[]{type}; - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/PickFirstResolver.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/PickFirstResolver.java b/src/main/groovy/transform/stc/PickFirstResolver.java deleted file mode 100644 index 0bebb3e..0000000 --- a/src/main/groovy/transform/stc/PickFirstResolver.java +++ /dev/null @@ -1,45 +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.transform.stc; - -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.Expression; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -import java.util.Collections; -import java.util.List; - -/** - * Returns the first of several candidates found. - * This is useful if several types should be supported but only the first - * should be the default/inferred type. Other options in the list are - * obtained through explicitly typing the parameter(s). - * - * @since 2.5.0 - */ -public class PickFirstResolver extends ClosureSignatureConflictResolver { - @Override - public List<ClassNode[]> resolve(List<ClassNode[]> candidates, ClassNode receiver, Expression arguments, ClosureExpression closure, - MethodNode methodNode, SourceUnit sourceUnit, CompilationUnit compilationUnit, String[] options) { - return Collections.singletonList(candidates.get(0)); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/SecondParam.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/SecondParam.java b/src/main/groovy/transform/stc/SecondParam.java deleted file mode 100644 index c077750..0000000 --- a/src/main/groovy/transform/stc/SecondParam.java +++ /dev/null @@ -1,93 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -/** - * <p>A hint used to instruct the type checker to pick the second parameter type. For example:</p> - * <code>public <T,U> def doWith(T first, U second, @ClosureParams(SecondParam.class) Closure c) { c.call(src); }</code> - * - * <p>This class has several inner classes that also helps picking generic argument types instead of the parameter type.</p> - * - * @author Cédric Champeau - * @since 2.3.0 - */ -public class SecondParam extends PickAnyArgumentHint { - public SecondParam() { - super(1,-1); - } - - /** - * <p>A hint used to instruct the type checker to pick the first generic type of the second parameter type. For example:</p> - * <code>void <T> doWithElements(String base, List<T> src, @ClosureParams(SecondParam.FirstGenericType.class) Closure c) { ... } }</code> - * - * @author Cédric Champeau - * @since 2.3.0 - */ - public static class FirstGenericType extends PickAnyArgumentHint { - public FirstGenericType() { - super(1,0); - } - } - - /** - * <p>A hint used to instruct the type checker to pick the second generic type of the second parameter type. For example:</p> - * <code>void <T,U> doWithElements(String base, Tuple<T,U> src, @ClosureParams(SecondParam.SecondGenericType.class) Closure c) { ... }</code> - * - * @author Cédric Champeau - * @since 2.3.0 - */ - public static class SecondGenericType extends PickAnyArgumentHint { - public SecondGenericType() { - super(1,1); - } - } - - /** - * <p>A hint used to instruct the type checker to pick the second generic type of the second parameter type. For example:</p> - * <code>void <T,U,V> doWithElements(String base, Triple<T,U,V> src, @ClosureParams(SecondParam.ThirdGenericType.class) Closure c) { ... }</code> - * - * @author Cédric Champeau - * @since 2.3.0 - */ - public static class ThirdGenericType extends PickAnyArgumentHint { - public ThirdGenericType() { - super(1,2); - } - } - - /** - * <p>A hint used to instruct the type checker to pick the type of the component of the second parameter type, which is therefore - * expected to be an array, like in this example:</p> - * <code>void <T> doWithArray(String first, T[] array, @ClosureParams(FirstParam.Component.class) Closure c) { ... }</code> - */ - public static class Component extends SecondParam { - @Override - public ClassNode[] getParameterTypes(final MethodNode node, final String[] options, final SourceUnit sourceUnit, final CompilationUnit unit, final ASTNode usage) { - final ClassNode[] parameterTypes = super.getParameterTypes(node, options, sourceUnit, unit, usage); - parameterTypes[0] = parameterTypes[0].getComponentType(); - return parameterTypes; - } - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/SimpleType.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/SimpleType.java b/src/main/groovy/transform/stc/SimpleType.java deleted file mode 100644 index 8866e3b..0000000 --- a/src/main/groovy/transform/stc/SimpleType.java +++ /dev/null @@ -1,36 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -public class SimpleType extends SingleSignatureClosureHint { - @Override - public ClassNode[] getParameterTypes(final MethodNode node, final String[] options, final SourceUnit sourceUnit, final CompilationUnit unit, final ASTNode usage) { - ClassNode[] result = new ClassNode[options.length]; - for (int i = 0; i < result.length; i++) { - result[i] = findClassNode(sourceUnit, unit, options[i]); - } - return result; - } - } http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/SingleSignatureClosureHint.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/SingleSignatureClosureHint.java b/src/main/groovy/transform/stc/SingleSignatureClosureHint.java deleted file mode 100644 index 3db66ff..0000000 --- a/src/main/groovy/transform/stc/SingleSignatureClosureHint.java +++ /dev/null @@ -1,44 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -import java.util.Collections; -import java.util.List; - -/** - * A simplified version of a {@link groovy.transform.stc.ClosureSignatureHint} which is suitable - * for monomorphic closures, that is to say closures which only respond to a single signature. - * - * @author Cédric Champeau - * @since 2.3.0 - */ -public abstract class SingleSignatureClosureHint extends ClosureSignatureHint { - - public abstract ClassNode[] getParameterTypes(final MethodNode node, final String[] options, final SourceUnit sourceUnit, final CompilationUnit unit, final ASTNode usage); - - public List<ClassNode[]> getClosureSignatures(final MethodNode node, final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final String[] options, final ASTNode usage) { - return Collections.singletonList(getParameterTypes(node, options, sourceUnit, compilationUnit, usage)); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/transform/stc/ThirdParam.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/stc/ThirdParam.java b/src/main/groovy/transform/stc/ThirdParam.java deleted file mode 100644 index c493e36..0000000 --- a/src/main/groovy/transform/stc/ThirdParam.java +++ /dev/null @@ -1,94 +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.transform.stc; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.SourceUnit; - -/** - * <p>A hint used to instruct the type checker to pick the third parameter type. For example:</p> - * <code>public <T,U,V> def doWith(T first, U second, V third, @ClosureParams(ThirdParam.class) Closure c) { ... }</code> - * - * <p>This class has several inner classes that also helps picking generic argument types instead of the parameter type.</p> - * - * @author Cédric Champeau - * @since 2.3.0 - */ -public class ThirdParam extends PickAnyArgumentHint { - public ThirdParam() { - super(2,-1); - } - - /** - * <p>A hint used to instruct the type checker to pick the first generic type of the third parameter type. For example:</p> - * <code>void <T> doWithElements(String first, Integer second, List<T> third, @ClosureParams(SecondParam.FirstGenericType.class) Closure c) { ... } }</code> - * - * @author Cédric Champeau - * @since 2.3.0 - */ - public static class FirstGenericType extends PickAnyArgumentHint { - public FirstGenericType() { - super(2,0); - } - } - - - /** - * <p>A hint used to instruct the type checker to pick the second generic type of the third parameter type. For example:</p> - * <code>void <T,U> doWithElements(String first, Integer second, Tuple<T,U> third, @ClosureParams(SecondParam.SecondGenericType.class) Closure c) { ... }</code> - * - * @author Cédric Champeau - * @since 2.3.0 - */ - public static class SecondGenericType extends PickAnyArgumentHint { - public SecondGenericType() { - super(2,1); - } - } - - /** - * <p>A hint used to instruct the type checker to pick the second generic type of the third parameter type. For example:</p> - * <code>void <T,U,V> doWithElements(String first, Integer second, Triple<T,U,V> src, @ClosureParams(SecondParam.ThirdGenericType.class) Closure c) { ... }</code> - * - * @author Cédric Champeau - * @since 2.3.0 - */ - public static class ThirdGenericType extends PickAnyArgumentHint { - public ThirdGenericType() { - super(2,2); - } - } - - /** - * <p>A hint used to instruct the type checker to pick the type of the component of the third parameter type, which is therefore - * expected to be an array, like in this example:</p> - * <code>void <T> doWithArray(String first, int second, T[] third, @ClosureParams(FirstParam.Component.class) Closure c) { ... }</code> - */ - public static class Component extends ThirdParam { - @Override - public ClassNode[] getParameterTypes(final MethodNode node, final String[] options, final SourceUnit sourceUnit, final CompilationUnit unit, final ASTNode usage) { - final ClassNode[] parameterTypes = super.getParameterTypes(node, options, sourceUnit, unit, usage); - parameterTypes[0] = parameterTypes[0].getComponentType(); - return parameterTypes; - } - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/ui/GroovyMain.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/ui/GroovyMain.java b/src/main/groovy/ui/GroovyMain.java deleted file mode 100644 index a4d5986..0000000 --- a/src/main/groovy/ui/GroovyMain.java +++ /dev/null @@ -1,597 +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.ui; - -import groovy.lang.Binding; -import groovy.lang.GroovyCodeSource; -import groovy.lang.GroovyRuntimeException; -import groovy.lang.GroovyShell; -import groovy.lang.GroovySystem; -import groovy.lang.MissingMethodException; -import groovy.lang.Script; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.CompilerConfiguration; -import org.codehaus.groovy.control.customizers.ImportCustomizer; -import org.codehaus.groovy.runtime.InvokerHelper; -import org.codehaus.groovy.runtime.InvokerInvocationException; -import org.codehaus.groovy.runtime.ResourceGroovyMethods; -import org.codehaus.groovy.runtime.StackTraceUtils; -import org.codehaus.groovy.runtime.StringGroovyMethods; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.math.BigInteger; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.regex.Pattern; - -import static org.apache.commons.cli.Option.builder; - -/** - * A Command line to execute groovy. - */ -public class GroovyMain { - - // arguments to the script - private List args; - - // is this a file on disk - private boolean isScriptFile; - - // filename or content of script - private String script; - - // process args as input files - private boolean processFiles; - - // edit input files in place - private boolean editFiles; - - // automatically output the result of each script - private boolean autoOutput; - - // automatically split each line using the splitpattern - private boolean autoSplit; - - // The pattern used to split the current line - private String splitPattern = " "; - - // process sockets - private boolean processSockets; - - // port to listen on when processing sockets - private int port; - - // backup input files with extension - private String backupExtension; - - // do you want full stack traces in script exceptions? - private boolean debug = false; - - // Compiler configuration, used to set the encodings of the scripts/classes - private CompilerConfiguration conf = new CompilerConfiguration(System.getProperties()); - - /** - * Main CLI interface. - * - * @param args all command line args. - */ - public static void main(String args[]) { - processArgs(args, System.out); - } - - // package-level visibility for testing purposes (just usage/errors at this stage) - // TODO: should we have an 'err' printstream too for ParseException? - static void processArgs(String[] args, final PrintStream out) { - Options options = buildOptions(); - - try { - CommandLine cmd = parseCommandLine(options, args); - - if (cmd.hasOption('h')) { - printHelp(out, options); - } else if (cmd.hasOption('v')) { - String version = GroovySystem.getVersion(); - out.println("Groovy Version: " + version + " JVM: " + System.getProperty("java.version") + - " Vendor: " + System.getProperty("java.vm.vendor") + " OS: " + System.getProperty("os.name")); - } else { - // If we fail, then exit with an error so scripting frameworks can catch it - // TODO: pass printstream(s) down through process - if (!process(cmd)) { - System.exit(1); - } - } - } catch (ParseException pe) { - out.println("error: " + pe.getMessage()); - printHelp(out, options); - } catch (IOException ioe) { - out.println("error: " + ioe.getMessage()); - } - } - - private static void printHelp(PrintStream out, Options options) { - HelpFormatter formatter = new HelpFormatter(); - PrintWriter pw = new PrintWriter(out); - - formatter.printHelp( - pw, - 80, - "groovy [options] [filename] [args]", - "The Groovy command line processor.\nOptions:", - options, - 2, - 4, - null, // footer - false); - - pw.flush(); - } - - /** - * Parse the command line. - * - * @param options the options parser. - * @param args the command line args. - * @return parsed command line. - * @throws ParseException if there was a problem. - */ - private static CommandLine parseCommandLine(Options options, String[] args) throws ParseException { - CommandLineParser parser = new DefaultParser(); - return parser.parse(options, args, true); - } - - /** - * Build the options parser. - * - * @return an options parser. - */ - private static Options buildOptions() { - return new Options() - .addOption(builder("classpath").hasArg().argName("path").desc("Specify where to find the class files - must be first argument").build()) - .addOption(builder("cp").longOpt("classpath").hasArg().argName("path").desc("Aliases for '-classpath'").build()) - .addOption(builder("D").longOpt("define").desc("Define a system property").numberOfArgs(2).valueSeparator().argName("name=value").build()) - .addOption( - builder().longOpt("disableopt") - .desc("Disables one or all optimization elements; " + - "optlist can be a comma separated list with the elements: " + - "all (disables all optimizations), " + - "int (disable any int based optimizations)") - .hasArg().argName("optlist").build()) - .addOption(builder("h").hasArg(false).desc("Usage information").longOpt("help").build()) - .addOption(builder("d").hasArg(false).desc("Debug mode will print out full stack traces").longOpt("debug").build()) - .addOption(builder("v").hasArg(false).desc("Display the Groovy and JVM versions").longOpt("version").build()) - .addOption(builder("c").argName("charset").hasArg().desc("Specify the encoding of the files").longOpt("encoding").build()) - .addOption(builder("e").argName("script").hasArg().desc("Specify a command line script").build()) - .addOption(builder("i").argName("extension").optionalArg(true).desc("Modify files in place; create backup if extension is given (e.g. \'.bak\')").build()) - .addOption(builder("n").hasArg(false).desc("Process files line by line using implicit 'line' variable").build()) - .addOption(builder("p").hasArg(false).desc("Process files line by line and print result (see also -n)").build()) - .addOption(builder("pa").hasArg(false).desc("Generate metadata for reflection on method parameter names (jdk8+ only)").longOpt("parameters").build()) - .addOption(builder("l").argName("port").optionalArg(true).desc("Listen on a port and process inbound lines (default: 1960)").build()) - .addOption(builder("a").argName("splitPattern").optionalArg(true).desc("Split lines using splitPattern (default '\\s') using implicit 'split' variable").longOpt("autosplit").build()) - .addOption(builder().longOpt("indy").desc("Enables compilation using invokedynamic").build()) - .addOption(builder().longOpt("configscript").hasArg().desc("A script for tweaking the configuration options").build()) - .addOption(builder("b").longOpt("basescript").hasArg().argName("class").desc("Base class name for scripts (must derive from Script)").build()); - } - - /** - * Process the users request. - * - * @param line the parsed command line. - * @throws ParseException if invalid options are chosen - */ - private static boolean process(CommandLine line) throws ParseException, IOException { - List args = line.getArgList(); - - if (line.hasOption('D')) { - Properties optionProperties = line.getOptionProperties("D"); - Enumeration<String> propertyNames = (Enumeration<String>) optionProperties.propertyNames(); - while (propertyNames.hasMoreElements()) { - String nextName = propertyNames.nextElement(); - System.setProperty(nextName, optionProperties.getProperty(nextName)); - } - } - - GroovyMain main = new GroovyMain(); - - // add the ability to parse scripts with a specified encoding - main.conf.setSourceEncoding(line.getOptionValue('c',main.conf.getSourceEncoding())); - - main.isScriptFile = !line.hasOption('e'); - main.debug = line.hasOption('d'); - main.conf.setDebug(main.debug); - main.conf.setParameters(line.hasOption("pa")); - main.processFiles = line.hasOption('p') || line.hasOption('n'); - main.autoOutput = line.hasOption('p'); - main.editFiles = line.hasOption('i'); - if (main.editFiles) { - main.backupExtension = line.getOptionValue('i'); - } - main.autoSplit = line.hasOption('a'); - String sp = line.getOptionValue('a'); - if (sp != null) - main.splitPattern = sp; - - if (main.isScriptFile) { - if (args.isEmpty()) - throw new ParseException("neither -e or filename provided"); - - main.script = (String) args.remove(0); - if (main.script.endsWith(".java")) - throw new ParseException("error: cannot compile file with .java extension: " + main.script); - } else { - main.script = line.getOptionValue('e'); - } - - main.processSockets = line.hasOption('l'); - if (main.processSockets) { - String p = line.getOptionValue('l', "1960"); // default port to listen to - main.port = Integer.parseInt(p); - } - - // we use "," as default, because then split will create - // an empty array if no option is set - String disabled = line.getOptionValue("disableopt", ","); - String[] deopts = disabled.split(","); - for (String deopt_i : deopts) { - main.conf.getOptimizationOptions().put(deopt_i,false); - } - - if (line.hasOption("indy")) { - CompilerConfiguration.DEFAULT.getOptimizationOptions().put("indy", true); - main.conf.getOptimizationOptions().put("indy", true); - } - - if (line.hasOption("basescript")) { - main.conf.setScriptBaseClass(line.getOptionValue("basescript")); - } - - String configScripts = System.getProperty("groovy.starter.configscripts", null); - if (line.hasOption("configscript") || (configScripts != null && !configScripts.isEmpty())) { - List<String> scripts = new ArrayList<String>(); - if (line.hasOption("configscript")) { - scripts.add(line.getOptionValue("configscript")); - } - if (configScripts != null) { - scripts.addAll(StringGroovyMethods.tokenize((CharSequence) configScripts, ',')); - } - processConfigScripts(scripts, main.conf); - } - - main.args = args; - return main.run(); - } - - public static void processConfigScripts(List<String> scripts, CompilerConfiguration conf) throws IOException { - if (scripts.isEmpty()) return; - Binding binding = new Binding(); - binding.setVariable("configuration", conf); - CompilerConfiguration configuratorConfig = new CompilerConfiguration(); - ImportCustomizer customizer = new ImportCustomizer(); - customizer.addStaticStars("org.codehaus.groovy.control.customizers.builder.CompilerCustomizationBuilder"); - configuratorConfig.addCompilationCustomizers(customizer); - GroovyShell shell = new GroovyShell(binding, configuratorConfig); - for (String script : scripts) { - shell.evaluate(new File(script)); - } - } - - - /** - * Run the script. - */ - private boolean run() { - try { - if (processSockets) { - processSockets(); - } else if (processFiles) { - processFiles(); - } else { - processOnce(); - } - return true; - } catch (CompilationFailedException e) { - System.err.println(e); - return false; - } catch (Throwable e) { - if (e instanceof InvokerInvocationException) { - InvokerInvocationException iie = (InvokerInvocationException) e; - e = iie.getCause(); - } - System.err.println("Caught: " + e); - if (!debug) { - StackTraceUtils.deepSanitize(e); - } - e.printStackTrace(); - return false; - } - } - - /** - * Process Sockets. - */ - private void processSockets() throws CompilationFailedException, IOException, URISyntaxException { - GroovyShell groovy = new GroovyShell(conf); - new GroovySocketServer(groovy, getScriptSource(isScriptFile, script), autoOutput, port); - } - - /** - * Get the text of the Groovy script at the given location. - * If the location is a file path and it does not exist as given, - * then {@link GroovyMain#huntForTheScriptFile(String)} is called to try - * with some Groovy extensions appended. - * - * This method is not used to process scripts and is retained for backward - * compatibility. If you want to modify how GroovyMain processes scripts - * then use {@link GroovyMain#getScriptSource(boolean, String)}. - * - * @param uriOrFilename - * @return the text content at the location - * @throws IOException - * @deprecated - */ - @Deprecated - public String getText(String uriOrFilename) throws IOException { - if (URI_PATTERN.matcher(uriOrFilename).matches()) { - try { - return ResourceGroovyMethods.getText(new URL(uriOrFilename)); - } catch (Exception e) { - throw new GroovyRuntimeException("Unable to get script from URL: ", e); - } - } - return ResourceGroovyMethods.getText(huntForTheScriptFile(uriOrFilename)); - } - - /** - * Get a new GroovyCodeSource for a script which may be given as a location - * (isScript is true) or as text (isScript is false). - * - * @param isScriptFile indicates whether the script parameter is a location or content - * @param script the location or context of the script - * @return a new GroovyCodeSource for the given script - * @throws IOException - * @throws URISyntaxException - * @since 2.3.0 - */ - protected GroovyCodeSource getScriptSource(boolean isScriptFile, String script) throws IOException, URISyntaxException { - //check the script is currently valid before starting a server against the script - if (isScriptFile) { - // search for the file and if it exists don't try to use URIs ... - File scriptFile = huntForTheScriptFile(script); - if (!scriptFile.exists() && URI_PATTERN.matcher(script).matches()) { - return new GroovyCodeSource(new URI(script)); - } - return new GroovyCodeSource( scriptFile ); - } - return new GroovyCodeSource(script, "script_from_command_line", GroovyShell.DEFAULT_CODE_BASE); - } - - // RFC2396 - // scheme = alpha *( alpha | digit | "+" | "-" | "." ) - // match URIs but not Windows filenames, e.g.: http://cnn.com but not C:\xxx\file.ext - private static final Pattern URI_PATTERN = Pattern.compile("\\p{Alpha}[-+.\\p{Alnum}]*:[^\\\\]*"); - - /** - * Search for the script file, doesn't bother if it is named precisely. - * - * Tries in this order: - * - actual supplied name - * - name.groovy - * - name.gvy - * - name.gy - * - name.gsh - * - * @since 2.3.0 - */ - public static File searchForGroovyScriptFile(String input) { - String scriptFileName = input.trim(); - File scriptFile = new File(scriptFileName); - // TODO: Shouldn't these extensions be kept elsewhere? What about CompilerConfiguration? - // This method probably shouldn't be in GroovyMain either. - String[] standardExtensions = {".groovy",".gvy",".gy",".gsh"}; - int i = 0; - while (i < standardExtensions.length && !scriptFile.exists()) { - scriptFile = new File(scriptFileName + standardExtensions[i]); - i++; - } - // if we still haven't found the file, point back to the originally specified filename - if (!scriptFile.exists()) { - scriptFile = new File(scriptFileName); - } - return scriptFile; - } - - /** - * Hunt for the script file by calling searchForGroovyScriptFile(String). - * - * @see GroovyMain#searchForGroovyScriptFile(String) - */ - public File huntForTheScriptFile(String input) { - return GroovyMain.searchForGroovyScriptFile(input); - } - - // GROOVY-6771 - private static void setupContextClassLoader(GroovyShell shell) { - final Thread current = Thread.currentThread(); - class DoSetContext implements PrivilegedAction { - ClassLoader classLoader; - - public DoSetContext(ClassLoader loader) { - classLoader = loader; - } - - public Object run() { - current.setContextClassLoader(classLoader); - return null; - } - } - - AccessController.doPrivileged(new DoSetContext(shell.getClassLoader())); - } - - /** - * Process the input files. - */ - private void processFiles() throws CompilationFailedException, IOException, URISyntaxException { - GroovyShell groovy = new GroovyShell(conf); - setupContextClassLoader(groovy); - - Script s = groovy.parse(getScriptSource(isScriptFile, script)); - - if (args.isEmpty()) { - BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - PrintWriter writer = new PrintWriter(System.out); - - try { - processReader(s, reader, writer); - } finally { - reader.close(); - writer.close(); - } - - } else { - Iterator i = args.iterator(); - while (i.hasNext()) { - String filename = (String) i.next(); - //TODO: These are the arguments for -p and -i. Why are we searching using Groovy script extensions? - // Where is this documented? - File file = huntForTheScriptFile(filename); - processFile(s, file); - } - } - } - - /** - * Process a single input file. - * - * @param s the script to execute. - * @param file the input file. - */ - private void processFile(Script s, File file) throws IOException { - if (!file.exists()) - throw new FileNotFoundException(file.getName()); - - if (!editFiles) { - BufferedReader reader = new BufferedReader(new FileReader(file)); - try { - PrintWriter writer = new PrintWriter(System.out); - processReader(s, reader, writer); - writer.flush(); - } finally { - reader.close(); - } - } else { - File backup; - if (backupExtension == null) { - backup = File.createTempFile("groovy_", ".tmp"); - backup.deleteOnExit(); - } else { - backup = new File(file.getPath() + backupExtension); - } - backup.delete(); - if (!file.renameTo(backup)) - throw new IOException("unable to rename " + file + " to " + backup); - - BufferedReader reader = new BufferedReader(new FileReader(backup)); - try { - PrintWriter writer = new PrintWriter(new FileWriter(file)); - try { - processReader(s, reader, writer); - } finally { - writer.close(); - } - } finally { - reader.close(); - } - } - } - - /** - * Process a script against a single input file. - * - * @param s script to execute. - * @param reader input file. - * @param pw output sink. - */ - private void processReader(Script s, BufferedReader reader, PrintWriter pw) throws IOException { - String line; - String lineCountName = "count"; - s.setProperty(lineCountName, BigInteger.ZERO); - String autoSplitName = "split"; - s.setProperty("out", pw); - - try { - InvokerHelper.invokeMethod(s, "begin", null); - } catch (MissingMethodException mme) { - // ignore the missing method exception - // as it means no begin() method is present - } - - while ((line = reader.readLine()) != null) { - s.setProperty("line", line); - s.setProperty(lineCountName, ((BigInteger)s.getProperty(lineCountName)).add(BigInteger.ONE)); - - if(autoSplit) { - s.setProperty(autoSplitName, line.split(splitPattern)); - } - - Object o = s.run(); - - if (autoOutput && o != null) { - pw.println(o); - } - } - - try { - InvokerHelper.invokeMethod(s, "end", null); - } catch (MissingMethodException mme) { - // ignore the missing method exception - // as it means no end() method is present - } - } - - /** - * Process the standard, single script with args. - */ - private void processOnce() throws CompilationFailedException, IOException, URISyntaxException { - GroovyShell groovy = new GroovyShell(conf); - setupContextClassLoader(groovy); - groovy.run(getScriptSource(isScriptFile, script), args); - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/ui/GroovySocketServer.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/ui/GroovySocketServer.java b/src/main/groovy/ui/GroovySocketServer.java deleted file mode 100644 index b0d27c5..0000000 --- a/src/main/groovy/ui/GroovySocketServer.java +++ /dev/null @@ -1,226 +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.ui; - -import groovy.lang.GroovyCodeSource; -import groovy.lang.GroovyRuntimeException; -import groovy.lang.GroovyShell; -import groovy.lang.Script; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.regex.Pattern; - -/** - * Simple server that executes supplied script against a socket. - * <p> - * Typically this is used from the groovy command line agent but it can be - * invoked programmatically. To run this program from the command line please - * refer to the command line documentation at - * <a href="http://docs.groovy-lang.org/docs/latest/html/documentation/#_running_groovy_from_the_commandline"> - * Running Groovy from the commandline</a>. - * <p> - * Here is an example of how to use this class to open a listening socket on the server, - * listen for incoming data, and then echo the data back to the client in reverse order: - * <pre> - * new GroovySocketServer( - * new GroovyShell(), // evaluator - * false, // is not a file - * "println line.reverse()", // script to evaluate - * true, // return result to client - * 1960) //port - * </pre> - * There are several variables in the script binding: - * <ul> - * <li>line - The data from the socket</li> - * <li>out - The output PrintWriter, should you need it for some reason.</li> - * <li>socket - The socket, should you need it for some reason.</li> - * </ul> - * - * @author Jeremy Rayner - */ -public class GroovySocketServer implements Runnable { - private URL url; - private final GroovyShell groovy; - private final GroovyCodeSource source; - private final boolean autoOutput; - private static int counter; - - /** - * This creates and starts the socket server on a new Thread. There is no need to call run or spawn - * a new thread yourself. - * @param groovy - * The GroovyShell object that evaluates the incoming text. If you need additional classes in the - * classloader then configure that through this object. - * @param isScriptFile - * Whether the incoming socket data String will be a script or a file path. - * @param scriptFilenameOrText - * This will be a groovy script or a file location depending on the argument isScriptFile. - * @param autoOutput - * whether output should be automatically echoed back to the client - * @param port - * the port to listen on - * - */ - public GroovySocketServer(GroovyShell groovy, boolean isScriptFile, String scriptFilenameOrText, boolean autoOutput, int port) { - this(groovy, getCodeSource(isScriptFile, scriptFilenameOrText), autoOutput, port); - } - - private static GroovyCodeSource getCodeSource(boolean scriptFile, String scriptFilenameOrText) { - if (scriptFile) { - try { - if (URI_PATTERN.matcher(scriptFilenameOrText).matches()) { - return new GroovyCodeSource(new URI(scriptFilenameOrText)); - } else { - return new GroovyCodeSource(GroovyMain.searchForGroovyScriptFile(scriptFilenameOrText)); - } - } catch (IOException e) { - throw new GroovyRuntimeException("Unable to get script from: " + scriptFilenameOrText, e); - } catch (URISyntaxException e) { - throw new GroovyRuntimeException("Unable to get script from URI: " + scriptFilenameOrText, e); - } - } else { - // We could jump through some hoops to have GroovyShell make our script name, but that seems unwarranted. - // If we *did* jump through that hoop then we should probably change the run loop to not recompile - // the script on every iteration since the script text can't change (the reason for the recompilation). - return new GroovyCodeSource(scriptFilenameOrText, generateScriptName(), GroovyShell.DEFAULT_CODE_BASE); - } - } - - private static synchronized String generateScriptName() { - return "ServerSocketScript" + (++counter) + ".groovy"; - } - - - // RFC2396 - // scheme = alpha *( alpha | digit | "+" | "-" | "." ) - private static final Pattern URI_PATTERN = Pattern.compile("\\p{Alpha}[-+.\\p{Alnum}]*:.*"); - - /** - * This creates and starts the socket server on a new Thread. There is no need to call run or spawn - * a new thread yourself. - * @param groovy - * The GroovyShell object that evaluates the incoming text. If you need additional classes in the - * classloader then configure that through this object. - * @param source - * GroovyCodeSource for the Groovy script - * @param autoOutput - * whether output should be automatically echoed back to the client - * @param port - * the port to listen on - * @since 2.3.0 - */ - public GroovySocketServer(GroovyShell groovy, GroovyCodeSource source, boolean autoOutput, int port) { - this.groovy = groovy; - this.source = source; - this.autoOutput = autoOutput; - try { - url = new URL("http", InetAddress.getLocalHost().getHostAddress(), port, "/"); - System.out.println("groovy is listening on port " + port); - } catch (IOException e) { - e.printStackTrace(); - } - new Thread(this).start(); - } - - /** - * Runs this server. There is typically no need to call this method, as the object's constructor - * creates a new thread and runs this object automatically. - */ - public void run() { - try { - ServerSocket serverSocket = new ServerSocket(url.getPort()); - while (true) { - // Create one script per socket connection. - // This is purposefully not caching the Script - // so that the script source file can be changed on the fly, - // as each connection is made to the server. - //FIXME: Groovy has other mechanisms specifically for watching to see if source code changes. - // We should probably be using that here. - // See also the comment about the fact we recompile a script that can't change. - Script script = groovy.parse(source); - new GroovyClientConnection(script, autoOutput, serverSocket.accept()); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - static class GroovyClientConnection implements Runnable { - private Script script; - private Socket socket; - private BufferedReader reader; - private PrintWriter writer; - private boolean autoOutputFlag; - - GroovyClientConnection(Script script, boolean autoOutput,Socket socket) throws IOException { - this.script = script; - this.autoOutputFlag = autoOutput; - this.socket = socket; - reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); - writer = new PrintWriter(socket.getOutputStream()); - new Thread(this, "Groovy client connection - " + socket.getInetAddress().getHostAddress()).start(); - } - public void run() { - try { - String line = null; - script.setProperty("out", writer); - script.setProperty("socket", socket); - script.setProperty("init", Boolean.TRUE); - while ((line = reader.readLine()) != null) { - // System.out.println(line); - script.setProperty("line", line); - Object o = script.run(); - script.setProperty("init", Boolean.FALSE); - if (o != null) { - if ("success".equals(o)) { - break; // to close sockets gracefully etc... - } else { - if (autoOutputFlag) { - writer.println(o); - } - } - } - writer.flush(); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - writer.flush(); - writer.close(); - } finally { - try { - socket.close(); - } catch (IOException e3) { - e3.printStackTrace(); - } - } - } - } - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/AbstractFactory.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/util/AbstractFactory.java b/src/main/groovy/util/AbstractFactory.java deleted file mode 100644 index d3e628c..0000000 --- a/src/main/groovy/util/AbstractFactory.java +++ /dev/null @@ -1,63 +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.util; - -import groovy.lang.Closure; - -import java.util.Map; - -/** - * @author <a href="mailto:[email protected]">Andres Almiray</a> - * @author Danno Ferrin - */ -public abstract class AbstractFactory implements Factory { - public boolean isLeaf() { - return false; - } - - public boolean isHandlesNodeChildren() { - return false; - } - - public void onFactoryRegistration(FactoryBuilderSupport builder, String registeredName, String group) { - // do nothing - } - - public boolean onHandleNodeAttributes( FactoryBuilderSupport builder, Object node, - Map attributes ) { - return true; - } - - public boolean onNodeChildren( FactoryBuilderSupport builder, Object node, Closure childContent) { - return true; - } - - public void onNodeCompleted( FactoryBuilderSupport builder, Object parent, Object node ) { - // do nothing - } - - public void setParent( FactoryBuilderSupport builder, Object parent, Object child ) { - // do nothing - } - - public void setChild( FactoryBuilderSupport builder, Object parent, Object child ) { - // do nothing - } - -} http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/BufferedIterator.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/util/BufferedIterator.java b/src/main/groovy/util/BufferedIterator.java deleted file mode 100644 index 6fa50a9..0000000 --- a/src/main/groovy/util/BufferedIterator.java +++ /dev/null @@ -1,31 +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.util; - -import java.util.Iterator; - -/** - * An iterator that allows examining the next element without consuming it. - * - * @author Andrew Taylor - * @since 2.5.0 - */ -public interface BufferedIterator<T> extends Iterator<T> { - T head(); -}
