You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by cc...@apache.org on 2017/12/14 21:56:58 UTC

[33/57] [abbrv] [partial] groovy git commit: Move Java source set into `src/main/java`

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/EmptyExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/EmptyExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/EmptyExpression.java
new file mode 100644
index 0000000..401f906
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/EmptyExpression.java
@@ -0,0 +1,137 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.AnnotationNode;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.NodeMetaDataHandler;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class is a place holder for an empty expression. 
+ * Empty expression are used in closures lists like (;). During
+ * class Generation this expression should be either ignored or
+ * replace with a null value.
+ *   
+ * @author Jochen Theodorou
+ * @see org.codehaus.groovy.ast.stmt.EmptyStatement
+ */
+
+public class EmptyExpression extends Expression {
+    public static final EmptyExpression INSTANCE = new EmptyExpression();
+
+    private EmptyExpression() {}
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        return this;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        return;
+    }
+
+
+    @Override
+    public void setType(ClassNode t) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void addAnnotation(AnnotationNode value) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void addAnnotations(List<AnnotationNode> annotations) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setSynthetic(boolean synthetic) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setDeclaringClass(ClassNode declaringClass) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setHasNoRealSourcePosition(boolean value) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setLineNumber(int lineNumber) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setColumnNumber(int columnNumber) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setLastLineNumber(int lastLineNumber) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setLastColumnNumber(int lastColumnNumber) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setSourcePosition(ASTNode node) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void copyNodeMetaData(NodeMetaDataHandler other) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setNodeMetaData(Object key, Object value) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public Object putNodeMetaData(Object key, Object value) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void removeNodeMetaData(Object key) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setMetaDataMap(Map<?, ?> metaDataMap) {
+        throw createUnsupportedOperationException();
+    }
+
+    private UnsupportedOperationException createUnsupportedOperationException() {
+        return new UnsupportedOperationException("EmptyExpression.INSTANCE is immutable");
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/Expression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/Expression.java b/src/main/java/org/codehaus/groovy/ast/expr/Expression.java
new file mode 100644
index 0000000..f9991d2
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/Expression.java
@@ -0,0 +1,81 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.ast.AnnotatedNode;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a base class for expressions which evaluate as an object
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public abstract class Expression extends AnnotatedNode {
+    public static final Expression[] EMPTY_ARRAY = new Expression[0];
+    private ClassNode type=ClassHelper.DYNAMIC_TYPE;
+    
+    /**
+     * Return a copy of the expression calling the transformer on any nested expressions 
+     * @param transformer
+     */
+    public abstract Expression transformExpression(ExpressionTransformer transformer);
+
+    /**
+     * Transforms the list of expressions
+     * @return a new list of transformed expressions
+     */
+    protected List<Expression> transformExpressions(List<? extends Expression> expressions, ExpressionTransformer transformer) {
+        List<Expression> list = new ArrayList<Expression>(expressions.size());
+        for (Expression expr : expressions ) {
+            list.add(transformer.transform(expr));
+        }
+        return list;
+    }
+
+    /**
+     * Transforms the list of expressions, and checks that all transformed expressions have the given type.
+     *
+     * @return a new list of transformed expressions
+     */
+    protected <T extends Expression> List<T> transformExpressions(List<? extends Expression> expressions,
+            ExpressionTransformer transformer, Class<T> transformedType) {
+        List<T> list = new ArrayList<T>(expressions.size());
+        for (Expression expr : expressions) {
+            Expression transformed = transformer.transform(expr);
+            if (!transformedType.isInstance(transformed))
+                throw new GroovyBugError(String.format("Transformed expression should have type %s but has type %s",
+                    transformedType, transformed.getClass()));
+            list.add(transformedType.cast(transformed));
+        }
+        return list;
+    }
+    
+    public ClassNode getType() {
+        return type;
+    }
+    
+    public void setType(ClassNode t) {
+        type=t;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/ExpressionTransformer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/ExpressionTransformer.java b/src/main/java/org/codehaus/groovy/ast/expr/ExpressionTransformer.java
new file mode 100644
index 0000000..459ed43
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/ExpressionTransformer.java
@@ -0,0 +1,33 @@
+/*
+ *  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.ast.expr;
+
+
+/**
+ * Provides a way to transform expressions
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public interface ExpressionTransformer {
+    
+    /** 
+     * Transforms the given expression into another expression
+     */
+    Expression transform(Expression expression);
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/FieldExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/FieldExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/FieldExpression.java
new file mode 100644
index 0000000..41b5acf
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/FieldExpression.java
@@ -0,0 +1,83 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * Represents a field access such as the expression "this.foo".
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class FieldExpression extends Expression {
+
+    private final FieldNode field;
+    private boolean useRef;
+    
+    public FieldExpression(FieldNode field) {
+        this.field = field;
+    }
+    
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitFieldExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        return this;
+    }
+    
+    public String getFieldName() {
+        return field.getName();
+    }
+
+    public FieldNode getField() {
+        return field;
+    }
+
+    public String getText() {
+        return "this." + field.getName();
+    }
+
+    public boolean isDynamicTyped() {
+        return field.isDynamicTyped();
+    }
+
+    public void setType(ClassNode type) {
+        super.setType(type);
+        field.setType(type);
+    }
+    
+    public ClassNode getType() {
+        return field.getType();
+    }
+    
+    public void setUseReferenceDirectly(boolean useRef) {
+        this.useRef = useRef;        
+    }
+    
+    public boolean isUseReferenceDirectly() {
+        return useRef;
+    }
+    
+    public String toString() {
+        return "field("+getType()+" "+getFieldName()+")";
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/GStringExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/GStringExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/GStringExpression.java
new file mode 100644
index 0000000..7ccf355
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/GStringExpression.java
@@ -0,0 +1,116 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a String expression which contains embedded values inside
+ * it such as "hello there ${user} how are you" which is expanded lazily
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class GStringExpression extends Expression {
+
+    private final String verbatimText;
+    private final List<ConstantExpression> strings;
+    private final List<Expression> values;
+    
+    public GStringExpression(String verbatimText) {
+        this.verbatimText = verbatimText;
+        super.setType(ClassHelper.GSTRING_TYPE);
+        this.strings = new ArrayList<ConstantExpression>();
+        this.values = new ArrayList<Expression>();
+    }
+
+    public GStringExpression(String verbatimText, List<ConstantExpression> strings, List<Expression> values) {
+        this.verbatimText = verbatimText;
+        this.strings = strings;
+        this.values = values;
+        super.setType(ClassHelper.GSTRING_TYPE);
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitGStringExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new GStringExpression(
+                verbatimText,
+                transformExpressions(strings, transformer, ConstantExpression.class),
+                transformExpressions(values, transformer));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;        
+    }
+
+    public String toString() {
+        return super.toString() + "[strings: " + strings + " values: " + values + "]";
+    }
+
+    public String getText() {
+        return verbatimText;
+    }
+
+    public List<ConstantExpression> getStrings() {
+        return strings;
+    }
+
+    public List<Expression> getValues() {
+        return values;
+    }
+
+    public void addString(ConstantExpression text) {
+        if (text == null) {
+            throw new NullPointerException("Cannot add a null text expression");
+        }
+        strings.add(text);
+    }
+
+    public void addValue(Expression value) {
+        // If the first thing is an value, then we need a dummy empty string in front of it so that when we
+        // toString it they come out in the correct order.
+        if (strings.isEmpty())
+            strings.add(ConstantExpression.EMPTY_STRING);
+        values.add(value);
+    }
+
+    public Expression getValue(int idx) {
+        return values.get(idx);
+    }
+
+    public boolean isConstantString() {
+        return values.isEmpty();
+    }
+
+    public Expression asConstantString() {
+        StringBuilder buffer = new StringBuilder();
+        for (ConstantExpression expression : strings) {
+            Object value = expression.getValue();
+            if (value != null) {
+                buffer.append(value);
+            }
+        }
+        return new ConstantExpression(buffer.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/LambdaExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/LambdaExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/LambdaExpression.java
new file mode 100644
index 0000000..f4f1001
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/LambdaExpression.java
@@ -0,0 +1,47 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.AstToTextHelper;
+import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.stmt.Statement;
+
+/**
+ * Represents a lambda expression such as e -> e * 2
+ * or (x, y) -> x + y or (x, y) -> { x + y } or (int x, int y) -> { x + y }
+ *
+ * @author  <a href="mailto:realbluesun@hotmail.com">Daniel.Sun</a>
+ * Created on    2016/10/18
+ */
+public class LambdaExpression extends ClosureExpression {
+    public LambdaExpression(Parameter[] parameters, Statement code) {
+        super(parameters, code);
+    }
+
+    @Override
+    public String getText() {
+        String paramText = AstToTextHelper.getParametersText(this.getParameters());
+        if (paramText.length() > 0) {
+            return "(" + paramText + ") -> { ... }";
+        } else {
+            return "() -> { ... }";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/ListExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/ListExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/ListExpression.java
new file mode 100644
index 0000000..94ab0d2
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/ListExpression.java
@@ -0,0 +1,97 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a list expression [1, 2, 3] which creates a mutable List
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class ListExpression extends Expression {
+    private final List<Expression> expressions;
+    private boolean wrapped = false;
+
+    public ListExpression() {
+        this(new ArrayList<Expression>());
+    }
+
+    public ListExpression(List<Expression> expressions) {
+        this.expressions = expressions;
+        //TODO: get the type's of the expressions to specify the
+        // list type to List<X> if possible.
+        setType(ClassHelper.LIST_TYPE);
+    }
+
+    public void addExpression(Expression expression) {
+        expressions.add(expression);
+    }
+
+    public List<Expression> getExpressions() {
+        return expressions;
+    }
+
+    public void setWrapped(boolean value) {
+        wrapped = value;
+    }
+
+    public boolean isWrapped() {
+        return wrapped;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitListExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new ListExpression(transformExpressions(getExpressions(), transformer));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public Expression getExpression(int i) {
+        return expressions.get(i);
+    }
+
+    public String getText() {
+        StringBuilder buffer = new StringBuilder("[");
+        boolean first = true;
+        for (Expression expression : expressions) {
+            if (first) {
+                first = false;
+            } else {
+                buffer.append(", ");
+            }
+
+            buffer.append(expression.getText());
+        }
+        buffer.append("]");
+        return buffer.toString();
+    }
+
+    public String toString() {
+        return super.toString() + expressions;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/MapEntryExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/MapEntryExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/MapEntryExpression.java
new file mode 100644
index 0000000..3426fe0
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/MapEntryExpression.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 org.codehaus.groovy.ast.expr;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+
+/**
+ * Represents an entry inside a map expression such as 1 : 2.
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class MapEntryExpression extends Expression {
+    private Expression keyExpression;
+    private Expression valueExpression;
+
+    public MapEntryExpression(Expression keyExpression, Expression valueExpression) {
+        this.keyExpression = keyExpression;
+        this.valueExpression = valueExpression;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitMapEntryExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new MapEntryExpression(transformer.transform(keyExpression), transformer.transform(valueExpression));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;        
+    }
+
+    public String toString() {
+        return super.toString() + "(key: " + keyExpression + ", value: " + valueExpression + ")";
+    }
+
+    public Expression getKeyExpression() {
+        return keyExpression;
+    }
+
+    public Expression getValueExpression() {
+        return valueExpression;
+    }
+
+    public void setKeyExpression(Expression keyExpression) {
+        this.keyExpression = keyExpression;
+    }
+
+    public void setValueExpression(Expression valueExpression) {
+        this.valueExpression = valueExpression;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/MapExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/MapExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/MapExpression.java
new file mode 100644
index 0000000..0effc80
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/MapExpression.java
@@ -0,0 +1,100 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a map expression [1 : 2, "a" : "b", x : y] which creates a mutable Map
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class MapExpression extends Expression {
+    private final List<MapEntryExpression> mapEntryExpressions;
+
+    public MapExpression() {
+        this(new ArrayList<MapEntryExpression>());
+    }
+
+    public MapExpression(List<MapEntryExpression> mapEntryExpressions) {
+        this.mapEntryExpressions = mapEntryExpressions;
+        //TODO: get the type's of the expressions to specify the
+        // map type to Map<X> if possible.
+        setType(ClassHelper.MAP_TYPE);
+    }
+
+    public void addMapEntryExpression(MapEntryExpression expression) {
+        mapEntryExpressions.add(expression);
+    }
+
+    public List<MapEntryExpression> getMapEntryExpressions() {
+        return mapEntryExpressions;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitMapExpression(this);
+    }
+
+    public boolean isDynamic() {
+        return false;
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new MapExpression(transformExpressions(getMapEntryExpressions(), transformer, MapEntryExpression.class));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public String toString() {
+        return super.toString() + mapEntryExpressions;
+    }
+
+    public String getText() {
+        StringBuilder sb = new StringBuilder(32);
+        sb.append("[");
+        int size = mapEntryExpressions.size();
+        MapEntryExpression mapEntryExpression = null;
+        if (size > 0) {
+            mapEntryExpression = mapEntryExpressions.get(0);
+            sb.append(mapEntryExpression.getKeyExpression().getText()).append(":").append(mapEntryExpression.getValueExpression().getText());
+            for (int i = 1; i < size; i++) {
+                mapEntryExpression = mapEntryExpressions.get(i);
+                sb.append(", ").append(mapEntryExpression.getKeyExpression().getText()).append(":").append(mapEntryExpression.getValueExpression().getText());
+                if (sb.length() > 120 && i < size - 1) {
+                    sb.append(", ... ");
+                    break;
+                }
+            }
+        } else {
+            sb.append(":");
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public void addMapEntryExpression(Expression keyExpression, Expression valueExpression) {
+        addMapEntryExpression(new MapEntryExpression(keyExpression, valueExpression));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/MethodCall.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/MethodCall.java b/src/main/java/org/codehaus/groovy/ast/expr/MethodCall.java
new file mode 100644
index 0000000..e2e889d
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/MethodCall.java
@@ -0,0 +1,34 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ASTNode;
+
+/**
+ * Interface defining common methods for method calls.
+ *
+ * @author Cedric Champeau
+ * @since 2.1.0
+ */
+public interface MethodCall {
+    ASTNode getReceiver();
+    String getMethodAsString();
+    Expression getArguments();
+    String getText();
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java
new file mode 100644
index 0000000..089d930
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java
@@ -0,0 +1,214 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.GenericsType;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.MethodNode;
+
+/**
+ * A method call on an object or class
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class MethodCallExpression extends Expression implements MethodCall {
+
+    private Expression objectExpression;
+    private Expression method;
+    private Expression arguments;
+    private boolean spreadSafe = false;
+    private boolean safe = false;
+    private boolean implicitThis;
+
+    // type spec for generics
+    private GenericsType[] genericsTypes = null;
+    private boolean usesGenerics = false;
+
+    private MethodNode target;
+
+    public static final Expression NO_ARGUMENTS = new TupleExpression();
+
+    public MethodCallExpression(Expression objectExpression, String method, Expression arguments) {
+        this(objectExpression,new ConstantExpression(method),arguments);
+    }
+
+    public MethodCallExpression(Expression objectExpression, Expression method, Expression arguments) {
+        this.objectExpression = objectExpression;
+        this.method = method;
+        if (!(arguments instanceof TupleExpression)){
+            this.arguments = new TupleExpression(arguments);
+        } else {
+            this.arguments = arguments;
+        }
+        //TODO: set correct type here
+        // if setting type and a methodcall is the last expression in a method,
+        // then the method will return null if the method itself is not void too!
+        // (in bytecode after call: aconst_null, areturn)
+        this.setType(ClassHelper.DYNAMIC_TYPE);
+        this.setImplicitThis(true);
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitMethodCallExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        MethodCallExpression answer =
+            new MethodCallExpression(transformer.transform(objectExpression), transformer.transform(method), transformer.transform(arguments));
+        answer.setSafe(safe);
+        answer.setSpreadSafe(spreadSafe);
+        answer.setImplicitThis(implicitThis);
+        answer.setGenericsTypes(genericsTypes);
+        answer.setSourcePosition(this);
+        answer.setMethodTarget(target);
+        answer.copyNodeMetaData(this);
+        return answer;
+    }
+
+    public Expression getArguments() {
+        return arguments;
+    }
+
+    public void setArguments(Expression arguments) {
+        if (!(arguments instanceof TupleExpression)){
+            this.arguments = new TupleExpression(arguments);
+        } else {
+            this.arguments = arguments;
+        }
+    }
+
+    public Expression getMethod() {
+        return method;
+    }
+
+    public void setMethod(Expression method) {
+      this.method = method;
+    }
+
+    public ASTNode getReceiver() {
+        return getObjectExpression();
+    }
+
+    /**
+     * This method returns the method name as String if it is no dynamic
+     * calculated method name, but a constant.
+     */
+    public String getMethodAsString() {
+        if (! (method instanceof ConstantExpression)) return null;
+        ConstantExpression constant = (ConstantExpression) method;
+        return constant.getText();
+    }
+
+    public void setObjectExpression(Expression objectExpression) {
+      this.objectExpression = objectExpression;
+    }
+
+    public Expression getObjectExpression() {
+        return objectExpression;
+    }
+
+    public String getText() {
+        String object = objectExpression.getText();
+        String meth = method.getText();
+        String args = arguments.getText();
+        String spread = spreadSafe ? "*" : "";
+        String dereference = safe ? "?" : "";
+        return object + spread + dereference + "." + meth + args;
+    }
+
+    /**
+     * @return is this a safe method call, i.e. if true then if the source object is null
+     * then this method call will return null rather than throwing a null pointer exception
+     */
+    public boolean isSafe() {
+        return safe;
+    }
+
+    public void setSafe(boolean safe) {
+        this.safe = safe;
+    }
+
+    public boolean isSpreadSafe() {
+        return spreadSafe;
+    }
+
+    public void setSpreadSafe(boolean value) {
+        spreadSafe = value;
+    }
+
+    /**
+     * @return true if no object expression was specified otherwise if
+     * some expression was specified for the object on which to evaluate
+     * the method then return false
+     */
+    public boolean isImplicitThis() {
+        return implicitThis;
+    }
+
+    public void setImplicitThis(boolean implicitThis) {
+        this.implicitThis = implicitThis;
+    }
+
+    public String toString() {
+        return super.toString()
+            + "[object: "
+            + objectExpression
+            + " method: "
+            + method
+            + " arguments: "
+            + arguments
+            + "]";
+    }
+
+    public GenericsType[] getGenericsTypes() {
+        return genericsTypes;
+    }
+
+    public void setGenericsTypes(GenericsType[] genericsTypes) {
+        usesGenerics = usesGenerics || genericsTypes != null;
+        this.genericsTypes = genericsTypes;
+    }
+
+    public boolean isUsingGenerics() {
+        return usesGenerics;
+    }
+
+    /**
+     * Sets a method call target for a direct method call.
+     * WARNING: A method call made this way will run outside of the MOP!
+     * @param mn the target as MethodNode, mn==null means no target
+     */
+    public void setMethodTarget(MethodNode mn) {
+        this.target = mn;
+        if (mn!=null) {
+            setType(target.getReturnType());
+        } else {
+            setType(ClassHelper.OBJECT_TYPE);
+        }
+    }
+
+    /**
+     * @return the target as method node if set
+     */
+    public MethodNode getMethodTarget() {
+        return target;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/MethodPointerExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/MethodPointerExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/MethodPointerExpression.java
new file mode 100644
index 0000000..f4d2422
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/MethodPointerExpression.java
@@ -0,0 +1,91 @@
+/*
+ *  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.ast.expr;
+
+import groovy.lang.Closure;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * Represents a method pointer on an object such as
+ * foo.&bar which means find the method pointer on foo for the method called "bar"
+ * which is equivalent to
+ * <code>
+ * foo.metaClass.getMethodPointer(foo, "bar")
+ * </code>
+ */
+public class MethodPointerExpression extends Expression {
+
+    private final Expression expression;
+    private final Expression methodName;
+
+    public MethodPointerExpression(Expression expression, Expression methodName) {
+        this.expression = expression;
+        this.methodName = methodName;
+    }
+
+    public Expression getExpression() {
+        if (expression == null)
+            return VariableExpression.THIS_EXPRESSION;
+        else
+            return expression;
+    }
+
+    public Expression getMethodName() {
+        return methodName;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitMethodPointerExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret;
+        Expression mname = transformer.transform(methodName);
+        if (expression == null) {
+            ret = new MethodPointerExpression(VariableExpression.THIS_EXPRESSION, mname);
+        } else {
+            ret = new MethodPointerExpression(transformer.transform(expression), mname);
+        }
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public String getText() {
+        if (expression == null) {
+            return "&" + methodName;
+        } else {
+            return expression.getText() + ".&" + methodName.getText();
+        }
+    }
+
+    public ClassNode getType() {
+        return ClassHelper.CLOSURE_TYPE.getPlainNodeReference();
+    }
+
+    public boolean isDynamic() {
+        return false;
+    }
+
+    public Class getTypeClass() {
+        return Closure.class;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/MethodReferenceExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/MethodReferenceExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/MethodReferenceExpression.java
new file mode 100644
index 0000000..0a8ebc8
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/MethodReferenceExpression.java
@@ -0,0 +1,45 @@
+/*
+ *  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.ast.expr;
+
+/**
+ * Represents a method reference or a constructor reference,
+ * e.g. System.out::println OR Objects::requireNonNull OR Integer::new OR int[]::new
+ *
+ * @author  <a href="mailto:realbluesun@hotmail.com">Daniel.Sun</a>
+ * Created on    2016/10/19
+ */
+public class MethodReferenceExpression extends MethodPointerExpression {
+    public MethodReferenceExpression(Expression expression, Expression methodName) {
+        super(expression, methodName);
+    }
+
+    @Override
+    public String getText() {
+        Expression expression = this.getExpression();
+        Expression methodName = this.getMethodName();
+
+        if (expression == null) {
+            return "::" + methodName;
+        } else {
+            return expression.getText() + "::" + methodName.getText();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/NamedArgumentListExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/NamedArgumentListExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/NamedArgumentListExpression.java
new file mode 100644
index 0000000..b53b89b
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/NamedArgumentListExpression.java
@@ -0,0 +1,45 @@
+/*
+ *  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.ast.expr;
+
+import java.util.List;
+
+/**
+ * Represents one or more arguments being passed into a method by name
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class NamedArgumentListExpression extends MapExpression {
+
+    public NamedArgumentListExpression() {
+    }
+    
+    public NamedArgumentListExpression(List<MapEntryExpression> mapEntryExpressions) {
+        super(mapEntryExpressions);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new NamedArgumentListExpression(
+            transformExpressions(getMapEntryExpressions(), transformer, MapEntryExpression.class)); 
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;        
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/NotExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/NotExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/NotExpression.java
new file mode 100644
index 0000000..ec227ee
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/NotExpression.java
@@ -0,0 +1,46 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * @author sam
+ */
+public class NotExpression extends BooleanExpression {
+
+    public NotExpression(Expression expression) {
+        super(expression);
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitNotExpression(this);
+    }
+
+    public boolean isDynamic() {
+        return false;
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new NotExpression(transformer.transform(getExpression()));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/PostfixExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/PostfixExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/PostfixExpression.java
new file mode 100644
index 0000000..16d12dc
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/PostfixExpression.java
@@ -0,0 +1,75 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.syntax.Token;
+
+/**
+ * Represents a postfix expression like foo++ or bar++
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class PostfixExpression extends Expression {
+
+    private final Token operation;
+    private Expression expression;
+
+    public PostfixExpression(Expression expression, Token operation) {
+        this.operation = operation;
+        this.expression = expression;
+    }
+
+    public String toString() {
+        return super.toString() + "[" + expression + operation + "]";
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitPostfixExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new PostfixExpression(transformer.transform(expression), operation); 
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public void setExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    public Token getOperation() {
+        return operation;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public String getText() {
+        return "(" + expression.getText() + operation.getText() + ")";
+    }
+
+    public ClassNode getType() {
+        return expression.getType();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/PrefixExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/PrefixExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/PrefixExpression.java
new file mode 100644
index 0000000..8d8f7b2
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/PrefixExpression.java
@@ -0,0 +1,75 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.syntax.Token;
+
+/**
+ * Represents a prefix expression like ++foo or --bar
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class PrefixExpression extends Expression {
+
+    private final Token operation;
+    private Expression expression;
+
+    public PrefixExpression(Token operation, Expression expression) {
+        this.operation = operation;
+        this.expression = expression;
+    }
+
+    public String toString() {
+        return super.toString() + "[" + operation + expression + "]";
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitPrefixExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new PrefixExpression(operation, transformer.transform(expression)); 
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public void setExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    public Token getOperation() {
+        return operation;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public String getText() {
+        return "(" + operation.getText() + expression.getText() + ")";
+    }
+
+    public ClassNode getType() {
+        return expression.getType();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/PropertyExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/PropertyExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/PropertyExpression.java
new file mode 100644
index 0000000..0b22c02
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/PropertyExpression.java
@@ -0,0 +1,133 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * Represents a property access such as the expression "foo.bar".
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class PropertyExpression extends Expression {
+
+    private Expression objectExpression;
+    private final Expression property;
+    private boolean spreadSafe = false;
+    private boolean safe = false;
+    private boolean isStatic = false;
+
+    private boolean implicitThis = false;
+
+    public boolean isStatic() {
+        return isStatic;
+    }
+
+    public PropertyExpression(Expression objectExpression, String property) {
+        this(objectExpression, new ConstantExpression(property), false);
+    }
+    
+    public PropertyExpression(Expression objectExpression, Expression property) {
+        this(objectExpression, property, false);
+    }
+
+    public PropertyExpression(Expression objectExpression, Expression property, boolean safe) {
+        this.objectExpression = objectExpression;
+        this.property = property;
+        this.safe = safe;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitPropertyExpression(this);
+    }
+
+    public boolean isDynamic() {
+        return true;
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        PropertyExpression ret = new PropertyExpression(transformer.transform(objectExpression),
+                transformer.transform(property), safe);
+        ret.setSpreadSafe(spreadSafe);
+        ret.setStatic(isStatic);
+        ret.setImplicitThis(implicitThis);
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public Expression getObjectExpression() {
+        return objectExpression;
+    }
+
+    public void setObjectExpression(Expression exp) {
+        objectExpression=exp;
+    }    
+    
+    public Expression getProperty() {
+        return property;
+    }
+    
+    public String getPropertyAsString() {
+        if (property==null) return null;
+        if (! (property instanceof ConstantExpression)) return null;
+        ConstantExpression constant = (ConstantExpression) property;
+        return constant.getText();
+    }
+
+    public String getText() {
+        String object = objectExpression.getText();
+        String text = property.getText();
+        String spread = isSpreadSafe() ? "*" : "";
+        String safe = isSafe() ? "?" : "";
+        return object + spread + safe + "." + text;
+    }
+
+    /**
+     * @return is this a safe navigation, i.e. if true then if the source object is null
+     * then this navigation will return null
+     */
+    public boolean isSafe() {
+        return safe;
+    }
+
+    public boolean isSpreadSafe() {
+        return spreadSafe;
+    }
+
+    public void setSpreadSafe(boolean value) {
+        spreadSafe = value;
+    }
+
+    public String toString() {
+        return super.toString() + "[object: " + objectExpression + " property: " + property + "]";
+    }
+
+    public void setStatic(boolean aStatic) {
+        this.isStatic = aStatic;
+    }
+    
+    public boolean isImplicitThis(){
+        return implicitThis;
+    }
+    
+    public void setImplicitThis(boolean it) {
+        implicitThis  = it;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/RangeExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/RangeExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/RangeExpression.java
new file mode 100644
index 0000000..9067725
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/RangeExpression.java
@@ -0,0 +1,70 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * Represents a range expression such as for iterating.
+ * E.g.:
+ * <pre>for i in 0..10 {...}</pre>
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class RangeExpression extends Expression {
+
+    private final Expression from;
+    private final Expression to;
+    private final boolean inclusive;
+
+    public RangeExpression(Expression from, Expression to, boolean inclusive) {
+        this.from = from;
+        this.to = to;
+        this.inclusive = inclusive;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitRangeExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new RangeExpression(transformer.transform(from), transformer.transform(to), inclusive); 
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public Expression getFrom() {
+        return from;
+    }
+
+    public Expression getTo() {
+        return to;
+    }
+
+    public boolean isInclusive() {
+        return inclusive;
+    }
+
+    public String getText() {
+        return "(" + from.getText() +
+               (!isInclusive()? "..<" : ".." ) +
+               to.getText() + ")";
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/SpreadExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/SpreadExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/SpreadExpression.java
new file mode 100644
index 0000000..43a8926
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/SpreadExpression.java
@@ -0,0 +1,58 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * Represents a spread expression *x in the list expression [1, *x, 2].
+ *
+ */
+public class SpreadExpression extends Expression {
+
+    private final Expression expression;
+
+    public SpreadExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitSpreadExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new SpreadExpression(transformer.transform(expression));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public String getText() {
+        return "*" + expression.getText();
+    }
+
+    public ClassNode getType() {
+        return expression.getType();
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/SpreadMapExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/SpreadMapExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/SpreadMapExpression.java
new file mode 100644
index 0000000..ea6318b
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/SpreadMapExpression.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 org.codehaus.groovy.ast.expr;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * Represents a spread map expression *:m
+ * in the map expression [1, *:m, 2, "c":100]
+ * or in the method invoke expression func(1, *:m, 2, "c":100).
+ *
+ */
+public class SpreadMapExpression extends Expression {
+
+    private final Expression expression;
+
+    public SpreadMapExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitSpreadMapExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new SpreadMapExpression(transformer.transform(expression));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public String getText() {
+        return "*:" + expression.getText();
+    }
+
+    public ClassNode getType() {
+        return expression.getType();
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/StaticMethodCallExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/StaticMethodCallExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/StaticMethodCallExpression.java
new file mode 100644
index 0000000..679b250
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/StaticMethodCallExpression.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 org.codehaus.groovy.ast.expr;
+
+import groovy.lang.MetaMethod;
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * A static method call on a class
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class StaticMethodCallExpression extends Expression implements MethodCall {
+
+    private ClassNode ownerType;
+    private final String method;
+    private final Expression arguments;
+    private MetaMethod metaMethod = null;
+
+    public StaticMethodCallExpression(ClassNode type, String method, Expression arguments) {
+        ownerType = type;
+        this.method = method;
+        this.arguments = arguments;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitStaticMethodCallExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new StaticMethodCallExpression(getOwnerType(), method, transformer.transform(arguments));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public ASTNode getReceiver() {
+        return ownerType;
+    }
+
+    public String getMethodAsString() {
+        return method;
+    }
+
+    public Expression getArguments() {
+        return arguments;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public String getText() {
+        return getOwnerType().getName() + "." + method + arguments.getText();
+    }
+
+    public String toString() {
+        return super.toString() + "[" + getOwnerType().getName() + "#" + method + " arguments: " + arguments + "]";
+    }
+
+    public ClassNode getOwnerType() {
+        return ownerType;
+    }
+
+    public void setOwnerType(ClassNode ownerType) {
+        this.ownerType = ownerType;
+    }
+
+    public void setMetaMethod(MetaMethod metaMethod) {
+        this.metaMethod = metaMethod;
+    }
+
+    public MetaMethod getMetaMethod() {
+        return metaMethod;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/TernaryExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/TernaryExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/TernaryExpression.java
new file mode 100644
index 0000000..a24fd63
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/TernaryExpression.java
@@ -0,0 +1,86 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * Represents a ternary expression (booleanExpression) ? expression : expression
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class TernaryExpression extends Expression {
+
+    private final BooleanExpression booleanExpression;
+    private final Expression trueExpression;
+    private final Expression falseExpression;
+
+    public TernaryExpression(
+        BooleanExpression booleanExpression,
+        Expression trueExpression,
+        Expression falseExpression) {
+        this.booleanExpression = booleanExpression;
+        this.trueExpression = trueExpression;
+        this.falseExpression = falseExpression;
+    }
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitTernaryExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new TernaryExpression(
+                (BooleanExpression) transformer.transform(booleanExpression),
+                transformer.transform(trueExpression),
+                transformer.transform(falseExpression)); 
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret; 
+    }
+
+    public String toString() {
+        return super.toString() +"[" + booleanExpression + " ? " + trueExpression + " : " + falseExpression + "]";
+    }
+    
+    public BooleanExpression getBooleanExpression() {
+        return booleanExpression;
+    }
+
+    public Expression getFalseExpression() {
+        return falseExpression;
+    }
+
+    public Expression getTrueExpression() {
+        return trueExpression;
+    }
+
+    public String getText() {
+        return "("
+            + booleanExpression.getText()
+            + ") ? "
+            + trueExpression.getText()
+            + " : "
+            + falseExpression.getText();
+    }
+
+    public ClassNode getType() {
+        return ClassHelper.OBJECT_TYPE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/TupleExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/TupleExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/TupleExpression.java
new file mode 100644
index 0000000..113706a
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/TupleExpression.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 org.codehaus.groovy.ast.expr;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Represents a tuple expression {1, 2, 3} which creates an immutable List
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class TupleExpression extends Expression implements Iterable<Expression> {
+    private final List<Expression> expressions;
+
+    public TupleExpression() {
+        this(0);
+    }
+
+    public TupleExpression(Expression expr) {
+        this(1);
+        addExpression(expr);
+    }
+
+    public TupleExpression(Expression expr1, Expression expr2) {
+        this(2);
+        addExpression(expr1);
+        addExpression(expr2);
+    }
+
+    public TupleExpression(Expression expr1, Expression expr2, Expression expr3) {
+        this(3);
+        addExpression(expr1);
+        addExpression(expr2);
+        addExpression(expr3);
+    }
+    
+    public TupleExpression(int length) {
+        this.expressions = new ArrayList<Expression>(length);
+    }
+    
+    public TupleExpression(List<Expression> expressions) {
+        this.expressions = expressions;
+    }
+    
+    public TupleExpression(Expression[] expressionArray) {
+        this();
+        expressions.addAll(Arrays.asList(expressionArray));
+    }
+
+    public TupleExpression addExpression(Expression expression) {
+        expressions.add(expression);
+        return this;
+    }
+    
+    public List<Expression> getExpressions() {
+        return expressions;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitTupleExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new TupleExpression(transformExpressions(getExpressions(), transformer)); 
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public Expression getExpression(int i) {
+        return expressions.get(i);
+    }
+
+    public String getText() {
+        StringBuilder buffer = new StringBuilder("(");
+        boolean first = true;
+        for (Expression expression : expressions) {
+            if (first) {
+                first = false;
+            }
+            else {
+                buffer.append(", ");
+            }
+            
+            buffer.append(expression.getText());
+        }
+        buffer.append(")");
+        return buffer.toString();
+    }
+
+    public String toString() {
+        return super.toString() + expressions;
+    }
+
+    public Iterator<Expression> iterator() {
+        return Collections.unmodifiableList(expressions).iterator();
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/UnaryMinusExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/UnaryMinusExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/UnaryMinusExpression.java
new file mode 100644
index 0000000..8d1315e
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/UnaryMinusExpression.java
@@ -0,0 +1,62 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * @author sam
+ */
+public class UnaryMinusExpression extends Expression {
+
+    private final Expression expression;
+
+    public UnaryMinusExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitUnaryMinusExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new UnaryMinusExpression(transformer.transform(expression));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public String getText() {
+        return expression.getText();
+    }
+
+    public ClassNode getType() {
+        return expression.getType();
+    }
+
+    public boolean isDynamic() {
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/UnaryPlusExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/UnaryPlusExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/UnaryPlusExpression.java
new file mode 100644
index 0000000..7c3f990
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/UnaryPlusExpression.java
@@ -0,0 +1,62 @@
+/*
+ *  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.ast.expr;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+/**
+ * @author Paul King
+ */
+public class UnaryPlusExpression extends Expression {
+
+    private final Expression expression;
+
+    public UnaryPlusExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitUnaryPlusExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        Expression ret = new UnaryPlusExpression(transformer.transform(expression));
+        ret.setSourcePosition(this);
+        ret.copyNodeMetaData(this);
+        return ret;
+    }
+
+    public String getText() {
+        return expression.getText();
+    }
+
+    public ClassNode getType() {
+        return expression.getType();
+    }
+
+    public boolean isDynamic() {
+        return false;
+    }
+
+}
\ No newline at end of file